mirror of
https://github.com/NotAShelf/nvf.git
synced 2025-09-05 18:01:32 +00:00
178 lines
5.7 KiB
Nix
178 lines
5.7 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
...
|
|
}: let
|
|
inherit (builtins) filter;
|
|
inherit (lib.modules) mkIf mkMerge;
|
|
inherit (lib.nvim.dag) entryBefore;
|
|
|
|
cfg = config.vim.lsp;
|
|
in {
|
|
config = mkMerge [
|
|
(mkIf (cfg.servers != {}) {
|
|
vim.luaConfigRC.lsp-util =
|
|
entryBefore ["lsp-servers"]
|
|
/*
|
|
lua
|
|
*/
|
|
''
|
|
-- Port of nvim-lspconfig util
|
|
local util = { path = {} }
|
|
|
|
util.default_config = {
|
|
log_level = vim.lsp.protocol.MessageType.Warning,
|
|
message_level = vim.lsp.protocol.MessageType.Warning,
|
|
settings = vim.empty_dict(),
|
|
init_options = vim.empty_dict(),
|
|
handlers = {},
|
|
autostart = true,
|
|
capabilities = vim.lsp.protocol.make_client_capabilities(),
|
|
}
|
|
|
|
-- global on_setup hook
|
|
util.on_setup = nil
|
|
|
|
do
|
|
local validate = vim.validate
|
|
local api = vim.api
|
|
local lsp = vim.lsp
|
|
local nvim_eleven = vim.fn.has 'nvim-0.11' == 1
|
|
|
|
local iswin = vim.uv.os_uname().version:match 'Windows'
|
|
|
|
local function escape_wildcards(path)
|
|
return path:gsub('([%[%]%?%*])', '\\%1')
|
|
end
|
|
|
|
local function is_fs_root(path)
|
|
if iswin then
|
|
return path:match '^%a:$'
|
|
else
|
|
return path == '/'
|
|
end
|
|
end
|
|
|
|
local function traverse_parents(path, cb)
|
|
path = vim.uv.fs_realpath(path)
|
|
local dir = path
|
|
-- Just in case our algo is buggy, don't infinite loop.
|
|
for _ = 1, 100 do
|
|
dir = vim.fs.dirname(dir)
|
|
if not dir then
|
|
return
|
|
end
|
|
-- If we can't ascend further, then stop looking.
|
|
if cb(dir, path) then
|
|
return dir, path
|
|
end
|
|
if is_fs_root(dir) then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
util.root_pattern = function(...)
|
|
local patterns = util.tbl_flatten { ... }
|
|
return function(startpath)
|
|
startpath = util.strip_archive_subpath(startpath)
|
|
for _, pattern in ipairs(patterns) do
|
|
local match = util.search_ancestors(startpath, function(path)
|
|
for _, p in ipairs(vim.fn.glob(table.concat({ escape_wildcards(path), pattern }, '/'), true, true)) do
|
|
if vim.uv.fs_stat(p) then
|
|
return path
|
|
end
|
|
end
|
|
end)
|
|
|
|
if match ~= nil then
|
|
return match
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
util.root_markers_with_field = function(root_files, new_names, field, fname)
|
|
local path = vim.fn.fnamemodify(fname, ':h')
|
|
local found = vim.fs.find(new_names, { path = path, upward = true })
|
|
|
|
for _, f in ipairs(found or {}) do
|
|
-- Match the given `field`.
|
|
for line in io.lines(f) do
|
|
if line:find(field) then
|
|
root_files[#root_files + 1] = vim.fs.basename(f)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
return root_files
|
|
end
|
|
|
|
util.insert_package_json = function(root_files, field, fname)
|
|
return util.root_markers_with_field(root_files, { 'package.json', 'package.json5' }, field, fname)
|
|
end
|
|
|
|
util.strip_archive_subpath = function(path)
|
|
-- Matches regex from zip.vim / tar.vim
|
|
path = vim.fn.substitute(path, 'zipfile://\\(.\\{-}\\)::[^\\\\].*$', '\\1', ''')
|
|
path = vim.fn.substitute(path, 'tarfile:\\(.\\{-}\\)::.*$', '\\1', ''')
|
|
return path
|
|
end
|
|
|
|
util.get_typescript_server_path = function(root_dir)
|
|
local project_roots = vim.fs.find('node_modules', { path = root_dir, upward = true, limit = math.huge })
|
|
for _, project_root in ipairs(project_roots) do
|
|
local typescript_path = project_root .. '/typescript'
|
|
local stat = vim.loop.fs_stat(typescript_path)
|
|
if stat and stat.type == 'directory' then
|
|
return typescript_path .. '/lib'
|
|
end
|
|
end
|
|
return '''
|
|
end
|
|
|
|
util.search_ancestors = function(startpath, func)
|
|
if nvim_eleven then
|
|
validate('func', func, 'function')
|
|
end
|
|
if func(startpath) then
|
|
return startpath
|
|
end
|
|
local guard = 100
|
|
for path in vim.fs.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
|
|
|
|
util.path.is_descendant = function(root, path)
|
|
if not path then
|
|
return false
|
|
end
|
|
|
|
local function cb(dir, _)
|
|
return dir == root
|
|
end
|
|
|
|
local dir, _ = traverse_parents(path, cb)
|
|
|
|
return dir == root
|
|
end
|
|
|
|
util.tbl_flatten = function(t)
|
|
--- @diagnostic disable-next-line:deprecated
|
|
return nvim_eleven and vim.iter(t):flatten(math.huge):totable() or vim.tbl_flatten(t)
|
|
end
|
|
end
|
|
'';
|
|
})
|
|
];
|
|
}
|