Skip to content

Commit e248527

Browse files
cameronrsudo-tee
authored andcommitted
fix(renderer): actions off by one when inserting
Caused by the double newline we keep at the end. Also, standardize on api-indexing (0 based line numbers) for actions.
1 parent fb4c89b commit e248527

File tree

4 files changed

+27
-12
lines changed

4 files changed

+27
-12
lines changed

lua/opencode/ui/contextual_actions.lua

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
local state = require('opencode.state')
2-
local keymap = require('opencode.keymap')
32
local output_window = require('opencode.ui.output_window')
43

54
local M = {}
@@ -26,6 +25,13 @@ function M.setup_contextual_actions(windows)
2625
callback = function()
2726
vim.schedule(function()
2827
local line_num = vim.api.nvim_win_get_cursor(0)[1]
28+
29+
if not line_num or line_num <= 0 or not state.windows or not state.windows.output_buf then
30+
return
31+
end
32+
33+
line_num = line_num - 1 -- need api-indexing (e.g. 0 based line #), win_get_cursor returns 1 based line #
34+
2935
local actions = require('opencode.ui.renderer').get_actions_for_line(line_num)
3036
last_line_num = line_num
3137

@@ -34,7 +40,7 @@ function M.setup_contextual_actions(windows)
3440

3541
if actions and #actions > 0 then
3642
dirty = true
37-
M.show_contextual_actions_menu(state.windows.output_buf, line_num, actions, ns_id)
43+
M.show_contextual_actions_menu(state.windows.output_buf, actions, ns_id)
3844
end
3945
end)
4046
end,
@@ -48,6 +54,7 @@ function M.setup_contextual_actions(windows)
4854
if not output_window.mounted() then
4955
return
5056
end
57+
---@cast state.windows { output_buf: integer}
5158
local line_num = vim.api.nvim_win_get_cursor(0)[1]
5259
if last_line_num == line_num and not dirty then
5360
return
@@ -61,15 +68,17 @@ function M.setup_contextual_actions(windows)
6168
group = augroup,
6269
buffer = windows.output_buf,
6370
callback = function()
64-
vim.api.nvim_buf_clear_namespace(state.windows.output_buf, ns_id, 0, -1)
65-
clear_keymaps(state.windows.output_buf)
71+
if state.windows and state.windows.output_buf then
72+
vim.api.nvim_buf_clear_namespace(state.windows.output_buf, ns_id, 0, -1)
73+
clear_keymaps(state.windows.output_buf)
74+
end
6675
last_line_num = nil
6776
dirty = false
6877
end,
6978
})
7079
end
7180

72-
function M.show_contextual_actions_menu(buf, line_num, actions, ns_id)
81+
function M.show_contextual_actions_menu(buf, actions, ns_id)
7382
clear_keymaps(buf)
7483

7584
for _, action in ipairs(actions) do
@@ -80,7 +89,7 @@ function M.show_contextual_actions_menu(buf, line_num, actions, ns_id)
8089
hl_mode = 'combine',
8190
}
8291

83-
vim.api.nvim_buf_set_extmark(buf, ns_id, action.display_line - 1, 0, mark)
92+
vim.api.nvim_buf_set_extmark(buf, ns_id, action.display_line, 0, mark --[[@as vim.api.keyset.set_extmark]])
8493
end
8594
-- Setup key mappings for actions
8695
for _, action in ipairs(actions) do

lua/opencode/ui/formatter.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ function M._format_revert_message(session_data, start_idx)
155155
end
156156

157157
local function add_action(output, text, action_type, args, key, line)
158+
-- actions use api-indexing (e.g. 0 indexed)
158159
line = (line or output:get_line_count()) - 1
159160
output:add_action({
160161
text = text,

lua/opencode/ui/render_state.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ function RenderState:get_message_at_line(line)
119119
end
120120

121121
---Get actions at specific line
122-
---@param line integer Line number (1-indexed)
122+
---@param line integer Line number (0-indexed)
123123
---@return table[] List of actions at that line
124124
function RenderState:get_actions_at_line(line)
125125
self:_ensure_line_index()

lua/opencode/ui/renderer.lua

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,6 @@ function M._write_formatted_data(formatted_data, part_id, start_line)
275275
return nil
276276
end
277277

278-
if part_id and formatted_data.actions then
279-
M._render_state:add_actions(part_id, formatted_data.actions, target_line)
280-
end
281-
282278
if is_insertion then
283279
output_window.set_lines(new_lines, target_line, target_line)
284280
else
@@ -287,6 +283,15 @@ function M._write_formatted_data(formatted_data, part_id, start_line)
287283
target_line = target_line - 1
288284
output_window.set_lines(extra_newline, target_line)
289285
end
286+
287+
-- update actions and extmarks after the insertion because that may
288+
-- adjust target_line (e.g. when we we're replacing the double newline at
289+
-- the end)
290+
291+
if part_id and formatted_data.actions then
292+
M._render_state:add_actions(part_id, formatted_data.actions, target_line)
293+
end
294+
290295
output_window.set_extmarks(extmarks, target_line)
291296

292297
return {
@@ -959,7 +964,7 @@ function M.on_session_changed(_, new, _)
959964
end
960965

961966
---Get all actions available at a specific line
962-
---@param line integer 1-indexed line number
967+
---@param line integer 0-indexed line number
963968
---@return table[] List of actions available at that line
964969
function M.get_actions_for_line(line)
965970
return M._render_state:get_actions_at_line(line)

0 commit comments

Comments
 (0)