mirror of
https://github.com/prabirshrestha/vim-lsp.git
synced 2025-12-14 20:35:59 +01:00
Search for multiple file/dir names in lsp#utils#find_nearest_parent_file_directory (#373)
* Search for multiple file/dir names in lsp#utils#find_nearest_parent_file_directory * Add tests for lsp#utils#find_nearest_parent_file_directory * Document lsp#utils#find_nearest_parent_file_directory
This commit is contained in:
committed by
Prabir Shrestha
parent
a80d617938
commit
fe2ec6e040
@@ -107,13 +107,38 @@ function! lsp#utils#find_nearest_parent_file(path, filename) abort
|
||||
endfunction
|
||||
|
||||
" Find a nearest to a `path` parent filename `filename` by traversing the filesystem upwards
|
||||
" The filename ending with '/' or '\' will be regarded as directory name,
|
||||
" otherwith as file name
|
||||
function! lsp#utils#find_nearest_parent_file_directory(path, filename) abort
|
||||
let l:path = lsp#utils#find_nearest_parent_file(a:path, a:filename)
|
||||
if type(a:filename) == 3
|
||||
let l:matched_paths = {}
|
||||
for current_name in a:filename
|
||||
let l:path = lsp#utils#find_nearest_parent_file_directory(a:path, current_name)
|
||||
|
||||
if !empty(l:path)
|
||||
return fnamemodify(l:path, ':p:h')
|
||||
if !empty(l:path)
|
||||
if has_key(l:matched_paths, l:path)
|
||||
let l:matched_paths[l:path] += 1
|
||||
else
|
||||
let l:matched_paths[l:path] = 1
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
return empty(l:matched_paths) ?
|
||||
\ '' :
|
||||
\ keys(l:matched_paths)[index(values(l:matched_paths), max(values(l:matched_paths)))]
|
||||
|
||||
elseif type(a:filename) == 1
|
||||
if a:filename[-1:] ==# '/' || a:filename[-1:] ==# '\'
|
||||
let l:modify_str = ':p:h:h'
|
||||
let l:path = lsp#utils#find_nearest_parent_directory(a:path, a:filename[:-2])
|
||||
else
|
||||
let l:modify_str = ':p:h'
|
||||
let l:path = lsp#utils#find_nearest_parent_file(a:path, a:filename)
|
||||
endif
|
||||
|
||||
return empty(l:path) ? '' : fnamemodify(l:path, l:modify_str)
|
||||
else
|
||||
return ''
|
||||
echoerr "The type of argument \"filename\" must be String or List"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ CONTENTS *vim-lsp-contents*
|
||||
disable |vim-lsp-disable|
|
||||
register_server |vim-lsp-register_server|
|
||||
stop_server |vim-lsp-stop_server|
|
||||
utils#find_nearest_parent_file_directory
|
||||
|vim-lsp-utils-find_nearest_parent_file_directory|
|
||||
Commands |vim-lsp-commands|
|
||||
LspCodeAction |LspCodeAction|
|
||||
LspDocumentDiagnostics |LspDocumentDiagnostics|
|
||||
@@ -406,6 +408,37 @@ Get the status of a server.
|
||||
Returns one of "unknown server", " "exited", "starting", "failed",
|
||||
"running", "not running".
|
||||
|
||||
*vim-lsp-utils-find_nearest_parent_file_directory*
|
||||
utils#find_nearest_parent_file_directory
|
||||
|
||||
Find the nearest parent directory which contains the specific files or
|
||||
diretories. The method has two parameters. The first is the path where
|
||||
searching starts. The second is the files or directories names which
|
||||
you want to find. The return value is the directory path which is found
|
||||
the most times.
|
||||
This method is mainly used to generate 'root_uri' when registering server.
|
||||
|
||||
Example:
|
||||
if executable('ccls')
|
||||
au User lsp_setup call lsp#register_server({
|
||||
\ 'name': 'ccls',
|
||||
\ 'cmd': {server_info->['ccls']},
|
||||
\ 'root_uri':{server_info->lsp#utils#path_to_uri(
|
||||
\ lsp#utils#find_nearest_parent_file_directory(
|
||||
\ lsp#utils#get_buffer_path(),
|
||||
\ ['.ccls', 'compile_commands.json', '.git/']
|
||||
\ ))},
|
||||
\ 'initialization_options': {},
|
||||
\ 'whitelist': ['c', 'cpp', 'objc', 'objcpp', 'cc'],
|
||||
\ })
|
||||
endif
|
||||
Note:
|
||||
* The second parameter can be a |String| or a string |List|.
|
||||
* For the second parameter, the string ends with '/' or '\' will
|
||||
be regarded as a directory name, otherwise as a file name.
|
||||
* If there is not directory with the specific files or diretories
|
||||
found, the method will return an empty string.
|
||||
|
||||
===============================================================================
|
||||
Commands *vim-lsp-commands*
|
||||
|
||||
|
||||
@@ -45,4 +45,40 @@ Describe lsp#utils
|
||||
endfor
|
||||
End
|
||||
End
|
||||
|
||||
Describe lsp#utils#find_nearest_parent_file_directory
|
||||
It should return the root directory if it is found
|
||||
let tests = [
|
||||
\ {'from': './test/testproject/src/main.cpp', 'target': ['.ccls', 'compile_commands.json', 'README.md', 'git/'], 'root': './test/testproject'},
|
||||
\ {'from': './test/testproject/src/main.cpp', 'target': ['.ccls', 'build/', 'CMakeLists.txt', 'git/'], 'root': './test/testproject'},
|
||||
\ {'from': './test/testproject/src/main.cpp', 'target': '.ccls', 'root': './test/testproject'},
|
||||
\ {'from': './test/testproject/src/main.cpp', 'target': 'git/', 'root': './test/testproject'},
|
||||
\ {'from': './test/testproject/src/main.cpp', 'target': 'CMakeLists.txt', 'root': './test/testproject/src'},
|
||||
\ {'from': './test/testproject/README.md', 'target': ['.ccls', 'compile_commands.json', 'README.md', 'git/'], 'root': './test/testproject'},
|
||||
\ {'from': './test/testproject/README.md', 'target': ['.ccls', 'build/', 'CMakeLists.txt', 'git/'], 'root': './test/testproject'},
|
||||
\ {'from': './test/testproject/README.md', 'target': '.ccls', 'root': './test/testproject'},
|
||||
\ {'from': './test/testproject/README.md', 'target': 'git/', 'root': './test/testproject'},
|
||||
\ {'from': './test/testproject/README.md', 'target': 'CMakeLists.txt', 'root': './test/testproject'},
|
||||
\]
|
||||
for test in tests
|
||||
let path = lsp#utils#find_nearest_parent_file_directory(fnamemodify(test.from, ':p:h'), test.target)
|
||||
Assert Equals(path, fnamemodify(test.root, ':p:h'))
|
||||
endfor
|
||||
End
|
||||
|
||||
It should return an empty string if not target has been found
|
||||
let tests = [
|
||||
\ {'from': './test/testproject/src/main.cpp', 'target': ['fdrvbws/', 'asbr/', 'bgdf/', 'abfrb.txt', 'ngo.c']},
|
||||
\ {'from': './test/testproject/src/main.cpp', 'target': 'asbr/'},
|
||||
\ {'from': './test/testproject/src/main.cpp', 'target': 'btr.c'},
|
||||
\ {'from': './test/testproject/.gitignore', 'target': ['fdrvbws/', 'asbr/', 'bgdf/', 'abfrb.txt', 'ngo.c']},
|
||||
\ {'from': './test/testproject/.gitignore', 'target': 'asbr/'},
|
||||
\ {'from': './test/testproject/.gitignore', 'target': 'btr.c'},
|
||||
\]
|
||||
for test in tests
|
||||
let path = lsp#utils#find_nearest_parent_file_directory(fnamemodify(test.from, ':p:h'), test.target)
|
||||
Assert Empty(path)
|
||||
endfor
|
||||
End
|
||||
End
|
||||
End
|
||||
|
||||
0
test/testproject/.ccls
Normal file
0
test/testproject/.ccls
Normal file
0
test/testproject/CMakeLists.txt
Normal file
0
test/testproject/CMakeLists.txt
Normal file
0
test/testproject/README.md
Normal file
0
test/testproject/README.md
Normal file
0
test/testproject/compile_commands.json
Normal file
0
test/testproject/compile_commands.json
Normal file
0
test/testproject/git/.gitignore
vendored
Normal file
0
test/testproject/git/.gitignore
vendored
Normal file
0
test/testproject/src/CMakeLists.txt
Normal file
0
test/testproject/src/CMakeLists.txt
Normal file
0
test/testproject/src/main.cpp
Normal file
0
test/testproject/src/main.cpp
Normal file
Reference in New Issue
Block a user