nvim lsp work

This commit is contained in:
Henrik Bakken
2025-03-25 10:42:07 +01:00
parent 2f6009d3b6
commit f3f9fe7611
+257 -180
View File
@@ -144,202 +144,279 @@ vim.api.nvim_create_autocmd("ColorScheme", {
-- LSP -- LSP
-- ---------------------------------------- -- ----------------------------------------
-- vim.lsp.set_log_level(1) local function lspsetup()
vim.api.nvim_create_autocmd("LspAttach", { vim.lsp.set_log_level(2)
group = vim.api.nvim_create_augroup("UserLspAttach", { clear = true }), vim.keymap.set("n", "<leader>ll", "<cmd>e ~/.local/state/nvim/lsp.log<cr>", { noremap = true })
callback = function(ev) local lspgroup = vim.api.nvim_create_augroup("lsp", { clear = true })
vim.lsp.completion.enable(true, ev.data.client_id, ev.buf)
local bmap = function(mode, keys, func) vim.keymap.set(mode, keys, func, { buffer = ev.buf, noremap = true }) end
local diag = vim.diagnostic
local severity = diag.severity.HINT
-- workspaces
bmap("n", "<leader>wa", vim.lsp.buf.add_workspace_folder)
bmap("n", "<leader>wr", vim.lsp.buf.remove_workspace_folder)
bmap("n", "<leader>wl", function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end)
-- jump
bmap("n", "<M-i>", function() diag.open_float({ source = true }) end)
bmap("n", "<M-n>", function() diag.jump({ severity = { min = severity }, float = true, count = 1 }) end)
bmap("n", "<M-p>", function() diag.jump({ severity = { min = severity }, float = true, count = -1 }) end)
bmap("n", "gd", vim.lsp.buf.definition)
bmap("n", "gD", vim.lsp.buf.type_definition)
bmap("n", "gi", vim.lsp.buf.declaration)
bmap("n", "gI", vim.lsp.buf.implementation)
-- quickfix
bmap("n", "gl", diag.setloclist)
bmap("n", "gr", vim.lsp.buf.references)
-- popups
bmap({ "n", "i" }, "<M-x>", vim.lsp.buf.signature_help)
-- other
bmap("n", "K", vim.lsp.buf.hover)
bmap("n", "<M-r>", vim.lsp.buf.rename)
bmap("n", "<leader>ca", vim.lsp.buf.code_action)
-- NOTE: Using `assert` bypasses needing to do a nil check before accessing a member that could be nil vim.api.nvim_create_autocmd("LspAttach", {
local client = assert(vim.lsp.get_client_by_id(ev.data.client_id)) group = lspgroup,
end, callback = function(ev)
}) vim.lsp.completion.enable(true, ev.data.client_id, ev.buf)
vim.api.nvim_create_user_command("LspStop", function(kwargs) local diag = vim.diagnostic
local name = kwargs.fargs[1] local severity = diag.severity.HINT
for _, client in ipairs(vim.lsp.get_clients({ name = name })) do local keyspec = {
client:stop() -- workspaces
end { "<leader>wa", vim.lsp.buf.add_workspace_folder },
end, { { "<leader>wr", vim.lsp.buf.remove_workspace_folder },
nargs = "?", { "<leader>wl", function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end },
complete = function() -- jump
return vim.tbl_map(function(c) return c.name end, vim.lsp.get_clients()) { "<M-i>", function() diag.open_float({ source = true }) end },
end, { "<M-n>", function() diag.jump({ severity = { min = severity }, float = true, count = 1 }) end },
}) { "<M-p>", function() diag.jump({ severity = { min = severity }, float = true, count = -1 }) end },
{ "gd", vim.lsp.buf.definition },
{ "gD", vim.lsp.buf.type_definition },
{ "gi", vim.lsp.buf.declaration },
{ "gI", vim.lsp.buf.implementation },
-- quickfix
{ "gl", diag.setloclist },
{ "gr", function() vim.lsp.buf.references({ includeDeclaration = false }) end },
-- popups
{ "<M-x>", vim.lsp.buf.signature_help, { "n", "i" } },
-- symbols
{ "<leader>ds", vim.lsp.buf.document_symbol },
{ "<leader>ws", vim.lsp.buf.workspace_symbol },
-- other
{ "K", vim.lsp.buf.hover },
{ "<M-r>", vim.lsp.buf.rename },
{ "<leader>rn", function() Snacks.rename.rename_file() end },
{ "<leader>ca", vim.lsp.buf.code_action, { "n", "x" } },
}
for _, key in ipairs(keyspec) do
vim.keymap.set(key[3] or { "n" }, key[1], key[2], { buffer = ev.buf })
end
end,
})
vim.api.nvim_create_user_command("LspStop", function(kwargs)
local name = kwargs.fargs[1]
for _, client in ipairs(vim.lsp.get_clients({ name = name })) do
client:stop()
end
end, {
nargs = "?",
complete = function()
return vim.tbl_map(function(c) return c.name end, vim.lsp.get_clients())
end,
})
vim.api.nvim_create_user_command("LspRestart", function(kwargs) vim.api.nvim_create_user_command("LspRestart", function(kwargs)
local name = kwargs.fargs[1] local name = kwargs.fargs[1]
for _, client in ipairs(vim.lsp.get_clients({ name = name })) do for _, client in ipairs(vim.lsp.get_clients({ name = name })) do
local bufs = vim.lsp.get_buffers_by_client_id(client.id) local bufs = vim.lsp.get_buffers_by_client_id(client.id)
client:stop() client:stop()
vim.wait(30000, function() return vim.lsp.get_client_by_id(client.id) == nil end) vim.wait(30000, function() return vim.lsp.get_client_by_id(client.id) == nil end)
local client_id = vim.lsp.start(client.config, { attach = nil }) local client_id = vim.lsp.start(client.config, { attach = nil })
if client_id then if client_id then
for _, buf in ipairs(bufs) do for _, buf in ipairs(bufs) do
vim.lsp.buf_attach_client(buf, client_id) vim.lsp.buf_attach_client(buf, client_id)
end
end end
end end
end end, {
end, { nargs = "?",
nargs = "?", complete = function()
complete = function() return vim.tbl_map(function(c) return c.name end, vim.lsp.get_clients())
return vim.tbl_map(function(c) return c.name end, vim.lsp.get_clients()) end,
end, })
}) vim.api.nvim_create_autocmd("LspProgress", {
group = lspgroup,
callback = function(args)
local function is_blocking()
local mode = vim.api.nvim_get_mode()
for _, m in ipairs({ "ic", "ix", "c", "no", "r%?", "rm" }) do
if mode.mode:find(m) == 1 then return true end
end
return mode.blocking
end
local update_delay_ms = 300
local last_update = 0
local current_time = vim.uv.now()
if is_blocking() or (current_time - last_update) < update_delay_ms then return end
last_update = current_time
vim.lsp.config("*", { root_markers = { ".git" } }) local client = vim.lsp.get_client_by_id(args.data.client_id)
vim.lsp.config["lua_ls"] = { local value = args.data.params.value --[[@as {percentage?: number, title?: string, message?: string, kind: "begin"|"report"|"end"}]]
cmd = { "lua-language-server" }, if not client or type(value) ~= "table" then return end
filetypes = { "lua" }, local progress = vim.defaulttable()
root_markers = { local p = progress[client.id]
".luarc.json",
".luarc.jsonc", for i = 1, #p + 1 do
".stylua.toml", if i == #p + 1 or p[i].token == args.data.params.token then
"stylua.toml", p[1] = {
".git", token = args.data.params.token,
}, msg = ("[%3d%%] %s%s"):format(
settings = { value.kind == "end" and 100 or value.percentage or 100,
Lua = { value.title or "",
workspace = { value.message and (" **%s**"):format(value.message) or ""
checkThirdParty = false, ),
library = { vim.env.VIMRUNTIME }, done = value.kind == "end",
}, }
telemetry = { enable = false }, break
diagnostics = { globals = { "vim" } }, end
format = { enable = false }, end
runtime = { version = "LuaJIT" },
local msg = {} ---@type string[]
progress[client.id] = vim.tbl_filter(function(v) return table.insert(msg, v.msg) or not v.done end, p)
local spinner = { "", "", "", "", "", "", "", "", "", "" }
vim.notify(table.concat(msg, "\n"), "info", {
id = "lsp_progress",
title = client.name,
timeout = 1200,
level = 5000,
width = { min = 50, max = 50 },
opts = function(notif)
---@diagnostic disable-next-line: missing-fields
notif.icon = #progress[client.id] == 0 and ""
or spinner[math.floor(vim.uv.hrtime() / (1e6 * 80)) % #spinner + 1]
end,
})
end,
})
vim.lsp.config("*", { root_markers = { ".git" } })
vim.lsp.config["lua_ls"] = {
cmd = { "lua-language-server" },
filetypes = { "lua" },
root_markers = {
".luarc.json",
".luarc.jsonc",
".stylua.toml",
"stylua.toml",
".git",
}, },
}, settings = {
} Lua = {
vim.lsp.enable("lua_ls") workspace = {
vim.lsp.config["basedpyright"] = { checkThirdParty = false,
cmd = { "basedpyright-langserver", "--stdio" }, library = { vim.env.VIMRUNTIME },
filetypes = { "python" }, },
root_markers = { telemetry = { enable = false },
"pyproject.toml", diagnostics = { globals = { "vim" } },
"setup.py", format = { enable = false },
"setup.cfg", runtime = { version = "LuaJIT" },
"requirements.txt",
"pyrightconfig.json",
".git",
},
settings = {
python = {
analysis = { autoImportCompletions = false, diagnosticMode = "workspace", useLibraryCodeForTypes = false },
},
},
}
vim.lsp.enable("basedpyright")
vim.lsp.config["html"] = {
cmd = { "vscode-html-language-server", "--stdio" },
filetypes = { "html" },
settings = {
html = {
format = {
templating = true,
wrapLineLength = 120,
wrapAttributes = "auto",
},
hover = {
documentation = true,
references = true,
}, },
}, },
}, }
} vim.lsp.enable("lua_ls")
vim.lsp.enable("html") vim.lsp.config["basedpyright"] = {
vim.lsp.config["yaml"] = { cmd = { "basedpyright-langserver", "--stdio" },
cmd = { "yaml-language-server", "--stdio" }, filetypes = { "python" },
filetypes = { "yaml" }, root_markers = {
settings = { "pyproject.toml",
yaml = { "setup.py",
schemas = { kubernetes = "/home/hjalmarlucius/src/hjarl/system/manifests/*.yaml" }, "setup.cfg",
-- schemaStore = { enable = false, url = "" }, "requirements.txt",
"pyrightconfig.json",
".git",
}, },
}, settings = {
} python = {
vim.lsp.enable("yaml") analysis = {
vim.lsp.config["typst"] = { autoImportCompletions = false,
cmd = { "tinymist" }, diagnosticMode = "openFilesOnly",
filetypes = { "typst" }, useLibraryCodeForTypes = false,
settings = {},
}
vim.lsp.enable("typst")
vim.lsp.config["bash"] = {
cmd = { "bash-language-server", "start" },
filetypes = { "bash", "sh" },
}
vim.lsp.enable("bash")
vim.lsp.config["js"] = {
cmd = { "vtsls", "--stdio" },
root_markers = { ".git", "package.json", "tsconfig.json", "jsconfig.json" },
filetypes = { "javascript", "javascriptreact", "javascript.jsx", "typescript", "typescriptreact", "typescript.tsx" },
settings = {
complete_function_calls = true,
vtsls = {
enableMoveToFileCodeAction = true,
autoUseWorkspaceTsdk = true,
experimental = {
maxInlayHintLength = 30,
completion = {
enableServerSideFuzzyMatch = true,
}, },
}, },
}, },
javascript = { }
updateImportsOnFileMove = { enabled = "always" }, vim.lsp.enable("basedpyright")
suggest = { vim.lsp.config["html"] = {
completeFunctionCalls = true, cmd = { "vscode-html-language-server", "--stdio" },
}, filetypes = { "html" },
inlayHints = { settings = {
enumMemberValues = { enabled = true }, html = {
functionLikeReturnTypes = { enabled = true }, format = {
parameterNames = { enabled = "literals" }, templating = true,
parameterTypes = { enabled = true }, wrapLineLength = 120,
propertyDeclarationTypes = { enabled = true }, wrapAttributes = "auto",
variableTypes = { enabled = false }, },
hover = {
documentation = true,
references = true,
},
}, },
}, },
typescript = { }
updateImportsOnFileMove = { enabled = "always" }, vim.lsp.enable("html")
suggest = { vim.lsp.config["yaml"] = {
completeFunctionCalls = true, cmd = { "yaml-language-server", "--stdio" },
}, filetypes = { "yaml" },
inlayHints = { settings = {
enumMemberValues = { enabled = true }, yaml = {
functionLikeReturnTypes = { enabled = true }, schemas = { kubernetes = "/home/hjalmarlucius/src/hjarl/system/manifests/*.yaml" },
parameterNames = { enabled = "literals" }, -- schemaStore = { enable = false, url = "" },
parameterTypes = { enabled = true },
propertyDeclarationTypes = { enabled = true },
variableTypes = { enabled = false },
}, },
}, },
}, }
} vim.lsp.enable("yaml")
vim.lsp.enable("js") vim.lsp.config["typst"] = {
cmd = { "tinymist" },
filetypes = { "typst" },
settings = {},
}
vim.lsp.enable("typst")
vim.lsp.config["bash"] = {
cmd = { "bash-language-server", "start" },
filetypes = { "bash", "sh" },
}
vim.lsp.enable("bash")
vim.lsp.config["js"] = {
cmd = { "vtsls", "--stdio" },
root_markers = { ".git", "package.json", "tsconfig.json", "jsconfig.json" },
filetypes = {
"javascript",
"javascriptreact",
"javascript.jsx",
"typescript",
"typescriptreact",
"typescript.tsx",
},
settings = {
complete_function_calls = true,
vtsls = {
enableMoveToFileCodeAction = true,
autoUseWorkspaceTsdk = true,
experimental = {
maxInlayHintLength = 30,
completion = {
enableServerSideFuzzyMatch = true,
},
},
},
javascript = {
updateImportsOnFileMove = { enabled = "always" },
suggest = {
completeFunctionCalls = true,
},
inlayHints = {
enumMemberValues = { enabled = true },
functionLikeReturnTypes = { enabled = true },
parameterNames = { enabled = "literals" },
parameterTypes = { enabled = true },
propertyDeclarationTypes = { enabled = true },
variableTypes = { enabled = false },
},
},
typescript = {
updateImportsOnFileMove = { enabled = "always" },
suggest = {
completeFunctionCalls = true,
},
inlayHints = {
enumMemberValues = { enabled = true },
functionLikeReturnTypes = { enabled = true },
parameterNames = { enabled = "literals" },
parameterTypes = { enabled = true },
propertyDeclarationTypes = { enabled = true },
variableTypes = { enabled = false },
},
},
},
}
vim.lsp.enable("js")
end
lspsetup()
-- ---------------------------------------- -- ----------------------------------------
-- PLUGINS -- PLUGINS