Skip to content

Commit b83ba30

Browse files
committed
feat(pickers): add better highlight for supported pickers
Format the time as and highlight it as well as align it to the right
1 parent 03c1bef commit b83ba30

File tree

16 files changed

+153
-115
lines changed

16 files changed

+153
-115
lines changed

lua/opencode/config.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ M.defaults = {
176176
debug = {
177177
enabled = false,
178178
capture_streamed_events = false,
179+
show_ids = false,
179180
},
180181
prompt_guard = nil,
181182
}

lua/opencode/git_review.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ function M.with_restore_point(restore_point_id, fn)
365365
item.files and #item.files or 0,
366366
item.deleted_files and #item.deleted_files or 0,
367367
item.id:sub(1, 8),
368-
utils.time_ago(item.created_at) or 'unknown',
368+
utils.format_time(item.created_at) or 'unknown',
369369
item.from_snapshot_id and item.from_snapshot_id:sub(1, 8) or 'none'
370370
)
371371
end,

lua/opencode/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ function M.setup(opts)
88
local config = require('opencode.config')
99
config.setup(opts)
1010

11+
require('opencode.ui.highlight').setup()
1112
require('opencode.core').setup()
1213
require('opencode.api').setup()
1314
require('opencode.keymap').setup(config.keymap)

lua/opencode/types.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
---@class OpencodeDebugConfig
131131
---@field enabled boolean
132132
---@field capture_streamed_events boolean
133+
---@field show_ids boolean
133134

134135
--- @class OpencodeProviders
135136
--- @field [string] string[]

