Neovim lsp自动修复/修复当前?

10

我正在寻找类似于CoC的coc-fix-current解决方案,但使用Neovim 0.5的本地lsp,但我在文档中没有找到这样的东西,是否有其他方法可以实现这一点?

4个回答

7

自从neovim 0.8版本以来,由于这个PR的贡献,现在有了一个名为apply的布尔值。

为确保仅应用相关的修复程序,您可以使用filter属性并查找“首选”修复程序。

以下是我在我的配置文件中添加的内容:

local opts = { noremap=true, silent=true }

local function quickfix()
    vim.lsp.buf.code_action({
        filter = function(a) return a.isPreferred end,
        apply = true
    })
end

vim.keymap.set('n', '<leader>qf', quickfix, opts)

3

我曾经遇到过这个问题,通过调试telescope.nvim插件用于列出和运行代码操作的代码,我得到了以下代码:

local function run_action(action, offse)
    if action.edit or type(action.command) == "table" then
        if action.edit then
            vim.lsp.util.apply_workspace_edit(action.edit, offse)
        end
        if type(action.command) == "table" then
            vim.lsp.buf.execute_command(action.command)
        end
    else
        vim.lsp.buf.execute_command(action)
    end
end

local function do_action(action, client)
    if
      not action.edit
      and client
      and type(client.resolved_capabilities.code_action) == "table"
      and client.resolved_capabilities.code_action.resolveProvider
    then
        client.request("codeAction/resolve", action, function(err, real)
            if err then
                return
            end
            if real then
                run_action(real, client.offset_encoding)
            else
                run_action(action, client.offset_encoding)
            end
        end)
    else
        run_action(action, client.offset_encoding) 
    end
end

return function() 
    local params = vim.lsp.util.make_range_params() -- get params for current position
    params.context = {
        diagnostics = vim.lsp.diagnostic.get_line_diagnostics(),
        only = {"quickfix"}
    }

    local results, err = vim.lsp.buf_request_sync(
        0, -- current buffer
        "textDocument/codeAction", -- get code actions
        params,
        900
    )

    if err then return end

    if not results or vim.tbl_isempty(results) then
        print "No quickfixes!"
        return
    end

    -- we have an action!
    for cid, resp in pairs(results) do
        if resp.result then
            for _, result in pairs(resp.result) do 
                -- this is the first action, run it
                do_action(result, vim.lsp.get_client_by_id(cid))
                return
            end
        end 
    end

    print "No quickfixes!"
end

因为它是lua语言,所以您需要将其放在某个.lua文件中,该文件位于nvim搜索模块的位置(例如,作为~/.config/nvim/lua/lsp_fixcurrent.lua),然后绑定到:lua require("lsp_fixcurrent")()


您让我感到非常开心,虽然看起来有些粗糙但是运行得非常好,谢谢! - Oscar Lastra

2
也许你正在寻找:vim.lsp.buf.code_action()

1
据我所知,这提供了一个有效的答案来回答这个问题。使用这个函数,我能够修复可修复的LSP错误。 - Sassan
2
虽然它打开了一个窗口来选择代码动作,但这并不是我正在寻找的功能,我正在寻找像 coc 的 "coc-fix-current" 一样的功能,它会在函数调用时自动选择正确的代码动作,无论如何,感谢您的回答。 - Oscar Lastra
在我的情况下,我使用ccls作为C++的LSP服务器,并且有时候coc的coc-fix-current可以解决问题,而本地LSP vim.lsp.buf.code_action({"quickfix"})则声称没有代码操作,不确定这里发生了什么(可能是bug,或者只是我不理解的东西)。还没有尝试接受答案。 - Emile Vrijdags
对于Rust而言,似乎coc-fix-current会将代码更改为cargo clippy所说的,但是vim.lsp.buf.code_action()不会。 :( - MrZ

1

以下是更新后的mincrmatt12的答案,适用于较新版本的Neovim(0.8?),该版本会提示不应使用client.resolved_capabilities

local function run_action(action, offse)
    if action.edit or type(action.command) == "table" then
        if action.edit then
            vim.lsp.util.apply_workspace_edit(action.edit, offse)
        end
        if type(action.command) == "table" then
            vim.lsp.buf.execute_command(action.command)
        end
    else
        vim.lsp.buf.execute_command(action)
    end
end

local function do_action(action, client)
    if
        not action.edit
        and client
        and type(client.server_capabilities) == "table"
        and client.server_capabilities.resolveProvider
    then
        client.request("codeAction/resolve", action, function(err, real)
            if err then
                return
            end
            if real then
                run_action(real, client.offset_encoding)
            else
                run_action(action, client.offset_encoding)
            end
        end)
    else
        run_action(action, client.offset_encoding)
    end
end

return function()
    local params = vim.lsp.util.make_range_params() -- get params for current position
    params.context = {
        diagnostics = vim.lsp.diagnostic.get_line_diagnostics(),
        only = { "quickfix" },
    }

    local results, err = vim.lsp.buf_request_sync(
        0, -- current buffer
        "textDocument/codeAction", -- get code actions
        params,
        900
    )

    if err then
        return
    end

    if not results or vim.tbl_isempty(results) then
        print("No quickfixes!")
        return
    end

    -- we have an action!
    for cid, resp in pairs(results) do
        if resp.result then
            for _, result in pairs(resp.result) do
                -- this is the first action, run it
                do_action(result, vim.lsp.get_client_by_id(cid))
                return
            end
        end
    end

    print("No quickfixes!")
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接