Skip to content

Commit 25c5e10

Browse files
committed
fix(session_formatter): fix patch/code spacing
Also trim newlines off of _format_callout
1 parent 681b8e6 commit 25c5e10

File tree

5 files changed

+20
-18
lines changed

5 files changed

+20
-18
lines changed

lua/opencode/ui/session_formatter.lua

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,6 @@ end
261261

262262
function M._format_patch(part)
263263
local restore_points = snapshot.get_restore_points_by_parent(part.hash)
264-
M.output:add_empty_line()
265264
M._format_action(icons.get('snapshot') .. ' Created Snapshot', vim.trim(part.hash:sub(1, 8)))
266265
local snapshot_header_line = M.output:get_line_count()
267266

@@ -392,7 +391,9 @@ function M._format_callout(callout, text, title)
392391
text = ok and substituted or text
393392
end
394393

395-
local lines = vim.split(text, '\n')
394+
-- Trim off any trailing newlines so there isn't an extra line in the
395+
-- extmarks section
396+
local lines = vim.split(text:gsub('\n$', ''), '\n')
396397
if #lines == 1 and title == '' then
397398
M.output:add_line('> [!' .. callout .. '] ' .. lines[1])
398399
else
@@ -564,14 +565,14 @@ end
564565
---@param part MessagePart
565566
function M._format_tool(part)
566567
local tool = part.tool
567-
if not tool then
568+
if not tool or not part.state then
568569
return
569570
end
570571

571572
local start_line = M.output:get_line_count() + 1
572-
local input = (part.state and part.state.input) or {}
573-
local metadata = (part.state and part.state.metadata) or {}
574-
local output = (part.state and part.state.output) or ''
573+
local input = part.state.input or {}
574+
local metadata = part.state.metadata or {}
575+
local output = part.state.output or ''
575576

576577
if state.current_permission and state.current_permission.messageID == part.messageID then
577578
metadata = state.current_permission.metadata or metadata
@@ -597,12 +598,15 @@ function M._format_tool(part)
597598
M._format_action(icons.get('tool') .. ' tool', tool)
598599
end
599600

600-
if part.state then
601-
if part.state.status == 'error' then
602-
M._format_callout('ERROR', part.state.error)
603-
elseif part.state.input and part.state.input.error then
604-
M._format_callout('ERROR', part.state.input.error)
605-
end
601+
if part.state.status == 'error' then
602+
M.output:add_line('')
603+
M._format_callout('ERROR', part.state.error)
604+
---@diagnostic disable-next-line: undefined-field
605+
elseif part.state.input and part.state.input.error then
606+
M.output:add_line('')
607+
---I'm not sure about the type with state.input.error
608+
---@diagnostic disable-next-line: undefined-field
609+
M._format_callout('ERROR', part.state.input.error)
606610
end
607611

608612
if
@@ -658,7 +662,6 @@ function M._format_code(lines, language)
658662
M.output:add_line('```' .. (language or ''))
659663
M.output:add_lines(lines)
660664
M.output:add_line('```')
661-
M.output:add_empty_line()
662665
end
663666

664667
function M._format_diff(code, file_type)
@@ -695,7 +698,6 @@ function M._format_diff(code, file_type)
695698
end
696699
end
697700
M.output:add_line('```')
698-
M.output:add_empty_line()
699701
end
700702

701703
function M._add_vertical_border(start_line, end_line, hl_group, win_col)

