nvim中配置lsp
配置基础功能
Section titled “配置基础功能”在进行这一步之前,确保已安装telescope和aerial插件
创建 ~/.config/nvim/lua/lsp.lua 并写入以下内容
vim.api.nvim_create_autocmd("LspAttach", { group = vim.api.nvim_create_augroup("lsp-attach", { clear = true }), callback = function(event) local map = function(keys, func, desc, mode) mode = mode or "n" vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = "LSP: " .. desc }) end -- 设置一些快捷键,你可以使用这些快捷键进行LSP有关的操作 -- 你需要安装 Telescope map("grn", vim.lsp.buf.rename, "[R]ename") map("grs", require("telescope").extensions.aerial.aerial, "LSP Symbols") map("gra", vim.lsp.buf.code_action, "[G]oto Code [A]ction", { "n", "x" }) map("grr", require("telescope.builtin").lsp_references, "[G]oto [R]eferences") map("gri", require("telescope.builtin").lsp_implementations, "[G]oto [I]mplementation") map("grd", require("telescope.builtin").lsp_definitions, "[G]oto [D]efinition") map("grD", vim.lsp.buf.declaration, "[G]oto [D]eclaration") map("gO", require("telescope.builtin").lsp_document_symbols, "Open Document Symbols") map("grw", require("telescope.builtin").lsp_dynamic_workspace_symbols, "Open Workspace Symbols") map("grt", require("telescope.builtin").lsp_type_definitions, "[G]oto [T]ype Definition") map("grh", vim.lsp.buf.hover, "Hover") local function client_supports_method(client, method, bufnr) return client:supports_method(method, bufnr) end
-- 自动高亮你光标下内容的引用,并在光标移动时清除 local client = vim.lsp.get_client_by_id(event.data.client_id) if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_documentHighlight, event.buf) then local highlight_augroup = vim.api.nvim_create_augroup("lsp-highlight", { clear = false }) vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { buffer = event.buf, group = highlight_augroup, callback = vim.lsp.buf.document_highlight, })
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, { buffer = event.buf, group = highlight_augroup, callback = vim.lsp.buf.clear_references, })
vim.api.nvim_create_autocmd("LspDetach", { group = vim.api.nvim_create_augroup("lsp-detach", { clear = true }), callback = function(event2) vim.lsp.buf.clear_references() vim.api.nvim_clear_autocmds { group = "lsp-highlight", buffer = event2.buf, } end, }) end
-- 创建一个快捷键,以便切换是否启用 Inlay Hints(如果可用) if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_inlayHint, event.buf) then vim.lsp.inlay_hint.enable(true) -- 默认启用,你可以把它改为false vim.keymap.set("n", "<leader>uh", function() vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf }) if vim.lsp.inlay_hint.is_enabled { bufnr = event.buf } then vim.notify("Inlay hints: " .. "ON") else vim.notify("Inlay hints: " .. "OFF") end end, { desc = "Toggle Inlay Hints" }) end end,})
-- 诊断信息设置-- 查看 :help vim.diagnostic.Optsvim.diagnostic.config { severity_sort = true, float = { border = "rounded", source = "if_many" }, underline = { severity = vim.diagnostic.severity.ERROR }, signs = { text = { [vim.diagnostic.severity.ERROR] = " ", -- 这里配置“错误”的图标,需要nerd font字体 [vim.diagnostic.severity.WARN] = " ", [vim.diagnostic.severity.INFO] = " ", [vim.diagnostic.severity.HINT] = " ", }, }, virtual_text = { source = "if_many", spacing = 2, format = function(diagnostic) local diagnostic_message = { [vim.diagnostic.severity.ERROR] = diagnostic.message, [vim.diagnostic.severity.WARN] = diagnostic.message, [vim.diagnostic.severity.INFO] = diagnostic.message, [vim.diagnostic.severity.HINT] = diagnostic.message, } return diagnostic_message[diagnostic.severity] end, },}
-- 下面这一堆是跳转到诊断信息的快捷键vim.keymap.set( "n", "[h", function() vim.diagnostic.jump { severity = vim.diagnostic.severity.HINT, count = -1 } end, { desc = "Previous hint" })vim.keymap.set( "n", "]h", function() vim.diagnostic.jump { severity = vim.diagnostic.severity.HINT, count = 1 } end, { desc = "Next hint" })vim.keymap.set( "n", "[i", function() vim.diagnostic.jump { severity = vim.diagnostic.severity.INFO, count = -1 } end, { desc = "Previous info" })vim.keymap.set( "n", "]i", function() vim.diagnostic.jump { severity = vim.diagnostic.severity.INFO, count = 1 } end, { desc = "Next info" })vim.keymap.set( "n", "[w", function() vim.diagnostic.jump { severity = vim.diagnostic.severity.WARN, count = -1 } end, { desc = "Previous warning" })vim.keymap.set( "n", "]w", function() vim.diagnostic.jump { severity = vim.diagnostic.severity.WARN, count = 1 } end, { desc = "Next warning" })vim.keymap.set( "n", "[e", function() vim.diagnostic.jump { severity = vim.diagnostic.severity.ERROR, count = -1 } end, { desc = "Previous error" })vim.keymap.set( "n", "]e", function() vim.diagnostic.jump { severity = vim.diagnostic.severity.ERROR, count = 1 } end, { desc = "Next error" })
-- 当光标处有诊断信息时自动显示vim.api.nvim_create_autocmd("CursorHold", { pattern = "*", callback = function() vim.diagnostic.open_float(nil, { focusable = false, close_events = { "CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre" }, border = "rounded", scope = "cursor", }) end,})init.lua 中加入这一行:
require("lsp")安装自动补全插件 blink.cmp
-- Lua/plugins/blink-cmp.lualocal function has_words_before() local line, col = (unpack or table.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" == nilend
return { "Saghen/blink.cmp", dependencies = { "xzbdmw/colorful-menu.nvim", "rafamadriz/friendly-snippets", }, version = "1.*", event = { "InsertEnter", "CmdlineEnter" }, opts = { keymap = { ["<Up>"] = { "select_prev", "fallback" }, ["<Down>"] = { "select_next", "fallback" }, ["<C-U>"] = { "scroll_documentation_up", "fallback" }, ["<C-D>"] = { "scroll_documentation_down", "fallback" }, ["<C-e>"] = { "hide", "fallback" }, ["<CR>"] = { "accept", "fallback" }, ["<Tab>"] = { "snippet_forward", "select_next", function(cmp) if has_words_before() or vim.api.nvim_get_mode().mode == "c" then return cmp.show() end end, "fallback", }, ["<S-Tab>"] = { "select_prev", "snippet_backward", function(cmp) if vim.api.nvim_get_mode().mode == "c" then return cmp.show() end end, "fallback", }, },
completion = { list = { selection = { preselect = false } }, documentation = { auto_show = true }, menu = { border = "rounded", draw = { columns = { { "kind_icon" }, { "label", gap = 1 } }, components = { label = { text = function(ctx) return require("colorful-menu").blink_components_text(ctx) end, highlight = function(ctx) return require("colorful-menu").blink_components_highlight(ctx) end, }, }, }, }, }, signature = { enabled = true, }, cmdline = { completion = { list = { selection = { preselect = false } }, menu = { auto_show = true, }, }, }, sources = { default = { "lsp", "path", "snippets", "buffer" }, }, }, opts_extend = { "sources.default" },}Lua 配置
Section titled “Lua 配置”将以下内容写入 ~/.config/nvim/lsp/lua_ls.lua :
return { cmd = { 'lua-language-server' }, filetypes = { 'lua' }, root_markers = { '.luarc.json', '.luarc.jsonc', '.luacheckrc', '.stylua.toml', 'stylua.toml', 'selene.toml', 'selene.yml', '.git', },}这里的 cmd 是语言服务器的可执行文件。在 0.11 版本中,不需要使用 nvim-lspconfig 插件。
将以下内容添加到 ~/.config/nvim/lua/lsp.lua ,用于启动这个配置:
vim.lsp.enable('lua_ls')enable 后面的参数 lua_ls ,对应 lsp 文件夹内的 lua_ls.lua
安装三个插件
{ "mason-org/mason.nvim", event = "VeryLazy", keys = { { "<leader>M", "<cmd>Mason<cr>", desc = "Open Mason", }, }, opts = { ui = { icons = { package_installed = "●", package_pending = "○", package_uninstalled = "○", }, }, }, }, { "WhoIsSethDaniel/mason-tool-installer.nvim", event = "VeryLazy", }, { "mason-org/mason-lspconfig.nvim", event = "VeryLazy", config = function() local capabilities = require("blink.cmp").get_lsp_capabilities()
-- Enable the following language servers -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. -- -- Add any additional override configuration in the following tables. Available keys are: -- - cmd (table): Override the default command used to start the server -- - filetypes (table): Override the default list of associated filetypes for the server -- - capabilities (table): Override fields in capabilities. Can be used to disable certain LSP features. -- - settings (table): Override the default settings passed when initializing the server. -- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/ local servers = { lua_ls = {}, } local formatting_tools = { "stylua", } local ensure_installed = vim.list_extend(vim.tbl_keys(servers), formatting_tools) ensure_installed = vim.list_extend(ensure_installed, dap) require("mason").setup {} require("mason-lspconfig").setup { automatic_installation = false, automatic_enable = { "lua_ls", }, handlers = { function(server_name) local server = servers[server_name] or {} -- This handles overriding only values explicitly passed -- by the server configuration above. Useful when disabling -- certain features of an LSP (for example, turning off formatting for ts_ls) server.capabilities = vim.tbl_deep_extend("force", {}, capabilities, server.capabilities or {}) vim.lsp.config(server_name, server) end, }, } require("mason-tool-installer").setup { ensure_installed = ensure_installed, run_on_start = false, start_delay = 0, } vim.cmd "MasonToolsUpdate" end, },在 servers 变量中可以覆盖服务器的默认设置。插件会自动安装其中 servers, formatting_tools, dap 三个变量里面的工具。
lazydev 插件
Section titled “lazydev 插件”lazydev.nvim 插件提供了增强Lua补全功能,可以更好地适配Neovim的配置功能
若使用此插件,删除
lsp.lua中的vim.lsp.enable('lua_ls'),插件会自动调用这个函数
安装插件:
{ "folke/lazydev.nvim", ft = "lua", opts = { library = { -- Load luvit types when the `vim.uv` word is found { path = "${3rd}/luv/library", words = { "vim%.uv" } }, }, },}

