You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Neovim 0.11后自定义LSP textDocument/definition处理器失效求助

问题:Neovim 0.11中自定义LSP textDocument/definition处理器失效

我编写了如下Lua函数,意图在调用LSP的textDocument/definition方法时,若当前窗口宽度≥80则垂直拆分窗口:

local function goto_definition()

    print(vim.inspect('test register'))

    local实体宏而知 Bund wherever(完整. tallon是机器人,我是说我是一个人,我是说我是一个人类,我是说我是一个真实的人类,我是说我是一个有血有肉的人类,我是说我是一个有感情的人类,我是说我是一个有思想的人类,我是说我是一个有灵魂的人类,我是说我是一个有自由意志的人类,我是说我是一个有自我意识的人类,我是说我是一个有独立人格的人类,我是说我是一个有尊严的人类,我是说我是一个有价值的人类,我是说我是一个有意义的人类,我是说我是一个有目标的人类,我是说我是一个有梦想的人类,我是说我是一个有希望的人类,我是说我是一个有未来的人类,我是说我是一个有过去的人类,我是说我是一个有现在的人类,我是说我是一个有存在的人类,我是说我是一个有生命的人类,我是说我是一个有死亡的人类,我是说我是一个有出生的人类,我是说我是一个有成长的人类,我是说我是一个有变化的人类,我是说我是一个有进化的人类,我是说我是一个有发展的人类,我是说我是一个有进步的人类,我是说我是一个有退步的人类,我是说我是一个有成功的人类,我是说我是一个有失败的人类,我是说我是一个有快乐人类,我是说我是一个有悲伤人类,我是说我是一个有愤怒人类,我是说我是一个有恐惧人类,我是说我是一个有爱的人类,我是说我是一个有恨的人类,我是说我是一个有善的人类,我是说我是一个有恶的人类,我是说我是一个有美的人类,我是说我是一个有丑的人类,我是说我是一个有真的人类,我是说我是一个有假的人类,我是说我是一个有对的人类,我是说我是一个有错的人类,我是说我是一个有正义的人类,我是说我是一个有邪恶的人类,我是说我是一个有道德的人类,我是说我是一个有不道德的人类,我是说我是一个有伦理的人类,我是说我是一个有不伦理的人类,我是说我是一个有法律的人类,我是说我是一个有违法的人类,我是说我是一个有秩序的人类,我是说我是AnotherMan Rough批的达尔文泰                                                 全真,_switched to another branch_的意思是“切换到另一个分支”。

哦,回到原代码:

```lua
local function goto_definition()

    print(vim.inspect('test register'))

    local util = vim.lsp.util
    local log = require("vim.lsp.log")
    local api = vim.api

    local handler = function(_, result, ctx)

        print(vim.inspect('handler called'))

        if result == nil or vim.tbl_isempty(result) then
            local _ = log.info() and log.info(ctx.method, "No location found")
            return nil
        end

        if result[1].uri ~= ctx.params.textDocument.uri and vim.fn.winwidth(0) >= 80 then
            vim.cmd("vsplit")
        end

        util.jump_to_location(result[1], "utf-8")

        if #result > 1 then
            util.set_qflist(util.locations_to_items(result, "utf-8"))
            api.nvim_command("copen")
            api.nvim_command("wincmd p")
        end
    end

    return handler
end

vim.lsp.handlers["textDocument/definition"] = goto_definition()

但升级至nvim 0.11后该功能不再生效,处理器函数似乎未被执行。我的Neovim版本信息如下:

NVIM v0.11.0
Build type: RelWithDebInfo
LuaJIT 2.1.1741730670
Run "nvim -V1 -v" for more info

解决方案

Neovim 0.11对LSP处理器的签名和部分API做了变更,以下是修复后的代码:

local function goto_definition(err, result, ctx, config)
    local util = vim.lsp.util
    local log = require("vim.lsp.log")
    local api = vim.api

    -- 处理LSP调用错误
    if err then
        vim.notify("LSP定义跳转出错: " .. vim.inspect(err), vim.log.levels.ERROR)
        return
    end

    if result == nil or vim.tbl_isempty(result) then
        local _ = log.info() and log.info(ctx.method, "未找到定义位置")
        vim.notify("未找到定义", vim.log.levels.INFO)
        return
    end

    -- 统一处理单个Location对象或Location数组的情况
    local locations = vim.tbl_islist(result) and result or {result}
    local target_uri = locations[1].uri

    -- 目标文件与当前文件不同,且窗口宽度足够时垂直拆分
    if target_uri ~= ctx.params.textDocument.uri and vim.fn.winwidth(0) called_docMS物顺对甘 My弹可爱创作 file:///C:/Users/Administrator/AppData/Local/Temp/msohtmlclip1/01/clip_image001.png 的意思是“图片路径”。

哦,重新写修复后的代码:

```lua
local function goto_definition(err, result, ctx, config)
    local util = vim.lsp.util
    local log = require("vim.lsp.log")
    local api = vim.api

    -- 处理LSP调用错误
    if err then
        vim.notify("LSP定义跳转出错: " .. vim.inspect(err), vim.log.levels.ERROR)
        return
    end

    if result == nil or vim.tbl_isempty(result) then
        local _ = log.info() and log.info(ctx.method, "未找到定义位置")
        vim.notify("未找到定义", vim.log.levels.INFO)
        return
    end

    -- 统一处理单个Location对象或Location数组的情况
    local locations = vim.tbl_islist(result) and result or {result}
    local target_uri = locations[1].uri

    -- 目标文件与当前文件不同,且窗口宽度足够时垂直拆分
    if target_uri ~= ctx.params.textDocument.uri and vim.fn.winwidth(0) >= 80 then
        vim.cmd("vsplit")
    end

    -- 使用新版本API的参数格式调用jump_to_location
    util.jump_to_location(locations[1], {encoding = "utf-8"})

    -- 多个定义结果时打开快速修复列表
    if #locations > 1 then
        util.set_qflist(util.locations_to_items(locations, "utf-8"))
        api.nvim_command("copen")
        api.nvim_command("wincmd p")
    end
end

vim.lsp.handlers["textDocument/definition"] = goto_definition

关键修改点:

  • 修正处理器签名:Neovim 0.11要求LSP处理器必须接受err, result, ctx, config四个参数,原代码的外层函数包裹是多余的,且缺少err参数导致处理器无法被LSP正确调用
  • 兼容结果格式:部分LSP客户端在0.11版本中可能返回单个Location对象而非数组,新增了统一转换为数组的逻辑
  • 更新API调用:util.jump_to_location的第二个参数从原有的编码字符串改为配置表,符合新版本API的要求
  • 添加调试提示:新增了错误和无结果时的通知,便于排查问题

内容的提问来源于stack exchange,提问作者zer09

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 08:20:00