diff --git a/tools/completion/files.go b/tools/completion/files.go index be444a22f..3072eb3d4 100644 --- a/tools/completion/files.go +++ b/tools/completion/files.go @@ -28,10 +28,13 @@ func absolutize_path(path string) string { type CompleteFilesCallback func(completion_candidate, abspath string, d fs.DirEntry) error func complete_files(prefix string, callback CompleteFilesCallback) error { - abspath := absolutize_path(prefix) base := prefix - if s, err := os.Stat(abspath); err != nil || !s.IsDir() { - base = filepath.Dir(prefix) + if base != "~" && base != "./" { + if strings.Contains(base, string(os.PathSeparator)) { + base = filepath.Dir(base) + } else { + base = "" + } } num := 0 utils.WalkWithSymlink(base, func(path, abspath string, d fs.DirEntry, err error) error { @@ -43,9 +46,12 @@ func complete_files(prefix string, callback CompleteFilesCallback) error { return nil } completion_candidate := path - if strings.HasPrefix(completion_candidate, prefix) && completion_candidate != prefix { + if strings.HasPrefix(completion_candidate, prefix) { return callback(completion_candidate, abspath, d) } + if d.IsDir() { + return fs.SkipDir + } return nil }, absolutize_path) diff --git a/tools/completion/files_test.go b/tools/completion/files_test.go index 99b68cd94..f8c9f7357 100644 --- a/tools/completion/files_test.go +++ b/tools/completion/files_test.go @@ -54,7 +54,11 @@ func TestCompleteFiles(t *testing.T) { test_abs_candidates := func(prefix string, expected ...string) { e := make([]string, len(expected)) for i, x := range expected { - e[i] = filepath.Join(tdir, x) + if filepath.IsAbs(x) { + e[i] = x + } else { + e[i] = filepath.Join(tdir, x) + } } test_candidates(prefix, e...) } @@ -71,7 +75,7 @@ func TestCompleteFiles(t *testing.T) { test_cwd_prefix("t", "two.txt") test_cwd_prefix("x") - test_abs_candidates(tdir, "one.txt", "two.txt", "odir", "odir/three.txt", "odir/four.txt") + test_abs_candidates(tdir, tdir, "one.txt", "two.txt", "odir", "odir/three.txt", "odir/four.txt") test_abs_candidates(filepath.Join(tdir, "o"), "one.txt", "odir", "odir/three.txt", "odir/four.txt") test_candidates("", "one.txt", "two.txt", "odir", "odir/three.txt", "odir/four.txt") diff --git a/tools/utils/paths.go b/tools/utils/paths.go index d54dfc1bf..a6c10559d 100644 --- a/tools/utils/paths.go +++ b/tools/utils/paths.go @@ -134,7 +134,7 @@ func (self *transformed_walker) walk(dirpath string) error { } // we cant use filepath.Join here as it calls Clean() which can alter dirpath if it contains .. or . etc. path_based_on_original_dir := dirpath - if !strings.HasSuffix(dirpath, sep) { + if !strings.HasSuffix(dirpath, sep) && dirpath != "" { path_based_on_original_dir += sep } path_based_on_original_dir += rpath