aboutsummaryrefslogtreecommitdiffstats
path: root/worker/notmuch
diff options
context:
space:
mode:
authorJason Cox <me@jasoncarloscox.com>2024-02-17 12:34:23 -0500
committerRobin Jarry <robin@jarry.cc>2024-02-26 09:30:35 +0100
commitf3a61a341c81d70b51d91a71e1b0909acdcdb8f4 (patch)
tree58a3156dc63500fd4e0cd0034a59e86cdbb6a3cb /worker/notmuch
parentd8d5fc8d31f358c6425dfa18a9f8d2767bc6df40 (diff)
downloadaerc-f3a61a341c81d70b51d91a71e1b0909acdcdb8f4.tar.gz
commands: add :query to create named notmuch dirs
The current :cf command can be used to create folders for arbitrary notmuch queries. These folders use the query as their namee. In some cases, though, it's useful to give a more human-readable name. Create a new :query command to allow doing so. The :query command accepts an optional -n flag to specify a name. The remaining arguments are interpreted verbatim as a notmuch query. If no name is specified, the query itself is used as the name. For example, to create a new folder with the full thread of the current message, named by its subject, run the following command: :query -n "{{.SubjectBase}}" thread:"{mid:{{.MessageId}}}" :query could have been implemented as an additional flag to :cf. Giving a name to the created folder would make the smantics of :cf strange, though. For example, to create a named query folder, one would use :cf -n <name> <query>. This syntax feels odd; the name of the folder seems like it ought to be the positional argument of the change folder command. Alternatively, the usage could be :cf -q <query> <name>, but this feels wrong as well: the query, which is provided as a positional parameter when no name is specified, becomes a flag parameter when a name is specified. What's more, both of these potential usages add a notmuch-specific flag to an otherwise general command. Creating a new command feels cleaner. Perhaps the current query functionality of the :cf command could eventually be deprecated to remove the duplicate functionality and keep :cf limited to changing to existing folders. Changelog-added: Create notmuch named queries with the `:query` command. Signed-off-by: Jason Cox <me@jasoncarloscox.com> Tested-by: Inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'worker/notmuch')
-rw-r--r--worker/notmuch/eventhandlers.go7
-rw-r--r--worker/notmuch/worker.go60
2 files changed, 51 insertions, 16 deletions
diff --git a/worker/notmuch/eventhandlers.go b/worker/notmuch/eventhandlers.go
index be01a71b..76517953 100644
--- a/worker/notmuch/eventhandlers.go
+++ b/worker/notmuch/eventhandlers.go
@@ -55,6 +55,13 @@ func (w *worker) updateDirCounts() error {
}, nil)
}
+ for name, query := range w.dynamicNameQueryMap {
+ w.w.PostMessage(&types.DirectoryInfo{
+ Info: w.getDirectoryInfo(name, query),
+ Refetch: w.query == query,
+ }, nil)
+ }
+
return nil
}
diff --git a/worker/notmuch/worker.go b/worker/notmuch/worker.go
index c5792709..aa2da391 100644
--- a/worker/notmuch/worker.go
+++ b/worker/notmuch/worker.go
@@ -27,6 +27,7 @@ import (
"git.sr.ht/~rjarry/aerc/worker/lib"
notmuch "git.sr.ht/~rjarry/aerc/worker/notmuch/lib"
"git.sr.ht/~rjarry/aerc/worker/types"
+ "github.com/emersion/go-maildir"
)
func init() {
@@ -42,6 +43,7 @@ type worker struct {
currentQueryName string
queryMapOrder []string
nameQueryMap map[string]string
+ dynamicNameQueryMap map[string]string
store *lib.MaildirStore
maildirAccountPath string
db *notmuch.DB
@@ -70,6 +72,7 @@ func NewWorker(w *types.Worker) (types.Backend, error) {
Sort: true,
Thread: true,
},
+ dynamicNameQueryMap: make(map[string]string),
}, nil
}
@@ -284,6 +287,17 @@ func (w *worker) handleListDirectories(msg *types.ListDirectories) error {
},
}, nil)
}
+
+ for name := range w.dynamicNameQueryMap {
+ w.w.PostMessage(&types.Directory{
+ Message: types.RespondTo(msg),
+ Dir: &models.Directory{
+ Name: name,
+ Role: models.QueryRole,
+ },
+ }, nil)
+ }
+
// Update dir counts when listing directories
err := w.updateDirCounts()
if err != nil {
@@ -318,14 +332,15 @@ func (w *worker) handleOpenDirectory(msg *types.OpenDirectory) error {
if msg.Context.Err() != nil {
return context.Canceled
}
- w.w.Tracef("opening %s", msg.Directory)
+ w.w.Tracef("opening %s with query %s", msg.Directory, msg.Query)
- var isDynamicFolder bool
+ var exists bool
q := ""
if w.store != nil {
folders, _ := w.store.FolderMap()
- dir, ok := folders[msg.Directory]
- if ok {
+ var dir maildir.Dir
+ dir, exists = folders[msg.Directory]
+ if exists {
folder := filepath.Join(w.maildirAccountPath, msg.Directory)
q = fmt.Sprintf("folder:%s", strconv.Quote(folder))
if err := w.processNewMaildirFiles(string(dir)); err != nil {
@@ -334,19 +349,26 @@ func (w *worker) handleOpenDirectory(msg *types.OpenDirectory) error {
}
}
if q == "" {
- var ok bool
- q, ok = w.nameQueryMap[msg.Directory]
- if !ok {
+ q, exists = w.nameQueryMap[msg.Directory]
+ if !exists {
+ q, exists = w.dynamicNameQueryMap[msg.Directory]
+ }
+ }
+ if !exists {
+ q = msg.Query
+ if q == "" {
q = msg.Directory
- isDynamicFolder = true
- w.w.PostMessage(&types.Directory{
- Message: types.RespondTo(msg),
- Dir: &models.Directory{
- Name: q,
- Role: models.QueryRole,
- },
- }, nil)
}
+ w.dynamicNameQueryMap[msg.Directory] = q
+ w.w.PostMessage(&types.Directory{
+ Message: types.RespondTo(msg),
+ Dir: &models.Directory{
+ Name: msg.Directory,
+ Role: models.QueryRole,
+ },
+ }, nil)
+ } else if msg.Query != "" && msg.Query != q {
+ return errors.New("cannot use existing folder name for new query")
}
w.query = q
w.currentQueryName = msg.Directory
@@ -355,7 +377,7 @@ func (w *worker) handleOpenDirectory(msg *types.OpenDirectory) error {
Info: w.getDirectoryInfo(msg.Directory, w.query),
Message: types.RespondTo(msg),
}, nil)
- if isDynamicFolder {
+ if !exists {
w.w.PostMessage(&types.DirectoryInfo{
Info: w.getDirectoryInfo(msg.Directory, w.query),
Message: types.RespondTo(msg),
@@ -921,6 +943,12 @@ func (w *worker) handleRemoveDirectory(msg *types.RemoveDirectory) error {
return errUnsupported
}
+ if _, ok := w.dynamicNameQueryMap[msg.Directory]; ok {
+ delete(w.dynamicNameQueryMap, msg.Directory)
+ w.done(msg)
+ return nil
+ }
+
if w.store == nil {
w.done(msg)
return nil