Skip to content

Commit 9a72a68

Browse files
committed
feat(session_formatter): unify part formatting
use the same formatting function for both session and streaming formatting
1 parent 88c2056 commit 9a72a68

File tree

1 file changed

+25
-66
lines changed

1 file changed

+25
-66
lines changed

lua/opencode/ui/session_formatter.lua

Lines changed: 25 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,7 @@ function M._format_messages(session, messages)
6969
M._format_message_header(msg.info, i)
7070

7171
for j, part in ipairs(msg.parts or {}) do
72-
M._current = { msg_idx = i, part_idx = j, role = msg.info.role, type = part.type, snapshot = part.snapshot }
73-
M.output:add_metadata(M._current)
74-
75-
if part.type == 'text' and part.text then
76-
if msg.info.role == 'user' and part.synthetic ~= true then
77-
state.last_user_message = msg
78-
M._format_user_message(vim.trim(part.text), msg)
79-
elseif msg.info.role == 'assistant' then
80-
M._format_assistant_message(vim.trim(part.text))
81-
end
82-
elseif part.type == 'tool' then
83-
M._format_tool(part)
84-
elseif part.type == 'patch' and part.hash then
85-
M._format_patch(part)
86-
end
87-
M.output:add_empty_line()
72+
M.format_part_isolated(part, { msg_idx = i, part_idx = j, role = msg.info.role, message = msg }, M.output)
8873
end
8974

9075
if msg.info.error and msg.info.error ~= '' then
@@ -404,28 +389,10 @@ function M._format_callout(callout, text, title)
404389
end
405390

406391
---@param text string
407-
---@param message Message
408-
function M._format_user_message(text, message)
409-
local context = nil
410-
if vim.startswith(text, '<additional-data>') then
411-
context = context_module.extract_from_message_legacy(text)
412-
else
413-
context = context_module.extract_from_opencode_message(message)
414-
end
415-
392+
function M._format_user_prompt(text)
416393
local start_line = M.output:get_line_count()
417394

418-
M.output:add_lines(vim.split(context.prompt, '\n'))
419-
420-
if context.selected_text then
421-
M.output:add_empty_line()
422-
M.output:add_lines(vim.split(context.selected_text, '\n'))
423-
end
424-
425-
if context.current_file then
426-
M.output:add_empty_line()
427-
M._format_context_file(context.current_file)
428-
end
395+
M.output:add_lines(vim.split(text, '\n'))
429396

430397
local end_line = M.output:get_line_count()
431398

@@ -439,7 +406,6 @@ function M._format_selection_context(part)
439406
return
440407
end
441408
local start_line = M.output:get_line_count()
442-
M.output:add_empty_line()
443409
M.output:add_lines(vim.split(json.content, '\n'))
444410
M.output:add_empty_line()
445411

@@ -737,8 +703,8 @@ function M._add_vertical_border(start_line, end_line, hl_group, win_col)
737703
end
738704
end
739705

740-
function M.format_part_isolated(part, message_info)
741-
local temp_output = Output.new()
706+
function M.format_part_isolated(part, message_info, output)
707+
local temp_output = output or Output.new()
742708
local old_output = M.output
743709
M.output = temp_output
744710

@@ -753,37 +719,30 @@ function M.format_part_isolated(part, message_info)
753719

754720
local content_added = false
755721

756-
-- FIXME: _format_user_message calls to get context which iterates over
757-
-- parts. that won't work when streaming. we already handle file context
758-
-- but also need to handle selected text
759-
-- At some point, we should unify the rendering to use the streaming
760-
-- even when re-reading the whole session and should then not special
761-
-- case the context by looking ahead at the parts
762-
763-
if part.type == 'text' and part.text then
764-
if message_info.role == 'user' and part.synthetic ~= true then
765-
M._format_user_message(vim.trim(part.text), message_info.message)
722+
if message_info.role == 'user' then
723+
if part.type == 'text' and part.text then
724+
if part.synthetic == true then
725+
M._format_selection_context(part)
726+
else
727+
M._format_user_prompt(vim.trim(part.text))
728+
content_added = true
729+
end
730+
elseif part.type == 'file' then
731+
local file_line = M._format_context_file(part.filename)
732+
M._add_vertical_border(file_line - 1, file_line, 'OpencodeMessageRoleUser', -3)
766733
content_added = true
767-
elseif part.synthetic == true and message_info.role == 'user' then
768-
M._format_selection_context(part)
769-
elseif message_info.role == 'assistant' then
734+
end
735+
elseif message_info.role == 'assistant' then
736+
if part.type == 'text' and part.text then
770737
M._format_assistant_message(vim.trim(part.text))
771738
content_added = true
739+
elseif part.type == 'tool' then
740+
M._format_tool(part)
741+
content_added = true
742+
elseif part.type == 'patch' and part.hash then
743+
M._format_patch(part)
744+
content_added = true
772745
end
773-
elseif part.type == 'tool' then
774-
M._format_tool(part)
775-
content_added = true
776-
elseif part.type == 'patch' and part.hash then
777-
M._format_patch(part)
778-
content_added = true
779-
elseif part.type == 'file' then
780-
local file_line = M._format_context_file(part.filename)
781-
if message_info.role == 'user' then
782-
-- when streaming, the file comes in as a separate event, connect it to user
783-
-- message
784-
M._add_vertical_border(file_line - 1, file_line, 'OpencodeMessageRoleUser', -3)
785-
end
786-
content_added = true
787746
end
788747

789748
if content_added then

0 commit comments

Comments
 (0)