ale: add FindNearestFileOrDirectory function (#5033)
Some checks failed
CI / build_image (push) Has been cancelled
CI / test_ale (--linters-only) (push) Has been cancelled
CI / test_ale (--lua-only) (push) Has been cancelled
CI / test_ale (--neovim-07-only) (push) Has been cancelled
CI / test_ale (--neovim-08-only) (push) Has been cancelled
CI / test_ale (--vim-80-only) (push) Has been cancelled
CI / test_ale (--vim-90-only) (push) Has been cancelled

* test: rename `FindNearestFile` test file

It matches the API name better and now lives beside the test file for
`FindNearestDirectory`.

* ale: add `FindNearestFileOrDirectory` function

Some anchor paths can be files or directories (e.g., `.git` is a
directory normally, but a file for worktrees). Add a function that finds
either type of path and returns the nearest.
This commit is contained in:
Ben Boeckel
2025-08-21 07:59:18 -04:00
committed by GitHub
parent b415dddf9f
commit 528e25954b
9 changed files with 52 additions and 0 deletions

View File

@@ -62,6 +62,36 @@ function! ale#path#FindNearestDirectory(buffer, directory_name) abort
return ''
endfunction
" Given a buffer and a filename, find the nearest file or directory by
" searching upwards through the paths relative to the given buffer.
function! ale#path#FindNearestFileOrDirectory(buffer, filename) abort
let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p')
let l:buffer_filename = fnameescape(l:buffer_filename)
let l:relative_path_file = findfile(a:filename, l:buffer_filename . ';')
let l:relative_path_dir = finddir(a:filename, l:buffer_filename . ';')
" If we find both a file and directory, choose the shorter response by
" making the longer one empty instead.
if !empty(l:relative_path_file) && !empty(l:relative_path_dir)
if strlen(l:relative_path_file) > strlen(l:relative_path_dir)
let l:relative_path_dir = ''
else
let l:relative_path_file = ''
endif
endif
if !empty(l:relative_path_file)
return fnamemodify(l:relative_path_file, ':p')
endif
if !empty(l:relative_path_dir)
return fnamemodify(l:relative_path_dir, ':p')
endif
return ''
endfunction
" Given a buffer, a string to search for, and a global fallback for when
" the search fails, look for a file in parent paths, and if that fails,
" use the global fallback path instead.

View File

View File

@@ -0,0 +1,22 @@
Before:
call ale#test#SetDirectory('/testplugin/test')
After:
call ale#test#RestoreDirectory()
Execute(We should find a directory when searching and it is closer):
call ale#test#SetFilename('test-files/top/needle_dir/target/query/buffer.txt')
AssertEqual
\ ale#path#Simplify(expand('%:p:h:h:h:h:h:h') . '/test-files/top/needle_dir/target/needle/'),
\ ale#path#FindNearestFileOrDirectory(bufnr('%'), 'needle')
Execute(We should find a file when searching and it is closer):
call ale#test#SetFilename('test-files/top/needle_file/target/query/buffer.txt')
AssertEqual
\ ale#path#Simplify(expand('%:p:h:h:h:h:h:h') . '/test-files/top/needle_file/target/needle'),
\ ale#path#FindNearestFileOrDirectory(bufnr('%'), 'needle')
Execute(We shouldn't find anything for files which don't match):
AssertEqual '', ale#path#FindNearestFileOrDirectory(bufnr('%'), 'cantfindthis')