From 2a0961701c4cabecc53d134ed1782e5612e64580 Mon Sep 17 00:00:00 2001 From: Gregory Mullen Date: Thu, 27 Jun 2019 10:33:11 -0700 Subject: Implement basic tab completion support Tab completion currently only works on commands. Contextual completion will be added in the future. --- commands/commands.go | 78 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 9 deletions(-) (limited to 'commands/commands.go') diff --git a/commands/commands.go b/commands/commands.go index 04462d2..8d50b41 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -2,27 +2,47 @@ package commands import ( "errors" + "strings" "github.com/google/shlex" "git.sr.ht/~sircmpwn/aerc/widgets" ) -type AercCommand func(aerc *widgets.Aerc, args []string) error +type Command interface { + Aliases() []string + Execute(*widgets.Aerc, []string) error + Complete(*widgets.Aerc, []string) []string +} -type Commands map[string]AercCommand +type Commands map[string]Command func NewCommands() *Commands { - cmds := Commands(make(map[string]AercCommand)) + cmds := Commands(make(map[string]Command)) return &cmds } -func (cmds *Commands) dict() map[string]AercCommand { - return map[string]AercCommand(*cmds) +func (cmds *Commands) dict() map[string]Command { + return map[string]Command(*cmds) } -func (cmds *Commands) Register(name string, cmd AercCommand) { - cmds.dict()[name] = cmd +func (cmds *Commands) Names() []string { + names := make([]string, 0) + + for k := range cmds.dict() { + names = append(names, k) + } + return names +} + +func (cmds *Commands) Register(cmd Command) { + // TODO enforce unique aliases, until then, duplicate each + if len(cmd.Aliases()) < 1 { + return + } + for _, alias := range cmd.Aliases() { + cmds.dict()[alias] = cmd + } } type NoSuchCommand string @@ -43,8 +63,48 @@ func (cmds *Commands) ExecuteCommand(aerc *widgets.Aerc, cmd string) error { if len(args) == 0 { return errors.New("Expected a command.") } - if fn, ok := cmds.dict()[args[0]]; ok { - return fn(aerc, args) + if cmd, ok := cmds.dict()[args[0]]; ok { + return cmd.Execute(aerc, args) } return NoSuchCommand(args[0]) } + +func (cmds *Commands) GetCompletions(aerc *widgets.Aerc, cmd string) []string { + args, err := shlex.Split(cmd) + if err != nil { + return nil + } + + if len(args) == 0 { + return nil + } + + if len(args) > 1 { + if cmd, ok := cmds.dict()[args[0]]; ok { + completions := cmd.Complete(aerc, args[1:]) + if completions != nil && len(completions) == 0 { + return nil + } + + options := make([]string, 0) + for _, option := range completions { + options = append(options, args[0]+" "+option) + } + return options + } + return nil + } + + names := cmds.Names() + options := make([]string, 0) + for _, name := range names { + if strings.HasPrefix(name, args[0]) { + options = append(options, name) + } + } + + if len(options) > 0 { + return options + } + return nil +} -- cgit v1.2.3