Move completion package into cli

This commit is contained in:
Kovid Goyal 2022-09-25 18:42:13 +05:30
parent 3662efdf80
commit 97acb60981
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
13 changed files with 53 additions and 47 deletions

View File

@ -361,7 +361,7 @@ func add_rc_global_opts(cmd *cli.Command) {{
def update_completion() -> None: def update_completion() -> None:
orig = sys.stdout orig = sys.stdout
try: try:
with replace_if_needed('tools/completion/kitty_generated.go') as f: with replace_if_needed('tools/cli/completion/kitty_generated.go') as f:
sys.stdout = f sys.stdout = f
generate_completions_for_kitty() generate_completions_for_kitty()
finally: finally:

View File

@ -234,7 +234,7 @@ func get_cwd_for_completion(relative_to relative_to) string {
return "" return ""
} }
func make_completer(title string, relative_to relative_to, patterns []string, f func(string, string, []string) []string) completion_func { func make_completer(title string, relative_to relative_to, patterns []string, f func(string, string, []string) []string) CompletionFunc {
lpats := make([]string, 0, len(patterns)) lpats := make([]string, 0, len(patterns))
for _, p := range patterns { for _, p := range patterns {
lpats = append(lpats, strings.ToLower(p)) lpats = append(lpats, strings.ToLower(p))
@ -253,15 +253,15 @@ func make_completer(title string, relative_to relative_to, patterns []string, f
} }
} }
func fnmatch_completer(title string, relative_to relative_to, patterns ...string) completion_func { func fnmatch_completer(title string, relative_to relative_to, patterns ...string) CompletionFunc {
return make_completer(title, relative_to, patterns, complete_by_fnmatch) return make_completer(title, relative_to, patterns, complete_by_fnmatch)
} }
func mimepat_completer(title string, relative_to relative_to, patterns ...string) completion_func { func mimepat_completer(title string, relative_to relative_to, patterns ...string) CompletionFunc {
return make_completer(title, relative_to, patterns, complete_by_mimepat) return make_completer(title, relative_to, patterns, complete_by_mimepat)
} }
func directory_completer(title string, relative_to relative_to) completion_func { func directory_completer(title string, relative_to relative_to) CompletionFunc {
if title == "" { if title == "" {
title = "Directories" title = "Directories"
} }

View File

@ -54,7 +54,7 @@ func complete_kitty(completions *Completions, word string, arg_num int) {
} }
} }
func complete_kitty_override(title string, names []string) completion_func { func complete_kitty_override(title string, names []string) CompletionFunc {
return func(completions *Completions, word string, arg_num int) { return func(completions *Completions, word string, arg_num int) {
mg := completions.add_match_group(title) mg := completions.add_match_group(title)
mg.NoTrailingSpace = true mg.NoTrailingSpace = true

View File

@ -8,7 +8,6 @@ import (
"io" "io"
"os" "os"
"kitty/tools/cli"
"kitty/tools/tty" "kitty/tools/tty"
"kitty/tools/utils" "kitty/tools/utils"
) )
@ -45,7 +44,7 @@ func init() {
var registered_exes = make(map[string]func(root *Command)) var registered_exes = make(map[string]func(root *Command))
func main(args []string) error { func Main(args []string) error {
output_type := "json" output_type := "json"
if len(args) > 0 { if len(args) > 0 {
output_type = args[0] output_type = args[0]
@ -92,15 +91,3 @@ func main(args []string) error {
} }
return err return err
} }
func EntryPoint(tool_root *cli.Command) {
tool_root.AddSubCommand(&cli.Command{
Name: "__complete__", Hidden: true,
Usage: "output_type [shell state...]",
ShortDescription: "Generate completions for kitty commands",
HelpText: "Generate completion candidates for kitty commands. The command line is read from STDIN. output_type can be one of the supported shells or 'json' for JSON output.",
Run: func(cmd *cli.Command, args []string) (ret int, err error) {
return ret, main(args)
},
})
}

View File

@ -128,14 +128,14 @@ func (self *Completions) add_match_group(title string) *MatchGroup {
return &ans return &ans
} }
type completion_func func(completions *Completions, word string, arg_num int) type CompletionFunc func(completions *Completions, word string, arg_num int)
type Option struct { type Option struct {
Name string Name string
Aliases []string Aliases []string
Description string Description string
Has_following_arg bool Has_following_arg bool
Completion_for_arg completion_func Completion_for_arg CompletionFunc
} }
type CommandGroup struct { type CommandGroup struct {
@ -150,7 +150,7 @@ type Command struct {
Options []*Option Options []*Option
Groups []*CommandGroup Groups []*CommandGroup
Completion_for_arg completion_func Completion_for_arg CompletionFunc
Stop_processing_at_arg int Stop_processing_at_arg int
First_arg_may_not_be_subcommand bool First_arg_may_not_be_subcommand bool
Subcommand_must_be_first bool Subcommand_must_be_first bool
@ -257,7 +257,7 @@ func (self *Command) GetCompletions(argv []string, init_completions func(*Comple
return &ans return &ans
} }
func names_completer(title string, names ...string) completion_func { func names_completer(title string, names ...string) CompletionFunc {
return func(completions *Completions, word string, arg_num int) { return func(completions *Completions, word string, arg_num int) {
mg := completions.add_match_group(title) mg := completions.add_match_group(title)
for _, q := range names { for _, q := range names {
@ -268,7 +268,7 @@ func names_completer(title string, names ...string) completion_func {
} }
} }
func chain_completers(completers ...completion_func) completion_func { func chain_completers(completers ...CompletionFunc) CompletionFunc {
return func(completions *Completions, word string, arg_num int) { return func(completions *Completions, word string, arg_num int) {
for _, f := range completers { for _, f := range completers {
f(completions, word, arg_num) f(completions, word, arg_num)

View File

@ -99,12 +99,15 @@ type multi_scan struct {
var mpat *regexp.Regexp var mpat *regexp.Regexp
func (self *Option) init_option() {
self.values_from_cmdline = make([]string, 0, 1)
self.parsed_values_from_cmdline = make([]any, 0, 1)
}
func option_from_spec(spec OptionSpec) (*Option, error) { func option_from_spec(spec OptionSpec) (*Option, error) {
ans := Option{ ans := Option{
Help: spec.Help, Help: spec.Help,
values_from_cmdline: make([]string, 0, 1),
parsed_values_from_cmdline: make([]any, 0, 1),
} }
ans.init_option()
parts := strings.Split(spec.Name, " ") parts := strings.Split(spec.Name, " ")
ans.Name = camel_case_dest(parts[0]) ans.Name = camel_case_dest(parts[0])
ans.Aliases = make([]Alias, len(parts)) ans.Aliases = make([]Alias, len(parts))
@ -173,6 +176,7 @@ func option_from_spec(spec OptionSpec) (*Option, error) {
if ans.IsList { if ans.IsList {
ans.parsed_default = []string{} ans.parsed_default = []string{}
} }
ans.CompletionFunc = spec.CompletionFunc
if ans.Aliases == nil || len(ans.Aliases) == 0 { if ans.Aliases == nil || len(ans.Aliases) == 0 {
return nil, fmt.Errorf("No --aliases specified for option") return nil, fmt.Errorf("No --aliases specified for option")
} }

View File

@ -10,6 +10,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"kitty/tools/cli/completion"
"kitty/tools/utils" "kitty/tools/utils"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
@ -42,26 +43,28 @@ func (self *Alias) String() string {
} }
type OptionSpec struct { type OptionSpec struct {
Name string Name string
Type string Type string
Dest string Dest string
Choices string Choices string
Depth int Depth int
Default string Default string
Help string Help string
CompletionFunc *completion.CompletionFunc
} }
type Option struct { type Option struct {
Name string Name string
Aliases []Alias Aliases []Alias
Choices []string Choices []string
Default string Default string
OptionType OptionType OptionType OptionType
Hidden bool Hidden bool
Depth int Depth int
Help string Help string
IsList bool IsList bool
Parent *Command Parent *Command
CompletionFunc *completion.CompletionFunc
values_from_cmdline []string values_from_cmdline []string
parsed_values_from_cmdline []any parsed_values_from_cmdline []any
@ -241,6 +244,7 @@ func (self *OptionGroup) Clone(parent *Command) *OptionGroup {
ans := OptionGroup{Title: self.Title, Options: make([]*Option, len(self.Options))} ans := OptionGroup{Title: self.Title, Options: make([]*Option, len(self.Options))}
for i, o := range self.Options { for i, o := range self.Options {
c := *o c := *o
c.init_option()
c.Parent = parent c.Parent = parent
ans.Options[i] = &c ans.Options[i] = &c
} }

View File

@ -4,17 +4,28 @@ package main
import ( import (
"kitty/tools/cli" "kitty/tools/cli"
"kitty/tools/cli/completion"
"kitty/tools/cmd/at" "kitty/tools/cmd/at"
"kitty/tools/completion"
) )
func completion_entry_point(tool_root *cli.Command) {
tool_root.AddSubCommand(&cli.Command{
Name: "__complete__", Hidden: true,
Usage: "output_type [shell state...]",
ShortDescription: "Generate completions for kitty commands",
HelpText: "Generate completion candidates for kitty commands. The command line is read from STDIN. output_type can be one of the supported shells or 'json' for JSON output.",
Run: func(cmd *cli.Command, args []string) (ret int, err error) {
return ret, completion.Main(args)
},
})
}
func main() { func main() {
root := cli.NewRootCommand() root := cli.NewRootCommand()
root.ShortDescription = "Fast, statically compiled implementations for various kitty command-line tools" root.ShortDescription = "Fast, statically compiled implementations for various kitty command-line tools"
root.Usage = "command [command options] [command args]" root.Usage = "command [command options] [command args]"
at.EntryPoint(root) at.EntryPoint(root)
completion.EntryPoint(root) completion_entry_point(root)
root.Exec() root.Exec()
} }