aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Ovchinnikov <v@postbox.nz>2023-09-17 20:06:32 +0000
committerRobin Jarry <robin@jarry.cc>2023-09-19 10:45:09 +0200
commit194d263bbe2bd685b192ddcebbc64c099e3a8dc1 (patch)
tree28ba4855f780456a37727af9a455fa4e775b52d7
parent8f15b804d1a760d4f4e5c0c47a8a26ee2c04a830 (diff)
downloadaerc-194d263bbe2bd685b192ddcebbc64c099e3a8dc1.tar.gz
aerc-194d263bbe2bd685b192ddcebbc64c099e3a8dc1.zip
commands: run a command by its first letters
Check if the command entered after : is the abbreviation of an existing command and run that instead. This is only done if there is no complete name matching first-hand and if the abbreviation matches just one command. Signed-off-by: Vitaly Ovchinnikov <v@postbox.nz> Acked-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
-rw-r--r--main.go42
1 files changed, 42 insertions, 0 deletions
diff --git a/main.go b/main.go
index 4705c438..4e0e4a4d 100644
--- a/main.go
+++ b/main.go
@@ -62,11 +62,53 @@ func getCommands(selected libui.Drawable) []*commands.Commands {
}
}
+// Expand non-ambiguous command abbreviations.
+//
+// :q --> :quit
+// :ar --> :archive
+// :im --> :import-mbox
+func expandAbbreviations(cmd []string, sets []*commands.Commands) []string {
+ if len(cmd) == 0 {
+ return cmd
+ }
+ name := cmd[0]
+ candidate := ""
+ for _, set := range sets {
+ if set.ByName(name) != nil {
+ // Direct match, return it directly.
+ return cmd
+ }
+ // Check for partial matches.
+ for _, n := range set.Names() {
+ if !strings.HasPrefix(n, name) {
+ continue
+ }
+ if candidate != "" {
+ // 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 cmd
+ }
+ // We have a partial match.
+ candidate = n
+ }
+ }
+ // As we are here, we could have a command name matching our partial
+ // name in `cmd`. In that case we replace the name in `cmd` with the
+ // full name, otherwise we simply return `cmd` as is.
+ if candidate != "" {
+ cmd[0] = candidate
+ }
+ return cmd
+}
+
func execCommand(
aerc *widgets.Aerc, ui *libui.UI, cmd []string,
acct *config.AccountConfig, msg *models.MessageInfo,
) error {
cmds := getCommands(aerc.SelectedTabContent())
+ cmd = expandAbbreviations(cmd, cmds)
for i, set := range cmds {
err := set.ExecuteCommand(aerc, cmd, acct, msg)
if err != nil {