mirror of
				https://github.com/NotAShelf/nvf.git
				synced 2025-11-03 20:22:21 +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
 | 
						|
        '';
 | 
						|
    })
 | 
						|
  ];
 | 
						|
}
 |