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
128 lines (101 loc) · 3.41 KB
/
topbar.lua
File metadata and controls
128 lines (101 loc) · 3.41 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
local config = require('opencode.config')
local util = require('opencode.util')
local M = {}
local state = require('opencode.state')
local config_file = require('opencode.config_file')
local LABELS = {
NEW_SESSION_TITLE = 'New session',
}
local function format_model_info()
local parts = {}
if config.ui.display_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 or ''):upper() .. ' '
end
local function get_mode_highlight()
local mode = (state.current_mode or ''):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, win_width)
local left_content = ''
local right_content = ''
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 = ' '
vim.wo[win].winbar =
create_winbar_text(get_session_desc(), format_model_info(), format_mode_info(), 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