aboutsummaryrefslogtreecommitdiffstats
path: root/commands
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2024-01-28 02:08:27 +0100
committerRobin Jarry <robin@jarry.cc>2024-01-29 22:46:08 +0100
commit50705608bb39108ab7b6627c6a4146e66a2facf5 (patch)
tree4ce960217802175b5976e756e3d623f26af60fc4 /commands
parent5719041eb9b846c7d056952e9e14295c65a8b81a (diff)
downloadaerc-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.go103
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
}