args completion for rc commands
This commit is contained in:
parent
d4b67f3b6a
commit
c9d986f9a8
@ -51,6 +51,8 @@ def generate_completion_for_rc(name: str) -> None:
|
||||
cmd = command_for_name(name)
|
||||
if cmd.short_desc:
|
||||
print(f'{name}.Description = "{serialize_as_go_string(cmd.short_desc)}"')
|
||||
for x in cmd.args.as_go_completion_code(name):
|
||||
print(x)
|
||||
|
||||
|
||||
def generate_completions_for_kitty() -> None:
|
||||
|
||||
@ -197,6 +197,26 @@ class ArgsHandling:
|
||||
return 0
|
||||
return self.count
|
||||
|
||||
def as_go_completion_code(self, go_name: str) -> Iterator[str]:
|
||||
from ..cli import serialize_as_go_string
|
||||
c = self.args_count
|
||||
if c is not None:
|
||||
yield f'{go_name}.Stop_processing_at_arg = {c}'
|
||||
if self.completion:
|
||||
for k, v in self.completion.items():
|
||||
if k == 'files':
|
||||
title, pats = v
|
||||
assert isinstance(pats, tuple)
|
||||
gpats = (f'"{serialize_as_go_string(x)}"' for x in pats)
|
||||
yield f'{go_name}.Completion_for_arg = fnmatch_completer("{serialize_as_go_string(title)}", {", ".join(gpats)})'
|
||||
elif k == 'names':
|
||||
title, gen = v
|
||||
assert callable(gen)
|
||||
gpats = (f'"{serialize_as_go_string(x)}"' for x in gen())
|
||||
yield f'{go_name}.Completion_for_arg = names_completer("{serialize_as_go_string(title)}", {", ".join(gpats)})'
|
||||
else:
|
||||
raise KeyError(f'Unknown args completion type: {k}')
|
||||
|
||||
def as_go_code(self, cmd_name: str, field_types: Dict[str, str], handled_fields: Set[str]) -> Iterator[str]:
|
||||
c = self.args_count
|
||||
if c == 0:
|
||||
|
||||
@ -83,9 +83,9 @@ def completion(self: TestCompletion, tdir: str):
|
||||
make_file('bin/exe1', 0o700)
|
||||
make_file('bin/exe-not1')
|
||||
make_file('exe2', 0o700)
|
||||
make_file('exe-not2')
|
||||
make_file('exe-not2.jpeg')
|
||||
make_file('sub/exe3', 0o700)
|
||||
make_file('sub/exe-not3')
|
||||
make_file('sub/exe-not3.png')
|
||||
|
||||
add('kitty x', all_words())
|
||||
add('kitty e', all_words('exe1'))
|
||||
@ -96,6 +96,13 @@ def completion(self: TestCompletion, tdir: str):
|
||||
add('kitty ~/', all_words('~/exe3'))
|
||||
add('kitty ~/e', all_words('~/exe3'))
|
||||
|
||||
add('kitty @ goto-layout ', has_words('tall', 'fat'))
|
||||
add('kitty @ goto-layout spli', all_words('splits'))
|
||||
add('kitty @ goto-layout f f', all_words())
|
||||
add('kitty @ set-window-logo ', all_words('exe-not2.jpeg', 'sub/exe-not3.png'))
|
||||
add('kitty @ set-window-logo e', all_words('exe-not2.jpeg'))
|
||||
add('kitty @ set-window-logo e e', all_words())
|
||||
|
||||
for cmd, tests, result in zip(all_cmds, all_tests, run_tool()):
|
||||
self.current_cmd = cmd
|
||||
for test in tests:
|
||||
|
||||
@ -78,3 +78,36 @@ func complete_executables_in_path(prefix string, paths ...string) []string {
|
||||
}
|
||||
return ans
|
||||
}
|
||||
|
||||
func complete_by_fnmatch(prefix string, patterns []string) []string {
|
||||
ans := make([]string, 0, 1024)
|
||||
complete_files(prefix, func(completion_candidate, abspath string, d fs.DirEntry) error {
|
||||
q := strings.ToLower(filepath.Base(abspath))
|
||||
for _, pat := range patterns {
|
||||
matched, err := filepath.Match(pat, q)
|
||||
if err == nil && matched {
|
||||
ans = append(ans, completion_candidate)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return ans
|
||||
}
|
||||
|
||||
func fnmatch_completer(title string, patterns ...string) completion_func {
|
||||
lpats := make([]string, 0, len(patterns))
|
||||
for _, p := range patterns {
|
||||
lpats = append(lpats, strings.ToLower(p))
|
||||
}
|
||||
|
||||
return func(completions *Completions, word string, arg_num int) {
|
||||
q := complete_by_fnmatch(word, lpats)
|
||||
if len(q) > 0 {
|
||||
mg := completions.add_match_group(title)
|
||||
mg.IsFiles = true
|
||||
for _, c := range q {
|
||||
mg.add_match(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,3 +136,14 @@ func (self *Command) GetCompletions(argv []string) *Completions {
|
||||
ans.Groups = non_empty_groups
|
||||
return &ans
|
||||
}
|
||||
|
||||
func names_completer(title string, names ...string) completion_func {
|
||||
return func(completions *Completions, word string, arg_num int) {
|
||||
mg := completions.add_match_group(title)
|
||||
for _, q := range names {
|
||||
if strings.HasPrefix(q, word) {
|
||||
mg.add_match(q)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user