如何配置Neovim双Python LSP:Jedi做跳转,pylsp处理其他功能?
解决方案:为多LSP分配特定功能
当多个LSP服务同一文件类型时,Neovim默认会优先使用后启动的客户端的全部能力,导致前一个的功能被覆盖。要实现功能拆分,需要手动裁剪每个LSP的能力范围,让它们各司其职。
具体配置修改
修改你的nvim-lspconfig配置,分别限制pylsp和jedi-lsp的能力:
-- 先获取默认的LSP能力 local default_capabilities = require('lspconfig').util.default_capabilities() -- 配置pylsp:禁用"跳转到定义",保留其他所有功能 require("lspconfig").pylsp.setup{ capabilities = vim.tbl_deep_extend('force', default_capabilities, { textDocument = { definition = false, -- 关闭跳转定义能力 } }), settings = { pylsp = { plugins = { pycodestyle = { enabled = true }, flake8 = { enabled = true }, pyflakes = { enabled = true } } } } } -- 配置jedi-lsp:仅保留"跳转到定义",禁用其他所有功能 require('lspconfig').jedi_language_server.setup{ capabilities = { textDocument = { definition = true, -- 只开启跳转定义 -- 禁用其他所有不需要的能力 completion = false, hover = false, signatureHelp = false, declaration = false, typeDefinition = false, implementation = false, references = false, documentHighlight = false, documentSymbol = false, codeAction = false, codeLens = false, formatting = false, rangeFormatting = false, rename = false, foldingRange = false, }, workspace = { workspaceFolders = false, symbol = false, } } }
配置说明
- pylsp:通过
vim.tbl_deep_extend继承默认能力,仅关闭definition字段,保留格式化、自动补全、诊断等所有其他功能。 - jedi-lsp:不继承默认能力,仅显式开启
definition,其余能力全部关闭,确保它只处理跳转定义请求。
验证方法
- 重启Neovim后打开Python文件,运行
:LspInfo,确认两个客户端都已附加到缓冲区。 - 测试跳转到Pytest fixture:使用
gd(默认跳转定义快捷键),应该能正确跳转到fixture定义。 - 测试格式化:运行
:lua vim.lsp.buf.format(),应该调用pylsp的格式化功能,同时诊断信息(如flake8提示)正常显示。
更优实现建议
如果你使用mason-lspconfig管理LSP,可以把能力配置抽成通用函数,避免重复代码:
local function disable_capability(capabilities, capability) capabilities.textDocument[capability] = false end local function only_enable_capability(capabilities, capability) -- 重置所有能力为false for k, _ in pairs(capabilities.textDocument) do capabilities.textDocument[k] = false end capabilities.textDocument[capability] = true -- 关闭工作区相关能力 capabilities.workspace = {} end local default_capabilities = require('lspconfig').util.default_capabilities() -- pylsp配置 local pylsp_cap = vim.tbl_deep_extend('force', {}, default_capabilities) disable_capability(pylsp_cap, 'definition') require("lspconfig").pylsp.setup{ capabilities = pylsp_cap, settings = { ... } -- 你的原有设置 } -- jedi-lsp配置 local jedi_cap = require('lspconfig').util.default_capabilities() only_enable_capability(jedi_cap, 'definition') require('lspconfig').jedi_language_server.setup{ capabilities = jedi_cap }
这样代码更整洁,后续调整能力也更方便。
内容的提问来源于stack exchange,提问作者Свалов Семен
相关产品推荐
相关产品推荐