lua/opencode/ui/completion/commands.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ local command_source = {
7676
vim.api.nvim_win_set_cursor(0, { 1, #item.insert_text + 1 })
7777
return
7878
end
79-
item.data.fn()
79+
vim.defer_fn(function()
80+
item.data.fn()
81+
end, 10) -- slight delay to allow completion menu to close, this prevent a weird bug with mini.pick where it displays an empty window with `BlinkDonotRepeatHack` text inserted
8082
require('opencode.ui.input_window').set_content('')
8183
else
8284
vim.notify('Command not found: ' .. item.label, vim.log.levels.ERROR)

lua/opencode/ui/footer.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ function M.setup(windows)
8686
end
8787

8888
windows.footer_win = vim.api.nvim_open_win(windows.footer_buf, false, M._build_footer_win_config(windows.output_win))
89-
vim.api.nvim_set_option_value('winhl', 'Normal:OpenCodeHint', { win = windows.footer_win })
89+
vim.api.nvim_set_option_value('winhl', 'Normal:OpencodeHint', { win = windows.footer_win })
9090

9191
-- for stats changes
9292
state.subscribe('current_model', on_change)

lua/opencode/ui/highlight.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ function M.setup()
3232
vim.api.nvim_set_hl(0, 'OpencodeContextWarning', { link = 'DiagnosticWarn', default = true })
3333
vim.api.nvim_set_hl(0, 'OpencodeContextInfo', { link = 'DiagnosticInfo', default = true })
3434
vim.api.nvim_set_hl(0, 'OpencodeContextSwitchOn', { link = '@label', default = true })
35+
vim.api.nvim_set_hl(0, 'OpencodePickerTime', { link = 'Comment', default = true })
36+
vim.api.nvim_set_hl(0, 'OpencodeDebugText', { link = 'Comment', default = true })
3537
else
3638
vim.api.nvim_set_hl(0, 'OpencodeBorder', { fg = '#616161', default = true })
3739
vim.api.nvim_set_hl(0, 'OpencodeBackground', { link = 'Normal', default = true })
@@ -60,6 +62,8 @@ function M.setup()
6062
vim.api.nvim_set_hl(0, 'OpencodeContextError', { link = 'DiagnosticError', default = true })
6163
vim.api.nvim_set_hl(0, 'OpencodeContextWarning', { link = 'DiagnosticWarn', default = true })
6264
vim.api.nvim_set_hl(0, 'OpencodeContextSwitchOn', { link = '@label', default = true })
65+
vim.api.nvim_set_hl(0, 'OpencodePickerTime', { link = 'Comment', default = true })
66+
vim.api.nvim_set_hl(0, 'OpencodeDebugText', { link = 'Comment', default = true })
6367
end
6468
end
6569

lua/opencode/ui/input_window.lua

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,15 @@ function M.refresh_placeholder(windows, input_lines)
149149

150150
vim.api.nvim_buf_set_extmark(windows.input_buf, ns_id, 0, 0, {
151151
virt_text = {
152-
{ 'Type your prompt here... ', 'OpenCodeHint' },
152+
{ 'Type your prompt here... ', 'OpencodeHint' },
153153
{ slash_key or '/', 'OpencodeInputLegend' },
154-
{ ' commands ', 'OpenCodeHint' },
154+
{ ' commands ', 'OpencodeHint' },
155155
{ mention_key or '@', 'OpencodeInputLegend' },
156-
{ ' mentions ', 'OpenCodeHint' },
156+
{ ' mentions ', 'OpencodeHint' },
157157
{ mention_file_key or '~', 'OpencodeInputLegend' },
158-
{ ' files ', 'OpenCodeHint' },
158+
{ ' files ', 'OpencodeHint' },
159159
{ context_key or '#', 'OpencodeInputLegend' },
160-
{ ' context' .. padding, 'OpenCodeHint' },
160+
{ ' context' .. padding, 'OpencodeHint' },
161161
},
162162

163163
virt_text_pos = 'overlay',

lua/opencode/ui/loading_animation.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ M.render = vim.schedule_wrap(function(windows)
4545

4646
M._animation.extmark_id = vim.api.nvim_buf_set_extmark(windows.footer_buf, M._animation.ns_id, 0, 0, {
4747
id = M._animation.extmark_id or nil,
48-
virt_text = { { loading_text, 'OpenCodeHint' } },
48+
virt_text = { { loading_text, 'OpencodeHint' } },
4949
virt_text_pos = 'overlay',
5050
hl_mode = 'replace',
5151
})

lua/opencode/ui/picker_utils.lua

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
local config = require('opencode.config')
2+
local util = require('opencode.util')
3+
local M = {}
4+
5+
---@class PickerItem
6+
---@field content string Main content text
7+
---@field time_text? string Optional time text
8+
---@field debug_text? string Optional debug text
9+
---@field to_string fun(self: PickerItem): string
10+
---@field to_formatted_text fun(self: PickerItem): string, table
11+
12+
---@param text? string
13+
---@param width integer
14+
---@param opts? {align?: "left" | "right" | "center", truncate?: boolean}
15+
function M.align(text, width, opts)
16+
text = text or ''
17+
opts = opts or {}
18+
opts.align = opts.align or 'left'
19+
local tw = vim.api.nvim_strwidth(text)
20+
if tw > width then
21+
return opts.truncate and (vim.fn.strcharpart(text, 0, width - 1) .. '') or text
22+
end
23+
local left = math.floor((width - tw) / 2)
24+
local right = width - tw - left
25+
if opts.align == 'left' then
26+
left, right = 0, width - tw
27+
elseif opts.align == 'right' then
28+
left, right = width - tw, 0
29+
end
30+
return (' '):rep(left) .. text .. (' '):rep(right)
31+
end
32+
33+
---Creates a generic picker item that can format itself for different pickers
34+
---@param text string Array of text parts to join
35+
---@param time? number Optional time text to highlight
36+
---@param debug_text? string Optional debug text to append
37+
---@return PickerItem
38+
function M.create_picker_item(text, time, debug_text)
39+
local debug_offset = config.debug.show_ids and #debug_text or 0
40+
local item = {
41+
content = M.align(text, 70 - debug_offset + 1, { truncate = true }),
42+
time_text = time and M.align(util.format_time(time), 20, { align = 'right' }),
43+
debug_text = config.debug.show_ids and debug_text or nil,
44+
}
45+
46+
function item:to_string()
47+
local segments = { self.content }
48+
49+
if self.time_text then
50+
table.insert(segments, self.time_text)
51+
end
52+
53+
if self.debug_text then
54+
table.insert(segments, self.debug_text)
55+
end
56+
57+
return table.concat(segments, ' ')
58+
end
59+
60+
function item:to_formatted_text()
61+
local segments = { { self.content } }
62+
63+
if self.time_text then
64+
table.insert(segments, { ' ' .. self.time_text, 'OpencodePickerTime' })
65+
end
66+
67+
if self.debug_text then
68+
table.insert(segments, { ' ' .. self.debug_text, 'OpencodeDebugText' })
69+
end
70+
71+
return segments
72+
end
73+
74+
return item
75+
end
76+
77+
return M

0 commit comments

Comments
 (0)