Skip to content

Commit 0f8158d

Browse files
committed
navigate hunks with virtual text keymaps
1 parent d42f228 commit 0f8158d

File tree

5 files changed

+39
-29
lines changed

5 files changed

+39
-29
lines changed

lua/codecompanion/diff/keymaps.lua

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ end
3838
M.always_accept = {
3939
desc = "Always accept changes from this chat buffer",
4040
callback = function(diff_ui)
41-
log:trace("[Diff] Accepting diff for id=%s", tostring(diff_ui.diff_id))
41+
log:trace("[Diff] Accepting diff for id=%s", diff_ui.diff_id)
4242
notify(diff_ui.diff_id, true)
4343

4444
local approvals = require("codecompanion.interactions.chat.tools.approvals")
@@ -55,7 +55,7 @@ M.always_accept = {
5555
M.accept_change = {
5656
desc = "Accept all changes",
5757
callback = function(diff_ui)
58-
log:trace("[Diff] Accepting diff for id=%s", tostring(diff_ui.diff_id))
58+
log:trace("[Diff] Accepting diff for id=%s", diff_ui.diff_id)
5959
notify(diff_ui.diff_id, true)
6060

6161
local Diff = require("codecompanion.diff")
@@ -69,7 +69,7 @@ M.accept_change = {
6969
M.reject_change = {
7070
desc = "Reject all changes",
7171
callback = function(diff_ui)
72-
log:trace("[Diff] Rejecting diff for id=%s", tostring(diff_ui.diff_id))
72+
log:trace("[Diff] Rejecting diff for id=%s", diff_ui.diff_id)
7373
notify(diff_ui.diff_id, false)
7474

7575
local Diff = require("codecompanion.diff")
@@ -83,7 +83,7 @@ M.reject_change = {
8383
M.close_window = {
8484
desc = "Close window and reject",
8585
callback = function(diff_ui)
86-
log:trace("[Diff] Closing diff window for id=%s", tostring(diff_ui.diff_id))
86+
log:trace("[Diff] Closing diff window for id=%s", diff_ui.diff_id)
8787
notify(diff_ui.diff_id, false, true)
8888

8989
local Diff = require("codecompanion.diff")
@@ -102,11 +102,11 @@ M.next_hunk = {
102102
end,
103103
}
104104

105-
M.prev_hunk = {
105+
M.previous_hunk = {
106106
desc = "Previous hunk",
107107
callback = function(diff_ui)
108108
local cursor = api.nvim_win_get_cursor(diff_ui.winnr)
109-
diff_ui:prev_hunk(cursor[1])
109+
diff_ui:previous_hunk(cursor[1])
110110
end,
111111
}
112112

lua/codecompanion/diff/ui.lua

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,21 @@ end
2929

3030
---Show instructions for diff interaction
3131
---@param bufnr number
32-
---@param namespace number
32+
---@param opts {namespace: number, line?: number, clear?: boolean}
3333
---@return nil
34-
local function show_keymaps(bufnr, namespace)
34+
local function show_keymaps(bufnr, opts)
35+
local namespace = "codecompanion_diff_ui_" .. tostring(opts.namespace)
36+
3537
local always_accept = config.interactions.inline.keymaps.always_accept.modes.n
3638
local accept = config.interactions.inline.keymaps.accept_change.modes.n
3739
local reject = config.interactions.inline.keymaps.reject_change.modes.n
3840
local next_hunk = config.interactions.inline.keymaps.next_hunk.modes.n
3941
local previous_hunk = config.interactions.inline.keymaps.previous_hunk.modes.n
4042

43+
if opts.clear then
44+
ui_utils.clear_notification(bufnr, { namespace = namespace })
45+
end
46+
4147
ui_utils.show_buffer_notification(bufnr, {
4248
text = string.format(
4349
"[%s] Always Accept | [%s] Accept | [%s] Reject | [%s]/[%s] Next/Prev hunks | [q] Close",
@@ -48,8 +54,8 @@ local function show_keymaps(bufnr, namespace)
4854
previous_hunk
4955
),
5056
main_hl = "CodeCompanionChatSubtext",
51-
line = 0,
52-
namespace = "codecompanion_diff_ui_" .. namespace,
57+
line = opts.line or 0,
58+
namespace = namespace,
5359
})
5460
end
5561

@@ -59,29 +65,35 @@ function DiffUI:next_hunk(line)
5965
for _, hunk in ipairs(self.diff.hunks) do
6066
local hunk_line = hunk.pos[1] + 1
6167
if hunk_line > line then
68+
show_keymaps(self.bufnr, { clear = true, namespace = self.diff.namespace, line = hunk_line - 2 })
6269
return ui_utils.scroll_to_line(self.bufnr, hunk_line)
6370
end
6471
end
6572

6673
if #self.diff.hunks > 0 then
67-
ui_utils.scroll_to_line(self.bufnr, self.diff.hunks[1].pos[1] + 1)
74+
line = self.diff.hunks[1].pos[1] + 1
75+
show_keymaps(self.bufnr, { clear = true, namespace = self.diff.namespace, line = line - 2 })
76+
ui_utils.scroll_to_line(self.bufnr, line)
6877
end
6978
end
7079

7180
---Navigate to previous hunk
7281
---@param line number
7382
---@return nil
74-
function DiffUI:prev_hunk(line)
83+
function DiffUI:previous_hunk(line)
7584
for i = #self.diff.hunks, 1, -1 do
7685
local hunk = self.diff.hunks[i]
7786
local hunk_line = hunk.pos[1] + 1
7887
if hunk_line < line then
88+
show_keymaps(self.bufnr, { clear = true, namespace = self.diff.namespace, line = hunk_line - 2 })
7989
return ui_utils.scroll_to_line(self.bufnr, hunk_line)
8090
end
8191
end
8292

8393
if #self.diff.hunks > 0 then
84-
ui_utils.scroll_to_line(self.bufnr, self.diff.hunks[#self.diff.hunks].pos[1] + 1)
94+
line = self.diff.hunks[#self.diff.hunks].pos[1] + 1
95+
show_keymaps(self.bufnr, { clear = true, namespace = self.diff.namespace, line = line - 2 })
96+
ui_utils.scroll_to_line(self.bufnr, line)
8597
end
8698
end
8799

@@ -149,7 +161,7 @@ function M.show(diff, opts)
149161
-- Apply diff extmarks
150162
local Diff = require("codecompanion.diff")
151163
Diff.apply(diff, bufnr)
152-
show_keymaps(bufnr, diff.namespace)
164+
show_keymaps(bufnr, { namespace = diff.namespace })
153165

154166
-- Lock the buffer so the user can't make any changes
155167
vim.bo[bufnr].modified = false

lua/codecompanion/helpers.lua

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function M.get_prompt_aliases()
2323
end
2424

2525
---Create and show a diff in a floating window
26-
---@param args { from_lines: string[], to_lines: string[], ft: string, chat_bufnr?: number, title?: string, diff_id: number, width?: number, height?: number }
26+
---@param args { from_lines: string[], to_lines: string[], ft: string, chat_bufnr?: number, tool_name?: string, title?: string, diff_id: number }
2727
---@return CC.Diff diff, number bufnr, number winnr
2828
function M.show_diff(args)
2929
local bufnr = vim.api.nvim_create_buf(false, true)
@@ -38,12 +38,11 @@ function M.show_diff(args)
3838
})
3939

4040
local diff_ui = require("codecompanion.diff.ui")
41-
local bufnr, winnr = diff_ui.show(diff_obj, {
42-
chat_bufnr = args.chat_bufnr,
41+
return diff_ui.show(diff_obj, {
4342
diff_id = args.diff_id,
43+
chat_bufnr = args.chat_bufnr,
44+
tool_name = args.tool_name,
4445
})
45-
46-
return diff_obj, bufnr, winnr
4746
end
4847

4948
return M

lua/codecompanion/utils/diff_test.lua

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ function M.run_visual_test(test_num)
177177
local helpers = require("codecompanion.helpers")
178178
local diff_id = math.random(10000000)
179179

180-
local diff_obj, bufnr, winnr = helpers.show_diff({
180+
local diff_ui = helpers.show_diff({
181181
from_lines = before_lines,
182182
to_lines = after_lines,
183183
ft = test_case.filetype,
@@ -186,24 +186,24 @@ function M.run_visual_test(test_num)
186186
})
187187

188188
-- Add keymaps for cycling through test cases
189-
local keymap_opts = { buffer = bufnr, silent = true, nowait = true }
189+
local keymap_opts = { buffer = diff_ui.bufnr, silent = true, nowait = true }
190190

191191
vim.keymap.set("n", "n", function()
192192
local next_test = test_num % #M.test_cases + 1
193193
local Diff = require("codecompanion.diff")
194-
Diff.clear(diff_obj)
195-
if vim.api.nvim_win_is_valid(winnr) then
196-
vim.api.nvim_win_close(winnr, true)
194+
Diff.clear(diff_ui.diff)
195+
if vim.api.nvim_win_is_valid(diff_ui.winnr) then
196+
vim.api.nvim_win_close(diff_ui.winnr, true)
197197
end
198198
M.run_visual_test(next_test)
199199
end, vim.tbl_extend("force", keymap_opts, { desc = "Next test case" }))
200200

201201
vim.keymap.set("n", "p", function()
202202
local prev_test = test_num == 1 and #M.test_cases or test_num - 1
203203
local Diff = require("codecompanion.diff")
204-
Diff.clear(diff_obj)
205-
if vim.api.nvim_win_is_valid(winnr) then
206-
vim.api.nvim_win_close(winnr, true)
204+
Diff.clear(diff_ui.diff)
205+
if vim.api.nvim_win_is_valid(diff_ui.winnr) then
206+
vim.api.nvim_win_close(diff_ui.winnr, true)
207207
end
208208
M.run_visual_test(prev_test)
209209
end, vim.tbl_extend("force", keymap_opts, { desc = "Previous test case" }))
@@ -242,7 +242,7 @@ function M.run_visual_test(test_num)
242242
end,
243243
})
244244

245-
return diff_obj
245+
return diff_ui
246246
end
247247

248248
return M

tests/utils/test_ui.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ T["UI create_float Screenshots"]["Uses existing buffer with content overwrite (d
145145
filetype = "lua",
146146
title = "Debug Chat Info",
147147
style = "minimal",
148-
show_dim = true,
149148
})
150149
151150
-- Verify new content was set

0 commit comments

Comments
 (0)