forked from sudo-tee/opencode.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtopbar.lua
More file actions
144 lines (115 loc) · 3.92 KB
/
topbar.lua
File metadata and controls
144 lines (115 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
local util = require('opencode.util')
local M = {}
local state = require('opencode.state')
local config_file = require('opencode.config_file')
local prompt_guard_indicator = require('opencode.ui.prompt_guard_indicator')
local LABELS = {
NEW_SESSION_TITLE = 'New session',
}
local function format_model_info()
if not state.current_model or state.current_model == '' then
local info = config_file.get_opencode_config()
state.current_model = info and info.model
end
local config = require('opencode.config')
local parts = {}
if config.ui.display_model and state.current_model then
if state.current_model ~= '' then
table.insert(parts, state.current_model)
end
end
return table.concat(parts, ' ')
end
local function format_mode_info()
return ' ' .. state.current_mode:upper() .. ' '
end
local function get_mode_highlight()
local mode = state.current_mode:lower()
if mode == 'build' then
return '%#OpencodeAgentBuild#'
elseif mode == 'plan' then
return '%#OpencodeAgentPlan#'
else
return '%#OpencodeAgentCustom#'
end
end
local function create_winbar_text(description, model_info, mode_info, show_guard_indicator, win_width)
local left_content = ''
local right_content = ''
if show_guard_indicator then
left_content = left_content .. prompt_guard_indicator.get_formatted() .. ' '
end
right_content = model_info .. ' ' .. get_mode_highlight() .. mode_info .. '%*'
local desc_width = win_width - util.strdisplaywidth(left_content) - util.strdisplaywidth(right_content)
local desc_formatted
if #description >= desc_width then
local ellipsis = '... '
desc_formatted = description:sub(1, desc_width - #ellipsis) .. ellipsis
else
desc_formatted = description .. string.rep(' ', math.floor(desc_width - #description))
end
return left_content .. desc_formatted .. right_content
end
local function update_winbar_highlights(win_id)
local current = vim.api.nvim_get_option_value('winhighlight', { win = win_id })
local parts = vim.split(current, ',')
-- Remove any existing winbar highlights
parts = vim.tbl_filter(function(part)
return not part:match('^WinBar:') and not part:match('^WinBarNC:')
end, parts)
if not vim.tbl_contains(parts, 'Normal:OpencodeNormal') then
table.insert(parts, 'Normal:OpencodeNormal')
end
table.insert(parts, 'WinBar:OpencodeSessionDescription')
table.insert(parts, 'WinBarNC:OpencodeSessionDescription')
vim.api.nvim_set_option_value('winhighlight', table.concat(parts, ','), { win = win_id })
end
local function get_session_desc()
local session_desc = LABELS.NEW_SESSION_TITLE
if state.active_session then
local session = require('opencode.session').get_by_id(state.active_session.id)
if session and session.description ~= '' then
session_desc = session.description
end
end
return session_desc
end
function M.render()
vim.schedule(function()
if not state.windows then
return
end
local win = state.windows.output_win
if not win then
return
end
-- topbar needs to at least have a value to make sure footer is positioned correctly
vim.wo[win].winbar = ' '
local show_guard_indicator = prompt_guard_indicator.is_denied()
vim.wo[win].winbar = create_winbar_text(
get_session_desc(),
format_model_info(),
format_mode_info(),
show_guard_indicator,
vim.api.nvim_win_get_width(win)
)
update_winbar_highlights(win)
end)
end
local function on_change(_, _, _)
M.render()
end
function M.setup()
state.subscribe('current_mode', on_change)
state.subscribe('current_model', on_change)
state.subscribe('active_session', on_change)
state.subscribe('is_opencode_focused', on_change)
M.render()
end
function M.close()
state.unsubscribe('current_mode', on_change)
state.unsubscribe('current_model', on_change)
state.unsubscribe('active_session', on_change)
state.unsubscribe('is_opencode_focused', on_change)
end
return M