aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffas <dev@jeffas.io>2019-09-11 17:37:21 +0100
committerDrew DeVault <sir@cmpwn.com>2019-09-11 12:37:43 -0400
commit618a500341d54ec5bec6d035a86b1307ff1dad0a (patch)
tree090fdff220eeb29e4bee7347a16d9e5ff7fbd0b9
parent572d9ff72883264fbffe35e998b9a6193f20137a (diff)
Add display of unread messages in dirlist
Add an onUpdateDirs handler. This is used to invalidate the dirlist and redraw with the correct number of recent/unread/total messages is shown. A config option and formatting options are provided.
-rw-r--r--config/aerc.conf.in5
-rw-r--r--config/config.go7
-rw-r--r--doc/aerc-config.5.scd16
-rw-r--r--lib/msgstore.go8
-rw-r--r--widgets/dirlist.go99
5 files changed, 131 insertions, 4 deletions
diff --git a/config/aerc.conf.in b/config/aerc.conf.in
index 4d0f9fd..c50b7b9 100644
--- a/config/aerc.conf.in
+++ b/config/aerc.conf.in
@@ -43,6 +43,11 @@ mouse-enabled=false
# Default: yes
new-message-bell=true
+# Describes the format string to use for the directory list
+#
+# Default: %n %>r
+dirlist-format=%n %>r
+
[viewer]
#
# Specifies the pager to use when displaying emails. Note that some filters
diff --git a/config/config.go b/config/config.go
index 06caec1..738fd1d 100644
--- a/config/config.go
+++ b/config/config.go
@@ -35,6 +35,7 @@ type UIConfig struct {
NewMessageBell bool `ini:"new-message-bell"`
Spinner string `ini:"spinner"`
SpinnerDelimiter string `ini:"spinner-delimiter"`
+ DirListFormat string `ini:"dirlist-format"`
}
const (
@@ -349,9 +350,9 @@ func LoadConfigFromFile(root *string, sharedir string) (*AercConfig, error) {
EmptyDirlist: "(no folders)",
MouseEnabled: false,
NewMessageBell: true,
- Spinner:
- "[..] , [..] , [..] , [..] , [..], [..] , [..] , [..] ",
- SpinnerDelimiter: ",",
+ Spinner: "[..] , [..] , [..] , [..] , [..], [..] , [..] , [..] ",
+ SpinnerDelimiter: ",",
+ DirListFormat: "%n %>r",
},
Viewer: ViewerConfig{
diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
index 9257bde..d422e5d 100644
--- a/doc/aerc-config.5.scd
+++ b/doc/aerc-config.5.scd
@@ -125,6 +125,22 @@ These options are configured in the *[ui]* section of aerc.conf.
Default: ","
+*dirlist-format*
+ Describes the format string to use for the directory list
+
+ Default: %n %>r
+
+[- *Format specifier*
+:[ *Description*
+| %%
+: literal %
+| %n
+: directory name
+| %r
+: recent/unseen/total message count
+| %>X
+: make format specifier 'X' be right justified
+
## VIEWER
These options are configured in the *[viewer]* section of aerc.conf.
diff --git a/lib/msgstore.go b/lib/msgstore.go
index bbdfa57..2733288 100644
--- a/lib/msgstore.go
+++ b/lib/msgstore.go
@@ -27,6 +27,7 @@ type MessageStore struct {
// Map of uids we've asked the worker to fetch
onUpdate func(store *MessageStore) // TODO: multiple onUpdate handlers
+ onUpdateDirs func()
pendingBodies map[uint32]interface{}
pendingHeaders map[uint32]interface{}
worker *types.Worker
@@ -234,10 +235,17 @@ func (store *MessageStore) OnUpdate(fn func(store *MessageStore)) {
store.onUpdate = fn
}
+func (store *MessageStore) OnUpdateDirs(fn func()) {
+ store.onUpdateDirs = fn
+}
+
func (store *MessageStore) update() {
if store.onUpdate != nil {
store.onUpdate(store)
}
+ if store.onUpdateDirs != nil {
+ store.onUpdateDirs()
+ }
}
func (store *MessageStore) Delete(uids []uint32,
diff --git a/widgets/dirlist.go b/widgets/dirlist.go
index ec73082..ef2dd1e 100644
--- a/widgets/dirlist.go
+++ b/widgets/dirlist.go
@@ -1,15 +1,18 @@
package widgets
import (
+ "fmt"
"log"
"regexp"
"sort"
"github.com/gdamore/tcell"
+ "github.com/mattn/go-runewidth"
"git.sr.ht/~sircmpwn/aerc/config"
"git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/lib/ui"
+ "git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
@@ -105,6 +108,92 @@ func (dirlist *DirectoryList) Invalidate() {
dirlist.DoInvalidate(dirlist)
}
+func (dirlist *DirectoryList) getDirString(name string, width int, recentUnseen func() string) string {
+ percent := false
+ rightJustify := false
+ formatted := ""
+ doRightJustify := func(s string) {
+ formatted = runewidth.FillRight(formatted, width-len(s))
+ formatted = runewidth.Truncate(formatted, width-len(s), "…")
+ }
+ for _, char := range dirlist.uiConf.DirListFormat {
+ switch char {
+ case '%':
+ if percent {
+ formatted += string(char)
+ percent = false
+ } else {
+ percent = true
+ }
+ case '>':
+ if percent {
+ rightJustify = true
+ }
+ case 'n':
+ if percent {
+ if rightJustify {
+ doRightJustify(name)
+ rightJustify = false
+ }
+ formatted += name
+ percent = false
+ }
+ case 'r':
+ if percent {
+ rString := recentUnseen()
+ if rightJustify {
+ doRightJustify(rString)
+ rightJustify = false
+ }
+ formatted += rString
+ percent = false
+ }
+ default:
+ formatted += string(char)
+ }
+ }
+ return formatted
+}
+
+func (dirlist *DirectoryList) getRUEString(name string) string {
+ totalUnseen := 0
+ totalRecent := 0
+ totalExists := 0
+ if msgStore, ok := dirlist.MsgStore(name); ok {
+ for _, msg := range msgStore.Messages {
+ if msg == nil {
+ continue
+ }
+ seen := false
+ recent := false
+ for _, flag := range msg.Flags {
+ if flag == models.SeenFlag {
+ seen = true
+ } else if flag == models.RecentFlag {
+ recent = true
+ }
+ }
+ if !seen {
+ if recent {
+ totalRecent++
+ } else {
+ totalUnseen++
+ }
+ }
+ }
+ totalExists = msgStore.DirInfo.Exists
+ }
+ rueString := ""
+ if totalRecent > 0 {
+ rueString = fmt.Sprintf("%d/%d/%d", totalRecent, totalUnseen, totalExists)
+ } else if totalUnseen > 0 {
+ rueString = fmt.Sprintf("%d/%d", totalUnseen, totalExists)
+ } else if totalExists > 0 {
+ rueString = fmt.Sprintf("%d", totalExists)
+ }
+ return rueString
+}
+
func (dirlist *DirectoryList) Draw(ctx *ui.Context) {
ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', tcell.StyleDefault)
@@ -132,7 +221,12 @@ func (dirlist *DirectoryList) Draw(ctx *ui.Context) {
style = style.Foreground(tcell.ColorGray)
}
ctx.Fill(0, row, ctx.Width(), 1, ' ', style)
- ctx.Printf(0, row, style, "%s", name)
+
+ dirString := dirlist.getDirString(name, ctx.Width(), func() string {
+ return dirlist.getRUEString(name)
+ })
+
+ ctx.Printf(0, row, style, dirString)
row++
}
}
@@ -233,4 +327,7 @@ func (dirlist *DirectoryList) MsgStore(name string) (*lib.MessageStore, bool) {
func (dirlist *DirectoryList) SetMsgStore(name string, msgStore *lib.MessageStore) {
dirlist.store.SetMessageStore(name, msgStore)
+ msgStore.OnUpdateDirs(func() {
+ dirlist.Invalidate()
+ })
}