diff options
-rw-r--r-- | config/aerc.conf | 6 | ||||
-rw-r--r-- | config/ui.go | 14 | ||||
-rw-r--r-- | doc/aerc-config.5.scd | 9 | ||||
-rw-r--r-- | doc/aerc-templates.7.scd | 5 | ||||
-rw-r--r-- | lib/ui/tab.go | 8 | ||||
-rw-r--r-- | widgets/account.go | 29 | ||||
-rw-r--r-- | widgets/aerc.go | 2 | ||||
-rw-r--r-- | widgets/dirlist.go | 14 |
8 files changed, 86 insertions, 1 deletions
diff --git a/config/aerc.conf b/config/aerc.conf index 5f58ceb2..43d17727 100644 --- a/config/aerc.conf +++ b/config/aerc.conf @@ -125,6 +125,12 @@ # Default: true #new-message-bell=true +# +# Template to use for Account tab titles +# +# Default: {{.Account}} +#tab-title-account={{.Account}} + # Marker to show before a pinned tab's name. # # Default: ` diff --git a/config/ui.go b/config/ui.go index 5f51140c..1b4c35fb 100644 --- a/config/ui.go +++ b/config/ui.go @@ -6,6 +6,7 @@ import ( "regexp" "strconv" "strings" + "text/template" "time" "git.sr.ht/~rjarry/aerc/lib/templates" @@ -72,6 +73,9 @@ type UIConfig struct { ReverseThreadOrder bool `ini:"reverse-thread-order"` SortThreadSiblings bool `ini:"sort-thread-siblings"` + // Tab Templates + TabTitleAccount *template.Template `ini:"-"` + // private contextualUis []*UiConfigContext contextualCounts map[uiContextType]int @@ -102,6 +106,7 @@ func defaultUiConfig() *UIConfig { name, _ := templates.ParseTemplate("column-name", "{{index (.From | names) 0}}") flags, _ := templates.ParseTemplate("column-flags", `{{.Flags | join ""}}`) subject, _ := templates.ParseTemplate("column-subject", "{{.Subject}}") + tabTitleAccount, _ := templates.ParseTemplate("tab-title-account", "{{.Account}}") return &UIConfig{ IndexFormat: "", // deprecated IndexColumns: []*ColumnDef{ @@ -144,6 +149,7 @@ func defaultUiConfig() *UIConfig { MouseEnabled: false, ClientThreadsDelay: 50 * time.Millisecond, NewMessageBell: true, + TabTitleAccount: tabTitleAccount, FuzzyComplete: false, Spinner: "[..] , [..] , [..] , [..] , [..], [..] , [..] , [..] ", SpinnerDelimiter: ",", @@ -336,6 +342,14 @@ func (config *UIConfig) parse(section *ini.Section) error { } config.IndexColumns = columns } + if key, err := section.GetKey("tab-title-account"); err == nil { + val := key.Value() + tmpl, err := templates.ParseTemplate("tab-title-account", val) + if err != nil { + return err + } + config.TabTitleAccount = tmpl + } return nil } diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd index 74481b10..4939cf3d 100644 --- a/doc/aerc-config.5.scd +++ b/doc/aerc-config.5.scd @@ -163,6 +163,15 @@ These options are configured in the *[ui]* section of _aerc.conf_. Default: _true_ +*tab-title-account* = _<go_template>_ + The template to use for account tab titles. See *aerc-templates*(7) for + available field names. To conditionally show the unread count next to + the account name, set to: + + *tab-title-account* = {{.Account}} {{if .Unread}}({{.Unread}}){{end}} + + Default: _{{.Account}}_ + *pinned-tab-marker* = _"<string>"_ Marker to show before a pinned tab's name. diff --git a/doc/aerc-templates.7.scd b/doc/aerc-templates.7.scd index 8e616188..87713429 100644 --- a/doc/aerc-templates.7.scd +++ b/doc/aerc-templates.7.scd @@ -148,6 +148,11 @@ available always. {{.Folder}} ``` + Current message counts + ``` + {{.Recent}} {{.Unread}} {{.Exists}} + ``` + # TEMPLATE FUNCTIONS Besides the standard functions described in go's text/template documentation, diff --git a/lib/ui/tab.go b/lib/ui/tab.go index d4841efc..d336d646 100644 --- a/lib/ui/tab.go +++ b/lib/ui/tab.go @@ -30,6 +30,11 @@ type Tab struct { pinned bool indexBeforePin int uiConf *config.UIConfig + title string +} + +func (t *Tab) SetTitle(s string) { + t.title = s } type ( @@ -351,6 +356,9 @@ func (strip *TabStrip) Draw(ctx *Context) { tabWidth = ctx.Width() - x - 2 } name := tab.Name + if tab.title != "" { + name = tab.title + } if tab.pinned { name = uiConfig.PinnedTabMarker + name } diff --git a/widgets/account.go b/widgets/account.go index c2b8b8e9..6c9ab3eb 100644 --- a/widgets/account.go +++ b/widgets/account.go @@ -1,6 +1,7 @@ package widgets import ( + "bytes" "errors" "fmt" "sync" @@ -30,6 +31,7 @@ type AccountView struct { labels []string grid *ui.Grid host TabHost + tab *ui.Tab msglist *MessageList worker *types.Worker state *statusline.State @@ -351,6 +353,7 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) { acct.PushError(msg.Error) } acct.UpdateStatus() + acct.setTitle() } func (acct *AccountView) updateDirCounts(destination string, uids []uint32) { @@ -588,3 +591,29 @@ func (acct *AccountView) Vsplit(n int) error { acct.updateSplitView(acct.msglist.Selected()) return nil } + +// setTitle executes the title template and sets the tab title +func (acct *AccountView) setTitle() { + data := struct { + Account string + Recent int + Unread int + Exists int + Folder string + }{} + data.Account = acct.Name() + data.Folder = acct.SelectedDirectory() + for _, name := range acct.dirlist.List() { + r, u, e := acct.dirlist.GetRUECount(name) + data.Recent += r + data.Unread += u + data.Exists += e + } + buf := bytes.NewBuffer(nil) + err := acct.uiConf.TabTitleAccount.Execute(buf, data) + if err != nil { + acct.PushError(err) + return + } + acct.tab.SetTitle(buf.String()) +} diff --git a/widgets/aerc.go b/widgets/aerc.go index 59944cc6..f1e512f3 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -94,7 +94,7 @@ func NewAerc( tabs.Add(errorScreen(err.Error()), acct.Name, nil) } else { aerc.accounts[acct.Name] = view - tabs.Add(view, acct.Name, view.UiConfig()) + view.tab = tabs.Add(view, acct.Name, view.UiConfig()) } } diff --git a/widgets/dirlist.go b/widgets/dirlist.go index 09a1155a..8e6fa751 100644 --- a/widgets/dirlist.go +++ b/widgets/dirlist.go @@ -42,6 +42,7 @@ type DirectoryLister interface { SetMsgStore(string, *lib.MessageStore) FilterDirs([]string, []string, bool) []string + GetRUECount(string) (int, int, int) UiConfig(string) *config.UIConfig } @@ -254,6 +255,19 @@ func (dirlist *DirectoryList) getRUEString(name string) string { return rueString } +// Returns the Recent, Unread, and Exist counts for the named directory +func (dirlist *DirectoryList) GetRUECount(name string) (int, int, int) { + msgStore, ok := dirlist.MsgStore(name) + if !ok { + return 0, 0, 0 + } + if !msgStore.DirInfo.AccurateCounts { + msgStore.DirInfo.Recent, msgStore.DirInfo.Unseen = countRUE(msgStore) + } + di := msgStore.DirInfo + return di.Recent, di.Unseen, di.Exists +} + func (dirlist *DirectoryList) Draw(ctx *ui.Context) { ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', dirlist.UiConfig("").GetStyle(config.STYLE_DIRLIST_DEFAULT)) |