Skip to content

Commit 58f52b7

Browse files
IlyasYOYibhagwan
authored andcommitted
fix(actions): copy edits before preview
1 parent f233cb2 commit 58f52b7

2 files changed

Lines changed: 80 additions & 1 deletion

File tree

lua/fzf-lua/previewer/codeaction.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ local function diff_text_edits(text_edits, bufnr, offset_encoding, diff_opts)
3131
local orig_lines = get_lines(bufnr)
3232
local tmpbuf = vim.api.nvim_create_buf(false, true)
3333
vim.api.nvim_buf_set_lines(tmpbuf, 0, -1, false, orig_lines)
34-
vim.lsp.util.apply_text_edits(text_edits, tmpbuf, offset_encoding)
34+
-- deepcopy is necessary due to the apply_text_edits's logic to change the passed edits.
35+
vim.lsp.util.apply_text_edits(utils.deepcopy(text_edits), tmpbuf, offset_encoding)
3536
local new_lines = get_lines(tmpbuf)
3637
vim.api.nvim_buf_delete(tmpbuf, { force = true })
3738
---@diagnostic disable-next-line: deprecated

tests/codeaction_spec.lua

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---@diagnostic disable: unused-local
2+
local MiniTest = require("mini.test")
3+
local helpers = require("fzf-lua.test.helpers")
4+
local eq = helpers.expect.equality
5+
local new_set = MiniTest.new_set
6+
7+
local T = new_set()
8+
9+
T["codeaction"] = new_set()
10+
11+
T["codeaction"]["preview does not mutate same-position text edits"] = function()
12+
local utils = require("fzf-lua.utils")
13+
local codeaction = require("fzf-lua.previewer.codeaction")
14+
local original_lsp_get_clients = utils.lsp_get_clients
15+
local bufnr = vim.api.nvim_create_buf(true, true)
16+
local text_edits = {
17+
{
18+
range = {
19+
start = { line = 0, character = 7 },
20+
["end"] = { line = 0, character = 24 },
21+
},
22+
newText = "strings.CutSuffix",
23+
},
24+
{
25+
range = {
26+
start = { line = 0, character = 7 },
27+
["end"] = { line = 0, character = 24 },
28+
},
29+
newText = "strings.TrimSuffix",
30+
},
31+
}
32+
local before = vim.deepcopy(text_edits)
33+
34+
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
35+
"if strings.HasSuffix(name, suffix) {",
36+
"\treturn strings.TrimSuffix(name, suffix)",
37+
"}",
38+
})
39+
40+
---duplication is caused by the stubbign logic.
41+
---@diagnostic disable-next-line: duplicate-set-field
42+
utils.lsp_get_clients = function(opts)
43+
if opts.id == 1 then
44+
return {
45+
{
46+
offset_encoding = "utf-16",
47+
dynamic_capabilities = { get = function() end },
48+
supports_method = function() return false end,
49+
server_capabilities = {},
50+
},
51+
}
52+
end
53+
return original_lsp_get_clients(opts)
54+
end
55+
56+
local ok, err = pcall(function()
57+
local uri = vim.uri_from_bufnr(bufnr)
58+
codeaction.builtin.preview_action_tuple({
59+
opts = {
60+
_items = {
61+
{
62+
ctx = { client_id = 1, bufnr = bufnr },
63+
action = { edit = { changes = { [uri] = text_edits } } },
64+
},
65+
},
66+
},
67+
diff_opts = { ctxlen = 3 },
68+
_resolved_actions = { false },
69+
}, 1)
70+
end)
71+
utils.lsp_get_clients = original_lsp_get_clients
72+
vim.api.nvim_buf_delete(bufnr, { force = true })
73+
74+
if not ok then error(err) end
75+
eq(text_edits, before)
76+
end
77+
78+
return T

0 commit comments

Comments
 (0)