Skip to content

Commit 476b804

Browse files
committed
docs(streaming_renderer): add function comments
1 parent 7cefe17 commit 476b804

File tree

1 file changed

+74
-2
lines changed

1 file changed

+74
-2
lines changed

lua/opencode/ui/streaming_renderer.lua

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ M._part_cache = {}
77
M._namespace = vim.api.nvim_create_namespace('opencode_stream')
88
M._prev_line_count = 0
99

10+
---Reset streaming renderer state
1011
function M.reset()
1112
M._part_cache = {}
1213
M._prev_line_count = 0
@@ -18,7 +19,7 @@ function M.reset()
1819
state.messages = {}
1920
end
2021

21-
---Set up all subscriptions
22+
---Set up all subscriptions, for both local and server events
2223
function M.setup_subscriptions(_)
2324
M._subscriptions.active_session = function(_, _, old)
2425
if not old then
@@ -58,18 +59,27 @@ function M._cleanup_subscriptions()
5859
M._subscriptions = {}
5960
end
6061

62+
---Clean up and teardown streaming renderer. Unsubscribes from all
63+
---events, local state and server
6164
function M.teardown()
6265
M._cleanup_subscriptions()
6366
M.reset()
6467
end
6568

69+
---Get number of lines in output buffer
70+
---@return integer
6671
function M._get_buffer_line_count()
6772
if not state.windows or not state.windows.output_buf then
6873
return 0
6974
end
7075
return vim.api.nvim_buf_line_count(state.windows.output_buf)
7176
end
7277

78+
---Shift cached line positions by delta starting from from_line
79+
---Uses state.messages rather than M._part_cache so it can
80+
---stop early
81+
---@param from_line integer Line number to start shifting from
82+
---@param delta integer Number of lines to shift (positive or negative)
7383
function M._shift_lines(from_line, delta)
7484
if delta == 0 then
7585
return
@@ -105,6 +115,10 @@ function M._shift_lines(from_line, delta)
105115
-- vim.notify('Shifting lines from: ' .. from_line .. ' by delta: ' .. delta .. ' examined: ' .. examined .. ' shifted: ' .. shifted)
106116
end
107117

118+
---Apply extmarks to buffer at given line offset
119+
---@param buf integer Buffer handle
120+
---@param line_offset integer Line offset to apply extmarks at
121+
---@param extmarks table<integer, table[]>? Extmarks indexed by line
108122
function M._apply_extmarks(buf, line_offset, extmarks)
109123
if not extmarks or type(extmarks) ~= 'table' then
110124
return
@@ -122,12 +136,21 @@ function M._apply_extmarks(buf, line_offset, extmarks)
122136
end
123137
end
124138

139+
---The output buffer isn't modifiable so this is a wrapper that
140+
---temporarily makes the buffer modifiable while so we can add content
141+
---@param buf integer Buffer handle
142+
---@param start_line integer Start line (0-indexed)
143+
---@param end_line integer End line (0-indexed, -1 for end of buffer)
144+
---@param strict_indexing boolean Use strict indexing
145+
---@param lines string[] Lines to set
125146
function M._set_lines(buf, start_line, end_line, strict_indexing, lines)
126147
vim.api.nvim_set_option_value('modifiable', true, { buf = buf })
127148
vim.api.nvim_buf_set_lines(buf, start_line, end_line, strict_indexing, lines)
128149
vim.api.nvim_set_option_value('modifiable', false, { buf = buf })
129150
end
130151

152+
---Auto-scroll to bottom if user was already at bottom
153+
---Respects cursor position if user has scrolled up
131154
function M._scroll_to_bottom()
132155
local ok, line_count = pcall(vim.api.nvim_buf_line_count, state.windows.output_buf)
133156
if not ok then
@@ -153,6 +176,9 @@ function M._scroll_to_bottom()
153176
end
154177
end
155178

179+
---Write data to output_buf, including normal text and extmarks
180+
---@param formatted_data {lines: string[], extmarks: table?} Formatted data with lines and extmarks
181+
---@return {line_start: integer, line_end: integer}? Range where data was written
156182
function M._write_formatted_data(formatted_data)
157183
local buf = state.windows.output_buf
158184
local buf_lines = M._get_buffer_line_count()
@@ -171,13 +197,21 @@ function M._write_formatted_data(formatted_data)
171197
}
172198
end
173199

200+
---Write message header to buffer
201+
---@param message table Message object
202+
---@param msg_idx integer Message index
203+
---@return {line_start: integer, line_end: integer}? Range where header was written
174204
function M._write_message_header(message, msg_idx)
175205
local formatter = require('opencode.ui.session_formatter')
176206
local header_data = formatter.format_message_header_isolated(message, msg_idx)
177207
local line_range = M._write_formatted_data(header_data)
178208
return line_range
179209
end
180210

211+
---Insert new part at end of buffer
212+
---@param part_id string Part ID
213+
---@param formatted_data {lines: string[], extmarks: table?} Formatted data
214+
---@return boolean Success status
181215
function M._insert_part_to_buffer(part_id, formatted_data)
182216
local cached = M._part_cache[part_id]
183217
if not cached then
@@ -198,6 +232,11 @@ function M._insert_part_to_buffer(part_id, formatted_data)
198232
return true
199233
end
200234

