Skip to content

Commit 90fc43d

Browse files
committed
feat(footer): move the current model to the right
1 parent 677aa4c commit 90fc43d

File tree

1 file changed

+54
-36
lines changed

1 file changed

+54
-36
lines changed

lua/opencode/ui/footer.lua

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ local loading_animation = require('opencode.ui.loading_animation')
77

88
local M = {}
99

10+
local function utf8_len(str)
11+
return vim.fn.strchars(str)
12+
end
13+
1014
local function get_mode_highlight()
1115
local mode = (state.current_mode or ''):lower()
1216
local highlights = {
@@ -18,8 +22,12 @@ end
1822

1923
local function build_left_segments()
2024
local segments = {}
21-
if not state.is_running() and state.current_model then
22-
table.insert(segments, state.current_model)
25+
local restore_points = snapshot.get_restore_points()
26+
if restore_points and #restore_points > 0 then
27+
table.insert(segments, {
28+
string.format('%s %d', icons.get('restore_point'), #restore_points),
29+
'OpencodeHint',
30+
})
2331
end
2432
return segments
2533
end
@@ -29,53 +37,64 @@ local function build_right_segments()
2937

3038
if state.is_running() then
3139
local cancel_keymap = config.get_key_for_function('input_window', 'stop') or '<C-c>'
32-
table.insert(segments, string.format(' %s to cancel', cancel_keymap))
40+
table.insert(segments, { string.format('%s ', cancel_keymap), 'OpencodeInputLegend' })
41+
table.insert(segments, { 'to cancel', 'OpencodeHint' })
42+
table.insert(segments, { ' ' })
3343
end
3444

35-
local restore_points = snapshot.get_restore_points()
36-
if restore_points and #restore_points > 0 then
37-
table.insert(segments, string.format('%s %d', icons.get('restore_point'), #restore_points))
45+
if not state.is_running() and state.current_model then
46+
table.insert(segments, { state.current_model, 'OpencodeHint' })
47+
table.insert(segments, { ' ' })
3848
end
3949

4050
if state.current_mode then
41-
table.insert(segments, string.format(' %s ', state.current_mode:upper()))
51+
table.insert(segments, {
52+
string.format(' %s ', state.current_mode:upper()),
53+
get_mode_highlight(),
54+
})
4255
end
4356

4457
return segments
4558
end
4659

47-
local function build_footer_text(left_text, right_text, win_width)
48-
local left_len = #left_text > 0 and #left_text + 1 or 0
49-
local right_len = #right_text > 0 and #right_text + 1 or 0
50-
local padding = math.max(0, win_width - left_len - right_len)
60+
local function add_segments(segments, parts, highlights, col)
61+
for _, segment in ipairs(segments) do
62+
local text = segment[1]
63+
table.insert(parts, text)
5164

52-
local parts = {}
53-
if #left_text > 0 then
54-
table.insert(parts, left_text)
55-
end
56-
table.insert(parts, string.rep(' ', padding))
57-
if #right_text > 0 then
58-
table.insert(parts, right_text)
59-
end
65+
if segment[2] then
66+
table.insert(highlights, { group = segment[2], start_col = col, end_col = col + #text })
67+
end
6068

61-
return table.concat(parts, ' ')
69+
col = col + #text
70+
end
71+
return col
6272
end
6373

64-
local function create_mode_highlight(left_len, right_text, padding)
65-
if not state.current_mode then
66-
return {}
74+
local function build_footer_from_segments(left_segments, right_segments, win_width)
75+
local footer_parts = {}
76+
local highlights = {}
77+
local current_col = 0
78+
79+
current_col = add_segments(left_segments, footer_parts, highlights, current_col)
80+
81+
local left_text = table.concat(footer_parts, '')
82+
local left_len = utf8_len(left_text)
83+
84+
local right_len = 0
85+
for _, segment in ipairs(right_segments) do
86+
right_len = right_len + utf8_len(segment[1])
6787
end
6888

69-
local mode_text = string.format(' %s ', state.current_mode:upper())
70-
local mode_start = left_len + padding + (#right_text > 0 and 1 or 0)
89+
local padding_len = math.max(0, win_width - left_len - right_len)
90+
local padding = string.rep(' ', padding_len)
91+
table.insert(footer_parts, padding)
92+
current_col = current_col + padding_len
7193

72-
return {
73-
{
74-
group = get_mode_highlight(),
75-
start_col = mode_start + #right_text - #mode_text,
76-
end_col = mode_start + #right_text,
77-
},
78-
}
94+
current_col = add_segments(right_segments, footer_parts, highlights, current_col)
95+
96+
local footer_text = table.concat(footer_parts, '')
97+
return footer_text, highlights
7998
end
8099

81100
function M.render()
@@ -84,12 +103,11 @@ function M.render()
84103
end
85104
---@cast state.windows OpencodeWindowState
86105

87-
local left_text = table.concat(build_left_segments(), ' ')
88-
local right_text = table.concat(build_right_segments(), ' ')
106+
local left_segments = build_left_segments()
107+
local right_segments = build_right_segments()
89108
local win_width = vim.api.nvim_win_get_width(state.windows.output_win --[[@as integer]])
90109

91-
local footer_text = build_footer_text(left_text, right_text, win_width)
92-
local highlights = create_mode_highlight(#left_text, right_text, win_width - #left_text - #right_text - 1)
110+
local footer_text, highlights = build_footer_from_segments(left_segments, right_segments, win_width)
93111

94112
M.set_content({ footer_text }, highlights)
95113
end

0 commit comments

Comments
 (0)