diff options
author | Aivars Vaivods <aivars@vaivods.lv> | 2023-02-01 16:13:54 +0100 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-02-20 14:48:42 +0100 |
commit | 420a82a356d53e4b600ba54768f7ed21a43cf85e (patch) | |
tree | 86b7ddc08cc0663b167cb678b264995c9e4239de | |
parent | 70f99085d73b3bfc9b3338c52e6df7bebc7651c7 (diff) | |
download | aerc-420a82a356d53e4b600ba54768f7ed21a43cf85e.tar.gz |
commands: expand template placeholders
Interpret go template constructs in all aerc command arguments based on
the currently selected account, folder and message (if any).
Signed-off-by: Aivars Vaivods <aivars@vaivods.lv>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Tim Culverhouse <tim@timculverhouse.com>
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | commands/commands.go | 46 | ||||
-rw-r--r-- | doc/aerc.1.scd | 9 | ||||
-rw-r--r-- | lib/state/templates.go | 9 |
4 files changed, 61 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ccd714bd..67d0d264 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). the `[viewer]` section. - The standard Usenet signature delimiter `"-- "` is now prepended to `signature-file` and `signature-cmd` if not already present. +- All `aerc(1)` commands now interpret `aerc-templates(7)` markup. ### Deprecated diff --git a/commands/commands.go b/commands/commands.go index 6fe30592..bbd03237 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -1,6 +1,7 @@ package commands import ( + "bytes" "errors" "sort" "strings" @@ -8,7 +9,11 @@ import ( "github.com/google/shlex" + "git.sr.ht/~rjarry/aerc/config" + "git.sr.ht/~rjarry/aerc/lib/state" + "git.sr.ht/~rjarry/aerc/lib/templates" "git.sr.ht/~rjarry/aerc/log" + "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/widgets" ) @@ -65,13 +70,52 @@ type CommandSource interface { Commands() *Commands } +func templateData(aerc *widgets.Aerc) models.TemplateData { + var folder string + var cfg *config.AccountConfig + var msg *models.MessageInfo + + acct := aerc.SelectedAccount() + if acct != nil { + folder = acct.SelectedDirectory() + cfg = acct.AccountConfig() + msg, _ = acct.SelectedMessage() + } + + var data state.TemplateData + + data.SetAccount(cfg) + data.SetFolder(folder) + data.SetInfo(msg, 0, false) + + return &data +} + func (cmds *Commands) ExecuteCommand(aerc *widgets.Aerc, args []string) error { if len(args) == 0 { return errors.New("Expected a command.") } if cmd, ok := cmds.dict()[args[0]]; ok { log.Tracef("executing command %v", args) - return cmd.Execute(aerc, args) + var buf bytes.Buffer + data := templateData(aerc) + + processedArgs := make([]string, len(args)) + for i, arg := range args { + t, err := templates.ParseTemplate(arg, arg) + if err != nil { + return err + } + err = templates.Render(t, &buf, data) + if err != nil { + return err + } + arg = buf.String() + buf.Reset() + processedArgs[i] = arg + } + + return cmd.Execute(aerc, processedArgs) } return NoSuchCommand(args[0]) } diff --git a/doc/aerc.1.scd b/doc/aerc.1.scd index aac014c9..d4376be7 100644 --- a/doc/aerc.1.scd +++ b/doc/aerc.1.scd @@ -54,6 +54,15 @@ as the terminal emulator, *<c-x>* is used to bring up the command interface. Different commands work in different contexts, depending on the kind of tab you have selected. +Dynamic arguments are expanded following *aerc-templates*(7) depending on the +context. For example, if you have a message selected, the following command: + +``` +:filter -f "{{index (.From | emails) 0}}" +``` + +Will filter all messages sent by the same sender. + Aerc stores a history of commands, which can be cycled through in command mode. Pressing the up key cycles backwards in history, while pressing down cycles forwards. diff --git a/lib/state/templates.go b/lib/state/templates.go index b199cf25..48106295 100644 --- a/lib/state/templates.go +++ b/lib/state/templates.go @@ -47,9 +47,12 @@ func (d *TemplateData) SetInfo(info *models.MessageInfo, num int, marked bool) { func (d *TemplateData) SetAccount(acct *config.AccountConfig) { d.account = acct - d.myAddresses = map[string]bool{acct.From.Address: true} - for _, addr := range acct.Aliases { - d.myAddresses[addr.Address] = true + d.myAddresses = make(map[string]bool) + if acct != nil { + d.myAddresses[acct.From.Address] = true + for _, addr := range acct.Aliases { + d.myAddresses[addr.Address] = true + } } } |