235+
---Replace existing part in buffer
236+
---Adjusts line positions of subsequent parts if line count changes
237+
---@param part_id string Part ID
238+
---@param formatted_data {lines: string[], extmarks: table?} Formatted data
239+
---@return boolean Success status
201240
function M._replace_part_in_buffer(part_id, formatted_data)
202241
local cached = M._part_cache[part_id]
203242
if not cached or not cached.line_start or not cached.line_end then
@@ -227,6 +266,8 @@ function M._replace_part_in_buffer(part_id, formatted_data)
227266
return true
228267
end
229268

269+
---Remove part from buffer and adjust subsequent line positions
270+
---@param part_id string Part ID
230271
function M._remove_part_from_buffer(part_id)
231272
local cached = M._part_cache[part_id]
232273
if not cached or not cached.line_start or not cached.line_end then
@@ -247,6 +288,9 @@ function M._remove_part_from_buffer(part_id)
247288
M._part_cache[part_id] = nil
248289
end
249290

291+
---Event handler for message.updated events
292+
---Creates new message or updates existing message info
293+
---@param event EventMessageUpdated Event object
250294
function M.on_message_updated(event)
251295
if not event or not event.properties or not event.properties.info then
252296
return
@@ -283,6 +327,9 @@ function M.on_message_updated(event)
283327
M._scroll_to_bottom()
284328
end
285329

330+
---Event handler for message.part.updated events
331+
---Inserts new parts or replaces existing parts in buffer
332+
---@param event EventMessagePartUpdated Event object
286333
function M.on_part_updated(event)
287334
if not event or not event.properties or not event.properties.part then
288335
return
@@ -373,6 +420,8 @@ function M.on_part_updated(event)
373420
M._scroll_to_bottom()
374421
end
375422

423+
---Event handler for message.part.removed events
424+
---@param event EventMessagePartRemoved Event object
376425
function M.on_part_removed(event)
377426
-- XXX: I don't have any sessions that remove parts so this code is
378427
-- currently untested
@@ -407,6 +456,9 @@ function M.on_part_removed(event)
407456
M._remove_part_from_buffer(part_id)
408457
end
409458

459+
---Event handler for message.removed events
460+
---Removes message and all its parts from buffer
461+
---@param event EventMessageRemoved Event object
410462
function M.on_message_removed(event)
411463
-- XXX: I don't have any sessions that remove messages so this code is
412464
-- currently untested
@@ -443,17 +495,23 @@ function M.on_message_removed(event)
443495
table.remove(state.messages, message_idx)
444496
end
445497

446-
function M.on_session_compacted()
498+
---Event handler for session.compacted events
499+
---@param event EventSessionCompacted Event object
500+
function M.on_session_compacted(event)
447501
vim.notify('on_session_compacted')
448502
-- TODO: render a note that the session was compacted
449503
end
450504

505+
---Reset and re-render the whole session via output_renderer
506+
---This means something went wrong with streaming rendering
451507
function M.reset_and_render()
452508
M.reset()
453509
vim.notify('reset and render:\n' .. debug.traceback())
454510
require('opencode.ui.output_renderer').render(state.windows, true)
455511
end
456512

513+
---Event handler for session.error events
514+
---@param event EventSessionError Event object
457515
function M.on_session_error(event)
458516
if not event or not event.properties or not event.properties.error then
459517
return
@@ -469,6 +527,9 @@ function M.on_session_error(event)
469527
M._scroll_to_bottom()
470528
end
471529

530+
---Event handler for permission.updated events
531+
---Re-renders part that requires permission
532+
---@param event EventPermissionUpdated Event object
472533
function M.on_permission_updated(event)
473534
if not event or not event.properties then
474535
return
@@ -488,6 +549,9 @@ function M.on_permission_updated(event)
488549
end
489550
end
490551

552+
---Event handler for permission.replied events
553+
---Re-renders part after permission is resolved
554+
---@param event EventPermissionReplied Event object
491555
function M.on_permission_replied(event)
492556
if not event or not event.properties then
493557
return
@@ -505,6 +569,11 @@ function M.on_permission_replied(event)
505569
end
506570
end
507571

572+
---Find part ID by call ID
573+
---Searches messages in reverse order for efficiency
574+
---Useful for finding a part for a permission
575+
---@param call_id string Call ID to search for
576+
---@return string? part_id Part ID if found, nil otherwise
508577
function M._find_part_by_call_id(call_id)
509578
if not state.messages then
510579
return nil
@@ -525,6 +594,9 @@ function M._find_part_by_call_id(call_id)
525594
return nil
526595
end
527596

597+
---Re-render existing part with current state
598+
---Used for permission updates and other dynamic changes
599+
---@param part_id string Part ID to re-render
528600
function M._rerender_part(part_id)
529601
local cached = M._part_cache[part_id]
530602
if not cached then

0 commit comments

Comments
 (0)