Skip to content

Commit dd6dba0

Browse files
committed
feat(ui): refactor renderer and scrolling
- dialog: add support to extend vertical border to trailing blank via config.extend_border_to_trailing_blank - renderer: wrap full-session rendering in bulk flush (begin/end) and delegate scroll-to-bottom to scroll module - output_window: simplify visible-bottom-line calculation to use vim.fn.line('w$') - ui: guard treesitter language registration with pcall to avoid errors in minimal builds
1 parent 2b1eeda commit dd6dba0

4 files changed

Lines changed: 21 additions & 56 deletions

File tree

lua/opencode/ui/dialog.lua

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,11 @@ function Dialog:format_dialog(output, config)
261261
local end_line = output:get_line_count()
262262

263263
if config.border_hl then
264-
formatter.add_vertical_border(output, start_line + 1, end_line, config.border_hl, -2)
264+
local border_end = end_line
265+
if config.extend_border_to_trailing_blank then
266+
border_end = border_end + 1
267+
end
268+
formatter.add_vertical_border(output, start_line + 1, border_end, config.border_hl, -2)
265269
end
266270

267271
output:add_line('')

lua/opencode/ui/output_window.lua

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -117,37 +117,8 @@ function M.get_visible_bottom_line(win)
117117
if not win or not vim.api.nvim_win_is_valid(win) then
118118
return nil
119119
end
120-
121-
local buf = vim.api.nvim_win_get_buf(win)
122-
if not buf or not vim.api.nvim_buf_is_valid(buf) then
123-
return nil
124-
end
125-
126-
local line_count = vim.api.nvim_buf_line_count(buf)
127-
if line_count == 0 then
128-
return nil
129-
end
130-
131-
local ok_view, view = pcall(vim.api.nvim_win_call, win, vim.fn.winsaveview)
132-
if not ok_view or type(view) ~= 'table' then
133-
return nil
134-
end
135-
136-
local topline = math.max(1, view.topline or 1)
137-
local remaining_height = vim.api.nvim_win_get_height(win)
138-
for line = topline, line_count do
139-
local ok_height, result = pcall(vim.api.nvim_win_text_height, win, {
140-
start_row = line - 1,
141-
end_row = line - 1,
142-
})
143-
local line_height = ok_height and result and result.all or 1
144-
remaining_height = remaining_height - line_height
145-
if remaining_height <= 0 then
146-
return line
147-
end
148-
end
149-
150-
return line_count
120+
local ok, line = pcall(vim.fn.line, 'w$', win)
121+
return (ok and line and line > 0) and line or nil
151122
end
152123

153124
---@param win? integer

lua/opencode/ui/renderer.lua

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ local Promise = require('opencode.promise')
66
local ctx = require('opencode.ui.renderer.ctx')
77
local events = require('opencode.ui.renderer.events')
88
local flush = require('opencode.ui.renderer.flush')
9+
local scroll = require('opencode.ui.renderer.scroll')
910

1011
local M = {}
1112

@@ -123,6 +124,8 @@ function M._render_full_session_data(session_data)
123124
local revert_index = nil
124125
local set_mode_from_messages = not state.current_model
125126

127+
flush.begin_bulk_mode()
128+
126129
for i, msg in ipairs(session_data) do
127130
if state.active_session.revert and state.active_session.revert.messageID == msg.info.id then
128131
revert_index = i
@@ -159,6 +162,7 @@ function M._render_full_session_data(session_data)
159162
end
160163

161164
flush.flush()
165+
flush.end_bulk_mode()
162166

163167
if set_mode_from_messages then
164168
set_model_and_mode_from_messages()
@@ -216,28 +220,8 @@ function M.scroll_to_bottom(force)
216220
return
217221
end
218222

219-
local ok, line_count = pcall(vim.api.nvim_buf_line_count, output_buf)
220-
if not ok or line_count == 0 then
221-
return
222-
end
223-
224-
local prev_line_count = ctx.prev_line_count
225-
ctx.prev_line_count = line_count
226-
227-
local ok_cursor, cursor = pcall(vim.api.nvim_win_get_cursor, output_win)
228-
229-
local should_scroll = force
230-
or prev_line_count == 0
231-
or config.ui.output.always_scroll_to_bottom
232-
or (ok_cursor and cursor and cursor[1] >= prev_line_count)
233-
or output_window.is_at_bottom(output_win)
234-
235-
if should_scroll then
236-
local last_line = vim.api.nvim_buf_get_lines(output_buf, line_count - 1, line_count, false)[1] or ''
237-
vim.api.nvim_win_set_cursor(output_win, { line_count, #last_line })
238-
vim.api.nvim_win_call(output_win, function()
239-
vim.cmd('normal! zb')
240-
end)
223+
if force or config.ui.output.always_scroll_to_bottom or output_window.is_at_bottom(output_win) then
224+
scroll.scroll_win_to_bottom(output_win, output_buf)
241225
end
242226
end
243227

lua/opencode/ui/ui.lua

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,14 @@ end
335335

336336
function M.create_windows()
337337
if config.ui.enable_treesitter_markdown then
338-
vim.treesitter.language.register('markdown', 'opencode_output')
339-
vim.treesitter.language.register('markdown', 'opencode')
338+
local ok, treesitter = pcall(function()
339+
return vim.treesitter
340+
end)
341+
342+
if ok and treesitter and treesitter.language and treesitter.language.register then
343+
treesitter.language.register('markdown', 'opencode_output')
344+
treesitter.language.register('markdown', 'opencode')
345+
end
340346
end
341347

342348
local autocmds = require('opencode.ui.autocmds')

0 commit comments

Comments
 (0)