summaryrefslogtreecommitdiff
path: root/lua/lsp.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/lsp.lua')
-rw-r--r--lua/lsp.lua308
1 files changed, 0 insertions, 308 deletions
diff --git a/lua/lsp.lua b/lua/lsp.lua
deleted file mode 100644
index 1d2cb37..0000000
--- a/lua/lsp.lua
+++ /dev/null
@@ -1,308 +0,0 @@
--- my_lsp.lua
-local ok_cmp, cmp = pcall(require, "cmp")
-local ok_kind, lspkind = pcall(require, "lspkind")
-local ok_cmp_caps, cmp_caps = pcall(require, "cmp_nvim_lsp")
-local has_lspconfig, lspconfig = pcall(require, "lspconfig")
-
--- ── completion (cmp) ───────────────────────────────────────────────────────────
-vim.opt.completeopt = { "menu", "menuone", "noselect" }
-vim.opt.shortmess:append("c")
-
-if ok_kind then
- lspkind.init({
- symbol_map = {
- Text = "󰉿",
- Method = "󰊕",
- Function = "λ",
- Constructor = "",
- Field = "󰜢",
- Variable = "󰀫",
- Class = "󰠱",
- Interface = "",
- Module = "󰆧",
- Property = "󰜢",
- Unit = "󰑭",
- Value = "󰎠",
- Enum = "",
- Keyword = "󰌋",
- Snippet = "",
- Color = "󰏘",
- File = "󰈙",
- Reference = "󰈇",
- Folder = "󰉋",
- EnumMember = "",
- Constant = "󰏿",
- Struct = "󰙅",
- Event = "",
- Operator = "󰆕",
- TypeParameter = "τ",
- },
- })
-end
-
-local function has_words_before()
- local unpack = unpack or table.unpack
- local line, col = unpack(vim.api.nvim_win_get_cursor(0))
- if col == 0 then return false end
- local l = vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1] or ""
- return l:sub(col, col):match("%s") == nil
-end
-
-local function feedkey(key, mode)
- vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true)
-end
-
-if ok_cmp then
- cmp.setup({
- mapping = {
- ["<C-d>"] = cmp.mapping.scroll_docs(-4, { "i", "s" }),
- ["<C-u>"] = cmp.mapping.scroll_docs(4, { "i", "s" }),
- ["<C-e>"] = cmp.mapping.close(),
- ["<C-Space>"] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }),
- ["<C-n>"] = cmp.mapping(function()
- cmp.select_next_item()
- pcall(vim.fn["vsnip#deactivate"])
- end, { "i", "s" }),
- ["<C-p>"] = cmp.mapping(function()
- cmp.select_prev_item()
- pcall(vim.fn["vsnip#deactivate"])
- end, { "i", "s" }),
- ["<Tab>"] = cmp.mapping(function(fallback)
- if vim.fn == 1 then
- feedkey("<Plug>(vsnip-expand-or-jump)", "")
- elseif cmp.visible() then
- cmp.mapping.confirm({ select = true })()
- elseif has_words_before() then
- cmp.complete()
- else
- fallback()
- end
- end, { "i", "s" }),
- ["<S-Tab>"] = cmp.mapping(function()
- if cmp.visible() then
- cmp.select_prev_item()
- elseif vim.fn["vsnip#jumpable"](-1) == 1 then
- feedkey("<Plug>(vsnip-jump-prev)", "")
- end
- end, { "i", "s" }),
- },
- formatting = ok_kind and {
- format = lspkind.cmp_format({
- mode = "symbol_text",
- maxwidth = 50,
- ellipsis_char = "...",
- show_labelDetails = true,
- before = function(_, item)
- local function split_args(s)
- if #s == 0 or not s:find("%(") then return s, "" end
- local i = s:find("%(") - 1
- return s:sub(1, i), s:sub(i + 1)
- end
- local verbosity = (vim.bo.filetype == "java") and 2 or 1
- if vim.bo.filetype == "java" and item.kind == "Method" then
- local name, args = split_args(item.abbr)
- item.abbr = name
- item.menu = (args or "") .. (item.menu or "")
- end
- item.abbr = item.abbr:sub(1, 20 * verbosity)
- item.menu = (item.menu or ""):sub(1, 20 * verbosity)
- return item
- end,
- }),
- } or nil,
- sources = {
- { name = "nvim_lsp" },
- { name = "path" },
- { name = "vim_vsnip" },
- { name = "buffer", keyword_length = 5 },
- },
- sorting = { comparators = {} }, -- let LSP decide
- snippet = {
- expand = function(args) vim.fn["vsnip#anonymous"](args.body) end,
- },
- experimental = { native_menu = false, ghost_text = true },
- })
-
- -- zsh source on zsh buffers
- vim.api.nvim_create_augroup("CmpZsh", { clear = true })
- vim.api.nvim_create_autocmd("FileType", {
- group = "CmpZsh",
- pattern = "zsh",
- callback = function()
- require("cmp").setup.buffer { sources = { { name = "zsh" } } }
- end,
- })
-end
-
--- ── LSP shared on_attach & capabilities ───────────────────────────────────────
-local M = {}
-
-M.on_attach = function(client, bufnr)
- -- omnifunc, tagfunc, formatexpr
- vim.bo[bufnr].omnifunc = "v:lua.vim.lsp.omnifunc"
- if vim.lsp.formatexpr then vim.bo[bufnr].formatexpr = "v:lua.vim.lsp.formatexpr" end
- if vim.lsp.tagfunc then vim.bo[bufnr].tagfunc = "v:lua.vim.lsp.tagfunc" end
-
- local map = function(mode, lhs, rhs)
- vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, silent = true, noremap = true })
- end
- map("n", "<leader>rn", vim.lsp.buf.rename)
- map("n", "<leader>ca", vim.lsp.buf.code_action)
- map("n", "<M-k>", vim.lsp.buf.hover)
- map("n", "g0", vim.lsp.buf.document_symbol)
- map("n", "gW", vim.lsp.buf.workspace_symbol)
- map("n", "gd", vim.lsp.buf.definition)
- map("n", "gD", vim.lsp.buf.declaration)
- map("n", "gi", vim.lsp.buf.implementation)
- map("n", "gr", vim.lsp.buf.references)
- map("n", "<C-k>", vim.lsp.buf.signature_help)
- map("n", "g<space>", vim.lsp.buf.type_definition)
- map("n", "[d", vim.diagnostic.goto_prev)
- map("n", "]d", vim.diagnostic.goto_next)
-
- -- document highlight (only if server supports it)
- if client.server_capabilities.documentHighlightProvider then
- local gid = vim.api.nvim_create_augroup("LspDocumentHighlight" .. bufnr, { clear = true })
- vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
- group = gid, buffer = bufnr, callback = vim.lsp.buf.document_highlight,
- })
- vim.api.nvim_create_autocmd("CursorMoved", {
- group = gid, buffer = bufnr, callback = vim.lsp.buf.clear_references,
- })
- end
-
- vim.opt_local.signcolumn = "yes"
-end
-
-local capabilities = vim.lsp.protocol.make_client_capabilities()
-if ok_cmp_caps then
- capabilities = cmp_caps.default_capabilities(capabilities)
-end
-
--- nice diagnostics styling
-vim.cmd [[hi DiagnosticUnderlineError gui=undercurl guisp=salmon]]
-vim.cmd [[hi DiagnosticUnderlineWarn gui=undercurl guisp=gold]]
-for type, icon in pairs({ Error = " ", Warn = " ", Hint = " ", Info = " " }) do
- local hl = "DiagnosticSign" .. type
- vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = "" })
-end
-
--- ── Servers (one table to rule them all) ──────────────────────────────────────
-local servers = {
- bashls = { filetypes = { "bash", "sh" } },
- clangd = { filetypes = { "c", "cpp", "objc", "objcpp", "cuda" } },
- mlir = { filetypes = { "mlir" } },
- jqls = { filetypes = { "jq" } },
- lua_ls = {
- filetypes = { "lua" },
- settings = {
- Lua = {
- runtime = {
- version = "LuaJIT",
- },
- workspace = {
- checkThirdParty = false,
- library = {
- vim.env.VIMRUNTIME,
- },
- }
- }
- }
- },
- ocamllsp = {},
- perlpls = {},
- rust_analyzer = {
- settings = {
- semantic_tokens = {
- modifiers = {
- disabled = { "dead" },
- },
- },
- }
- },
- verible = {},
- vimls = {},
- zls = {},
- texlab = {},
- hls = {
- settings = { haskell = { plugin = { semanticTokens = { globalOn = true } } } }
- },
- pylsp = {
- settings = { pylsp = { plugins = { pycodestyle = { enabled = false } } } }
- },
-}
-
--- Fallback command guesses for native start (used only if lspconfig is absent)
-local default_cmd = {
- bashls = { "bash-language-server", "start" },
- clangd = { "clangd" },
- mlir = { "mlir-lsp-server" },
- jqls = { "jq-lsp" },
- lua_ls = { "lua-language-server" },
- ocamllsp = { "ocamllsp" },
- perlpls = { "perlpls" },
- rust_analyzer = { "rust-analyzer" },
- verible = { "verible-verilog-ls" },
- vimls = { "vim-language-server", "--stdio" },
- zls = { "zls" },
- texlab = { "texlab" },
- hls = { "haskell-language-server-wrapper", "--lsp" },
- pylsp = { "pylsp" },
-}
-
--- ── Setup: prefer native vim.lsp.config, fallback to lspconfig ───────────────
-local has_native = (vim.lsp and vim.lsp.config and vim.lsp.start)
-
-local function setup_with_native(name, opts)
- -- Build a vim.lsp.config() object and start per-filetype
- local cfg = vim.lsp.config(name, {
- name = name,
- cmd = opts.cmd or default_cmd[name],
- root_dir = opts.root_dir, -- optional; can rely on server defaults
- filetypes = opts.filetypes,
- settings = opts.settings,
- capabilities = capabilities,
- on_attach = M.on_attach,
- })
-
- vim.lsp.enable(name);
-
- -- if cfg.cmd == nil then
- -- vim.notify(("LSP %s: no cmd found; skipping native start."):format(name), vim.log.levels.WARN)
- -- return
- -- end
-
- -- Start when a matching buffer opens
- -- local pat = opts.filetypes or "*"
- -- vim.api.nvim_create_autocmd("FileType", {
- -- pattern = pat,
- -- callback = function(args)
- -- -- Only start if ft matches the server's filetypes (or none specified)
- -- if not cfg.filetypes or vim.tbl_contains(cfg.filetypes, vim.bo[args.buf].filetype) then
- -- vim.lsp.start(cfg, { bufnr = args.buf })
- -- end
- -- end,
- -- })
-end
-
-local function setup_with_lspconfig(name, opts)
- if not has_lspconfig then
- vim.notify(("lspconfig not found; cannot setup %s"):format(name), vim.log.levels.WARN)
- return
- end
- local final = vim.tbl_deep_extend("force", {
- capabilities = capabilities,
- on_attach = M.on_attach,
- }, opts or {})
- lspconfig[name].setup(final)
-end
-
-for name, opts in pairs(servers) do
- if has_native then
- setup_with_native(name, opts)
- else
- setup_with_lspconfig(name, opts)
- end
-end
-
-return M