handle bash splitting completion cmdline on equals

This commit is contained in:
Kovid Goyal 2022-09-19 17:37:25 +05:30
parent b04b483b3f
commit 24c2d27eea
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 19 additions and 2 deletions

View File

@ -22,7 +22,12 @@ func bash_output_serializer(completions []*Completions, shell_state map[string]s
return []byte(output.String()), nil return []byte(output.String()), nil
} }
func bash_init_completions(completions *Completions) {
completions.split_on_equals = true
}
func init() { func init() {
input_parsers["bash"] = shell_input_parser input_parsers["bash"] = shell_input_parser
output_serializers["bash"] = bash_output_serializer output_serializers["bash"] = bash_output_serializer
init_completions["bash"] = bash_init_completions
} }

View File

@ -38,6 +38,7 @@ type serializer_func func(completions []*Completions, shell_state map[string]str
var input_parsers = make(map[string]parser_func, 4) var input_parsers = make(map[string]parser_func, 4)
var output_serializers = make(map[string]serializer_func, 4) var output_serializers = make(map[string]serializer_func, 4)
var init_completions = make(map[string]func(*Completions), 4)
func init() { func init() {
input_parsers["json"] = json_input_parser input_parsers["json"] = json_input_parser
@ -84,7 +85,7 @@ func main(args []string) error {
all_completions := make([]*Completions, 0, 1) all_completions := make([]*Completions, 0, 1)
for _, argv := range all_argv { for _, argv := range all_argv {
all_completions = append(all_completions, root.GetCompletions(argv)) all_completions = append(all_completions, root.GetCompletions(argv, init_completions[output_type]))
} }
output, err := output_serializer(all_completions, shell_state) output, err := output_serializer(all_completions, shell_state)
if err == nil { if err == nil {

View File

@ -153,9 +153,15 @@ func default_parse_args(cmd *Command, words []string, completions *Completions)
} }
} }
if is_last_word { if is_last_word {
if completions.split_on_equals && word == "=" {
word = ""
}
complete_word(word, completions, only_args_allowed, expecting_arg_for, arg_num) complete_word(word, completions, only_args_allowed, expecting_arg_for, arg_num)
} else { } else {
if expecting_arg_for != nil { if expecting_arg_for != nil {
if completions.split_on_equals && word == "=" {
continue
}
expecting_arg_for = nil expecting_arg_for = nil
continue continue
} }

View File

@ -107,6 +107,8 @@ type Completions struct {
all_words []string // all words passed to parse_args() all_words []string // all words passed to parse_args()
current_word_idx int // index of current word in all_words current_word_idx int // index of current word in all_words
current_word_idx_in_parent int // index of current word in parents command line 1 for first word after parent current_word_idx_in_parent int // index of current word in parents command line 1 for first word after parent
split_on_equals bool // true if the cmdline is split on = (BASH does this because readline does this)
} }
func (self *Completions) add_prefix_to_all_matches(prefix string) { func (self *Completions) add_prefix_to_all_matches(prefix string) {
@ -229,8 +231,11 @@ func (self *Command) add_option(opt *Option) {
self.Options = append(self.Options, opt) self.Options = append(self.Options, opt)
} }
func (self *Command) GetCompletions(argv []string) *Completions { func (self *Command) GetCompletions(argv []string, init_completions func(*Completions)) *Completions {
ans := Completions{Groups: make([]*MatchGroup, 0, 4)} ans := Completions{Groups: make([]*MatchGroup, 0, 4)}
if init_completions != nil {
init_completions(&ans)
}
if len(argv) > 0 { if len(argv) > 0 {
exe := argv[0] exe := argv[0]
cmd := self.find_subcommand_with_name(exe) cmd := self.find_subcommand_with_name(exe)