From bdf75e4c1d984fe2f99ee0c2f5eec9dac98bee53 Mon Sep 17 00:00:00 2001 From: xesc Date: Sun, 23 Feb 2025 22:11:28 +0100 Subject: [PATCH] add lsp and snippets back --- lua/plugin/lsp.lua | 324 ++++++++++++++++++++++++++++++++++++++++ lua/plugin/snippets.lua | 20 +++ 2 files changed, 344 insertions(+) create mode 100644 lua/plugin/lsp.lua create mode 100644 lua/plugin/snippets.lua diff --git a/lua/plugin/lsp.lua b/lua/plugin/lsp.lua new file mode 100644 index 0000000..747b70a --- /dev/null +++ b/lua/plugin/lsp.lua @@ -0,0 +1,324 @@ +return { + { + "neovim/nvim-lspconfig", + dependencies = { + "williamboman/mason.nvim", + "williamboman/mason-lspconfig.nvim", + "hrsh7th/cmp-nvim-lsp", + "hrsh7th/cmp-buffer", + "hrsh7th/cmp-path", + "hrsh7th/cmp-cmdline", + "hrsh7th/nvim-cmp", + "L3MON4D3/LuaSnip", + "saadparwaiz1/cmp_luasnip", + "nvim-telescope/telescope-ui-select.nvim", + "nvimtools/none-ls.nvim", + "nvimdev/lspsaga.nvim", + 'nvim-treesitter/nvim-treesitter', + 'nvim-tree/nvim-web-devicons', + }, + config = function() + + -- setup -- + + local capabilities = vim.tbl_deep_extend( + "force", + {}, + vim.lsp.protocol.make_client_capabilities() + ) + + -- mason -- + + require("mason").setup({ + PATH = "append", + ui = { + border = "rounded", + icons = { + package_installed = "✔", + package_pending = "➜", + package_uninstalled = "✘" + } + } + }) + + -- mason lspconfig -- + + require("mason-lspconfig").setup({ + ensure_installed = { + "lua_ls", + "clangd", + "rust_analyzer", + }, + handlers = { + -- The first entry (without a key) will be the default handler + -- and will be called for each installed server that doesn't have + -- a dedicated handler. + function(server_name) -- default handler (optional) + require("lspconfig")[server_name].setup { + capabilities = capabilities + } + end, + } + }) + + -- telescope ui for null-ls + + require("telescope").setup { + extensions = { + ["ui-select"] = { + -- require("telescope.themes").get_dropdown { + -- -- even more opts + -- } + } + } + } + require("telescope").load_extension("ui-select") + + + -- null-ls (none-ls) + + local null_ls = require('null-ls') + require("null-ls").setup({ + sources = { + null_ls.builtins.diagnostics.trail_space.with { + disabled_filetypes = { "lua" } + }, + null_ls.builtins.code_actions.gitsigns, + null_ls.builtins.diagnostics.yamllint, + null_ls.builtins.formatting.yamlfmt, + null_ls.builtins.formatting.shfmt, + null_ls.builtins.formatting.shellharden, + }, + }) + + -- lspsaga (pretty lsp-windows) + + require('lspsaga').setup({ + symbol_in_winbar = { + enable = false, + show_file = false + }, + finder = { + keys = { + toggle_or_open = "", + quit = { '', 'q' } + } + }, + outline = { + win_position = 'right', + win_width = 32, + auto_preview = true, + }, + lightbulb = { + enable = false + }, + ui = { + code_action = '', + title = true, + border = 'rounded', + }, + rename = { + in_select = false, + keys = { + quit = { '', 'q' }, + select = '' + } + }, + hover_doc = { + open_cmd = '!firefox' + }, + code_action = { + keys = { + quit = { '', 'q' } + }, + extend_gitsigns = false, + }, + definition = { + keys = { + quit = { '', 'q' }, + }, + }, + diagnostic = { + border_follow = true, + extend_relatedInformation = true, + keys = { + quit = { '', 'q' }, + quit_in_show = { '', 'q' }, + } + } + }) + + -- autocomplete -- + + local kind_icons = { + 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 = "󰅲" + } + + local has_words_before = function() + unpack = unpack or table.unpack + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return col ~= 0 and + vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil + end + + local luasnip = require("luasnip") + local cmp = require("cmp") + cmp.setup({ + formatting = { + format = function(entry, vim_item) + -- Kind icons + vim_item.kind = string.format('%s %s', kind_icons[vim_item.kind], vim_item.kind) -- This concatonates the icons with the name of the item kind + -- Source + vim_item.menu = ({ + buffer = "", + nvim_lsp = "", + luasnip = "", + nvim_lua = "", + latex_symbols = "", + })[entry.source.name] + return vim_item + end + }, + snippet = { + expand = function(args) + require('luasnip').lsp_expand(args.body) -- For `luasnip` users. + end, + }, + window = { + completion = cmp.config.window.bordered(), + documentation = cmp.config.window.bordered(), + }, + mapping = cmp.mapping.preset.insert({ + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.abort() + else + cmp.complete() + end + end), + [''] = cmp.mapping.confirm({ select = false }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + -- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable() + -- they way you will only jump inside the snippet region + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + elseif has_words_before() then + cmp.complete() + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + }), + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + { name = 'luasnip' }, -- For luasnip users. + { + name = 'buffer', + option = { + get_bufnrs = function() + return vim.api.nvim_list_bufs() + end + }, + }, + }, { + }), + -- Set configuration for specific filetype. + -- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore). + cmp.setup.cmdline({ '/', '?' }, { + mapping = cmp.mapping.preset.cmdline(), + sources = { + { name = 'buffer' } + } + }), + -- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore). + cmp.setup.cmdline(':', { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = 'path' } + }, { + { name = 'cmdline' } + }) + }) + }) + + -- config -- + + vim.diagnostic.config({ + update_in_insert = true, + signs = { text = { [vim.diagnostic.severity.ERROR] = "✘ ", [vim.diagnostic.severity.WARN] = " ", [vim.diagnostic.severity.HINT] = " ", [vim.diagnostic.severity.INFO] = " " } }, + float = { + focusable = false, + style = "minimal", + border = "rounded", + source = "always", + header = "", + prefix = "", + }, + virtual_text = { + prefix = '●', -- Could be '●', '■', 'x', '▎', or anything else + }, + }) + + -- keymaps -- + + local opts = { noremap = true, silent = true } + vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts) + vim.keymap.set('n', 'K', function() vim.lsp.buf.hover { border = "rounded" } end, opts) + vim.keymap.set('n', 'k', function() vim.lsp.buf.hover { border = "rounded" } end, opts) + vim.keymap.set('n', 'cl', "LspInfo", opts) + vim.keymap.set('n', 'cd', vim.diagnostic.open_float, opts) + vim.keymap.set('n', '[n', vim.diagnostic.goto_prev, opts) + vim.keymap.set('n', ']n', vim.diagnostic.goto_next, opts) + vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts) + vim.keymap.set('n', 'cf', function() vim.lsp.buf.format { async = true } end, opts) + vim.keymap.set('v', 'cf', function() vim.lsp.buf.format { async = true } end, opts) + vim.keymap.set("n", "fws", function() vim.lsp.buf.workspace_symbol() end, opts) + vim.keymap.set("i", "", function() vim.lsp.buf.signature_help() end, opts) + vim.keymap.set('n', '', "Lspsaga term_toggle", opts) + vim.keymap.set('t', '', "Lspsaga term_toggle", opts) + vim.keymap.set('n', 'so', 'Lspsaga outline', opts) + vim.keymap.set('n', 'sf', 'Lspsaga finder', opts) + vim.keymap.set('n', 'sd', 'Lspsaga peek_definition', opts) + vim.keymap.set('n', 'cw', "Lspsaga rename mode=n", opts) + vim.keymap.set('n', 'cA', vim.lsp.buf.code_action, opts) + vim.keymap.set('n', 'ca', 'Lspsaga code_action', opts) + end, + } +} diff --git a/lua/plugin/snippets.lua b/lua/plugin/snippets.lua new file mode 100644 index 0000000..273e250 --- /dev/null +++ b/lua/plugin/snippets.lua @@ -0,0 +1,20 @@ +return { + { + "L3MON4D3/LuaSnip", + lazy = true, + dependencies = { + "rafamadriz/friendly-snippets", + config = function() + require("luasnip.loaders.from_vscode").lazy_load() + vim.api.nvim_set_hl(0, "PmenuSel", { fg = 'NONE', bg = '#272e33' }) + vim.api.nvim_set_hl(0, "Pmenu", { fg = 'NONE', bg = '#1e2326' }) + vim.api.nvim_set_hl(0, "CmpItemMenu", { fg = 'NONE', bg = '#272e33' }) + vim.api.nvim_set_hl(0, "CmpItemMenuDefault", { fg = 'NONE', bg = '#272e33' }) + vim.api.nvim_set_hl(0, "CmpItemKindFunction", { fg = '#d699b6', bg = 'NONE', italic = true }) + vim.api.nvim_set_hl(0, "CmpItemKindSnippet", { fg = '#dbbc7f', bg = 'NONE', italic = true }) + vim.api.nvim_set_hl(0, "CmpItemKindText", { fg = '#9da9a0', bg = 'NONE', italic = true }) + vim.api.nvim_set_hl(0, "CmpItemKindVariable", { fg = '#7fbbb3', bg = 'NONE', italic = true }) + end, + }, + } +}