tests/data/diff.expected.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"timestamp":1760315563,"extmarks":[[1,2,0,{"virt_text":[["▌󰭻 ","OpencodeMessageRoleUser"],[" "],["USER","OpencodeMessageRoleUser"],["","OpencodeHint"],[" (2025-10-11 23:42:56)","OpencodeHint"],[" [msg_9d7287269001C5gRusYfX7A1w1]","OpencodeHint"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-3,"priority":10,"virt_text_repeat_linebreak":false}],[2,3,0,{"virt_text":[["▌","OpencodeMessageRoleUser"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-3,"priority":4096,"virt_text_repeat_linebreak":true}],[3,4,0,{"virt_text":[["▌","OpencodeMessageRoleUser"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-3,"priority":4096,"virt_text_repeat_linebreak":true}],[4,5,0,{"virt_text":[["▌","OpencodeMessageRoleUser"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-3,"priority":4096,"virt_text_repeat_linebreak":true}],[5,6,0,{"virt_text":[["▌","OpencodeMessageRoleUser"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-3,"priority":4096,"virt_text_repeat_linebreak":true}],[6,9,0,{"virt_text":[[" ","OpencodeMessageRoleAssistant"],[" "],["BUILD","OpencodeMessageRoleAssistant"],[" claude-sonnet-4.5","OpencodeHint"],[" (2025-10-11 23:42:56)","OpencodeHint"],[" [msg_9d7287287001HVwpPaH7WkRVdN]","OpencodeHint"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-3,"priority":10,"virt_text_repeat_linebreak":false}],[21,11,0,{"virt_text":[["▌","OpencodeToolBorder"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-1,"priority":4096,"virt_text_repeat_linebreak":true}],[22,12,0,{"virt_text":[["▌","OpencodeToolBorder"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-1,"priority":4096,"virt_text_repeat_linebreak":true}],[23,13,0,{"virt_text":[["▌","OpencodeToolBorder"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-1,"priority":4096,"virt_text_repeat_linebreak":true}],[24,14,0,{"end_col":0,"end_row":15,"hl_eol":true,"right_gravity":true,"end_right_gravity":false,"virt_text_hide":false,"ns_id":3,"virt_text_repeat_linebreak":false,"priority":5000,"virt_text":[["-","OpencodeDiffDelete"]],"virt_text_pos":"overlay","hl_group":"OpencodeDiffDelete"}],[25,14,0,{"virt_text":[["▌","OpencodeToolBorder"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-1,"priority":4096,"virt_text_repeat_linebreak":true}],[26,15,0,{"end_col":0,"end_row":16,"hl_eol":true,"right_gravity":true,"end_right_gravity":false,"virt_text_hide":false,"ns_id":3,"virt_text_repeat_linebreak":false,"priority":5000,"virt_text":[["+","OpencodeDiffAdd"]],"virt_text_pos":"overlay","hl_group":"OpencodeDiffAdd"}],[27,15,0,{"virt_text":[["▌","OpencodeToolBorder"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-1,"priority":4096,"virt_text_repeat_linebreak":true}],[28,16,0,{"virt_text":[["▌","OpencodeToolBorder"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-1,"priority":4096,"virt_text_repeat_linebreak":true}],[29,17,0,{"virt_text":[["▌","OpencodeToolBorder"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-1,"priority":4096,"virt_text_repeat_linebreak":true}],[30,18,0,{"virt_text":[["▌","OpencodeToolBorder"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-1,"priority":4096,"virt_text_repeat_linebreak":true}],[31,23,0,{"virt_text":[[" ","OpencodeMessageRoleAssistant"],[" "],["BUILD","OpencodeMessageRoleAssistant"],[" claude-sonnet-4.5","OpencodeHint"],[" (2025-10-11 23:43:03)","OpencodeHint"],[" [msg_9d7288f2f001hW6NqqhtBc72UU]","OpencodeHint"]],"ns_id":3,"virt_text_hide":false,"right_gravity":true,"virt_text_pos":"win_col","virt_text_win_col":-3,"priority":10,"virt_text_repeat_linebreak":false}]],"lines":["","---","","","can you add \"great\" before \"string\" in @diff-test.txt?","","[diff-test.txt](diff-test.txt)","","---","","","** edit** `diff-test.txt`","","```txt"," this is a string"," this is a great string","","```","","","**󰻛 Created Snapshot** `1f593f7e`","","---","",""]}
1+
{"extmarks":[[1,2,0,{"virt_text_win_col":-3,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":10,"virt_text_repeat_linebreak":false,"virt_text":[["▌󰭻 ","OpencodeMessageRoleUser"],[" "],["USER","OpencodeMessageRoleUser"],["","OpencodeHint"],[" (2025-10-11 23:42:56)","OpencodeHint"],[" [msg_9d7287269001C5gRusYfX7A1w1]","OpencodeHint"]],"virt_text_pos":"win_col"}],[2,3,0,{"virt_text_win_col":-3,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text":[["▌","OpencodeMessageRoleUser"]],"virt_text_pos":"win_col"}],[3,4,0,{"virt_text_win_col":-3,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text":[["▌","OpencodeMessageRoleUser"]],"virt_text_pos":"win_col"}],[4,5,0,{"virt_text_win_col":-3,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text":[["▌","OpencodeMessageRoleUser"]],"virt_text_pos":"win_col"}],[5,6,0,{"virt_text_win_col":-3,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text":[["▌","OpencodeMessageRoleUser"]],"virt_text_pos":"win_col"}],[6,9,0,{"virt_text_win_col":-3,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":10,"virt_text_repeat_linebreak":false,"virt_text":[[" ","OpencodeMessageRoleAssistant"],[" "],["BUILD","OpencodeMessageRoleAssistant"],[" claude-sonnet-4.5","OpencodeHint"],[" (2025-10-11 23:42:56)","OpencodeHint"],[" [msg_9d7287287001HVwpPaH7WkRVdN]","OpencodeHint"]],"virt_text_pos":"win_col"}],[21,11,0,{"virt_text_win_col":-1,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col"}],[22,12,0,{"virt_text_win_col":-1,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col"}],[23,13,0,{"virt_text_win_col":-1,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col"}],[24,14,0,{"priority":5000,"ns_id":3,"end_col":0,"end_row":15,"hl_eol":true,"right_gravity":true,"end_right_gravity":false,"virt_text_hide":false,"hl_group":"OpencodeDiffDelete","virt_text_repeat_linebreak":false,"virt_text":[["-","OpencodeDiffDelete"]],"virt_text_pos":"overlay"}],[25,14,0,{"virt_text_win_col":-1,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col"}],[26,15,0,{"priority":5000,"ns_id":3,"end_col":0,"end_row":16,"hl_eol":true,"right_gravity":true,"end_right_gravity":false,"virt_text_hide":false,"hl_group":"OpencodeDiffAdd","virt_text_repeat_linebreak":false,"virt_text":[["+","OpencodeDiffAdd"]],"virt_text_pos":"overlay"}],[27,15,0,{"virt_text_win_col":-1,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col"}],[28,16,0,{"virt_text_win_col":-1,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col"}],[29,17,0,{"virt_text_win_col":-1,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col"}],[30,22,0,{"virt_text_win_col":-3,"right_gravity":true,"ns_id":3,"virt_text_hide":false,"priority":10,"virt_text_repeat_linebreak":false,"virt_text":[[" ","OpencodeMessageRoleAssistant"],[" "],["BUILD","OpencodeMessageRoleAssistant"],[" claude-sonnet-4.5","OpencodeHint"],[" (2025-10-11 23:43:03)","OpencodeHint"],[" [msg_9d7288f2f001hW6NqqhtBc72UU]","OpencodeHint"]],"virt_text_pos":"win_col"}]],"timestamp":1760401089,"lines":["","---","","","can you add \"great\" before \"string\" in @diff-test.txt?","","[diff-test.txt](diff-test.txt)","","---","","","** edit** `diff-test.txt`","","```txt"," this is a string"," this is a great string","","```","","**󰻛 Created Snapshot** `1f593f7e`","","---","",""]}

tests/data/permission-denied.expected.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"timestamp":1760310663,"lines":["","---","","","add a file, test.txt, with \":)\" in it","","---","","","** write** `test.txt`","","```txt",":)","```","","","**󰻛 Created Snapshot** `c78fb2dd`","","---","",""],"extmarks":[[1,2,0,{"virt_text_win_col":-3,"right_gravity":true,"virt_text_pos":"win_col","ns_id":3,"priority":10,"virt_text_hide":false,"virt_text":[["▌󰭻 ","OpencodeMessageRoleUser"],[" "],["USER","OpencodeMessageRoleUser"],["","OpencodeHint"],[" (2025-10-11 22:43:49)","OpencodeHint"],[" [msg_9d6f253910015UFmkGkiWtUsRW]","OpencodeHint"]],"virt_text_repeat_linebreak":false}],[2,3,0,{"virt_text_win_col":-3,"right_gravity":true,"virt_text_pos":"win_col","ns_id":3,"priority":4096,"virt_text_hide":false,"virt_text":[["▌","OpencodeMessageRoleUser"]],"virt_text_repeat_linebreak":true}],[3,4,0,{"virt_text_win_col":-3,"right_gravity":true,"virt_text_pos":"win_col","ns_id":3,"priority":4096,"virt_text_hide":false,"virt_text":[["▌","OpencodeMessageRoleUser"]],"virt_text_repeat_linebreak":true}],[4,7,0,{"virt_text_win_col":-3,"right_gravity":true,"virt_text_pos":"win_col","ns_id":3,"priority":10,"virt_text_hide":false,"virt_text":[[" ","OpencodeMessageRoleAssistant"],[" "],["BUILD","OpencodeMessageRoleAssistant"],[" claude-sonnet-4.5","OpencodeHint"],[" (2025-10-11 22:43:49)","OpencodeHint"],[" [msg_9d6f253df001TjqxW12FAjGf5s]","OpencodeHint"]],"virt_text_repeat_linebreak":false}],[27,9,0,{"virt_text_win_col":-1,"right_gravity":true,"virt_text_pos":"win_col","ns_id":3,"priority":4096,"virt_text_hide":false,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_repeat_linebreak":true}],[28,10,0,{"virt_text_win_col":-1,"right_gravity":true,"virt_text_pos":"win_col","ns_id":3,"priority":4096,"virt_text_hide":false,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_repeat_linebreak":true}],[29,11,0,{"virt_text_win_col":-1,"right_gravity":true,"virt_text_pos":"win_col","ns_id":3,"priority":4096,"virt_text_hide":false,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_repeat_linebreak":true}],[30,12,0,{"virt_text_win_col":-1,"right_gravity":true,"virt_text_pos":"win_col","ns_id":3,"priority":4096,"virt_text_hide":false,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_repeat_linebreak":true}],[31,13,0,{"virt_text_win_col":-1,"right_gravity":true,"virt_text_pos":"win_col","ns_id":3,"priority":4096,"virt_text_hide":false,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_repeat_linebreak":true}],[32,14,0,{"virt_text_win_col":-1,"right_gravity":true,"virt_text_pos":"win_col","ns_id":3,"priority":4096,"virt_text_hide":false,"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_repeat_linebreak":true}],[33,19,0,{"virt_text_win_col":-3,"right_gravity":true,"virt_text_pos":"win_col","ns_id":3,"priority":10,"virt_text_hide":false,"virt_text":[[" ","OpencodeMessageRoleAssistant"],[" "],["BUILD","OpencodeMessageRoleAssistant"],[" claude-sonnet-4.5","OpencodeHint"],[" (2025-10-11 22:44:00)","OpencodeHint"],[" [msg_9d6f27f4800103Tp3N6i6JW53p]","OpencodeHint"]],"virt_text_repeat_linebreak":false}]]}
1+
{"extmarks":[[1,2,0,{"virt_text":[["▌󰭻 ","OpencodeMessageRoleUser"],[" "],["USER","OpencodeMessageRoleUser"],["","OpencodeHint"],[" (2025-10-11 22:43:49)","OpencodeHint"],[" [msg_9d6f253910015UFmkGkiWtUsRW]","OpencodeHint"]],"virt_text_pos":"win_col","virt_text_win_col":-3,"right_gravity":true,"priority":10,"ns_id":3,"virt_text_hide":false,"virt_text_repeat_linebreak":false}],[2,3,0,{"virt_text":[["▌","OpencodeMessageRoleUser"]],"virt_text_pos":"win_col","virt_text_win_col":-3,"right_gravity":true,"priority":4096,"ns_id":3,"virt_text_hide":false,"virt_text_repeat_linebreak":true}],[3,4,0,{"virt_text":[["▌","OpencodeMessageRoleUser"]],"virt_text_pos":"win_col","virt_text_win_col":-3,"right_gravity":true,"priority":4096,"ns_id":3,"virt_text_hide":false,"virt_text_repeat_linebreak":true}],[4,7,0,{"virt_text":[[" ","OpencodeMessageRoleAssistant"],[" "],["BUILD","OpencodeMessageRoleAssistant"],[" claude-sonnet-4.5","OpencodeHint"],[" (2025-10-11 22:43:49)","OpencodeHint"],[" [msg_9d6f253df001TjqxW12FAjGf5s]","OpencodeHint"]],"virt_text_pos":"win_col","virt_text_win_col":-3,"right_gravity":true,"priority":10,"ns_id":3,"virt_text_hide":false,"virt_text_repeat_linebreak":false}],[26,9,0,{"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col","virt_text_win_col":-1,"right_gravity":true,"priority":4096,"ns_id":3,"virt_text_hide":false,"virt_text_repeat_linebreak":true}],[27,10,0,{"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col","virt_text_win_col":-1,"right_gravity":true,"priority":4096,"ns_id":3,"virt_text_hide":false,"virt_text_repeat_linebreak":true}],[28,11,0,{"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col","virt_text_win_col":-1,"right_gravity":true,"priority":4096,"ns_id":3,"virt_text_hide":false,"virt_text_repeat_linebreak":true}],[29,12,0,{"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col","virt_text_win_col":-1,"right_gravity":true,"priority":4096,"ns_id":3,"virt_text_hide":false,"virt_text_repeat_linebreak":true}],[30,13,0,{"virt_text":[["▌","OpencodeToolBorder"]],"virt_text_pos":"win_col","virt_text_win_col":-1,"right_gravity":true,"priority":4096,"ns_id":3,"virt_text_hide":false,"virt_text_repeat_linebreak":true}],[31,18,0,{"virt_text":[[" ","OpencodeMessageRoleAssistant"],[" "],["BUILD","OpencodeMessageRoleAssistant"],[" claude-sonnet-4.5","OpencodeHint"],[" (2025-10-11 22:44:00)","OpencodeHint"],[" [msg_9d6f27f4800103Tp3N6i6JW53p]","OpencodeHint"]],"virt_text_pos":"win_col","virt_text_win_col":-3,"right_gravity":true,"priority":10,"ns_id":3,"virt_text_hide":false,"virt_text_repeat_linebreak":false}]],"timestamp":1760401131,"lines":["","---","","","add a file, test.txt, with \":)\" in it","","---","","","** write** `test.txt`","","```txt",":)","```","","**󰻛 Created Snapshot** `c78fb2dd`","","---","",""]}

0 commit comments

Comments
 (0)