From 402612fd9788f071a5d7ae0045989977b98d896f Mon Sep 17 00:00:00 2001 From: Kalyan Sriram Date: Sat, 13 Nov 2021 08:10:09 +0000 Subject: [PATCH] notmuch: allow sort by file order When using the notmuch backend, it often makes more sense to sort folders (actual virtual folders, or queries) by the order specified in the query-map file, rather than alphabetically. This patch introduces a configuration option (disabled by default) that allows this. Additionally, due to the notmuch backend previously using maps (which are order-undefined) to store the list of queries, default query selection on aerc startup fluctuated. This patch fixes that by using slices to store query order. --- config/config.go | 49 ++++++++++++++++++++++------------------ doc/aerc-config.5.scd | 6 +++++ widgets/dirlist.go | 8 ++++++- worker/notmuch/worker.go | 4 +++- 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/config/config.go b/config/config.go index 3fc38e3..9be55c6 100644 --- a/config/config.go +++ b/config/config.go @@ -10,6 +10,7 @@ import ( "path" "regexp" "sort" + "strconv" "strings" "time" "unicode" @@ -74,23 +75,24 @@ const ( ) type AccountConfig struct { - Archive string - CopyTo string - Default string - Postpone string - From string - Aliases string - Name string - Source string - SourceCredCmd string - Folders []string - FoldersExclude []string - Params map[string]string - Outgoing string - OutgoingCredCmd string - SignatureFile string - SignatureCmd string - FoldersSort []string `ini:"folders-sort" delim:","` + Archive string + CopyTo string + Default string + Postpone string + From string + Aliases string + Name string + Source string + SourceCredCmd string + Folders []string + FoldersExclude []string + Params map[string]string + Outgoing string + OutgoingCredCmd string + SignatureFile string + SignatureCmd string + EnableFoldersSort bool `ini:"enable-folders-sort"` + FoldersSort []string `ini:"folders-sort" delim:","` } type BindingConfig struct { @@ -181,11 +183,12 @@ func loadAccountConfig(path string) ([]AccountConfig, error) { } sec := file.Section(_sec) account := AccountConfig{ - Archive: "Archive", - Default: "INBOX", - Postpone: "Drafts", - Name: _sec, - Params: make(map[string]string), + Archive: "Archive", + Default: "INBOX", + Postpone: "Drafts", + Name: _sec, + Params: make(map[string]string), + EnableFoldersSort: true, } if err = sec.MapTo(&account); err != nil { return nil, err @@ -213,6 +216,8 @@ func loadAccountConfig(path string) ([]AccountConfig, error) { account.CopyTo = val } else if key == "archive" { account.Archive = val + } else if key == "enable-folders-sort" { + account.EnableFoldersSort, _ = strconv.ParseBool(val) } else if key != "name" { account.Params[key] = val } diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd index fbfa64e..c647459 100644 --- a/doc/aerc-config.5.scd +++ b/doc/aerc-config.5.scd @@ -427,6 +427,12 @@ Note that many of these configuration options are written for you, such as Default: no folders +*enable-folders-sort* + If true, folders are sorted, first by specified folders (see *folders-sort*), + then alphabetically. + + Default: true + *folders-sort* Specifies a comma separated list of folders to be shown at the top of the list in the provided order. Remaining folders will be sorted alphabetically. diff --git a/widgets/dirlist.go b/widgets/dirlist.go index 4db80a4..0345380 100644 --- a/widgets/dirlist.go +++ b/widgets/dirlist.go @@ -105,7 +105,9 @@ func (dirlist *DirectoryList) Select(name string) { if !hasSelected && dirlist.selected != "" { dirlist.dirs = append(dirlist.dirs, dirlist.selected) } - sort.Strings(dirlist.dirs) + if dirlist.acctConf.EnableFoldersSort { + sort.Strings(dirlist.dirs) + } dirlist.sortDirsByFoldersSortConfig() } dirlist.Invalidate() @@ -376,6 +378,10 @@ func folderMatches(folder string, pattern string) bool { // AccountConfig.FoldersSort option. Folders not included in the option // will be appended at the end in alphabetical order func (dirlist *DirectoryList) sortDirsByFoldersSortConfig() { + if !dirlist.acctConf.EnableFoldersSort { + return + } + sort.Slice(dirlist.dirs, func(i, j int) bool { foldersSort := dirlist.acctConf.FoldersSort iInFoldersSort := findString(foldersSort, dirlist.dirs[i]) diff --git a/worker/notmuch/worker.go b/worker/notmuch/worker.go index 6300329..09b5d50 100644 --- a/worker/notmuch/worker.go +++ b/worker/notmuch/worker.go @@ -35,6 +35,7 @@ type worker struct { query string currentQueryName string uidStore *uidstore.Store + queryMapOrder []string nameQueryMap map[string]string db *notmuch.DB setupErr error @@ -185,7 +186,7 @@ func (w *worker) handleConnect(msg *types.Connect) error { } func (w *worker) handleListDirectories(msg *types.ListDirectories) error { - for name := range w.nameQueryMap { + for _, name := range w.queryMapOrder { w.w.PostMessage(&types.Directory{ Message: types.RespondTo(msg), Dir: &models.Directory{ @@ -508,6 +509,7 @@ func (w *worker) loadQueryMap(acctConfig *config.AccountConfig) error { return fmt.Errorf("%v: invalid line %q, want name=query", file, line) } w.nameQueryMap[split[0]] = split[1] + w.queryMapOrder = append(w.queryMapOrder, split[0]) } return nil }