From f3a61a341c81d70b51d91a71e1b0909acdcdb8f4 Mon Sep 17 00:00:00 2001 From: Jason Cox Date: Sat, 17 Feb 2024 12:34:23 -0500 Subject: 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 . 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 , 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 Tested-by: Inwit Acked-by: Robin Jarry --- commands/account/cf.go | 44 +++++++++++++++++-------------- commands/account/mkdir.go | 2 +- commands/account/query.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++ commands/account/rmdir.go | 4 +-- 4 files changed, 94 insertions(+), 23 deletions(-) create mode 100644 commands/account/query.go (limited to 'commands/account') diff --git a/commands/account/cf.go b/commands/account/cf.go index 2f32e8bc..0f818006 100644 --- a/commands/account/cf.go +++ b/commands/account/cf.go @@ -103,35 +103,39 @@ func (c ChangeFolder) Execute([]string) error { } finalize := func(msg types.WorkerMessage) { - // As we're waiting for the worker to report status we must run - // the rest of the actions in this callback. - switch msg := msg.(type) { - case *types.Error: - app.PushError(msg.Error.Error()) - case *types.Done: - curAccount := app.SelectedAccount() - previous := curAccount.Directories().Selected() - history[curAccount.Name()] = previous - // reset store filtering if we switched folders - store := acct.Store() - if store != nil { - store.ApplyClear() - acct.SetStatus(state.SearchFilterClear()) - } - // focus account tab - acct.Select() - } + handleDirOpenResponse(acct, msg) } if target == "-" { if dir, ok := history[acct.Name()]; ok { - acct.Directories().Open(dir, 0*time.Second, finalize) + acct.Directories().Open(dir, "", 0*time.Second, finalize) } else { return errors.New("No previous folder to return to") } } else { - acct.Directories().Open(target, 0*time.Second, finalize) + acct.Directories().Open(target, "", 0*time.Second, finalize) } return nil } + +func handleDirOpenResponse(acct *app.AccountView, msg types.WorkerMessage) { + // As we're waiting for the worker to report status we must run + // the rest of the actions in this callback. + switch msg := msg.(type) { + case *types.Error: + app.PushError(msg.Error.Error()) + case *types.Done: + curAccount := app.SelectedAccount() + previous := curAccount.Directories().Selected() + history[curAccount.Name()] = previous + // reset store filtering if we switched folders + store := acct.Store() + if store != nil { + store.ApplyClear() + acct.SetStatus(state.SearchFilterClear()) + } + // focus account tab + acct.Select() + } +} diff --git a/commands/account/mkdir.go b/commands/account/mkdir.go index c08c6d4b..9776e8f7 100644 --- a/commands/account/mkdir.go +++ b/commands/account/mkdir.go @@ -53,7 +53,7 @@ func (m MakeDir) Execute(args []string) error { case *types.Done: app.PushStatus("Directory created.", 10*time.Second) history[acct.Name()] = previous - acct.Directories().Open(m.Folder, 0, nil) + acct.Directories().Open(m.Folder, "", 0, nil) case *types.Error: app.PushError(msg.Error.Error()) } diff --git a/commands/account/query.go b/commands/account/query.go new file mode 100644 index 00000000..f116d405 --- /dev/null +++ b/commands/account/query.go @@ -0,0 +1,67 @@ +package account + +import ( + "errors" + "reflect" + "time" + + "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" + "git.sr.ht/~rjarry/aerc/worker/handlers" + "git.sr.ht/~rjarry/aerc/worker/types" +) + +type Query struct { + Account string `opt:"-a" complete:"CompleteAccount"` + Name string `opt:"-n"` + Query string `opt:"..."` +} + +func init() { + commands.Register(Query{}) +} + +func (Query) Context() commands.CommandContext { + return commands.ACCOUNT +} + +func (Query) Aliases() []string { + return []string{"query"} +} + +func (Query) CompleteAccount(arg string) []string { + return commands.FilterList(app.AccountNames(), arg, commands.QuoteSpace) +} + +func (q Query) Execute([]string) error { + var acct *app.AccountView + + if q.Account == "" { + acct = app.SelectedAccount() + if acct == nil { + return errors.New("No account selected") + } + } else { + var err error + acct, err = app.Account(q.Account) + if err != nil { + return err + } + } + + notmuch, _ := handlers.GetHandlerForScheme("notmuch", new(types.Worker)) + if reflect.TypeOf(notmuch) != reflect.TypeOf(acct.Worker().Backend) { + return errors.New(":query is only available for notmuch accounts") + } + + finalize := func(msg types.WorkerMessage) { + handleDirOpenResponse(acct, msg) + } + + name := q.Name + if name == "" { + name = q.Query + } + acct.Directories().Open(name, q.Query, 0*time.Second, finalize) + return nil +} diff --git a/commands/account/rmdir.go b/commands/account/rmdir.go index 00366bd0..48ea3581 100644 --- a/commands/account/rmdir.go +++ b/commands/account/rmdir.go @@ -89,9 +89,9 @@ func (r RemoveDir) Execute(args []string) error { return errors.New("No directory to move to afterwards!") } - reopenCurrentDir := func() { acct.Directories().Open(curDir, 0, nil) } + reopenCurrentDir := func() { acct.Directories().Open(curDir, "", 0, nil) } - acct.Directories().Open(newDir, 0, func(msg types.WorkerMessage) { + acct.Directories().Open(newDir, "", 0, func(msg types.WorkerMessage) { switch msg.(type) { case *types.Done: break -- cgit