@@ -7,6 +7,10 @@ local loading_animation = require('opencode.ui.loading_animation')
77
88local M = {}
99
10+ local function utf8_len (str )
11+ return vim .fn .strchars (str )
12+ end
13+
1014local function get_mode_highlight ()
1115 local mode = (state .current_mode or ' ' ):lower ()
1216 local highlights = {
1822
1923local 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
2533end
@@ -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
4558end
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
6272end
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
7998end
8099
81100function 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 )
95113end
0 commit comments