@@ -2,35 +2,61 @@ local M = {}
22
33--- @class FileInfo
44--- @field name string # File name or path
5- --- @field type string # File type (file/directory/etc)
5+ --- @field type string # File type (file/directory/link/ etc)
66--- @field size number # File size in bytes
77--- @field modified number # Last modification timestamp
8+ --- @field symlink_target string | nil # If type is 'link', the target path
89
910--- @class DirectoryInfo
1011--- @field path string # Current directory path
1112--- @field is_git boolean # Whether the directory is a git repository
1213--- @field files FileInfo[] # List of files in the directory
1314
15+ --- @param path ? string # Directory path to scan (defaults to current working directory)
16+ --- @return DirectoryInfo
1417--- @param path ? string # Directory path to scan (defaults to current working directory)
1518--- @return DirectoryInfo
1619function M .get_directory_info (path )
1720 path = path or vim .loop .cwd ()
18- -- Check if git repo
19- local is_git = vim .fn .system (" git rev-parse --is-inside-work-tree 2>/dev/null" ):match (" true" )
21+
22+ -- Normalize path separators
23+ path = vim .fn .fnamemodify (path , " :p:h" )
24+
25+ -- Check if the specified path is a git repo
26+ -- Use -C flag to specify directory instead of cd command for better cross-platform support
27+ local is_git = vim .fn
28+ .system (string.format (" git -C %s rev-parse --is-inside-work-tree 2>/dev/null" , vim .fn .shellescape (path )))
29+ :match (" true" )
2030 local files = {}
2131
2232 if is_git then
23- -- Use git ls-files for git-aware listing
24- local git_files = vim .fn .systemlist (" git ls-files --cached --others --exclude-standard" )
33+ -- Use git ls-files for git-aware listing in the specified directory
34+ local git_files = vim .fn .systemlist (
35+ string.format (" git -C %s ls-files --cached --others --exclude-standard" , vim .fn .shellescape (path ))
36+ )
2537 for _ , file in ipairs (git_files ) do
26- local stat = vim .loop .fs_stat (file )
27- if stat then
28- table.insert (files , {
38+ -- Build full path using cross-platform path joining
39+ local full_path = vim .fs .joinpath and vim .fs .joinpath (path , file ) or (path .. " /" .. file )
40+
41+ -- Use lstat to detect symlinks without following them
42+ local lstat = vim .loop .fs_lstat (full_path )
43+ if lstat then
44+ local file_info = {
2945 name = file ,
30- type = stat .type ,
31- size = stat .size ,
32- modified = stat .mtime .sec ,
33- })
46+ type = lstat .type ,
47+ size = lstat .size ,
48+ modified = lstat .mtime .sec ,
49+ }
50+
51+ -- If it's a symlink, get the target path
52+ if lstat .type == " link" then
53+ local target = vim .loop .fs_readlink (full_path )
54+ if target then
55+ file_info .symlink_target = target
56+ end
57+ end
58+
59+ table.insert (files , file_info )
3460 end
3561 end
3662 else
@@ -43,14 +69,28 @@ function M.get_directory_info(path)
4369 break
4470 end
4571
46- local stat = vim .loop .fs_stat (name )
47- if stat then
48- table.insert (files , {
72+ -- Build full path using cross-platform path joining
73+ local full_path = vim .fs .joinpath and vim .fs .joinpath (path , name ) or (path .. " /" .. name )
74+
75+ -- Use lstat to detect symlinks without following them
76+ local lstat = vim .loop .fs_lstat (full_path )
77+ if lstat then
78+ local file_info = {
4979 name = name ,
50- type = type or stat .type ,
51- size = stat .size ,
52- modified = stat .mtime .sec ,
53- })
80+ type = type or lstat .type ,
81+ size = lstat .size ,
82+ modified = lstat .mtime .sec ,
83+ }
84+
85+ -- If it's a symlink, get the target path
86+ if lstat .type == " link" then
87+ local target = vim .loop .fs_readlink (full_path )
88+ if target then
89+ file_info .symlink_target = target
90+ end
91+ end
92+
93+ table.insert (files , file_info )
5494 end
5595 end
5696 end
0 commit comments