跳转到内容

Neovim

有标签“Neovim” 的 1 篇文章

nvim中配置lsp

在进行这一步之前,确保已安装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.Opts
vim.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.lua
local 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" == nil
end
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" },
}

将以下内容写入 ~/.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.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" } },
},
},
}