mirror of https://github.com/mickael-menu/zk-nvim
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.3 KiB
Lua
108 lines
2.3 KiB
Lua
-- NOTE: everything in this module is copied from nvim-lspconfig (https://github.com/neovim/nvim-lspconfig)
|
|
-- NOTE: we need this util until the code from lspconfig is merged into core
|
|
|
|
local vim = vim
|
|
local validate = vim.validate
|
|
local uv = vim.loop
|
|
|
|
local M = {}
|
|
|
|
-- Some path utilities
|
|
M.path = (function()
|
|
local is_windows = uv.os_uname().version:match 'Windows'
|
|
|
|
local function exists(filename)
|
|
local stat = uv.fs_stat(filename)
|
|
return stat and stat.type or false
|
|
end
|
|
|
|
local function is_fs_root(path)
|
|
if is_windows then
|
|
return path:match '^%a:$'
|
|
else
|
|
return path == '/'
|
|
end
|
|
end
|
|
|
|
local function dirname(path)
|
|
local strip_dir_pat = '/([^/]+)$'
|
|
local strip_sep_pat = '/$'
|
|
if not path or #path == 0 then
|
|
return
|
|
end
|
|
local result = path:gsub(strip_sep_pat, ''):gsub(strip_dir_pat, '')
|
|
if #result == 0 then
|
|
if is_windows then
|
|
return path:sub(1, 2):upper()
|
|
else
|
|
return '/'
|
|
end
|
|
end
|
|
return result
|
|
end
|
|
|
|
local function path_join(...)
|
|
return table.concat(vim.tbl_flatten { ... }, '/')
|
|
end
|
|
|
|
-- Iterate the path until we find the rootdir.
|
|
local function iterate_parents(path)
|
|
local function it(_, v)
|
|
if v and not is_fs_root(v) then
|
|
v = dirname(v)
|
|
else
|
|
return
|
|
end
|
|
if v and uv.fs_realpath(v) then
|
|
return v, path
|
|
else
|
|
return
|
|
end
|
|
end
|
|
return it, path, path
|
|
end
|
|
|
|
return {
|
|
exists = exists,
|
|
join = path_join,
|
|
iterate_parents = iterate_parents,
|
|
}
|
|
end)()
|
|
|
|
function M.search_ancestors(startpath, func)
|
|
validate { func = { func, 'f' } }
|
|
if func(startpath) then
|
|
return startpath
|
|
end
|
|
local guard = 100
|
|
for path in M.path.iterate_parents(startpath) do
|
|
-- Prevent infinite recursion if our algorithm breaks
|
|
guard = guard - 1
|
|
if guard == 0 then
|
|
return
|
|
end
|
|
|
|
if func(path) then
|
|
return path
|
|
end
|
|
end
|
|
end
|
|
|
|
function M.root_pattern(...)
|
|
local patterns = vim.tbl_flatten { ... }
|
|
local function matcher(path)
|
|
for _, pattern in ipairs(patterns) do
|
|
for _, p in ipairs(vim.fn.glob(M.path.join(path, pattern), true, true)) do
|
|
if M.path.exists(p) then
|
|
return path
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return function(startpath)
|
|
return M.search_ancestors(startpath, matcher)
|
|
end
|
|
end
|
|
|
|
return M
|