From 0f716c49e7a57708f2c6bc4663a9352c9ce3bbf0 Mon Sep 17 00:00:00 2001 From: robin Date: Fri, 21 Mar 2025 23:19:58 +0000 Subject: [PATCH] feat(config/lsp): configure lsp servers --- config/lsp/astro.lua | 6 ++- config/lsp/bashls.lua | 21 +++++++- config/lsp/clangd.lua | 80 ++++++++++++++++++++++++++++ config/lsp/cssls.lua | 13 ++++- config/lsp/denols.lua | 18 +++++++ config/lsp/dockerls.lua | 7 ++- config/lsp/emmet_language_server.lua | 9 +++- config/lsp/gopls.lua | 5 +- config/lsp/helm_ls.lua | 1 - config/lsp/hls.lua | 13 ++++- config/lsp/html.lua | 12 ++++- config/lsp/intelephense.lua | 1 - config/lsp/jqls.lua | 1 - config/lsp/jsonls.lua | 12 ++++- config/lsp/marksman.lua | 7 ++- config/lsp/nil_ls.lua | 3 ++ config/lsp/nushell.lua | 9 +++- config/lsp/serve_d.lua | 1 - config/lsp/sourcekit.lua | 1 - config/lsp/tailwindcss.lua | 52 +++++++++++++++++- config/lsp/taplo.lua | 9 +++- config/lsp/teal_ls.lua | 9 ++++ config/lsp/tinymist.lua | 6 +++ config/lsp/ts_ls.lua | 10 ++++ config/lsp/volar.lua | 4 +- config/lsp/yamlls.lua | 6 +++ config/lsp/zk.lua | 65 ++++++++++++++++++++++ config/lua/ivy/init.lua | 67 ----------------------- pkgs/neovim.nix | 4 +- 29 files changed, 363 insertions(+), 89 deletions(-) create mode 100644 config/lsp/clangd.lua delete mode 100644 config/lsp/helm_ls.lua delete mode 100644 config/lsp/intelephense.lua delete mode 100644 config/lsp/jqls.lua delete mode 100644 config/lsp/serve_d.lua delete mode 100644 config/lsp/sourcekit.lua create mode 100644 config/lsp/zk.lua diff --git a/config/lsp/astro.lua b/config/lsp/astro.lua index a564707..8bb50f0 100644 --- a/config/lsp/astro.lua +++ b/config/lsp/astro.lua @@ -1 +1,5 @@ -return {} +return { + cmd = { "astro-ls", "--stdio" }, + filetypes = { "astro" }, + root_markers = { "package.json", "tsconfig.json", "jsconfig.json", ".git" }, +} diff --git a/config/lsp/bashls.lua b/config/lsp/bashls.lua index a564707..65a1881 100644 --- a/config/lsp/bashls.lua +++ b/config/lsp/bashls.lua @@ -1 +1,20 @@ -return {} +return { + cmd = { "bash-language-server", "start" }, + settings = { + bashIde = { + -- Glob pattern for finding and parsing shell script files in the workspace. + -- Used by the background analysis features across files. + + -- Prevent recursive scanning which will cause issues when opening a file + -- directly in the home directory (e.g. ~/foo.sh). + -- + -- Default upstream pattern is "**/*@(.sh|.inc|.bash|.command)". + globPattern = vim.env.GLOB_PATTERN or "*@(.sh|.inc|.bash|.command)", + }, + }, + filetypes = { "bash", "sh" }, + root_dir = function(buf) + return vim.fs.dirname(vim.fs.find(".git", { path = vim.api.nvim_buf_get_name(buf), upward = true })[1]) + end, + single_file_support = true, +} diff --git a/config/lsp/clangd.lua b/config/lsp/clangd.lua new file mode 100644 index 0000000..9e1b839 --- /dev/null +++ b/config/lsp/clangd.lua @@ -0,0 +1,80 @@ +-- https://clangd.llvm.org/extensions.html#switch-between-sourceheader +local function switch_source_header(bufnr) + local client = vim.lsp.get_clients({ bufnr = bufnr, name = "clangd" })[1] + if not client then + return vim.notify("Clangd client not found", vim.log.levels.ERROR) + end + local params = vim.lsp.util.make_text_document_params(bufnr) + client:request("textDocument/switchSourceHeader", params, function(err, result) + if err then + error(tostring(err)) + end + if not result then + vim.notify("corresponding file cannot be determined") + return + end + vim.cmd.edit(vim.uri_to_fname(result)) + end, bufnr) +end + +local function symbol_info() + local bufnr = vim.api.nvim_get_current_buf() + local clangd_client = vim.lsp.get_clients({ bufnr = bufnr, name = "clangd" })[1] + if not clangd_client or not clangd_client:supports_method("textDocument/symbolInfo") then + return vim.notify("Clangd client not found", vim.log.levels.ERROR) + end + local win = vim.api.nvim_get_current_win() + local params = vim.lsp.util.make_position_params(win, clangd_client.offset_encoding) + clangd_client:request("textDocument/symbolInfo", params, function(err, res) + if err or #res == 0 then + -- Clangd always returns an error, there is not reason to parse it + return + end + local container = string.format("container: %s", res[1].containerName) ---@type string + local name = string.format("name: %s", res[1].name) ---@type string + vim.lsp.util.open_floating_preview({ name, container }, "", { + height = 2, + width = math.max(string.len(name), string.len(container)), + focusable = false, + focus = false, + border = "single", + title = "Symbol Info", + }) + end, bufnr) +end + +return { + cmd = { "clangd" }, + filetypes = { "c", "cpp", "objc", "objcpp", "cuda", "proto" }, + root_markers = { + ".clangd", + ".clang-tidy", + ".clang-format", + "compile_commands.json", + "compile_flags.txt", + "configure.ac", -- AutoTools + }, + single_file_support = true, + capabilities = { + textDocument = { + completion = { + editsNearCursor = true, + }, + }, + offsetEncoding = { "utf-8", "utf-16" }, + }, + commands = { + ClangdSwitchSourceHeader = { + function() + switch_source_header(0) + end, + description = "Switch between source/header", + }, + ClangdShowSymbolInfo = { + function() + symbol_info() + end, + description = "Show symbol info", + }, + }, +} diff --git a/config/lsp/cssls.lua b/config/lsp/cssls.lua index a564707..ac04927 100644 --- a/config/lsp/cssls.lua +++ b/config/lsp/cssls.lua @@ -1 +1,12 @@ -return {} +return { + cmd = { "vscode-css-language-server", "--stdio" }, + filetypes = { "css", "scss", "less" }, + init_options = { provideFormatter = true }, -- needed to enable formatting capabilities + root_markers = { "package.json", ".git" }, + single_file_support = true, + settings = { + css = { validate = true }, + scss = { validate = true }, + less = { validate = true }, + }, +} diff --git a/config/lsp/denols.lua b/config/lsp/denols.lua index 948c4fe..83cbe9c 100644 --- a/config/lsp/denols.lua +++ b/config/lsp/denols.lua @@ -1,8 +1,26 @@ return { + cmd = { "deno", "lsp" }, + cmd_env = { NO_COLOR = true }, + filetypes = { + "javascript", + "javascriptreact", + "javascript.jsx", + "typescript", + "typescriptreact", + "typescript.tsx", + }, root_markers = { "deno.json", "deno.jsonc" }, single_file_support = false, settings = { deno = { + enable = true, + suggest = { + imports = { + hosts = { + ["https://deno.land"] = true, + }, + }, + }, inlayHints = { parameterNames = { enabled = "all", suppressWhenArgumentMatchesName = true }, parameterTypes = { enabled = true }, diff --git a/config/lsp/dockerls.lua b/config/lsp/dockerls.lua index a564707..32d4599 100644 --- a/config/lsp/dockerls.lua +++ b/config/lsp/dockerls.lua @@ -1 +1,6 @@ -return {} +return { + cmd = { "docker-langserver", "--stdio" }, + filetypes = { "dockerfile" }, + root_markers = { "Dockerfile" }, + single_file_support = true, +} diff --git a/config/lsp/emmet_language_server.lua b/config/lsp/emmet_language_server.lua index e6a01f3..9675b99 100644 --- a/config/lsp/emmet_language_server.lua +++ b/config/lsp/emmet_language_server.lua @@ -1,15 +1,22 @@ return { + cmd = { "emmet-language-server", "--stdio" }, filetypes = { "astro", "css", "eruby", "html", + "htmlangular", + "htmldjango", "javascript", "javascriptreact", "less", + "pug", "sass", "scss", - "pug", "typescriptreact", }, + single_file_support = true, + root_dir = function(buf) + return vim.fs.dirname(vim.fs.find(".git", { path = vim.api.nvim_buf_get_name(buf), upward = true })[1]) + end, } diff --git a/config/lsp/gopls.lua b/config/lsp/gopls.lua index 647ec31..df51f15 100644 --- a/config/lsp/gopls.lua +++ b/config/lsp/gopls.lua @@ -1,10 +1,11 @@ return { - single_file_support = true, - filetypes = { "go", "gomod", "gosum", "gotmpl", "gohtmltmpl", "gotexttmpl" }, cmd = { "gopls", -- share the gopls instance if there is one already "-remote.debug=:0", }, + filetypes = { "go", "gomod", "gosum", "gotmpl", "gohtmltmpl", "gotexttmpl" }, + single_file_support = true, + root_markers = { "go.work", "go.mod", ".git" }, settings = { gopls = { hints = { diff --git a/config/lsp/helm_ls.lua b/config/lsp/helm_ls.lua deleted file mode 100644 index a564707..0000000 --- a/config/lsp/helm_ls.lua +++ /dev/null @@ -1 +0,0 @@ -return {} diff --git a/config/lsp/hls.lua b/config/lsp/hls.lua index a564707..77df109 100644 --- a/config/lsp/hls.lua +++ b/config/lsp/hls.lua @@ -1 +1,12 @@ -return {} +return { + cmd = { "haskell-language-server-wrapper", "--lsp" }, + filetypes = { "haskell", "lhaskell" }, + root_markers = { "hie.yaml", "stack.yaml", "cabal.project", "*.cabal", "package.yaml" }, + single_file_support = true, + settings = { + haskell = { + formattingProvider = "ormolu", + cabalFormattingProvider = "cabalfmt", + }, + }, +} diff --git a/config/lsp/html.lua b/config/lsp/html.lua index a564707..de2bd5e 100644 --- a/config/lsp/html.lua +++ b/config/lsp/html.lua @@ -1 +1,11 @@ -return {} +return { + cmd = { "vscode-html-language-server", "--stdio" }, + filetypes = { "html", "templ" }, + root_dir = { "package.json", ".git" }, + single_file_support = true, + settings = { + provideFormatter = true, + embeddedLanguages = { css = true, javascript = true }, + configurationSection = { "html", "css", "javascript" }, + }, +} diff --git a/config/lsp/intelephense.lua b/config/lsp/intelephense.lua deleted file mode 100644 index a564707..0000000 --- a/config/lsp/intelephense.lua +++ /dev/null @@ -1 +0,0 @@ -return {} diff --git a/config/lsp/jqls.lua b/config/lsp/jqls.lua deleted file mode 100644 index a564707..0000000 --- a/config/lsp/jqls.lua +++ /dev/null @@ -1 +0,0 @@ -return {} diff --git a/config/lsp/jsonls.lua b/config/lsp/jsonls.lua index a564707..85e610e 100644 --- a/config/lsp/jsonls.lua +++ b/config/lsp/jsonls.lua @@ -1 +1,11 @@ -return {} +return { + cmd = { "vscode-json-language-server", "--stdio" }, + filetypes = { "json", "jsonc" }, + settings = { + provideFormatter = true, + }, + root_dir = function(buf) + return vim.fs.dirname(vim.fs.find(".git", { path = vim.api.nvim_buf_get_name(buf), upward = true })[1]) + end, + single_file_support = true, +} diff --git a/config/lsp/marksman.lua b/config/lsp/marksman.lua index a564707..05fd268 100644 --- a/config/lsp/marksman.lua +++ b/config/lsp/marksman.lua @@ -1 +1,6 @@ -return {} +return { + cmd = { "marksman", "server" }, + filetypes = { "markdown", "markdown.mdx" }, + root_markers = { ".marksman.toml", ".git" }, + single_file_support = true, +} diff --git a/config/lsp/nil_ls.lua b/config/lsp/nil_ls.lua index 2d01d72..98a19c9 100644 --- a/config/lsp/nil_ls.lua +++ b/config/lsp/nil_ls.lua @@ -1,5 +1,8 @@ return { cmd = { "nil" }, + filetypes = { "nix" }, + root_dir = { "flake.nix", ".git" }, + single_file_support = true, settings = { ["nil"] = { formatting = { diff --git a/config/lsp/nushell.lua b/config/lsp/nushell.lua index a564707..b115e70 100644 --- a/config/lsp/nushell.lua +++ b/config/lsp/nushell.lua @@ -1 +1,8 @@ -return {} +return { + cmd = { "nu", "--lsp" }, + filetypes = { "nu" }, + root_dir = function(buf) + return vim.fs.dirname(vim.fs.find(".git", { path = vim.api.nvim_buf_get_name(buf), upward = true })[1]) + end, + single_file_support = true, +} diff --git a/config/lsp/serve_d.lua b/config/lsp/serve_d.lua deleted file mode 100644 index a564707..0000000 --- a/config/lsp/serve_d.lua +++ /dev/null @@ -1 +0,0 @@ -return {} diff --git a/config/lsp/sourcekit.lua b/config/lsp/sourcekit.lua deleted file mode 100644 index a564707..0000000 --- a/config/lsp/sourcekit.lua +++ /dev/null @@ -1 +0,0 @@ -return {} diff --git a/config/lsp/tailwindcss.lua b/config/lsp/tailwindcss.lua index 675bcea..42ab93d 100644 --- a/config/lsp/tailwindcss.lua +++ b/config/lsp/tailwindcss.lua @@ -1,10 +1,60 @@ return { + cmd = { "tailwindcss-language-server", "--stdio" }, filetypes = { "astro", + "javascriptreact", "typescriptreact", - "html", + "css", + "less", + "postcss", + "sass", + "scss", + + "gohtml", + "gohtmltmpl", + "html", + "svelte", + "templ", "tera", + "vue", + }, + settings = { + tailwindCSS = { + validate = true, + lint = { + cssConflict = "warning", + invalidApply = "error", + invalidScreen = "error", + invalidVariant = "error", + invalidConfigPath = "error", + invalidTailwindDirective = "error", + recommendedVariantOrder = "warning", + }, + classAttributes = { + "class", + "className", + "class:list", + "classList", + "ngClass", + }, + includeLanguages = { + eelixir = "html-eex", + eruby = "erb", + templ = "html", + htmlangular = "html", + }, + }, + }, + root_markers = { + "tailwind.config.js", + "tailwind.config.cjs", + "tailwind.config.mjs", + "tailwind.config.ts", + "postcss.config.js", + "postcss.config.cjs", + "postcss.config.mjs", + "postcss.config.ts", }, } diff --git a/config/lsp/taplo.lua b/config/lsp/taplo.lua index a564707..4421b8f 100644 --- a/config/lsp/taplo.lua +++ b/config/lsp/taplo.lua @@ -1 +1,8 @@ -return {} +return { + cmd = { "taplo", "lsp", "stdio" }, + filetypes = { "toml" }, + root_dir = function(buf) + return vim.fs.dirname(vim.fs.find(".git", { path = vim.api.nvim_buf_get_name(buf), upward = true })[1]) + end, + single_file_support = true, +} diff --git a/config/lsp/teal_ls.lua b/config/lsp/teal_ls.lua index e69de29..75c4ee6 100644 --- a/config/lsp/teal_ls.lua +++ b/config/lsp/teal_ls.lua @@ -0,0 +1,9 @@ +return { + cmd = { + "teal-language-server", + }, + filetypes = { + "teal", + }, + root_markers = { "tlconfig.lua" }, +} diff --git a/config/lsp/tinymist.lua b/config/lsp/tinymist.lua index 6f90b64..e905c9f 100644 --- a/config/lsp/tinymist.lua +++ b/config/lsp/tinymist.lua @@ -1,4 +1,10 @@ return { + cmd = { "tinymist" }, + filetypes = { "typst" }, + root_dir = function(buf) + return vim.fs.dirname(vim.fs.find(".git", { path = vim.api.nvim_buf_get_name(buf), upward = true })[1]) + end, + single_file_support = true, settings = { formatterMode = "typstyle", exportPdf = "onDocumentHasTitle", diff --git a/config/lsp/ts_ls.lua b/config/lsp/ts_ls.lua index a42742f..864fceb 100644 --- a/config/lsp/ts_ls.lua +++ b/config/lsp/ts_ls.lua @@ -1,4 +1,14 @@ return { + cmd = { "typescript-language-server", "--stdio" }, + filetypes = { + "javascript", + "javascriptreact", + "javascript.jsx", + "typescript", + "typescriptreact", + "typescript.tsx", + }, + single_file_support = false, root_dir = function(buf) local root_dir = vim.fs.root(buf, { "package.json", "tsconfig.json" }) diff --git a/config/lsp/volar.lua b/config/lsp/volar.lua index 3ef4e47..b0dc845 100644 --- a/config/lsp/volar.lua +++ b/config/lsp/volar.lua @@ -1,4 +1,7 @@ return { + cmd = { "vue-language-server", "--stdio" }, + filetypes = { "vue" }, + root_markers = { "package.json" }, capabilities = { workspace = { didChangeWatchedFiles = { @@ -6,5 +9,4 @@ return { }, }, }, - root_markers = { "package.json" }, } diff --git a/config/lsp/yamlls.lua b/config/lsp/yamlls.lua index 6f62ab0..fb22287 100644 --- a/config/lsp/yamlls.lua +++ b/config/lsp/yamlls.lua @@ -1,4 +1,10 @@ return { + cmd = { "yaml-language-server", "--stdio" }, + filetypes = { "yaml", "yaml.docker-compose", "yaml.gitlab" }, + root_dir = function(buf) + return vim.fs.dirname(vim.fs.find(".git", { path = vim.api.nvim_buf_get_name(buf), upward = true })[1]) + end, + single_file_support = true, settings = { yaml = { completion = true, diff --git a/config/lsp/zk.lua b/config/lsp/zk.lua new file mode 100644 index 0000000..5f42512 --- /dev/null +++ b/config/lsp/zk.lua @@ -0,0 +1,65 @@ +local function find_zk_root(startpath) + for dir in vim.fs.parents(startpath) do + if vim.fn.isdirectory(vim.fs.joinpath(dir, ".zk")) == 1 then + return dir + end + end +end + +return { + cmd = { "zk", "lsp" }, + filetypes = { "markdown" }, + root_dir = { ".zk" }, + commands = { + ZkIndex = { + function() + local bufpath = vim.api.nvim_buf_get_name(0) + local root = find_zk_root(bufpath) + + vim.lsp.buf_request(0, "workspace/executeCommand", { + command = "zk.index", + arguments = { root, { select = { "path" } } }, + }) + end, + description = "ZkIndex", + }, + ZkList = { + function() + local bufpath = vim.api.nvim_buf_get_name(0) + local root = find_zk_root(bufpath) + + vim.lsp.buf_request(0, "workspace/executeCommand", { + command = "zk.list", + arguments = { root, { select = { "path" } } }, + }, function(_, result, _, _) + if not result then + return + end + local paths = vim.tbl_map(function(item) + return item.path + end, result) + vim.ui.select(paths, {}, vim.cmd.edit) + end) + end, + description = "ZkList", + }, + ZkNew = { + function(...) + vim.lsp.buf_request(0, "workspace/executeCommand", { + command = "zk.new", + arguments = { + vim.api.nvim_buf_get_name(0), + ..., + }, + }, function(_, result, _, _) + if not (result and result.path) then + return + end + vim.cmd.edit(result.path) + end) + end, + + description = "ZkNew", + }, + }, +} diff --git a/config/lua/ivy/init.lua b/config/lua/ivy/init.lua index 0dd2046..2ee99ac 100644 --- a/config/lua/ivy/init.lua +++ b/config/lua/ivy/init.lua @@ -36,30 +36,6 @@ require("lz.n").load({ end, servers = function() return { - astro = {}, - bashls = {}, - cssls = {}, - dockerls = {}, - emmet_language_server = { - filetypes = { - "astro", - "css", - "eruby", - "html", - "javascript", - "javascriptreact", - "less", - "sass", - "scss", - "pug", - "typescriptreact", - }, - }, - helm_ls = {}, - hls = {}, - html = {}, - intelephense = {}, - jqls = {}, jsonls = { settings = { json = { @@ -68,60 +44,17 @@ require("lz.n").load({ }, }, }, - marksman = {}, - nushell = {}, - serve_d = {}, - sourcekit = {}, - taplo = {}, - teal_ls = {}, - tailwindcss = { - filetypes = { - "astro", - "javascriptreact", - "typescriptreact", - "html", - "css", - "tera", - }, - }, - tinymist = { - settings = { - formatterMode = "typstyle", - exportPdf = "onDocumentHasTitle", - }, - }, - volar = { - capabilities = { - workspace = { - didChangeWatchedFiles = { - dynamicRegistration = true, - }, - }, - }, - root_markers = { "package.json" }, - }, yamlls = { settings = { yaml = { - completion = true, - validate = true, - suggest = { - parentSkeletonSelectedFirst = true, - }, schemas = vim.tbl_extend("keep", { ["https://json.schemastore.org/github-action"] = ".github/action.{yaml,yml}", ["https://json.schemastore.org/github-workflow"] = ".github/workflows/*", ["https://gitlab.com/gitlab-org/gitlab/-/raw/master/app/assets/javascripts/editor/schema/ci.json"] = "*lab-ci.{yaml,yml}", - ["https://json.schemastore.org/helmfile"] = "helmfile.{yaml,yml}", ["https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json"] = "docker-compose.{yml,yaml}", ["https://goreleaser.com/static/schema.json"] = ".goreleaser.{yml,yaml}", }, require("schemastore").yaml.schemas()), }, - redhat = { - telemetry = { - enabled = false, - }, - }, }, }, } diff --git a/pkgs/neovim.nix b/pkgs/neovim.nix index c337b71..7e8662a 100644 --- a/pkgs/neovim.nix +++ b/pkgs/neovim.nix @@ -25,11 +25,11 @@ gopls, haskell-language-server, lua-language-server, + luajitPackages, marksman, selene, tailwindcss-language-server, taplo, - teal-language-server, tinymist, typescript-language-server, vscode-langservers-extracted, @@ -194,7 +194,7 @@ let nodePackages.prettier proselint taplo # toml - teal-language-server + luajitPackages.teal-language-server yaml-language-server # yaml dockerfile-language-server-nodejs lazygit -- 2.51.2