update oc.nvim

This commit is contained in:
2026-03-11 16:01:26 +00:00
parent e12d425df5
commit eae286c5ab

View File

@@ -20,6 +20,36 @@ in {
render-markdown-nvim render-markdown-nvim
]; ];
extraConfigLua = '' extraConfigLua = ''
local api = vim.api
local opencode_output_filetype = 'opencode_output'
local opencode_window_filetypes = {
opencode = true,
opencode_output = true,
}
local palette = {
base = '#eff1f5',
mantle = '#e6e9ef',
surface0 = '#ccd0da',
surface1 = '#bcc0cc',
text = '#4c4f69',
subtext0 = '#6c6f85',
overlay0 = '#9ca0b0',
blue = '#1e66f5',
lavender = '#7287fd',
sapphire = '#209fb5',
teal = '#179299',
green = '#40a02b',
mauve = '#8839ef',
peach = '#fe640b',
}
local function set_highlights(highlights)
for group, spec in pairs(highlights) do
api.nvim_set_hl(0, group, spec)
end
end
local opencode_markdown_conceal_query = vim.treesitter.query.parse('markdown_inline', [[ local opencode_markdown_conceal_query = vim.treesitter.query.parse('markdown_inline', [[
[ [
(emphasis_delimiter) (emphasis_delimiter)
@@ -66,8 +96,28 @@ in {
] @conceal) ] @conceal)
]]) ]])
local function collect_conceal_marks(ctx)
local marks = {}
for _, node in opencode_markdown_conceal_query:iter_captures(ctx.root, ctx.buf) do
local start_row, start_col, end_row, end_col = node:range()
marks[#marks + 1] = {
conceal = true,
start_row = start_row,
start_col = start_col,
opts = {
end_row = end_row,
end_col = end_col,
conceal = "",
},
}
end
return marks
end
local function set_opencode_output_conceal() local function set_opencode_output_conceal()
if vim.bo.filetype ~= 'opencode_output' then if vim.bo.filetype ~= opencode_output_filetype then
return return
end end
@@ -75,101 +125,172 @@ in {
vim.wo.concealcursor = 'nvic' vim.wo.concealcursor = 'nvic'
end end
vim.treesitter.language.register('markdown', 'opencode_output') local function hide_opencode_statusline()
vim.treesitter.language.register('markdown_inline', 'opencode_output') if not opencode_window_filetypes[vim.bo.filetype] then
return
end
vim.api.nvim_create_autocmd({ 'FileType', 'BufWinEnter', 'WinEnter' }, { vim.wo.statusline = ' '
end
vim.treesitter.language.register('markdown', opencode_output_filetype)
vim.treesitter.language.register('markdown_inline', opencode_output_filetype)
api.nvim_create_autocmd({ 'FileType', 'BufWinEnter', 'WinEnter' }, {
callback = set_opencode_output_conceal, callback = set_opencode_output_conceal,
}) })
api.nvim_create_autocmd({ 'FileType', 'BufWinEnter', 'WinEnter', 'BufEnter' }, {
pattern = '*',
callback = hide_opencode_statusline,
})
require('render-markdown').setup({ set_highlights({
RenderMarkdownCode = { bg = palette.mantle },
RenderMarkdownCodeBorder = { fg = palette.surface0, bg = palette.mantle },
RenderMarkdownCodeInline = { bg = palette.mantle },
RenderMarkdownH1 = { fg = palette.blue, bold = true },
RenderMarkdownH2 = { fg = palette.mauve, bold = true },
RenderMarkdownH3 = { fg = palette.teal, bold = true },
RenderMarkdownH4 = { fg = palette.peach, bold = true },
OpencodeInputLegend = { fg = palette.subtext0, bold = true },
OpencodeAgentBuild = { bg = palette.overlay0, fg = palette.base, bold = true },
})
local render_markdown_config = {
anti_conceal = { enabled = false }, anti_conceal = { enabled = false },
heading = {
icons = { ' ', ' ', ' ', '· ', '· ', '· ' },
backgrounds = {},
position = 'inline',
width = 'block',
left_pad = 0,
right_pad = 2,
border = false,
sign = false,
},
code = {
sign = false,
width = 'full',
left_pad = 2,
right_pad = 0,
border = 'thin',
language_icon = false,
language_name = true,
},
bullet = {
icons = { '·', '', '·', '' },
},
custom_handlers = { custom_handlers = {
markdown_inline = { markdown_inline = {
extends = true, extends = true,
parse = function(ctx) parse = collect_conceal_marks,
local marks = {}
for _, node in opencode_markdown_conceal_query:iter_captures(ctx.root, ctx.buf) do
local start_row, start_col, end_row, end_col = node:range()
marks[#marks + 1] = {
conceal = true,
start_row = start_row,
start_col = start_col,
opts = {
end_row = end_row,
end_col = end_col,
conceal = "",
},
}
end
return marks
end,
}, },
}, },
file_types = { 'opencode_output' }, file_types = { opencode_output_filetype },
win_options = { win_options = {
conceallevel = { rendered = 3 }, conceallevel = { rendered = 3 },
concealcursor = { rendered = "nvic" }, concealcursor = { rendered = 'nvic' },
},
}
require('render-markdown').setup(render_markdown_config)
local opencode_icon_overrides = {
header_user = '',
header_assistant = '',
run = '',
task = '',
read = '',
edit = '',
write = '',
plan = '',
search = '',
web = '',
list = '',
tool = '',
snapshot = '',
restore_point = '',
file = '·',
folder = '·',
attached_file = '·',
agent = '·',
reference = '·',
reasoning = '',
question = '?',
border = '',
}
require('opencode').setup({
server = {
url = 'http://127.0.0.1',
port = 18822,
auto_kill = false,
},
input = {
text = {
wrap = true,
},
},
debug = {
show_ids = false,
},
ui = {
icons = {
preset = 'nerdfonts',
overrides = opencode_icon_overrides,
},
}, },
}) })
require('opencode').setup({
server = {
url = 'http://127.0.0.1',
port = 18822,
auto_kill = false,
},
input = {
text = {
wrap = true,
},
},
ui = {
icons = {
preset = 'nerdfonts',
},
},
})
do do
local config = require('opencode.config') local config = require('opencode.config')
local formatter = require('opencode.ui.formatter') local formatter = require('opencode.ui.formatter')
local format_utils = require('opencode.ui.formatter.utils') local format_utils = require('opencode.ui.formatter.utils')
local icons = require('opencode.ui.icons') local icons = require('opencode.ui.icons')
local util = require('opencode.util') local util = require('opencode.util')
formatter._format_reasoning = function(output, part) local function format_reasoning_title(part)
local text = vim.trim(part.text or "") local title = 'Reasoning'
local start_line = output:get_line_count() + 1 local time = part.time
local title = 'Reasoning' if time and type(time) == 'table' and time.start then
local time = part.time local duration_text = util.format_duration_seconds(time.start, time['end'])
if time and type(time) == 'table' and time.start then if duration_text then
local duration_text = util.format_duration_seconds(time.start, time['end']) title = string.format('%s %s', title, duration_text)
if duration_text then
title = string.format('%s %s', title, duration_text)
end
end
format_utils.format_action(output, icons.get('reasoning'), title, "")
if config.ui.output.tools.show_reasoning_output and text ~= "" then
output:add_empty_line()
output:add_lines(vim.split(text, '\n'), ' ')
output:add_empty_line()
end
local end_line = output:get_line_count()
if end_line - start_line > 1 then
formatter.add_vertical_border(output, start_line, end_line, 'OpencodeToolBorder', -1, 'OpencodeReasoningText')
else
output:add_extmark(start_line - 1, {
line_hl_group = 'OpencodeReasoningText',
})
end end
end end
return title
end end
local function highlight_reasoning_block(output, start_line)
local end_line = output:get_line_count()
if end_line - start_line > 1 then
formatter.add_vertical_border(output, start_line, end_line, 'OpencodeToolBorder', -1, 'OpencodeReasoningText')
return
end
output:add_extmark(start_line - 1, {
line_hl_group = 'OpencodeReasoningText',
})
end
formatter._format_reasoning = function(output, part)
local text = vim.trim(part.text or "")
local start_line = output:get_line_count() + 1
format_utils.format_action(output, icons.get('reasoning'), format_reasoning_title(part), "")
if config.ui.output.tools.show_reasoning_output and text ~= "" then
output:add_empty_line()
output:add_lines(vim.split(text, '\n'), ' ')
output:add_empty_line()
end
highlight_reasoning_block(output, start_line)
end
end
''; '';
}; };
} }