From 7ee0a3dd10b1a7e73e35e03f6b8cc86f20753b1d Mon Sep 17 00:00:00 2001 From: David Herman Date: Fri, 5 Jun 2026 09:47:23 +0200 Subject: [PATCH 1/2] fix(picker): support relative and opt-out picker_width values picker_width now supports three modes: - Absolute (>1): fixed column count, e.g. picker_width = 120 - Relative (01 = absolute columns; false = use picker backend defaults. ---@field display_model boolean ---@field display_context_size boolean ---@field display_cost boolean diff --git a/lua/opencode/ui/base_picker.lua b/lua/opencode/ui/base_picker.lua index bda35b20..7140f33f 100644 --- a/lua/opencode/ui/base_picker.lua +++ b/lua/opencode/ui/base_picker.lua @@ -844,6 +844,17 @@ function M.pick(opts) opts.width = config.ui.picker_width end + -- picker_width = false means "use picker backend defaults, no override" + if opts.width == false then + opts.width = nil + end + + -- Resolve relative width (0 < w <= 1) to absolute columns so that + -- format functions and all picker backends receive a consistent value. + if opts.width and opts.width > 0 and opts.width <= 1 then + opts.width = math.floor(vim.o.columns * opts.width) + end + local original_format_fn = opts.format_fn opts.format_fn = function(item) return original_format_fn(item, opts.width) diff --git a/lua/opencode/ui/history_picker.lua b/lua/opencode/ui/history_picker.lua index 429d6bef..d82811c7 100644 --- a/lua/opencode/ui/history_picker.lua +++ b/lua/opencode/ui/history_picker.lua @@ -104,7 +104,7 @@ function M.pick(callback) end end, title = 'Select History Entry', - width = config.ui.picker_width or 100, + width = config.ui.picker_width, layout_opts = config.ui.picker, }) end diff --git a/lua/opencode/ui/reference_picker.lua b/lua/opencode/ui/reference_picker.lua index 9f15e5b8..46d71b63 100644 --- a/lua/opencode/ui/reference_picker.lua +++ b/lua/opencode/ui/reference_picker.lua @@ -214,7 +214,7 @@ function M.pick() end end, title = 'Code References (' .. #refs .. ')', - width = config.ui.picker_width or 100, + width = config.ui.picker_width, preview = 'file', layout_opts = config.ui.picker, }) diff --git a/lua/opencode/ui/session_picker.lua b/lua/opencode/ui/session_picker.lua index ffc41a55..0df2eb6b 100644 --- a/lua/opencode/ui/session_picker.lua +++ b/lua/opencode/ui/session_picker.lua @@ -332,7 +332,7 @@ function M.pick(sessions, callback) actions = actions, callback = callback, title = 'Select A Session', - width = config.ui.picker_width or 100, + width = config.ui.picker_width, layout_opts = config.ui.picker, preview = 'custom', ---@param session table diff --git a/lua/opencode/ui/timeline_picker.lua b/lua/opencode/ui/timeline_picker.lua index 7caba0d6..e55fe39b 100644 --- a/lua/opencode/ui/timeline_picker.lua +++ b/lua/opencode/ui/timeline_picker.lua @@ -41,7 +41,7 @@ function M.pick(messages, callback) actions = actions, callback = callback, title = 'Timeline', - width = config.ui.picker_width or 100, + width = config.ui.picker_width, layout_opts = config.ui.picker, }) end From 8ebdfe27dbece3484d0476b7e6068f9963608f45 Mon Sep 17 00:00:00 2001 From: David Herman Date: Fri, 5 Jun 2026 13:23:16 +0200 Subject: [PATCH 2/2] fix(picker): pass picker_width in model picker and derive format width for opt-out mode The model picker was the only picker not passing width to base_picker.pick(), causing format_fn to fall back to the full neovim window width when picker_width was nil or false. This produced lines wider than the fzf-lua content area, clipping provider names on the right. Pass picker_width consistently and, when it resolves to nil (opt-out), derive format_width from fzf-lua's effective winopts.width so padded columns align to the actual content area. --- lua/opencode/model_picker.lua | 1 + lua/opencode/ui/base_picker.lua | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lua/opencode/model_picker.lua b/lua/opencode/model_picker.lua index 3af17d45..aa89045a 100644 --- a/lua/opencode/model_picker.lua +++ b/lua/opencode/model_picker.lua @@ -87,6 +87,7 @@ function M.select(cb) base_picker.pick({ title = 'Select model', items = models, + width = config.ui.picker_width, layout_opts = config.ui.picker, format_fn = function(item, width) local icon = item.icon or '' diff --git a/lua/opencode/ui/base_picker.lua b/lua/opencode/ui/base_picker.lua index 7140f33f..b0f43cb7 100644 --- a/lua/opencode/ui/base_picker.lua +++ b/lua/opencode/ui/base_picker.lua @@ -855,9 +855,33 @@ function M.pick(opts) opts.width = math.floor(vim.o.columns * opts.width) end + -- When width is nil (picker_width = false or unset), derive a content width + -- from the picker backend's default window size so format functions can + -- produce correctly-sized output that fills the backend's content area. + local format_width = opts.width + if not format_width then + if picker_type == 'fzf' then + -- Read fzf-lua's effective winopts.width (respects user customization). + local fzf_win_width = 0.8 + local ok, fzf_config = pcall(require, 'fzf-lua.config') + if ok and fzf_config and fzf_config.globals and fzf_config.globals.winopts then + fzf_win_width = fzf_config.globals.winopts.width or fzf_win_width + end + -- Resolve fraction to absolute columns + if fzf_win_width > 0 and fzf_win_width <= 1 then + fzf_win_width = math.floor(vim.o.columns * fzf_win_width) + end + -- Subtract the same chrome offset used when we set winopts ourselves (+8), + -- which covers borders, padding, and fzf's pointer indicator. + format_width = fzf_win_width - 8 + else + format_width = math.floor(vim.o.columns * 0.8) + end + end + local original_format_fn = opts.format_fn opts.format_fn = function(item) - return original_format_fn(item, opts.width) + return original_format_fn(item, format_width) end local title_str = type(opts.title) == 'function' and opts.title() or opts.title --[[@as string]]