diff --git a/ftdetect/superhtml.lua b/ftdetect/superhtml.lua deleted file mode 100644 index 15edece..0000000 --- a/ftdetect/superhtml.lua +++ /dev/null @@ -1,9 +0,0 @@ -vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, { - pattern = { "*.shtml" }, - callback = function() - vim.bo.filetype = "superhtml" - end, -}) -vim.filetype.add({ extension = { - shtml = "superhtml", -} }) diff --git a/init.lua b/init.lua index d81d753..64288fc 100644 --- a/init.lua +++ b/init.lua @@ -42,7 +42,6 @@ vim.pack.add({ github("nvim-lua/plenary.nvim"), github("Saecki/crates.nvim"), github("ziglang/zig.vim"), - { src = github("saghen/blink.cmp"), version = vim.version.range("1.*") }, github("EdenEast/nightfox.nvim"), github("ethanholz/nvim-lastplace"), github("folke/which-key.nvim"), @@ -98,10 +97,12 @@ require("snacks").setup({ picker = { sources = { files = { - exclude = { "*.lock" }, + hidden = true, + exclude = { "*.lock", ".env*" }, }, grep = { - exclude = { "*.lock" }, + hidden = true, + exclude = { "*.lock", ".env*" }, }, }, }, @@ -117,19 +118,6 @@ require("snacks").setup({ require("mini.icons").setup() require("trouble").setup() -require("blink.cmp").setup({ - completion = { - documentation = { - auto_show = true, - auto_show_delay_ms = 500, - }, - }, - keymap = { - preset = "default", - [""] = { "select_next", "fallback" }, - [""] = { "select_prev", "fallback" }, - }, -}) require("crates").setup({ lsp = { enabled = true, @@ -172,7 +160,18 @@ if cwd:sub(1, #conform_folder) ~= conform_folder then end require("mappings") +vim.api.nvim_create_autocmd("LspAttach", { + callback = function(ev) + local client = vim.lsp.get_client_by_id(ev.data.client_id) + if client ~= nil and client:supports_method("textDocument/completion") then + vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true }) + end + end, +}) + require("lsp") +vim.cmd("set completeopt+=noselect") +vim.lsp.enable({ "lua_ls", "gh_actions_ls", "gopls" }) vim.treesitter.language.register("markdown", "mdx") vim.treesitter.language.register("html", "superhtml") @@ -184,14 +183,13 @@ vim.api.nvim_create_autocmd({ "FileType" }, { pattern = { "gitcommit", "markdown", "txt" }, desc = "Enable spell checking and text wrapping for certain filetypes", callback = function() - -- vim.opt_local.wrap = true vim.opt_local.spell = true end, }) vim.opt.spell = false vim.diagnostic.config({ - update_in_insert = false, - -- virtual_text = { current_line = true }, + -- update_in_insert = false, + virtual_text = true, virtual_lines = { current_line = true }, }) diff --git a/lsp/gh_actions_ls.lua b/lsp/gh_actions_ls.lua new file mode 100644 index 0000000..17b42e9 --- /dev/null +++ b/lsp/gh_actions_ls.lua @@ -0,0 +1,57 @@ +---@brief +--- https://github.com/lttb/gh-actions-language-server +--- +--- Language server for GitHub Actions. +--- +--- The projects [forgejo](https://forgejo.org/) and [gitea](https://about.gitea.com/) +--- design their actions to be as compatible to github as possible +--- with only [a few differences](https://docs.gitea.com/usage/actions/comparison#unsupported-workflows-syntax) between the systems. +--- The `gh_actions_ls` is therefore enabled for those `yaml` files as well. +--- +--- The `gh-actions-language-server` can be installed via `npm`: +--- +--- ```sh +--- npm install -g gh-actions-language-server +--- ``` + +---@type vim.lsp.Config +return { + cmd = { "gh-actions-language-server", "--stdio" }, + filetypes = { "yaml.github" }, + + -- `root_dir` ensures that the LSP does not attach to all yaml files + root_dir = function(bufnr, on_dir) + local parent = vim.fs.dirname(vim.api.nvim_buf_get_name(bufnr)) + if + vim.endswith(parent, "/.github/workflows") + or vim.endswith(parent, "/.forgejo/workflows") + or vim.endswith(parent, "/.gitea/workflows") + then + on_dir(parent) + end + end, + handlers = { + ["actions/readFile"] = function(_, result) + if type(result.path) ~= "string" then + return nil, nil + end + local file_path = vim.uri_to_fname(result.path) + if vim.fn.filereadable(file_path) == 1 then + local f = assert(io.open(file_path, "r")) + local text = f:read("*a") + f:close() + + return text, nil + end + return nil, nil + end, + }, + init_options = {}, -- needs to be present https://github.com/neovim/nvim-lspconfig/pull/3713#issuecomment-2857394868 + capabilities = { + workspace = { + didChangeWorkspaceFolders = { + dynamicRegistration = true, + }, + }, + }, +} diff --git a/lsp/gopls.lua b/lsp/gopls.lua index 5375194..05730b0 100644 --- a/lsp/gopls.lua +++ b/lsp/gopls.lua @@ -1,6 +1,120 @@ +---@brief +--- +--- https://github.com/golang/tools/tree/master/gopls +--- +--- Google's lsp server for golang. +--- +--- [Settings documentation](https://go.dev/gopls/settings) +--- +--- NOTE: since v0.22.0 gopls no longer advertises semantic tokens to clients +--- by default. To maintain previous behavior, semantic tokens are enabled on client side. +--- To disable this feature, set `semanticTokens` option to `false`. +--- +--- ```lua +--- vim.lsp.config('gopls', { +--- settings = { +--- gopls = { +--- semanticTokens = false +--- } +--- } +--- }) +--- ``` + +--- @class go_dir_custom_args +--- +--- @field envvar_id string +--- +--- @field custom_subdir string? + +local mod_cache = nil +local std_lib = nil + +---@param custom_args go_dir_custom_args +---@param on_complete fun(dir: string | nil) +local function identify_go_dir(custom_args, on_complete) + local cmd = { "go", "env", custom_args.envvar_id } + vim.system(cmd, { text = true }, function(output) + local res = vim.trim(output.stdout or "") + if output.code == 0 and res ~= "" then + if custom_args.custom_subdir and custom_args.custom_subdir ~= "" then + res = res .. custom_args.custom_subdir + end + on_complete(res) + else + vim.schedule(function() + vim.notify( + ("[gopls] identify " .. custom_args.envvar_id .. " dir cmd failed with code %d: %s\n%s"):format( + output.code, + vim.inspect(cmd), + output.stderr + ) + ) + end) + on_complete(nil) + end + end) +end + +---@return string? +local function get_std_lib_dir() + if std_lib and std_lib ~= "" then + return std_lib + end + + identify_go_dir({ envvar_id = "GOROOT", custom_subdir = "/src" }, function(dir) + if dir then + std_lib = dir + end + end) + return std_lib +end + +---@return string? +local function get_mod_cache_dir() + if mod_cache and mod_cache ~= "" then + return mod_cache + end + + identify_go_dir({ envvar_id = "GOMODCACHE" }, function(dir) + if dir then + mod_cache = dir + end + end) + return mod_cache +end + +---@param fname string +---@return string? +local function get_root_dir(fname) + if mod_cache and fname:sub(1, #mod_cache) == mod_cache then + local clients = vim.lsp.get_clients({ name = "gopls" }) + if #clients > 0 then + return clients[#clients].config.root_dir + end + end + if std_lib and fname:sub(1, #std_lib) == std_lib then + local clients = vim.lsp.get_clients({ name = "gopls" }) + if #clients > 0 then + return clients[#clients].config.root_dir + end + end + return vim.fs.root(fname, "go.work") or vim.fs.root(fname, "go.mod") or vim.fs.root(fname, ".git") +end + +---@type vim.lsp.Config return { + cmd = { "gopls" }, + filetypes = { "go", "gomod", "gowork", "gotmpl" }, + root_dir = function(bufnr, on_dir) + local fname = vim.api.nvim_buf_get_name(bufnr) + get_mod_cache_dir() + get_std_lib_dir() + -- see: https://github.com/neovim/nvim-lspconfig/issues/804 + on_dir(get_root_dir(fname)) + end, settings = { gopls = { + semanticTokens = true, gofumpt = true, analyses = { unusedparams = true, diff --git a/lsp/harper_ls.lua b/lsp/harper_ls.lua new file mode 100644 index 0000000..c2c308e --- /dev/null +++ b/lsp/harper_ls.lua @@ -0,0 +1,8 @@ +return { + cmd = { "harper-ls", "--stdio" }, + filetypes = { + "gitcommit", + "markdown", + }, + root_markers = { ".harper-dictionary.txt", ".git" }, +} diff --git a/lsp/lua_ls.lua b/lsp/lua_ls.lua index 573f271..828921a 100644 --- a/lsp/lua_ls.lua +++ b/lsp/lua_ls.lua @@ -1,17 +1,33 @@ +local root_markers1 = { + ".emmyrc.json", + ".luarc.json", + ".luarc.jsonc", +} +local root_markers2 = { + ".luacheckrc", + ".stylua.toml", + "stylua.toml", + "selene.toml", + "selene.yml", +} + +---@type vim.lsp.Config return { + cmd = { "lua-language-server" }, + filetypes = { "lua" }, + root_markers = vim.fn.has("nvim-0.11.3") == 1 and { root_markers1, root_markers2, { ".git" } } + or vim.list_extend(vim.list_extend(root_markers1, root_markers2), { ".git" }), + ---@type lspconfig.settings.lua_ls settings = { Lua = { - runtime = { - -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) - version = "LuaJIT", - }, + codeLens = { enable = true }, diagnostics = { -- Get the language server to recognize the `vim` global and `awesome` globals = { "vim", "use", "beautiful", "awful" }, }, workspace = { -- Make the server aware of Neovim runtime files - library = vim.api.nvim_get_runtime_file("", true), + library = { vim.env.VIMRUNTIME }, checkThirdParty = false, }, hint = { diff --git a/lsp/superhtml.lua b/lsp/superhtml.lua deleted file mode 100644 index db30bb2..0000000 --- a/lsp/superhtml.lua +++ /dev/null @@ -1,3 +0,0 @@ -return { - filetypes = { "html", "superhtml", "htm", "shtml" }, -} diff --git a/lua/lsp.lua b/lua/lsp.lua index 09be4b1..c0a6a5f 100644 --- a/lua/lsp.lua +++ b/lua/lsp.lua @@ -1,9 +1,5 @@ -vim.o.completeopt = "menuone,noinsert,noselect" --- local lspkind = require("lspkind") -- A table of servers used for setting up LSP local servers = { - -- "bashls", - "superhtml", -- "pyright", "nixd", "zls", @@ -12,10 +8,6 @@ local servers = { "just", "ty", "templ", - { - "harper_ls", - exec = "harper-ls", - }, { "terraformls", exec = "terraform-ls", @@ -28,10 +20,6 @@ local servers = { "nil_ls", exec = "nil", }, - -- { - -- "ltex", - -- exec = "ltex-ls", - -- }, { "ts_ls", exec = "typescript-language-server", @@ -40,15 +28,7 @@ local servers = { "astro", exec = "astro-ls", }, - { - "lua_ls", - exec = "lua-language-server", - }, "gopls", - { - "gh_actions_ls", - exec = "gh-actions-language-server", - }, { "yamlls", exec = "yaml-language-server", @@ -85,8 +65,6 @@ for _, server in ipairs(servers) do ::continue:: end -vim.lsp.enable("biome-custom") - vim.g.rustaceanvim = { server = { on_attach = function(client, _) diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json index 0045481..6ac7fde 100644 --- a/nvim-pack-lock.json +++ b/nvim-pack-lock.json @@ -1,10 +1,5 @@ { "plugins": { - "blink.cmp": { - "rev": "78336bc89ee5365633bcf754d93df01678b5c08f", - "src": "https://github.com/saghen/blink.cmp", - "version": "1.0.0 - 2.0.0" - }, "conform.nvim": { "rev": "619363c30309d29ffa631e67c8183f2a72caa373", "src": "https://github.com/stevearc/conform.nvim"