diff options
96 files changed, 665 insertions, 435 deletions
diff --git a/commands/account/account.go b/commands/account/account.go deleted file mode 100644 index fc17fa2d..00000000 --- a/commands/account/account.go +++ /dev/null @@ -1,14 +0,0 @@ -package account - -import ( - "git.sr.ht/~rjarry/aerc/commands" -) - -var AccountCommands *commands.Commands - -func register(cmd commands.Command) { - if AccountCommands == nil { - AccountCommands = commands.NewCommands() - } - AccountCommands.Register(cmd) -} diff --git a/commands/account/cf.go b/commands/account/cf.go index 579ddd72..2f32e8bc 100644 --- a/commands/account/cf.go +++ b/commands/account/cf.go @@ -23,7 +23,11 @@ type ChangeFolder struct { func init() { history = make(map[string]string) - register(ChangeFolder{}) + commands.Register(ChangeFolder{}) +} + +func (ChangeFolder) Context() commands.CommandContext { + return commands.ACCOUNT } func (ChangeFolder) Aliases() []string { diff --git a/commands/account/check-mail.go b/commands/account/check-mail.go index d31b2648..bc41a935 100644 --- a/commands/account/check-mail.go +++ b/commands/account/check-mail.go @@ -4,12 +4,17 @@ import ( "errors" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type CheckMail struct{} func init() { - register(CheckMail{}) + commands.Register(CheckMail{}) +} + +func (CheckMail) Context() commands.CommandContext { + return commands.ACCOUNT } func (CheckMail) Aliases() []string { diff --git a/commands/account/clear.go b/commands/account/clear.go index dec6bcd2..46335431 100644 --- a/commands/account/clear.go +++ b/commands/account/clear.go @@ -4,6 +4,7 @@ import ( "errors" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib/state" ) @@ -12,7 +13,11 @@ type Clear struct { } func init() { - register(Clear{}) + commands.Register(Clear{}) +} + +func (Clear) Context() commands.CommandContext { + return commands.ACCOUNT } func (Clear) Aliases() []string { diff --git a/commands/account/compose.go b/commands/account/compose.go index fe86a179..e45f77c3 100644 --- a/commands/account/compose.go +++ b/commands/account/compose.go @@ -24,7 +24,11 @@ type Compose struct { } func init() { - register(Compose{}) + commands.Register(Compose{}) +} + +func (Compose) Context() commands.CommandContext { + return commands.ACCOUNT } func (c *Compose) ParseHeader(arg string) error { diff --git a/commands/account/connection.go b/commands/account/connection.go index d633c1ce..75171cf4 100644 --- a/commands/account/connection.go +++ b/commands/account/connection.go @@ -4,6 +4,7 @@ import ( "errors" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib/state" "git.sr.ht/~rjarry/aerc/worker/types" ) @@ -11,7 +12,11 @@ import ( type Connection struct{} func init() { - register(Connection{}) + commands.Register(Connection{}) +} + +func (Connection) Context() commands.CommandContext { + return commands.ACCOUNT } func (Connection) Aliases() []string { diff --git a/commands/account/expand-folder.go b/commands/account/expand-folder.go index c264872a..5bb686e0 100644 --- a/commands/account/expand-folder.go +++ b/commands/account/expand-folder.go @@ -4,12 +4,17 @@ import ( "errors" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type ExpandCollapseFolder struct{} func init() { - register(ExpandCollapseFolder{}) + commands.Register(ExpandCollapseFolder{}) +} + +func (ExpandCollapseFolder) Context() commands.CommandContext { + return commands.ACCOUNT } func (ExpandCollapseFolder) Aliases() []string { diff --git a/commands/account/export-mbox.go b/commands/account/export-mbox.go index 6a36d375..53f22d87 100644 --- a/commands/account/export-mbox.go +++ b/commands/account/export-mbox.go @@ -22,7 +22,11 @@ type ExportMbox struct { } func init() { - register(ExportMbox{}) + commands.Register(ExportMbox{}) +} + +func (ExportMbox) Context() commands.CommandContext { + return commands.ACCOUNT } func (ExportMbox) Aliases() []string { diff --git a/commands/account/import-mbox.go b/commands/account/import-mbox.go index c38aeb8f..2d9c81f9 100644 --- a/commands/account/import-mbox.go +++ b/commands/account/import-mbox.go @@ -23,7 +23,11 @@ type ImportMbox struct { } func init() { - register(ImportMbox{}) + commands.Register(ImportMbox{}) +} + +func (ImportMbox) Context() commands.CommandContext { + return commands.ACCOUNT } func (ImportMbox) Aliases() []string { diff --git a/commands/account/mkdir.go b/commands/account/mkdir.go index 7e49ad8b..c08c6d4b 100644 --- a/commands/account/mkdir.go +++ b/commands/account/mkdir.go @@ -15,7 +15,11 @@ type MakeDir struct { } func init() { - register(MakeDir{}) + commands.Register(MakeDir{}) +} + +func (MakeDir) Context() commands.CommandContext { + return commands.ACCOUNT } func (MakeDir) Aliases() []string { diff --git a/commands/account/next-folder.go b/commands/account/next-folder.go index f44abdc1..c16a7717 100644 --- a/commands/account/next-folder.go +++ b/commands/account/next-folder.go @@ -4,6 +4,7 @@ import ( "errors" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type NextPrevFolder struct { @@ -11,7 +12,11 @@ type NextPrevFolder struct { } func init() { - register(NextPrevFolder{}) + commands.Register(NextPrevFolder{}) +} + +func (NextPrevFolder) Context() commands.CommandContext { + return commands.ACCOUNT } func (NextPrevFolder) Aliases() []string { diff --git a/commands/account/next-result.go b/commands/account/next-result.go index d624e559..f36ba941 100644 --- a/commands/account/next-result.go +++ b/commands/account/next-result.go @@ -4,13 +4,18 @@ import ( "errors" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib/ui" ) type NextPrevResult struct{} func init() { - register(NextPrevResult{}) + commands.Register(NextPrevResult{}) +} + +func (NextPrevResult) Context() commands.CommandContext { + return commands.ACCOUNT } func (NextPrevResult) Aliases() []string { diff --git a/commands/account/next.go b/commands/account/next.go index 142f6151..262e308d 100644 --- a/commands/account/next.go +++ b/commands/account/next.go @@ -2,11 +2,16 @@ package account import ( "errors" + "fmt" "strconv" "strings" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" + "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/ui" + "git.sr.ht/~rjarry/aerc/models" + "git.sr.ht/~rjarry/aerc/worker/types" ) type NextPrevMsg struct { @@ -15,7 +20,11 @@ type NextPrevMsg struct { } func init() { - register(NextPrevMsg{}) + commands.Register(NextPrevMsg{}) +} + +func (NextPrevMsg) Context() commands.CommandContext { + return commands.ACCOUNT | commands.MESSAGE_VIEWER } func (np *NextPrevMsg) ParseAmount(arg string) error { @@ -40,23 +49,48 @@ func (np NextPrevMsg) Execute(args []string) error { if acct == nil { return errors.New("No account selected") } + store := acct.Store() + if store == nil { + return fmt.Errorf("No message store set.") + } n := np.Amount if np.Percent { n = int(float64(acct.Messages().Height()) * (float64(n) / 100.0)) } if args[0] == "prev-message" || args[0] == "prev" { - store := acct.Store() - if store != nil { - store.NextPrev(-n) - ui.Invalidate() - } + store.NextPrev(-n) } else { - store := acct.Store() - if store != nil { - store.NextPrev(n) - ui.Invalidate() + store.NextPrev(n) + } + + if mv, ok := app.SelectedTabContent().(*app.MessageViewer); ok { + reloadViewer := func(nextMsg *models.MessageInfo) { + lib.NewMessageStoreView(nextMsg, mv.MessageView().SeenFlagSet(), + store, app.CryptoProvider(), app.DecryptKeys, + func(view lib.MessageView, err error) { + if err != nil { + app.PushError(err.Error()) + return + } + nextMv := app.NewMessageViewer(acct, view) + app.ReplaceTab(mv, nextMv, + nextMsg.Envelope.Subject, true) + }) + } + if nextMsg := store.Selected(); nextMsg != nil { + reloadViewer(nextMsg) + } else { + store.FetchHeaders([]uint32{store.SelectedUid()}, + func(msg types.WorkerMessage) { + if m, ok := msg.(*types.MessageInfo); ok { + reloadViewer(m.Info) + } + }) } } + + ui.Invalidate() + return nil } diff --git a/commands/account/recover.go b/commands/account/recover.go index a2170edd..f38d9920 100644 --- a/commands/account/recover.go +++ b/commands/account/recover.go @@ -20,7 +20,11 @@ type Recover struct { } func init() { - register(Recover{}) + commands.Register(Recover{}) +} + +func (Recover) Context() commands.CommandContext { + return commands.ACCOUNT } func (Recover) Aliases() []string { diff --git a/commands/account/rmdir.go b/commands/account/rmdir.go index 8bf4d6b2..00366bd0 100644 --- a/commands/account/rmdir.go +++ b/commands/account/rmdir.go @@ -5,6 +5,7 @@ import ( "time" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/worker/types" ) @@ -14,7 +15,11 @@ type RemoveDir struct { } func init() { - register(RemoveDir{}) + commands.Register(RemoveDir{}) +} + +func (RemoveDir) Context() commands.CommandContext { + return commands.ACCOUNT } func (RemoveDir) Aliases() []string { diff --git a/commands/account/search.go b/commands/account/search.go index 10481e8e..be3b125f 100644 --- a/commands/account/search.go +++ b/commands/account/search.go @@ -34,7 +34,11 @@ type SearchFilter struct { } func init() { - register(SearchFilter{}) + commands.Register(SearchFilter{}) +} + +func (SearchFilter) Context() commands.CommandContext { + return commands.ACCOUNT } func (SearchFilter) Aliases() []string { diff --git a/commands/account/select.go b/commands/account/select.go index 884b4bce..cbaaf6e9 100644 --- a/commands/account/select.go +++ b/commands/account/select.go @@ -4,6 +4,7 @@ import ( "errors" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type SelectMessage struct { @@ -11,7 +12,11 @@ type SelectMessage struct { } func init() { - register(SelectMessage{}) + commands.Register(SelectMessage{}) +} + +func (SelectMessage) Context() commands.CommandContext { + return commands.ACCOUNT } func (SelectMessage) Aliases() []string { diff --git a/commands/account/sort.go b/commands/account/sort.go index 3103a388..0e80aec8 100644 --- a/commands/account/sort.go +++ b/commands/account/sort.go @@ -18,7 +18,11 @@ type Sort struct { } func init() { - register(Sort{}) + commands.Register(Sort{}) +} + +func (Sort) Context() commands.CommandContext { + return commands.ACCOUNT } func (Sort) Aliases() []string { diff --git a/commands/account/split.go b/commands/account/split.go index 8690d99a..4b01da2d 100644 --- a/commands/account/split.go +++ b/commands/account/split.go @@ -6,6 +6,7 @@ import ( "strings" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type Split struct { @@ -14,7 +15,11 @@ type Split struct { } func init() { - register(Split{}) + commands.Register(Split{}) +} + +func (Split) Context() commands.CommandContext { + return commands.ACCOUNT } func (s *Split) ParseSize(arg string) error { diff --git a/commands/account/view.go b/commands/account/view.go index 87705a1a..4177b906 100644 --- a/commands/account/view.go +++ b/commands/account/view.go @@ -5,6 +5,7 @@ import ( "errors" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/state" "git.sr.ht/~rjarry/aerc/lib/templates" @@ -16,7 +17,11 @@ type ViewMessage struct { } func init() { - register(ViewMessage{}) + commands.Register(ViewMessage{}) +} + +func (ViewMessage) Context() commands.CommandContext { + return commands.ACCOUNT } func (ViewMessage) Aliases() []string { diff --git a/commands/cd.go b/commands/cd.go index cd206c3c..1d71882f 100644 --- a/commands/cd.go +++ b/commands/cd.go @@ -15,7 +15,11 @@ type ChangeDirectory struct { } func init() { - register(ChangeDirectory{}) + Register(ChangeDirectory{}) +} + +func (ChangeDirectory) Context() CommandContext { + return GLOBAL } func (ChangeDirectory) Aliases() []string { diff --git a/commands/choose.go b/commands/choose.go index 19958dce..4ecff0ea 100644 --- a/commands/choose.go +++ b/commands/choose.go @@ -11,7 +11,11 @@ type Choose struct { } func init() { - register(Choose{}) + Register(Choose{}) +} + +func (Choose) Context() CommandContext { + return GLOBAL } func (Choose) Aliases() []string { diff --git a/commands/close.go b/commands/close.go new file mode 100644 index 00000000..c74a705e --- /dev/null +++ b/commands/close.go @@ -0,0 +1,24 @@ +package commands + +import ( + "git.sr.ht/~rjarry/aerc/app" +) + +type Close struct{} + +func init() { + Register(Close{}) +} + +func (Close) Context() CommandContext { + return MESSAGE_VIEWER | TERMINAL +} + +func (Close) Aliases() []string { + return []string{"close"} +} + +func (Close) Execute([]string) error { + app.RemoveTab(app.SelectedTabContent(), true) + return nil +} diff --git a/commands/commands.go b/commands/commands.go index 3270bee6..fa8ef287 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -19,56 +19,148 @@ import ( "git.sr.ht/~rjarry/aerc/models" ) +type CommandContext uint32 + +const ( + NONE = 1 << iota + // available everywhere + GLOBAL + // only when a message list is focused + ACCOUNT + // only when a message composer is focused + COMPOSE + // only when a message list or message viewer is focused + MESSAGE + // only when a message viewer is focused + MESSAGE_VIEWER + // only when a terminal + TERMINAL +) + +func CurrentContext() CommandContext { + var context CommandContext = GLOBAL + + switch app.SelectedTabContent().(type) { + case *app.AccountView: + context |= ACCOUNT | MESSAGE + case *app.Composer: + context |= COMPOSE + case *app.MessageViewer: + context |= COMPOSE | MESSAGE | MESSAGE_VIEWER + case *app.Terminal: + context |= TERMINAL + } + + return context +} + type Command interface { + Context() CommandContext Aliases() []string Execute([]string) error } -type Commands map[string]Command +var allCommands map[string]Command -func NewCommands() *Commands { - cmds := Commands(make(map[string]Command)) - return &cmds +func Register(cmd Command) { + if allCommands == nil { + allCommands = make(map[string]Command) + } + for _, alias := range cmd.Aliases() { + if allCommands[alias] != nil { + panic("duplicate command alias: " + alias) + } + allCommands[alias] = cmd + } } -func (cmds *Commands) dict() map[string]Command { - return map[string]Command(*cmds) +func ActiveCommands() []Command { + var cmds []Command + context := CurrentContext() + + for _, cmd := range allCommands { + if cmd.Context()&context != 0 { + cmds = append(cmds, cmd) + } + } + + return cmds } -func (cmds *Commands) Names() []string { - names := make([]string, 0) +func ActiveCommandNames() []string { + var names []string + context := CurrentContext() - for k := range cmds.dict() { - names = append(names, k) + for alias, cmd := range allCommands { + if cmd.Context()&context != 0 { + names = append(names, alias) + } } + return names } -func (cmds *Commands) ByName(name string) Command { - if cmd, ok := cmds.dict()[name]; ok { - return cmd - } - return nil +type NoSuchCommand string + +func (err NoSuchCommand) Error() string { + return "Unknown command " + string(err) } -func (cmds *Commands) Register(cmd Command) { - // TODO enforce unique aliases, until then, duplicate each - if len(cmd.Aliases()) < 1 { - return +// Expand non-ambiguous command abbreviations. +// +// q --> quit +// ar --> archive +// im --> import-mbox +func ExpandAbbreviations(name string) (string, Command, error) { + context := CurrentContext() + name = strings.TrimLeft(name, ":") + + cmd, found := allCommands[name] + if found && cmd.Context()&context != 0 { + return name, cmd, nil } - for _, alias := range cmd.Aliases() { - cmds.dict()[alias] = cmd + + var candidate Command + var candidateName string + + for alias, cmd := range allCommands { + if cmd.Context()&context == 0 || !strings.HasPrefix(alias, name) { + continue + } + if candidate != nil { + // We have more than one command partially + // matching the input. + return name, nil, NoSuchCommand(name) + } + // We have a partial match. + candidate = cmd + candidateName = alias } -} -type NoSuchCommand string + if candidate == nil { + return name, nil, NoSuchCommand(name) + } -func (err NoSuchCommand) Error() string { - return "Unknown command " + string(err) + return candidateName, candidate, nil } -type CommandSource interface { - Commands() *Commands +func ResolveCommand( + cmdline string, acct *config.AccountConfig, msg *models.MessageInfo, +) (string, Command, error) { + cmdline, err := ExpandTemplates(cmdline, acct, msg) + if err != nil { + return "", nil, err + } + name, rest, didCut := strings.Cut(cmdline, " ") + name, cmd, err := ExpandAbbreviations(name) + if err != nil { + return "", nil, err + } + cmdline = name + if didCut { + cmdline += " " + rest + } + return cmdline, cmd, nil } func templateData( diff --git a/commands/compose/abort.go b/commands/compose/abort.go index cde43f46..f446c306 100644 --- a/commands/compose/abort.go +++ b/commands/compose/abort.go @@ -2,12 +2,17 @@ package compose import ( "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type Abort struct{} func init() { - register(Abort{}) + commands.Register(Abort{}) +} + +func (Abort) Context() commands.CommandContext { + return commands.COMPOSE } func (Abort) Aliases() []string { diff --git a/commands/compose/attach-key.go b/commands/compose/attach-key.go index 6ba5eae0..047b9c08 100644 --- a/commands/compose/attach-key.go +++ b/commands/compose/attach-key.go @@ -2,12 +2,17 @@ package compose import ( "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type AttachKey struct{} func init() { - register(AttachKey{}) + commands.Register(AttachKey{}) +} + +func (AttachKey) Context() commands.CommandContext { + return commands.COMPOSE } func (AttachKey) Aliases() []string { diff --git a/commands/compose/attach.go b/commands/compose/attach.go index 52ce55cb..cb59eb5f 100644 --- a/commands/compose/attach.go +++ b/commands/compose/attach.go @@ -28,7 +28,11 @@ type Attach struct { } func init() { - register(Attach{}) + commands.Register(Attach{}) +} + +func (Attach) Context() commands.CommandContext { + return commands.COMPOSE } func (Attach) Aliases() []string { diff --git a/commands/compose/cc-bcc.go b/commands/compose/cc-bcc.go index dd5e9614..d54a9895 100644 --- a/commands/compose/cc-bcc.go +++ b/commands/compose/cc-bcc.go @@ -2,6 +2,7 @@ package compose import ( "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type CC struct { @@ -9,7 +10,11 @@ type CC struct { } func init() { - register(CC{}) + commands.Register(CC{}) +} + +func (CC) Context() commands.CommandContext { + return commands.COMPOSE } func (CC) Aliases() []string { diff --git a/commands/compose/compose.go b/commands/compose/compose.go deleted file mode 100644 index f325e4e2..00000000 --- a/commands/compose/compose.go +++ /dev/null @@ -1,14 +0,0 @@ -package compose - -import ( - "git.sr.ht/~rjarry/aerc/commands" -) - -var ComposeCommands *commands.Commands - -func register(cmd commands.Command) { - if ComposeCommands == nil { - ComposeCommands = commands.NewCommands() - } - ComposeCommands.Register(cmd) -} diff --git a/commands/compose/detach.go b/commands/compose/detach.go index 0ac3334e..36c7c314 100644 --- a/commands/compose/detach.go +++ b/commands/compose/detach.go @@ -12,7 +12,11 @@ type Detach struct { } func init() { - register(Detach{}) + commands.Register(Detach{}) +} + +func (Detach) Context() commands.CommandContext { + return commands.COMPOSE } func (Detach) Aliases() []string { diff --git a/commands/compose/edit.go b/commands/compose/edit.go index 1929f45a..45c55046 100644 --- a/commands/compose/edit.go +++ b/commands/compose/edit.go @@ -4,6 +4,7 @@ import ( "errors" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/config" ) @@ -13,7 +14,11 @@ type Edit struct { } func init() { - register(Edit{}) + commands.Register(Edit{}) +} + +func (Edit) Context() commands.CommandContext { + return commands.COMPOSE } func (Edit) Aliases() []string { diff --git a/commands/compose/encrypt.go b/commands/compose/encrypt.go index ee902f6e..5e52f821 100644 --- a/commands/compose/encrypt.go +++ b/commands/compose/encrypt.go @@ -2,12 +2,17 @@ package compose import ( "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type Encrypt struct{} func init() { - register(Encrypt{}) + commands.Register(Encrypt{}) +} + +func (Encrypt) Context() commands.CommandContext { + return commands.COMPOSE } func (Encrypt) Aliases() []string { diff --git a/commands/compose/header.go b/commands/compose/header.go index 3283d4e3..839896c3 100644 --- a/commands/compose/header.go +++ b/commands/compose/header.go @@ -26,7 +26,11 @@ var headers = []string{ } func init() { - register(Header{}) + commands.Register(Header{}) +} + +func (Header) Context() commands.CommandContext { + return commands.COMPOSE } func (Header) Aliases() []string { diff --git a/commands/compose/multipart.go b/commands/compose/multipart.go index a004ea2b..13fe8ca3 100644 --- a/commands/compose/multipart.go +++ b/commands/compose/multipart.go @@ -15,7 +15,11 @@ type Multipart struct { } func init() { - register(Multipart{}) + commands.Register(Multipart{}) +} + +func (Multipart) Context() commands.CommandContext { + return commands.COMPOSE } func (Multipart) Aliases() []string { diff --git a/commands/compose/next-field.go b/commands/compose/next-field.go index 396c1ce1..6c96cd94 100644 --- a/commands/compose/next-field.go +++ b/commands/compose/next-field.go @@ -2,12 +2,17 @@ package compose import ( "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type NextPrevField struct{} func init() { - register(NextPrevField{}) + commands.Register(NextPrevField{}) +} + +func (NextPrevField) Context() commands.CommandContext { + return commands.COMPOSE } func (NextPrevField) Aliases() []string { diff --git a/commands/compose/postpone.go b/commands/compose/postpone.go index 098b7039..a869417b 100644 --- a/commands/compose/postpone.go +++ b/commands/compose/postpone.go @@ -18,7 +18,11 @@ type Postpone struct { } func init() { - register(Postpone{}) + commands.Register(Postpone{}) +} + +func (Postpone) Context() commands.CommandContext { + return commands.COMPOSE } func (Postpone) Aliases() []string { diff --git a/commands/compose/send.go b/commands/compose/send.go index c642c356..dfd531ee 100644 --- a/commands/compose/send.go +++ b/commands/compose/send.go @@ -33,7 +33,11 @@ type Send struct { } func init() { - register(Send{}) + commands.Register(Send{}) +} + +func (Send) Context() commands.CommandContext { + return commands.COMPOSE } func (Send) Aliases() []string { diff --git a/commands/compose/sign.go b/commands/compose/sign.go index faeceed4..692ef108 100644 --- a/commands/compose/sign.go +++ b/commands/compose/sign.go @@ -4,12 +4,17 @@ import ( "time" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type Sign struct{} func init() { - register(Sign{}) + commands.Register(Sign{}) +} + +func (Sign) Context() commands.CommandContext { + return commands.COMPOSE } func (Sign) Aliases() []string { diff --git a/commands/compose/switch.go b/commands/compose/switch.go index c71716e0..c9d1013c 100644 --- a/commands/compose/switch.go +++ b/commands/compose/switch.go @@ -18,7 +18,11 @@ type SwitchAccount struct { } func init() { - register(SwitchAccount{}) + commands.Register(SwitchAccount{}) +} + +func (SwitchAccount) Context() commands.CommandContext { + return commands.COMPOSE } func (SwitchAccount) Aliases() []string { diff --git a/commands/ct.go b/commands/ct.go index 9948e691..1f99c6a5 100644 --- a/commands/ct.go +++ b/commands/ct.go @@ -13,7 +13,11 @@ type ChangeTab struct { } func init() { - register(ChangeTab{}) + Register(ChangeTab{}) +} + +func (ChangeTab) Context() CommandContext { + return GLOBAL } func (ChangeTab) Aliases() []string { diff --git a/commands/eml.go b/commands/eml.go index ebf3abfa..a786942c 100644 --- a/commands/eml.go +++ b/commands/eml.go @@ -16,7 +16,11 @@ type Eml struct { } func init() { - register(Eml{}) + Register(Eml{}) +} + +func (Eml) Context() CommandContext { + return GLOBAL } func (Eml) Aliases() []string { diff --git a/commands/exec.go b/commands/exec.go index 2a3ed5f5..874b2714 100644 --- a/commands/exec.go +++ b/commands/exec.go @@ -15,7 +15,11 @@ type ExecCmd struct { } func init() { - register(ExecCmd{}) + Register(ExecCmd{}) +} + +func (ExecCmd) Context() CommandContext { + return GLOBAL } func (ExecCmd) Aliases() []string { diff --git a/commands/global.go b/commands/global.go deleted file mode 100644 index ec7d623c..00000000 --- a/commands/global.go +++ /dev/null @@ -1,10 +0,0 @@ -package commands - -var GlobalCommands *Commands - -func register(cmd Command) { - if GlobalCommands == nil { - GlobalCommands = NewCommands() - } - GlobalCommands.Register(cmd) -} diff --git a/commands/help.go b/commands/help.go index 3d8d5ecf..ce86e3ac 100644 --- a/commands/help.go +++ b/commands/help.go @@ -29,7 +29,11 @@ var pages = []string{ } func init() { - register(Help{}) + Register(Help{}) +} + +func (Help) Context() CommandContext { + return GLOBAL } func (Help) Aliases() []string { diff --git a/commands/move-tab.go b/commands/move-tab.go index 7ebe269c..c8e1b99a 100644 --- a/commands/move-tab.go +++ b/commands/move-tab.go @@ -13,7 +13,11 @@ type MoveTab struct { } func init() { - register(MoveTab{}) + Register(MoveTab{}) +} + +func (MoveTab) Context() CommandContext { + return GLOBAL } func (m *MoveTab) ParseIndex(arg string) error { diff --git a/commands/msg/archive.go b/commands/msg/archive.go index a46cc986..13f53290 100644 --- a/commands/msg/archive.go +++ b/commands/msg/archive.go @@ -35,7 +35,11 @@ func (a *Archive) ParseArchiveType(arg string) error { } func init() { - register(Archive{}) + commands.Register(Archive{}) +} + +func (Archive) Context() commands.CommandContext { + return commands.MESSAGE } func (Archive) Aliases() []string { diff --git a/commands/msg/copy.go b/commands/msg/copy.go index f91d885b..3620238a 100644 --- a/commands/msg/copy.go +++ b/commands/msg/copy.go @@ -15,7 +15,11 @@ type Copy struct { } func init() { - register(Copy{}) + commands.Register(Copy{}) +} + +func (Copy) Context() commands.CommandContext { + return commands.MESSAGE } func (Copy) Aliases() []string { diff --git a/commands/msg/delete.go b/commands/msg/delete.go index 869c6888..19f44b43 100644 --- a/commands/msg/delete.go +++ b/commands/msg/delete.go @@ -5,6 +5,7 @@ import ( "time" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/ui" @@ -15,7 +16,11 @@ import ( type Delete struct{} func init() { - register(Delete{}) + commands.Register(Delete{}) +} + +func (Delete) Context() commands.CommandContext { + return commands.MESSAGE } func (Delete) Aliases() []string { diff --git a/commands/msg/envelope.go b/commands/msg/envelope.go index 62a266b0..24867fc1 100644 --- a/commands/msg/envelope.go +++ b/commands/msg/envelope.go @@ -6,6 +6,7 @@ import ( "strings" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib/format" "git.sr.ht/~rjarry/aerc/log" "git.sr.ht/~rjarry/aerc/models" @@ -18,7 +19,11 @@ type Envelope struct { } func init() { - register(Envelope{}) + commands.Register(Envelope{}) +} + +func (Envelope) Context() commands.CommandContext { + return commands.MESSAGE } func (Envelope) Aliases() []string { diff --git a/commands/msg/fold.go b/commands/msg/fold.go index e8eb7741..057d454e 100644 --- a/commands/msg/fold.go +++ b/commands/msg/fold.go @@ -3,6 +3,7 @@ package msg import ( "errors" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib/ui" ) @@ -12,7 +13,11 @@ type Fold struct { } func init() { - register(Fold{}) + commands.Register(Fold{}) +} + +func (Fold) Context() commands.CommandContext { + return commands.MESSAGE } func (Fold) Aliases() []string { diff --git a/commands/msg/forward.go b/commands/msg/forward.go index 20e945c1..093ca2e2 100644 --- a/commands/msg/forward.go +++ b/commands/msg/forward.go @@ -33,7 +33,11 @@ type forward struct { } func init() { - register(forward{}) + commands.Register(forward{}) +} + +func (forward) Context() commands.CommandContext { + return commands.MESSAGE } func (forward) Aliases() []string { diff --git a/commands/msg/invite.go b/commands/msg/invite.go index 12bea93e..862af23c 100644 --- a/commands/msg/invite.go +++ b/commands/msg/invite.go @@ -6,6 +6,7 @@ import ( "io" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/calendar" @@ -21,7 +22,11 @@ type invite struct { } func init() { - register(invite{}) + commands.Register(invite{}) +} + +func (invite) Context() commands.CommandContext { + return commands.MESSAGE } func (invite) Aliases() []string { diff --git a/commands/msg/mark.go b/commands/msg/mark.go index 9547548f..f86c3413 100644 --- a/commands/msg/mark.go +++ b/commands/msg/mark.go @@ -2,6 +2,8 @@ package msg import ( "fmt" + + "git.sr.ht/~rjarry/aerc/commands" ) type Mark struct { @@ -13,7 +15,11 @@ type Mark struct { } func init() { - register(Mark{}) + commands.Register(Mark{}) +} + +func (Mark) Context() commands.CommandContext { + return commands.MESSAGE } func (Mark) Aliases() []string { diff --git a/commands/msg/modify-labels.go b/commands/msg/modify-labels.go index 8cc72f2a..e2637805 100644 --- a/commands/msg/modify-labels.go +++ b/commands/msg/modify-labels.go @@ -13,7 +13,11 @@ type ModifyLabels struct { } func init() { - register(ModifyLabels{}) + commands.Register(ModifyLabels{}) +} + +func (ModifyLabels) Context() commands.CommandContext { + return commands.MESSAGE } func (ModifyLabels) Aliases() []string { diff --git a/commands/msg/move.go b/commands/msg/move.go index 4eac1c14..000e2b2a 100644 --- a/commands/msg/move.go +++ b/commands/msg/move.go @@ -19,7 +19,11 @@ type Move struct { } func init() { - register(Move{}) + commands.Register(Move{}) +} + +func (Move) Context() commands.CommandContext { + return commands.MESSAGE } func (Move) Aliases() []string { diff --git a/commands/msg/msg.go b/commands/msg/msg.go deleted file mode 100644 index 65a40562..00000000 --- a/commands/msg/msg.go +++ /dev/null @@ -1,14 +0,0 @@ -package msg - -import ( - "git.sr.ht/~rjarry/aerc/commands" -) - -var MessageCommands *commands.Commands - -func register(cmd commands.Command) { - if MessageCommands == nil { - MessageCommands = commands.NewCommands() - } - MessageCommands.Register(cmd) -} diff --git a/commands/msg/pipe.go b/commands/msg/pipe.go index ee5cd965..8b47c418 100644 --- a/commands/msg/pipe.go +++ b/commands/msg/pipe.go @@ -25,7 +25,11 @@ type Pipe struct { } func init() { - register(Pipe{}) + commands.Register(Pipe{}) +} + +func (Pipe) Context() commands.CommandContext { + return commands.MESSAGE } func (Pipe) Aliases() []string { diff --git a/commands/msg/read.go b/commands/msg/read.go index e682a156..b487d8a8 100644 --- a/commands/msg/read.go +++ b/commands/msg/read.go @@ -19,7 +19,11 @@ type FlagMsg struct { } func init() { - register(FlagMsg{}) + commands.Register(FlagMsg{}) +} + +func (FlagMsg) Context() commands.CommandContext { + return commands.MESSAGE } func (FlagMsg) Aliases() []string { diff --git a/commands/msg/recall.go b/commands/msg/recall.go index a676010a..059fe558 100644 --- a/commands/msg/recall.go +++ b/commands/msg/recall.go @@ -11,6 +11,7 @@ import ( "github.com/pkg/errors" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/log" @@ -24,7 +25,11 @@ type Recall struct { } func init() { - register(Recall{}) + commands.Register(Recall{}) +} + +func (Recall) Context() commands.CommandContext { + return commands.MESSAGE } func (Recall) Aliases() []string { diff --git a/commands/msg/reply.go b/commands/msg/reply.go index 333b3e3a..04c2eba5 100644 --- a/commands/msg/reply.go +++ b/commands/msg/reply.go @@ -34,7 +34,11 @@ type reply struct { } func init() { - register(reply{}) + commands.Register(reply{}) +} + +func (reply) Context() commands.CommandContext { + return commands.MESSAGE } func (reply) Aliases() []string { diff --git a/commands/msg/toggle-thread-context.go b/commands/msg/toggle-thread-context.go index 4b87eaa8..dfae3a22 100644 --- a/commands/msg/toggle-thread-context.go +++ b/commands/msg/toggle-thread-context.go @@ -1,13 +1,18 @@ package msg import ( + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib/ui" ) type ToggleThreadContext struct{} func init() { - register(ToggleThreadContext{}) + commands.Register(ToggleThreadContext{}) +} + +func (ToggleThreadContext) Context() commands.CommandContext { + return commands.MESSAGE } func (ToggleThreadContext) Aliases() []string { diff --git a/commands/msg/toggle-threads.go b/commands/msg/toggle-threads.go index d2933bba..21accc2c 100644 --- a/commands/msg/toggle-threads.go +++ b/commands/msg/toggle-threads.go @@ -1,6 +1,7 @@ package msg import ( + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib/state" "git.sr.ht/~rjarry/aerc/lib/ui" ) @@ -8,7 +9,11 @@ import ( type ToggleThreads struct{} func init() { - register(ToggleThreads{}) + commands.Register(ToggleThreads{}) +} + +func (ToggleThreads) Context() commands.CommandContext { + return commands.MESSAGE } func (ToggleThreads) Aliases() []string { diff --git a/commands/msg/unsubscribe.go b/commands/msg/unsubscribe.go index c6a0b23f..7ba497b4 100644 --- a/commands/msg/unsubscribe.go +++ b/commands/msg/unsubscribe.go @@ -9,6 +9,7 @@ import ( "time" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/log" @@ -23,7 +24,11 @@ type Unsubscribe struct { } func init() { - register(Unsubscribe{}) + commands.Register(Unsubscribe{}) +} + +func (Unsubscribe) Context() commands.CommandContext { + return commands.MESSAGE } // Aliases returns a list of aliases for the :unsubscribe command diff --git a/commands/msgview/close.go b/commands/msgview/close.go deleted file mode 100644 index 95960ef3..00000000 --- a/commands/msgview/close.go +++ /dev/null @@ -1,21 +0,0 @@ -package msgview - -import ( - "git.sr.ht/~rjarry/aerc/app" -) - -type Close struct{} - -func init() { - register(Close{}) -} - -func (Close) Aliases() []string { - return []string{"close"} -} - -func (Close) Execute(args []string) error { - mv, _ := app.SelectedTabContent().(*app.MessageViewer) - app.RemoveTab(mv, true) - return nil -} diff --git a/commands/msgview/msgview.go b/commands/msgview/msgview.go deleted file mode 100644 index fb32d8e1..00000000 --- a/commands/msgview/msgview.go +++ /dev/null @@ -1,14 +0,0 @@ -package msgview - -import ( - "git.sr.ht/~rjarry/aerc/commands" -) - -var MessageViewCommands *commands.Commands - -func register(cmd commands.Command) { - if MessageViewCommands == nil { - MessageViewCommands = commands.NewCommands() - } - MessageViewCommands.Register(cmd) -} diff --git a/commands/msgview/next-part.go b/commands/msgview/next-part.go index 77eb008d..b5375d75 100644 --- a/commands/msgview/next-part.go +++ b/commands/msgview/next-part.go @@ -2,6 +2,7 @@ package msgview import ( "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type NextPrevPart struct { @@ -9,7 +10,11 @@ type NextPrevPart struct { } func init() { - register(NextPrevPart{}) + commands.Register(NextPrevPart{}) +} + +func (NextPrevPart) Context() commands.CommandContext { + return commands.MESSAGE_VIEWER } func (NextPrevPart) Aliases() []string { diff --git a/commands/msgview/next.go b/commands/msgview/next.go deleted file mode 100644 index c953cd5d..00000000 --- a/commands/msgview/next.go +++ /dev/null @@ -1,83 +0,0 @@ -package msgview - -import ( - "errors" - "fmt" - "strconv" - "strings" - - "git.sr.ht/~rjarry/aerc/app" - "git.sr.ht/~rjarry/aerc/commands/account" - "git.sr.ht/~rjarry/aerc/lib" - "git.sr.ht/~rjarry/aerc/models" - "git.sr.ht/~rjarry/aerc/worker/types" -) - -type NextPrevMsg struct { - Amount int `opt:"n" default:"1" metavar:"N[%]" action:"ParseAmount"` - Percent bool -} - -func init() { - register(NextPrevMsg{}) -} - -func (np *NextPrevMsg) ParseAmount(arg string) error { - if strings.HasSuffix(arg, "%") { - np.Percent = true - arg = strings.TrimSuffix(arg, "%") - } - i, err := strconv.ParseInt(arg, 10, 64) - if err != nil { - return err - } - np.Amount = int(i) - return nil -} - -func (NextPrevMsg) Aliases() []string { - return []string{"next", "next-message", "prev", "prev-message"} -} - -func (np NextPrevMsg) Execute(args []string) error { - cmd := account.NextPrevMsg{Amount: np.Amount, Percent: np.Percent} - err := cmd.Execute(args) - if err != nil { - return err - } - - mv, _ := app.SelectedTabContent().(*app.MessageViewer) - acct := mv.SelectedAccount() - if acct == nil { - return errors.New("No account selected") - } - store := mv.Store() - if store == nil { - return fmt.Errorf("Cannot perform action. No message store set.") - } - executeNextPrev := func(nextMsg *models.MessageInfo) { - lib.NewMessageStoreView(nextMsg, mv.MessageView().SeenFlagSet(), - store, app.CryptoProvider(), app.DecryptKeys, - func(view lib.MessageView, err error) { - if err != nil { - app.PushError(err.Error()) - return - } - nextMv := app.NewMessageViewer(acct, view) - app.ReplaceTab(mv, nextMv, - nextMsg.Envelope.Subject, true) - }) - } - if nextMsg := store.Selected(); nextMsg != nil { - executeNextPrev(nextMsg) - } else { - store.FetchHeaders([]uint32{store.SelectedUid()}, - func(msg types.WorkerMessage) { - if m, ok := msg.(*types.MessageInfo); ok { - executeNextPrev(m.Info) - } - }) - } - - return nil -} diff --git a/commands/msgview/open-link.go b/commands/msgview/open-link.go index b13f5d4f..e64e6e2f 100644 --- a/commands/msgview/open-link.go +++ b/commands/msgview/open-link.go @@ -16,7 +16,11 @@ type OpenLink struct { } func init() { - register(OpenLink{}) + commands.Register(OpenLink{}) +} + +func (OpenLink) Context() commands.CommandContext { + return commands.MESSAGE_VIEWER } func (OpenLink) Aliases() []string { diff --git a/commands/msgview/open.go b/commands/msgview/open.go index a8443404..3943b21a 100644 --- a/commands/msgview/open.go +++ b/commands/msgview/open.go @@ -8,6 +8,7 @@ import ( "path/filepath" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/log" ) @@ -18,7 +19,11 @@ type Open struct { } func init() { - register(Open{}) + commands.Register(Open{}) +} + +func (Open) Context() commands.CommandContext { + return commands.MESSAGE_VIEWER } func (Open) Options() string { diff --git a/commands/msgview/save.go b/commands/msgview/save.go index bcaf9eb2..d9320293 100644 --- a/commands/msgview/save.go +++ b/commands/msgview/save.go @@ -26,7 +26,11 @@ type Save struct { } func init() { - register(Save{}) + commands.Register(Save{}) +} + +func (Save) Context() commands.CommandContext { + return commands.MESSAGE_VIEWER } func (Save) Options() string { diff --git a/commands/msgview/toggle-headers.go b/commands/msgview/toggle-headers.go index 37f5b22f..201fce90 100644 --- a/commands/msgview/toggle-headers.go +++ b/commands/msgview/toggle-headers.go @@ -2,12 +2,17 @@ package msgview import ( "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" ) type ToggleHeaders struct{} func init() { - register(ToggleHeaders{}) + commands.Register(ToggleHeaders{}) +} + +func (ToggleHeaders) Context() commands.CommandContext { + return commands.MESSAGE_VIEWER } func (ToggleHeaders) Aliases() []string { diff --git a/commands/msgview/toggle-key-passthrough.go b/commands/msgview/toggle-key-passthrough.go index b4c5f2c7..1b3f8628 100644 --- a/commands/msgview/toggle-key-passthrough.go +++ b/commands/msgview/toggle-key-passthrough.go @@ -2,13 +2,18 @@ package msgview import ( "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib/state" ) type ToggleKeyPassthrough struct{} func init() { - register(ToggleKeyPassthrough{}) + commands.Register(ToggleKeyPassthrough{}) +} + +func (ToggleKeyPassthrough) Context() commands.CommandContext { + return commands.MESSAGE_VIEWER } func (ToggleKeyPassthrough) Aliases() []string { diff --git a/commands/new-account.go b/commands/new-account.go index 1a14a821..5a5499df 100644 --- a/commands/new-account.go +++ b/commands/new-account.go @@ -9,7 +9,11 @@ type NewAccount struct { } func init() { - register(NewAccount{}) + Register(NewAccount{}) +} + +func (NewAccount) Context() CommandContext { + return GLOBAL } func (NewAccount) Aliases() []string { diff --git a/commands/next-tab.go b/commands/next-tab.go index f1f34d22..adab95ae 100644 --- a/commands/next-tab.go +++ b/commands/next-tab.go @@ -9,7 +9,11 @@ type NextPrevTab struct { } func init() { - register(NextPrevTab{}) + Register(NextPrevTab{}) +} + +func (NextPrevTab) Context() CommandContext { + return GLOBAL } func (NextPrevTab) Aliases() []string { diff --git a/commands/patch/apply.go b/commands/patch/apply.go index 2806b7d1..5ffe86d1 100644 --- a/commands/patch/apply.go +++ b/commands/patch/apply.go @@ -24,6 +24,10 @@ func init() { register(Apply{}) } +func (Apply) Context() commands.CommandContext { + return commands.MESSAGE +} + func (Apply) Aliases() []string { return []string{"apply"} } diff --git a/commands/patch/cd.go b/commands/patch/cd.go index 86a2db3e..bbca1eba 100644 --- a/commands/patch/cd.go +++ b/commands/patch/cd.go @@ -6,6 +6,7 @@ import ( "time" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib/pama" ) @@ -15,6 +16,10 @@ func init() { register(Cd{}) } +func (Cd) Context() commands.CommandContext { + return commands.GLOBAL +} + func (Cd) Aliases() []string { return []string{"cd"} } diff --git a/commands/patch/delete.go b/commands/patch/delete.go index 2e51ab7c..24351f7c 100644 --- a/commands/patch/delete.go +++ b/commands/patch/delete.go @@ -18,6 +18,10 @@ func init() { register(Delete{}) } +func (Delete) Context() commands.CommandContext { + return commands.GLOBAL +} + func (Delete) Aliases() []string { return []string{"delete"} } diff --git a/commands/patch/find.go b/commands/patch/find.go index 9579e1f8..a508551d 100644 --- a/commands/patch/find.go +++ b/commands/patch/find.go @@ -23,6 +23,10 @@ func init() { register(Find{}) } +func (Find) Context() commands.CommandContext { + return commands.GLOBAL +} + func (Find) Aliases() []string { return []string{"find"} } diff --git a/commands/patch/init.go b/commands/patch/init.go index 328fcd9f..de0c6e45 100644 --- a/commands/patch/init.go +++ b/commands/patch/init.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/lib/pama" ) @@ -17,6 +18,10 @@ func init() { register(Init{}) } +func (Init) Context() commands.CommandContext { + return commands.GLOBAL +} + func (Init) Aliases() []string { return []string{"init"} } diff --git a/commands/patch/list.go b/commands/patch/list.go index 6dcc06e8..73461f2e 100644 --- a/commands/patch/list.go +++ b/commands/patch/list.go @@ -8,6 +8,7 @@ import ( "time" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib/pama" "git.sr.ht/~rjarry/aerc/lib/pama/models" @@ -24,6 +25,10 @@ func init() { register(List{}) } +func (List) Context() commands.CommandContext { + return commands.GLOBAL +} + func (List) Aliases() []string { return []string{"list", "ls"} } diff --git a/commands/patch/patch.go b/commands/patch/patch.go index 0807c1fa..25d7850a 100644 --- a/commands/patch/patch.go +++ b/commands/patch/patch.go @@ -8,32 +8,31 @@ import ( "git.sr.ht/~rjarry/go-opt" ) -var ( - PatchCommands *commands.Commands - subCommands *commands.Commands -) +var subCommands map[string]commands.Command func register(cmd commands.Command) { if subCommands == nil { - subCommands = commands.NewCommands() + subCommands = make(map[string]commands.Command) + } + for _, alias := range cmd.Aliases() { + if subCommands[alias] != nil { + panic("duplicate sub command alias: " + alias) + } + subCommands[alias] = cmd } - subCommands.Register(cmd) } -func registerPatch(cmd commands.Command) { - if PatchCommands == nil { - PatchCommands = commands.NewCommands() - } - PatchCommands.Register(cmd) +type Patch struct { + SubCmd commands.Command `opt:"command" action:"ParseSub" complete:"CompleteSubNames"` + Args string `opt:"..." required:"false" complete:"CompleteSubArgs"` } func init() { - registerPatch(Patch{}) + commands.Register(Patch{}) } -type Patch struct { - SubCmd commands.Command `opt:"command" action:"ParseSub" complete:"CompleteSubNames"` - Args string `opt:"..." required:"false" complete:"CompleteSubArgs"` +func (Patch) Context() commands.CommandContext { + return commands.GLOBAL } func (Patch) Aliases() []string { @@ -41,16 +40,26 @@ func (Patch) Aliases() []string { } func (p *Patch) ParseSub(arg string) error { - p.SubCmd = subCommands.ByName(arg) - if p.SubCmd == nil { - return fmt.Errorf("%s unknown sub-command", arg) + cmd, ok := subCommands[arg] + if ok { + context := commands.CurrentContext() + if cmd.Context()&context != 0 { + p.SubCmd = cmd + return nil + } } - return nil + return fmt.Errorf("%s unknown sub-command", arg) } func (*Patch) CompleteSubNames(arg string) []string { - options := subCommands.Names() - return commands.FilterList(options, arg, nil) + context := commands.CurrentContext() + options := make([]string, 0, len(subCommands)) + for alias, cmd := range subCommands { + if cmd.Context()&context != 0 { + options = append(options, alias) + } + } + return commands.FilterList(options, arg, commands.QuoteSpace) } func (p *Patch) CompleteSubArgs(arg string) []string { diff --git a/commands/patch/rebase.go b/commands/patch/rebase.go index 10da2a63..6ef43299 100644 --- a/commands/patch/rebase.go +++ b/commands/patch/rebase.go @@ -12,6 +12,7 @@ import ( "time" "git.sr.ht/~rjarry/aerc/app" + "git.sr.ht/~rjarry/aerc/commands" "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib/pama" "git.sr.ht/~rjarry/aerc/lib/pama/models" @@ -27,6 +28,10 @@ func init() { register(Rebase{}) } +func (Rebase) Context() commands.CommandContext { + return commands.GLOBAL +} + func (Rebase) Aliases() []string { return []string{"rebase"} } diff --git a/commands/patch/remove.go b/commands/patch/remove.go index 6697177b..29849e51 100644 --- a/commands/patch/remove.go +++ b/commands/patch/remove.go @@ -18,6 +18,10 @@ func init() { register(Remove{}) } +func (Remove) Context() commands.CommandContext { + return commands.GLOBAL +} + func (Remove) Aliases() []string { return []string{"remove"} } diff --git a/commands/patch/switch.go b/commands/patch/switch.go index b1193be7..aab2acb6 100644 --- a/commands/patch/switch.go +++ b/commands/patch/switch.go @@ -18,6 +18,10 @@ func init() { register(Switch{}) } +func (Switch) Context() commands.CommandContext { + return commands.GLOBAL +} + func (Switch) Aliases() []string { return []string{"switch"} } diff --git a/commands/patch/term.go b/commands/patch/term.go index f2c50b15..f9f79be1 100644 --- a/commands/patch/term.go +++ b/commands/patch/term.go @@ -13,6 +13,10 @@ func init() { register(Term{}) } +func (Term) Context() commands.CommandContext { + return commands.GLOBAL +} + func (Term) Aliases() []string { return []string{"term"} } diff --git a/commands/pin-tab.go b/commands/pin-tab.go index d5013bf6..aaac356d 100644 --- a/commands/pin-tab.go +++ b/commands/pin-tab.go @@ -7,7 +7,11 @@ import ( type PinTab struct{} func init() { - register(PinTab{}) + Register(PinTab{}) +} + +func (PinTab) Context() CommandContext { + return GLOBAL } func (PinTab) Aliases() []string { diff --git a/commands/prompt.go b/commands/prompt.go index 4fcf8a80..9ab2aac1 100644 --- a/commands/prompt.go +++ b/commands/prompt.go @@ -12,7 +12,11 @@ type Prompt struct { } func init() { - register(Prompt{}) + Register(Prompt{}) +} + +func (Prompt) Context() CommandContext { + return GLOBAL } func (Prompt) Aliases() []string { @@ -20,7 +24,7 @@ func (Prompt) Aliases() []string { } func (*Prompt) CompleteCommand(arg string) []string { - return FilterList(GlobalCommands.Names(), arg, nil) + return FilterList(ActiveCommandNames(), arg, nil) } func (p Prompt) Execute(args []string) error { diff --git a/commands/pwd.go b/commands/pwd.go index 2b1961a1..fb1d04f1 100644 --- a/commands/pwd.go +++ b/commands/pwd.go @@ -10,7 +10,11 @@ import ( type PrintWorkDir struct{} func init() { - register(PrintWorkDir{}) + Register(PrintWorkDir{}) +} + +func (PrintWorkDir) Context() CommandContext { + return GLOBAL } func (PrintWorkDir) Aliases() []string { diff --git a/commands/quit.go b/commands/quit.go index e96c9253..aa996422 100644 --- a/commands/quit.go +++ b/commands/quit.go @@ -11,7 +11,11 @@ type Quit struct { } func init() { - register(Quit{}) + Register(Quit{}) +} + +func (Quit) Context() CommandContext { + return GLOBAL } func (Quit) Aliases() []string { diff --git a/commands/send-keys.go b/commands/send-keys.go index bb872a33..a7b6dee9 100644 --- a/commands/send-keys.go +++ b/commands/send-keys.go @@ -12,7 +12,11 @@ type SendKeys struct { } func init() { - register(SendKeys{}) + Register(SendKeys{}) +} + +func (SendKeys) Context() CommandContext { + return GLOBAL } func (SendKeys) Aliases() []string { diff --git a/commands/suspend.go b/commands/suspend.go index a8996441..52198774 100644 --- a/commands/suspend.go +++ b/commands/suspend.go @@ -5,7 +5,11 @@ import "git.sr.ht/~rjarry/aerc/lib/ui" type Suspend struct{} func init() { - register(Suspend{}) + Register(Suspend{}) +} + +func (Suspend) Context() CommandContext { + return GLOBAL } func (Suspend) Aliases() []string { diff --git a/commands/term.go b/commands/term.go index d115cd25..e8b1919d 100644 --- a/commands/term.go +++ b/commands/term.go @@ -15,7 +15,11 @@ type Term struct { } func init() { - register(Term{}) + Register(Term{}) +} + +func (Term) Context() CommandContext { + return GLOBAL } func (Term) Aliases() []string { diff --git a/commands/terminal/close.go b/commands/terminal/close.go deleted file mode 100644 index 610a8463..00000000 --- a/commands/terminal/close.go +++ /dev/null @@ -1,21 +0,0 @@ -package terminal - -import ( - "git.sr.ht/~rjarry/aerc/app" -) - -type Close struct{} - -func init() { - register(Close{}) -} - -func (Close) Aliases() []string { - return []string{"close"} -} - -func (Close) Execute(args []string) error { - term, _ := app.SelectedTabContent().(*app.Terminal) - term.Close() - return nil -} diff --git a/commands/terminal/terminal.go b/commands/terminal/terminal.go deleted file mode 100644 index edc8429f..00000000 --- a/commands/terminal/terminal.go +++ /dev/null @@ -1,14 +0,0 @@ -package terminal - -import ( - "git.sr.ht/~rjarry/aerc/commands" -) - -var TerminalCommands *commands.Commands - -func register(cmd commands.Command) { - if TerminalCommands == nil { - TerminalCommands = commands.NewCommands() - } - TerminalCommands.Register(cmd) -} diff --git a/commands/z.go b/commands/z.go index a2363ae2..ef26ae9c 100644 --- a/commands/z.go +++ b/commands/z.go @@ -30,10 +30,14 @@ func ZoxideQuery(args []string) (string, error) { func init() { _, err := exec.LookPath("zoxide") if err == nil { - register(Zoxide{}) + Register(Zoxide{}) } } +func (Zoxide) Context() CommandContext { + return GLOBAL +} + func (Zoxide) Aliases() []string { return []string{"z"} } @@ -18,12 +18,6 @@ import ( "git.sr.ht/~rjarry/aerc/app" "git.sr.ht/~rjarry/aerc/commands" - "git.sr.ht/~rjarry/aerc/commands/account" - "git.sr.ht/~rjarry/aerc/commands/compose" - "git.sr.ht/~rjarry/aerc/commands/msg" - "git.sr.ht/~rjarry/aerc/commands/msgview" - "git.sr.ht/~rjarry/aerc/commands/patch" - "git.sr.ht/~rjarry/aerc/commands/terminal" "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib/crypto" "git.sr.ht/~rjarry/aerc/lib/hooks" @@ -33,98 +27,22 @@ import ( "git.sr.ht/~rjarry/aerc/log" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/worker/types" -) - -func getCommands(selected ui.Drawable) []*commands.Commands { - switch selected.(type) { - case *app.AccountView: - return []*commands.Commands{ - account.AccountCommands, - msg.MessageCommands, - commands.GlobalCommands, - patch.PatchCommands, - } - case *app.Composer: - return []*commands.Commands{ - compose.ComposeCommands, - commands.GlobalCommands, - patch.PatchCommands, - } - case *app.MessageViewer: - return []*commands.Commands{ - msgview.MessageViewCommands, - msg.MessageCommands, - commands.GlobalCommands, - patch.PatchCommands, - } - case *app.Terminal: - return []*commands.Commands{ - terminal.TerminalCommands, - commands.GlobalCommands, - patch.PatchCommands, - } - default: - return []*commands.Commands{ - commands.GlobalCommands, - patch.PatchCommands, - } - } -} -// Expand non-ambiguous command abbreviations. -// -// q --> quit -// ar --> archive -// im --> import-mbox -func expandAbbreviations(name string, sets []*commands.Commands) (string, commands.Command) { - var candidateCmd commands.Command - candidateName := name - - for _, set := range sets { - cmd := set.ByName(name) - if cmd != nil { - // Direct match, return it directly. - return name, cmd - } - // Check for partial matches. - for _, n := range set.Names() { - if !strings.HasPrefix(n, name) { - continue - } - if candidateCmd != nil { - // We have more than one command partially - // matching the input. We can't expand such an - // abbreviation, so return the command as is so - // it can raise an error later. - return name, nil - } - // We have a partial match. - candidateName = n - candidateCmd = set.ByName(n) - } - } - return candidateName, candidateCmd -} + _ "git.sr.ht/~rjarry/aerc/commands/account" + _ "git.sr.ht/~rjarry/aerc/commands/compose" + _ "git.sr.ht/~rjarry/aerc/commands/msg" + _ "git.sr.ht/~rjarry/aerc/commands/msgview" + _ "git.sr.ht/~rjarry/aerc/commands/patch" +) func execCommand( cmdline string, acct *config.AccountConfig, msg *models.MessageInfo, ) error { - cmdline, err := commands.ExpandTemplates(cmdline, acct, msg) + cmdline, cmd, err := commands.ResolveCommand(cmdline, acct, msg) if err != nil { return err } - cmdline = strings.TrimLeft(cmdline, ":") - name, rest, didCut := strings.Cut(cmdline, " ") - cmds := getCommands(app.SelectedTabContent()) - name, cmd := expandAbbreviations(name, cmds) - if cmd == nil { - return commands.NoSuchCommand(name) - } - cmdline = name - if didCut { - cmdline += " " + rest - } err = commands.ExecuteCommand(cmd, cmdline) if errors.As(err, new(commands.ErrorExit)) { ui.Exit() @@ -134,8 +52,6 @@ func execCommand( } func getCompletions(cmdline string) ([]string, string) { - cmdline = strings.TrimLeft(cmdline, ":") - // complete template terms if options, prefix, ok := commands.GetTemplateCompletion(cmdline); ok { sort.Strings(options) @@ -143,16 +59,13 @@ func getCompletions(cmdline string) ([]string, string) { } args := opt.LexArgs(cmdline) - cmds := getCommands(app.SelectedTabContent()) if args.Count() < 2 && args.TrailingSpace() == "" { // complete command names var completions []string - for _, set := range cmds { - for _, n := range set.Names() { - if strings.HasPrefix(n, cmdline) { - completions = append(completions, n+" ") - } + for _, name := range commands.ActiveCommandNames() { + if strings.HasPrefix(name, cmdline) { + completions = append(completions, name+" ") } } sort.Strings(completions) @@ -160,8 +73,8 @@ func getCompletions(cmdline string) ([]string, string) { } // complete command arguments - _, cmd := expandAbbreviations(args.Arg(0), cmds) - if cmd == nil { + _, cmd, err := commands.ExpandAbbreviations(args.Arg(0)) + if err != nil { return nil, cmdline } return commands.GetCompletions(cmd, args) |