mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-10-26 15:13:22 +03:00
204 lines
5.1 KiB
Go
204 lines
5.1 KiB
Go
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
|
|
|
|
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
var _ = fmt.Print
|
|
var _ = os.Getenv
|
|
|
|
func (self *Completions) add_group(group *MatchGroup) {
|
|
if len(group.Matches) > 0 {
|
|
self.Groups = append(self.Groups, group)
|
|
}
|
|
}
|
|
|
|
func (self *Completions) add_options_group(options []*Option, word string) {
|
|
group := self.AddMatchGroup("Options")
|
|
if strings.HasPrefix(word, "--") {
|
|
if word == "--" {
|
|
group.Matches = append(group.Matches, &Match{Word: "--", Description: "End of options"})
|
|
}
|
|
for _, opt := range options {
|
|
for _, q := range opt.Aliases {
|
|
if strings.HasPrefix(q.String(), word) {
|
|
group.Matches = append(group.Matches, &Match{Word: q.String(), Description: opt.Help})
|
|
break
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if word == "-" {
|
|
group.Matches = append(group.Matches, &Match{Word: "--", Description: "End of options"})
|
|
for _, opt := range options {
|
|
has_single_letter_alias := false
|
|
for _, q := range opt.Aliases {
|
|
if q.IsShort {
|
|
group.AddMatch("-"+q.NameWithoutHyphens, opt.Help)
|
|
has_single_letter_alias = true
|
|
break
|
|
}
|
|
}
|
|
if !has_single_letter_alias {
|
|
for _, q := range opt.Aliases {
|
|
if !q.IsShort {
|
|
group.AddMatch(q.String(), opt.Help)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
runes := []rune(word)
|
|
last_letter := string(runes[len(runes)-1])
|
|
for _, opt := range options {
|
|
for _, q := range opt.Aliases {
|
|
if q.IsShort && q.NameWithoutHyphens == last_letter {
|
|
group.AddMatch(word, opt.Help)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (self *Command) sub_command_allowed_at(completions *Completions, arg_num int) bool {
|
|
if self.SubCommandMustBeFirst {
|
|
return arg_num == 1 && completions.CurrentWordIdxInParent == 1
|
|
}
|
|
return arg_num == 1
|
|
}
|
|
|
|
func complete_word(word string, completions *Completions, only_args_allowed bool, expecting_arg_for *Option, arg_num int) {
|
|
cmd := completions.CurrentCmd
|
|
if expecting_arg_for != nil {
|
|
if expecting_arg_for.Completer != nil {
|
|
expecting_arg_for.Completer(completions, word, arg_num)
|
|
}
|
|
return
|
|
}
|
|
if !only_args_allowed && strings.HasPrefix(word, "-") {
|
|
if strings.HasPrefix(word, "--") && strings.Contains(word, "=") {
|
|
idx := strings.Index(word, "=")
|
|
option := cmd.FindOption(word[:idx])
|
|
if option != nil {
|
|
if option.Completer != nil {
|
|
option.Completer(completions, word[idx+1:], arg_num)
|
|
completions.AddPrefixToAllMatches(word[:idx+1])
|
|
}
|
|
}
|
|
} else {
|
|
completions.add_options_group(cmd.AllOptions(), word)
|
|
}
|
|
return
|
|
}
|
|
if cmd.HasVisibleSubCommands() && cmd.sub_command_allowed_at(completions, arg_num) {
|
|
for _, cg := range cmd.SubCommandGroups {
|
|
group := completions.AddMatchGroup(cg.Title)
|
|
if group.Title == "" {
|
|
group.Title = "Sub-commands"
|
|
}
|
|
for _, sc := range cg.SubCommands {
|
|
if strings.HasPrefix(sc.Name, word) {
|
|
t := sc.ShortDescription
|
|
if t == "" {
|
|
t = sc.HelpText
|
|
}
|
|
group.AddMatch(sc.Name, t)
|
|
}
|
|
}
|
|
}
|
|
if cmd.SubCommandIsOptional && cmd.ArgCompleter != nil {
|
|
cmd.ArgCompleter(completions, word, arg_num)
|
|
}
|
|
return
|
|
}
|
|
|
|
if cmd.ArgCompleter != nil {
|
|
cmd.ArgCompleter(completions, word, arg_num)
|
|
}
|
|
return
|
|
}
|
|
|
|
func completion_parse_args(cmd *Command, words []string, completions *Completions) {
|
|
completions.CurrentCmd = cmd
|
|
if len(words) == 0 {
|
|
complete_word("", completions, false, nil, 0)
|
|
return
|
|
}
|
|
completions.AllWords = words
|
|
|
|
var expecting_arg_for *Option
|
|
only_args_allowed := false
|
|
arg_num := 0
|
|
|
|
for i, word := range words {
|
|
cmd = completions.CurrentCmd
|
|
completions.CurrentWordIdx = i
|
|
completions.CurrentWordIdxInParent++
|
|
is_last_word := i == len(words)-1
|
|
is_option_equal := completions.split_on_equals && word == "=" && expecting_arg_for != nil
|
|
if only_args_allowed || (expecting_arg_for == nil && !strings.HasPrefix(word, "-")) {
|
|
if !is_option_equal {
|
|
arg_num++
|
|
}
|
|
if arg_num == 1 {
|
|
cmd.IndexOfFirstArg = completions.CurrentWordIdx
|
|
}
|
|
}
|
|
if is_last_word {
|
|
if is_option_equal {
|
|
word = ""
|
|
}
|
|
complete_word(word, completions, only_args_allowed, expecting_arg_for, arg_num)
|
|
} else {
|
|
if expecting_arg_for != nil {
|
|
if is_option_equal {
|
|
continue
|
|
}
|
|
expecting_arg_for = nil
|
|
continue
|
|
}
|
|
if word == "--" {
|
|
only_args_allowed = true
|
|
continue
|
|
}
|
|
if !only_args_allowed && strings.HasPrefix(word, "-") {
|
|
if !strings.Contains(word, "=") {
|
|
option := cmd.FindOption(word)
|
|
if option != nil && option.needs_argument() {
|
|
expecting_arg_for = option
|
|
}
|
|
}
|
|
continue
|
|
}
|
|
if cmd.HasVisibleSubCommands() && cmd.sub_command_allowed_at(completions, arg_num) {
|
|
sc := cmd.FindSubCommand(word)
|
|
if sc == nil {
|
|
only_args_allowed = true
|
|
continue
|
|
}
|
|
completions.CurrentCmd = sc
|
|
cmd = sc
|
|
arg_num = 0
|
|
completions.CurrentWordIdxInParent = 0
|
|
only_args_allowed = cmd.OnlyArgsAllowed
|
|
if cmd.ParseArgsForCompletion != nil {
|
|
cmd.ParseArgsForCompletion(cmd, words[i+1:], completions)
|
|
return
|
|
}
|
|
} else if cmd.StopCompletingAtArg > 0 && arg_num >= cmd.StopCompletingAtArg {
|
|
return
|
|
} else {
|
|
only_args_allowed = true
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
}
|