When completing on patterns exclude directories that only contain files that dont match

This commit is contained in:
Kovid Goyal 2022-09-16 08:56:07 +05:30
parent 3c29ce936b
commit 18c3e46ac6
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 39 additions and 7 deletions

View File

@ -99,7 +99,7 @@ def completion(self: TestCompletion, tdir: str):
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/', 'bin/'))
add('kitty @ set-window-logo ', all_words('exe-not2.jpeg', 'sub/'))
add('kitty @ set-window-logo e', all_words('exe-not2.jpeg'))
add('kitty @ set-window-logo e e', all_words())

View File

@ -121,19 +121,51 @@ func complete_executables_in_path(prefix string, paths ...string) []string {
return ans
}
func is_dir_or_symlink_to_dir(entry os.DirEntry, path string) bool {
if entry.IsDir() {
return true
}
if entry.Type()&os.ModeSymlink == os.ModeSymlink {
p, err := filepath.EvalSymlinks(path)
if err == nil {
s, err := os.Stat(p)
if err == nil && s.IsDir() {
return true
}
}
}
return false
}
func complete_by_fnmatch(prefix string, patterns []string) []string {
ans := make([]string, 0, 1024)
matches := func(name string) bool {
for _, pat := range patterns {
matched, err := filepath.Match(pat, name)
if err == nil && matched {
return true
}
}
return false
}
complete_files(prefix, func(entry *FileEntry) {
if entry.is_dir && !entry.is_empty_dir {
ans = append(ans, entry.completion_candidate)
entries, err := os.ReadDir(entry.abspath)
if err == nil {
for _, e := range entries {
if matches(e.Name()) || is_dir_or_symlink_to_dir(e, filepath.Join(entry.abspath, e.Name())) {
ans = append(ans, entry.completion_candidate)
return
}
}
}
return
}
q := strings.ToLower(entry.name)
for _, pat := range patterns {
matched, err := filepath.Match(pat, q)
if err == nil && matched {
ans = append(ans, entry.completion_candidate)
}
if matches(q) {
ans = append(ans, entry.completion_candidate)
}
})
return ans