From 324b95f825502f1d9b00784a9bdf8aaf9acf105b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 25 Jun 2025 08:35:38 +0530 Subject: [PATCH] Fix recursion into symlinks to dirs --- kittens/choose_files/results.go | 7 ++++++- kittens/choose_files/scan.go | 7 ++++--- tools/icons/file-types.go | 6 +++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/kittens/choose_files/results.go b/kittens/choose_files/results.go index 49c46ea79..d61f6f72c 100644 --- a/kittens/choose_files/results.go +++ b/kittens/choose_files/results.go @@ -109,7 +109,12 @@ func icon_for(path string, x os.FileMode) string { if ans := icon_cache[path]; ans != "" { return ans } - ans := icons.IconForFileWithMode(path, x, true) + var ans string + if x == fs.ModeDir|1 { + ans = string(icons.SYMLINK_TO_DIR) + } else { + ans = icons.IconForFileWithMode(path, x, true) + } if wcswidth.Stringwidth(ans) == 1 { ans += " " } diff --git a/kittens/choose_files/scan.go b/kittens/choose_files/scan.go index fd6e7a2bd..89bb1ebab 100644 --- a/kittens/choose_files/scan.go +++ b/kittens/choose_files/scan.go @@ -196,6 +196,7 @@ func (fss *FileSystemScanner) worker() { }() seen_dirs := make(map[string]bool) dir, _ := filepath.Abs(fss.root_dir) + root_dir := dir base := "" pos := 0 var arena []sortable_dir_entry @@ -210,7 +211,7 @@ func (fss *FileSystemScanner) worker() { seen_dirs[dir] = true entries, err := fss.dir_reader(dir) if err != nil { - if dir == fss.root_dir { + if dir == root_dir { fss.keep_going.Store(false) fss.mutex.Lock() fss.err = err @@ -224,11 +225,12 @@ func (fss *FileSystemScanner) worker() { } arena = arena[:len(entries)] sortable = sortable[:len(entries)] + bdir := dir + string(os.PathSeparator) for i, e := range entries { arena[i].name = e.Name() ftype := e.Type() if ftype&fs.ModeSymlink != 0 { - if st, err := e.Info(); err == nil && st.IsDir() { + if st, err := os.Stat(bdir + arena[i].name); err == nil && st.IsDir() { ftype = fs.ModeDir | 1 // 1 indicates was originally a symlink } } @@ -250,7 +252,6 @@ func (fss *FileSystemScanner) worker() { copy(ns, fss.results) } new_items := ns[len(ns):new_sz] - bdir := dir + string(os.PathSeparator) for i, e := range sortable { new_items[i].ftype = e.ftype new_items[i].abspath = bdir + e.name diff --git a/tools/icons/file-types.go b/tools/icons/file-types.go index 9098f4195..213dd6da0 100644 --- a/tools/icons/file-types.go +++ b/tools/icons/file-types.go @@ -139,7 +139,8 @@ const ( SQLITE rune = 0xe7c4 //  SUBLIME rune = 0xe7aa //  SUBTITLE rune = 0xf0a16 // 󰨖 - SYMLINK rune = 0xf481 + SYMLINK rune = 0xf481 //  + SYMLINK_TO_DIR rune = 0xf482 //  TERRAFORM rune = 0xf1062 // 󱁢 TEXT rune = 0xf15c //  TMUX rune = 0xebc8 //  @@ -1109,6 +1110,9 @@ func IconForFileWithMode(path string, mode fs.FileMode, follow_symlinks bool) st if follow_symlinks { if dest, err := os.Readlink(path); err == nil { if st, err := os.Stat(dest); err == nil { + if st.IsDir() { + return string(SYMLINK_TO_DIR) + } return IconForFileWithMode(dest, st.Mode(), follow_symlinks) } }