Skip to content

Commit b4ad8c1

Browse files
authored
feat(ui): add support for 'current' position in UI configuration (#146)
* feat(ui): add support for 'current' position in UI configuration - allow 'current' as a valid position option for UI placement - update position handling in dimensions and window closing logic - ensure compatibility with existing configurations * fix(ui): disable winfixbuf in 'current' mode and auto-close on buffer switch When 'ui.position' is set to 'current', disabling 'winfixbuf' prevents E1513 errors when external pickers (like Snacks) try to switch buffers. Added a BufEnter autocmd to automatically close the Opencode UI when a non-Opencode buffer enters an Opencode window in this mode. * docs(readme): update UI position options in configuration - clarify that UI position can now be 'current' alongside 'right' and 'left' - improve documentation for better user understanding of options
1 parent bd3073b commit b4ad8c1

File tree

7 files changed

+60
-9
lines changed

7 files changed

+60
-9
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ require('opencode').setup({
175175
}
176176
},
177177
ui = {
178-
position = 'right', -- 'right' (default) or 'left'. Position of the UI split
178+
position = 'right', -- 'right' (default), 'left' or 'current'. Position of the UI split. 'current' uses the current window for the output.
179179
input_position = 'bottom', -- 'bottom' (default) or 'top'. Position of the input window
180180
window_width = 0.40, -- Width as percentage of editor width
181181
zoom_width = 0.8, -- Zoom width as percentage of editor width

lua/opencode/health.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ local function check_configuration()
113113

114114
---@cast config OpencodeConfig
115115

116-
local valid_positions = { 'left', 'right', 'top', 'bottom' }
116+
local valid_positions = { 'left', 'right', 'top', 'bottom', 'current' }
117117
if not vim.tbl_contains(valid_positions, config.ui.position) then
118118
health.warn(
119119
string.format('Invalid UI position: %s', config.ui.position),

lua/opencode/types.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@
114114
---@field frames string[]
115115

116116
---@class OpencodeUIConfig
117-
---@field position 'right'|'left' # Position of the UI (default: 'right')
117+
---@field position 'right'|'left'|'current' # Position of the UI (default: 'right')
118118
---@field input_position 'bottom'|'top' # Position of the input window (default: 'bottom')
119119
---@field window_width number
120120
---@field zoom_width number

lua/opencode/ui/autocmds.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,32 @@ function M.setup_autocmds(windows)
4242
require('opencode.state').is_opencode_focused = require('opencode.ui.ui').is_opencode_focused()
4343
end,
4444
})
45+
46+
if require('opencode.config').ui.position == 'current' then
47+
vim.api.nvim_create_autocmd('BufEnter', {
48+
group = group,
49+
callback = function()
50+
local current_win = vim.api.nvim_get_current_win()
51+
local current_buf = vim.api.nvim_get_current_buf()
52+
53+
if current_win ~= windows.output_win and current_win ~= windows.input_win then
54+
return
55+
end
56+
57+
local is_opencode_buf = (
58+
current_buf == windows.output_buf
59+
or current_buf == windows.input_buf
60+
or (windows.footer_buf and current_buf == windows.footer_buf)
61+
)
62+
63+
if not is_opencode_buf then
64+
vim.schedule(function()
65+
require('opencode.ui.ui').close_windows(windows)
66+
end)
67+
end
68+
end,
69+
})
70+
end
4571
end
4672

4773
function M.setup_resize_handler(windows)

lua/opencode/ui/input_window.lua

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ function M.setup(windows)
107107
vim.api.nvim_set_option_value('buftype', 'nofile', { buf = windows.input_buf })
108108
vim.api.nvim_set_option_value('swapfile', false, { buf = windows.input_buf })
109109
-- vim.b[windows.input_buf].completion = false
110-
vim.api.nvim_set_option_value('winfixbuf', true, { win = windows.input_win })
110+
if config.ui.position ~= 'current' then
111+
vim.api.nvim_set_option_value('winfixbuf', true, { win = windows.input_win })
112+
end
111113
vim.api.nvim_set_option_value('winfixheight', true, { win = windows.input_win })
112114
vim.api.nvim_set_option_value('winfixwidth', true, { win = windows.input_win })
113115

@@ -124,11 +126,17 @@ function M.update_dimensions(windows)
124126
return
125127
end
126128

127-
local total_width = vim.api.nvim_get_option_value('columns', {})
128129
local total_height = vim.api.nvim_get_option_value('lines', {})
129-
local width = math.floor(total_width * config.ui.window_width)
130130
local height = math.floor(total_height * config.ui.input_height)
131131

132+
if config.ui.position == 'current' then
133+
pcall(vim.api.nvim_win_set_height, windows.input_win, height)
134+
return
135+
end
136+
137+
local total_width = vim.api.nvim_get_option_value('columns', {})
138+
local width = math.floor(total_width * config.ui.window_width)
139+
132140
vim.api.nvim_win_set_config(windows.input_win, { width = width, height = height })
133141
end
134142

lua/opencode/ui/output_window.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ function M.setup(windows)
6666
vim.api.nvim_set_option_value('modifiable', false, { buf = windows.output_buf })
6767
vim.api.nvim_set_option_value('buftype', 'nofile', { buf = windows.output_buf })
6868
vim.api.nvim_set_option_value('swapfile', false, { buf = windows.output_buf })
69-
vim.api.nvim_set_option_value('winfixbuf', true, { win = windows.output_win })
69+
if config.ui.position ~= 'current' then
70+
vim.api.nvim_set_option_value('winfixbuf', true, { win = windows.output_win })
71+
end
7072
vim.api.nvim_set_option_value('winfixheight', true, { win = windows.output_win })
7173
vim.api.nvim_set_option_value('winfixwidth', true, { win = windows.output_win })
7274
vim.api.nvim_set_option_value('signcolumn', 'yes', { scope = 'local', win = windows.output_win })
@@ -78,6 +80,9 @@ function M.setup(windows)
7880
end
7981

8082
function M.update_dimensions(windows)
83+
if config.ui.position == 'current' then
84+
return
85+
end
8186
local total_width = vim.api.nvim_get_option_value('columns', {})
8287
local width = math.floor(total_width * config.ui.window_width)
8388

lua/opencode/ui/ui.lua

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,14 @@ function M.close_windows(windows)
2626

2727
---@cast windows { input_win: integer, output_win: integer, input_buf: integer, output_buf: integer }
2828
pcall(vim.api.nvim_win_close, windows.input_win, true)
29-
pcall(vim.api.nvim_win_close, windows.output_win, true)
29+
if config.ui.position == 'current' then
30+
pcall(vim.api.nvim_set_option_value, 'winfixbuf', false, { win = windows.output_win })
31+
if state.current_code_buf and vim.api.nvim_buf_is_valid(state.current_code_buf) then
32+
pcall(vim.api.nvim_win_set_buf, windows.output_win, state.current_code_buf)
33+
end
34+
else
35+
pcall(vim.api.nvim_win_close, windows.output_win, true)
36+
end
3037
pcall(vim.api.nvim_buf_delete, windows.input_buf, { force = true })
3138
pcall(vim.api.nvim_buf_delete, windows.output_buf, { force = true })
3239
footer.close()
@@ -67,7 +74,12 @@ function M.create_split_windows(input_buf, output_buf)
6774
end
6875
local ui_conf = config.ui
6976

70-
local main_win = open_split(ui_conf.position, 'vertical')
77+
local main_win
78+
if ui_conf.position == 'current' then
79+
main_win = vim.api.nvim_get_current_win()
80+
else
81+
main_win = open_split(ui_conf.position, 'vertical')
82+
end
7183
vim.api.nvim_set_current_win(main_win)
7284

7385
local input_win = open_split(ui_conf.input_position, 'horizontal')

0 commit comments

Comments
 (0)