Skip to content

Commit 700066e

Browse files
committed
refactor(ui/navigation): use renderer state for message navigation
Replace manual extmark scanning and header detection with the renderer API. Use renderer.get_rendered_message, get_next_rendered_message and get_prev_rendered_message and simplify cursor positioning to use rendered_msg.line_start + 1. Remove dependency on output_window and the is_message_header helper. This should fix #348
1 parent 1d10bf9 commit 700066e

1 file changed

Lines changed: 12 additions & 56 deletions

File tree

lua/opencode/ui/navigation.lua

Lines changed: 12 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,7 @@
11
local M = {}
22

33
local state = require('opencode.state')
4-
local output_window = require('opencode.ui.output_window')
5-
6-
local function is_message_header(details)
7-
local icons = require('opencode.ui.icons')
8-
local header_user_icon = icons.get('header_user')
9-
local header_assistant_icon = icons.get('header_assistant')
10-
11-
if not details or not details.virt_text then
12-
return false
13-
end
14-
15-
local first_virt_text = details.virt_text[1]
16-
if not first_virt_text then
17-
return false
18-
end
19-
20-
return first_virt_text[1] == header_user_icon or first_virt_text[1] == header_assistant_icon
21-
end
4+
local renderer = require('opencode.ui.renderer')
225

236
function M.goto_message_by_id(message_id)
247
require('opencode.ui.ui').focus_output()
@@ -30,12 +13,11 @@ function M.goto_message_by_id(message_id)
3013
return
3114
end
3215

33-
local rendered_msg = require('opencode.ui.renderer').get_rendered_message(message_id)
16+
local rendered_msg = renderer.get_rendered_message(message_id)
3417
if not rendered_msg or not rendered_msg.line_start then
3518
return
3619
end
37-
local sep_offset = #require('opencode.ui.formatter').separator
38-
vim.api.nvim_win_set_cursor(win, { rendered_msg.line_start + sep_offset, 0 })
20+
vim.api.nvim_win_set_cursor(win, { rendered_msg.line_start + 1, 0 })
3921
end
4022

4123
function M.goto_next_message()
@@ -49,23 +31,10 @@ function M.goto_next_message()
4931
end
5032

5133
local current_line = vim.api.nvim_win_get_cursor(win)[1]
52-
53-
local extmarks = vim.api.nvim_buf_get_extmarks(
54-
buf,
55-
output_window.namespace,
56-
{ current_line, 0 },
57-
-1,
58-
{ details = true }
59-
)
60-
61-
for _, extmark in ipairs(extmarks) do
62-
local line = extmark[2] + 1
63-
local details = extmark[4]
64-
65-
if line > current_line and is_message_header(details) then
66-
vim.api.nvim_win_set_cursor(win, { line, 0 })
67-
return
68-
end
34+
local next_message = renderer.get_next_rendered_message(current_line)
35+
if next_message and next_message.line_start then
36+
vim.api.nvim_win_set_cursor(win, { next_message.line_start + 1, 0 })
37+
return
6938
end
7039

7140
local line_count = vim.api.nvim_buf_line_count(buf)
@@ -83,25 +52,12 @@ function M.goto_prev_message()
8352
end
8453

8554
local current_line = vim.api.nvim_win_get_cursor(win)[1]
86-
87-
local extmarks = vim.api.nvim_buf_get_extmarks(
88-
buf,
89-
output_window.namespace,
90-
0,
91-
{ current_line - 1, -1 },
92-
{ details = true }
93-
)
94-
95-
for i = #extmarks, 1, -1 do
96-
local extmark = extmarks[i]
97-
local line = extmark[2] + 1
98-
local details = extmark[4]
99-
100-
if line < current_line and is_message_header(details) then
101-
vim.api.nvim_win_set_cursor(win, { line, 0 })
102-
return
103-
end
55+
local previous_message = renderer.get_prev_rendered_message(current_line)
56+
if previous_message and previous_message.line_start then
57+
vim.api.nvim_win_set_cursor(win, { previous_message.line_start + 1, 0 })
58+
return
10459
end
60+
10561
vim.api.nvim_win_set_cursor(win, { 1, 0 })
10662
end
10763

0 commit comments

Comments
 (0)