diff options
author | Koni Marti <koni.marti@gmail.com> | 2024-01-28 02:08:27 +0100 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2024-01-29 22:46:08 +0100 |
commit | 50705608bb39108ab7b6627c6a4146e66a2facf5 (patch) | |
tree | 4ce960217802175b5976e756e3d623f26af60fc4 /commands | |
parent | 5719041eb9b846c7d056952e9e14295c65a8b81a (diff) | |
download | aerc-50705608bb39108ab7b6627c6a4146e66a2facf5.tar.gz |
menu: use listbox as fallback command
Implement the listbox widget as fallback picker when no command to :menu
was specified or the command cannot be found in PATH.
The listbox will also be used with "-" as the shell command:
:menu -c "-" -d :cf
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'commands')
-rw-r--r-- | commands/menu.go | 103 |
1 files changed, 76 insertions, 27 deletions
diff --git a/commands/menu.go b/commands/menu.go index 908a354c..e14e4e83 100644 --- a/commands/menu.go +++ b/commands/menu.go @@ -44,9 +44,11 @@ func (m Menu) Execute([]string) error { if m.Command == "" { m.Command = config.General.DefaultMenuCmd } - if m.Command == "" { - return errors.New( - "Either -c <command> or default-menu-cmd is required.") + useFallback := m.useFallback() + if m.Background && useFallback { + return errors.New("Either -c <command> or " + + "default-menu-cmd is required to run " + + "in the background.") } if _, _, err := ResolveCommand(m.Xargs, nil, nil); err != nil { return err @@ -57,6 +59,12 @@ func (m Menu) Execute([]string) error { return err } + title := " :" + strings.TrimLeft(m.Xargs, ": \t") + " ... " + + if useFallback { + return m.fallback(title, lines) + } + pick, err := os.CreateTemp("", "aerc-menu-*") if err != nil { return err @@ -91,26 +99,7 @@ func (m Menu) Execute([]string) error { if len(buf) == 0 { return } - var cmd Command - var cmdline string - - for _, line := range strings.Split(string(buf), "\n") { - line = strings.TrimSpace(line) - if line == "" { - continue - } - cmdline = m.Xargs + " " + line - cmdline, cmd, err = ResolveCommand(cmdline, nil, nil) - if err == nil { - err = ExecuteCommand(cmd, cmdline) - } - if err != nil { - app.PushError(m.Xargs + ": " + err.Error()) - if m.ErrExit { - return - } - } - } + m.runCmd(string(buf)) } if m.Background { @@ -129,13 +118,73 @@ func (m Menu) Execute([]string) error { xargs(err) } - title := " :" + strings.TrimLeft(m.Xargs, ": \t") + " ... " + widget := ui.NewBox(term, title, "", app.SelectedAccountUiConfig()) + app.AddDialog(app.DefaultDialog(widget)) + } + + return nil +} + +func (m Menu) useFallback() bool { + if m.Command == "" || m.Command == "-" { + warnMsg := "no command provided, falling back on aerc's picker." + log.Warnf(warnMsg) + app.PushWarning(warnMsg) + return true + } + cmd, _, _ := strings.Cut(m.Command, " ") + _, err := exec.LookPath(cmd) + if err != nil { + warnMsg := "command '" + cmd + "' not found in PATH, " + + "falling back on aerc's picker." + log.Warnf(warnMsg) + app.PushWarning(warnMsg) + return true + } + return false +} - app.AddDialog(app.DefaultDialog( - ui.NewBox(term, title, "", app.SelectedAccountUiConfig()), - )) +func (m Menu) runCmd(buffer string) { + var ( + cmd Command + cmdline string + err error + ) + + for _, line := range strings.Split(buffer, "\n") { + line = strings.TrimSpace(line) + if line == "" { + continue + } + cmdline = m.Xargs + " " + line + cmdline, cmd, err = ResolveCommand(cmdline, nil, nil) + if err == nil { + err = ExecuteCommand(cmd, cmdline) + } + if err != nil { + app.PushError(m.Xargs + ": " + err.Error()) + if m.ErrExit { + return + } + } } +} +func (m Menu) fallback(title string, lines []string) error { + listBox := app.NewListBox( + title, lines, app.SelectedAccountUiConfig(), + func(line string) { + app.CloseDialog() + if line == "" { + return + } + m.runCmd(line) + }) + listBox.SetTextFilter(func(list []string, term string) []string { + return FilterList(list, term, func(s string) string { return s }) + }) + widget := ui.NewBox(listBox, "", "", app.SelectedAccountUiConfig()) + app.AddDialog(app.DefaultDialog(widget)) return nil } |