Compare commits

..

11 Commits

Author SHA1 Message Date
Junegunn Choi f70cc6738d Redraw when change-header changes line count
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
The inline header slot's row budget depends on header content length,
but resizeIfNeeded() tolerates a shorter-than-wanted inline window, so
the stale slot stays. Drive a redraw on length change to re-run the
layout.
2026-04-19 22:40:33 +09:00
Junegunn Choi dacb87abca Let inline sections take precedence over --header-first
--header-first previously was rejected with --header-border=inline or
--header-lines-border=inline. Now, inline placement wins: an inline
section stays inside the list frame, and --header-first only affects
non-inline sections (mainly the main --header).
2026-04-19 22:39:47 +09:00
Junegunn Choi abfa60b7d0 Set inline separator caps per side 2026-04-19 20:47:38 +09:00
Junegunn Choi 12199823ab Update man page: clarify inline list-border shape requirements 2026-04-19 20:47:31 +09:00
Junegunn Choi 2c459ffdff Update CHANGELOG: clarify inline list-border shape requirements 2026-04-19 20:47:25 +09:00
Junegunn Choi f80ba22ab9 Fix misleading comment on printHeader nil-window guard
The guard fires when hasHeaderWindow() returned false at resize time,
not when addInline had no budget (placeInlineStack always leaves a
non-nil 0-height placeholder).
2026-04-19 20:47:17 +09:00
Junegunn Choi 4cd97ba35b Fix inline header/footer border color when falling back to line
InitTheme was called before the runtime coerced BorderInline to
BorderLine, so HeaderBorder / FooterBorder inherited from ListBorder
even when the effective shape was 'line'. Mirror the coercion so
color inheritance matches the rendered shape.
2026-04-19 20:47:09 +09:00
Junegunn Choi 332382e5e7 Add --{header,header-lines,footer}-border=inline
New BorderShape that embeds the section inside the --list-border
frame, joined to the list content by a horizontal separator with
T-junctions where the list shape has side borders. Requires a list
border with both top and bottom segments; falls back to 'line'
otherwise. Stacks when multiple sections are inline.

Sections inherit --color list-border by default and are colored as a
uniform block via their own --color *-border and *-bg.

Incompatible with --header-first. --header-border=inline requires
--header-lines-border to be inline or unset.
2026-04-19 20:47:00 +09:00
Junegunn Choi 987c37cb2d Add a test case for click-header with --header and --header-lines combined
The two sections swap order between layouts, and header-lines are
reversed under layout=default, so expected LINE values differ per
layout.
2026-04-19 20:46:49 +09:00
Junegunn Choi 9deb7c5489 Add test cases for click-header and click-footer
Injects SGR 1006 mouse events via tmux send-keys -l to exercise
FZF_CLICK_HEADER_* / FZF_CLICK_FOOTER_* across all three layouts,
with and without a header border.
2026-04-19 20:46:41 +09:00
Junegunn Choi 5352b88c5a Clean up non-ascii characters 2026-04-19 20:28:28 +09:00
4 changed files with 28 additions and 65 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
go-version: "1.23"
- name: Setup Ruby
uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1
uses: ruby/setup-ruby@3ff19f5e2baf30647122352b96108b1fbe250c64 # v1
with:
ruby-version: 3.4.6
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
go-version: "1.23"
- name: Setup Ruby
uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1
uses: ruby/setup-ruby@3ff19f5e2baf30647122352b96108b1fbe250c64 # v1
with:
ruby-version: 3.0.0
+1 -6
View File
@@ -15,12 +15,7 @@ CHANGELOG
```
- `--header-label` and `--footer-label` render on their respective separator row.
- The separator inherits `--color list-border` when the section's own border color is not explicitly set.
- `inline` takes precedence over `--header-first`: the inline section stays inside the list frame. `--header-border=inline` requires `--header-lines-border` to be `inline` or unset.
- [vim] Move and resize popup window when detecting `VimResized` event (#4778) (@Vulcalien)
- Bug fixes
- Fixed gutter display in `--style=minimal`
- Fixed arrow keys / Home / End without modifiers being ignored under the kitty keyboard protocol (#4776) (@TymekDev)
- bash: Persist history deletion when `histappend` is on (#4764)
- `--header-first` is not compatible with `--header-border=inline` or `--header-lines-border=inline`; `--header-border=inline` requires `--header-lines-border` to be `inline` or unset.
0.71.0
------
+25 -57
View File
@@ -896,7 +896,6 @@ function! s:execute_term(dict, command, temps) abort
endif
endfunction
function! fzf.on_exit(id, code, ...)
silent! autocmd! fzf_popup_resize
if s:getpos() == self.ppos " {'window': 'enew'}
for [opt, val] in items(self.winopts)
execute 'let' opt '=' val
@@ -1024,17 +1023,15 @@ function! s:callback(dict, lines) abort
endfunction
if has('nvim')
function! s:create_popup() abort
let opts = s:popup_bounds()
let opts = extend({'relative': 'editor', 'style': 'minimal'}, opts)
function s:create_popup(opts) abort
let buf = nvim_create_buf(v:false, v:true)
let s:popup_id = nvim_open_win(buf, v:true, opts)
call setwinvar(s:popup_id, '&colorcolumn', '')
let opts = extend({'relative': 'editor', 'style': 'minimal'}, a:opts)
let win = nvim_open_win(buf, v:true, opts)
call setwinvar(win, '&colorcolumn', '')
" Colors
try
call setwinvar(s:popup_id, '&winhighlight', 'Pmenu:,Normal:Normal')
call setwinvar(win, '&winhighlight', 'Pmenu:,Normal:Normal')
let rules = get(g:, 'fzf_colors', {})
if has_key(rules, 'bg')
let color = call('s:get_color', rules.bg)
@@ -1042,61 +1039,40 @@ if has('nvim')
let ns = nvim_create_namespace('fzf_popup')
let hl = nvim_set_hl(ns, 'Normal',
\ &termguicolors ? { 'bg': color } : { 'ctermbg': str2nr(color) })
call nvim_win_set_hl_ns(s:popup_id, ns)
call nvim_win_set_hl_ns(win, ns)
endif
endif
catch
endtry
return buf
endfunction
function! s:resize_popup() abort
if !exists('s:popup_id') || !nvim_win_is_valid(s:popup_id)
return
endif
let opts = s:popup_bounds()
let opts = extend({'relative': 'editor'}, opts)
call nvim_win_set_config(s:popup_id, opts)
endfunction
else
function! s:create_popup() abort
function! s:popup_create(buf)
let s:popup_id = popup_create(a:buf, #{zindex: 1000})
call s:resize_popup()
endfunction
function! s:create_popup(opts) abort
let s:popup_create = {buf -> popup_create(buf, #{
\ line: a:opts.row,
\ col: a:opts.col,
\ minwidth: a:opts.width,
\ maxwidth: a:opts.width,
\ minheight: a:opts.height,
\ maxheight: a:opts.height,
\ zindex: 1000,
\ })}
autocmd TerminalOpen * ++once call s:popup_create(str2nr(expand('<abuf>')))
endfunction
function! s:resize_popup() abort
if !exists('s:popup_id') || empty(popup_getpos(s:popup_id))
return
endif
let opts = s:popup_bounds()
call popup_move(s:popup_id, {
\ 'line': opts.row,
\ 'col': opts.col,
\ 'minwidth': opts.width,
\ 'maxwidth': opts.width,
\ 'minheight': opts.height,
\ 'maxheight': opts.height,
\ })
endfunction
endif
function! s:popup_bounds() abort
let opts = s:popup_opts
let xoffset = get(opts, 'xoffset', 0.5)
let yoffset = get(opts, 'yoffset', 0.5)
let relative = get(opts, 'relative', 0)
function! s:popup(opts) abort
let xoffset = get(a:opts, 'xoffset', 0.5)
let yoffset = get(a:opts, 'yoffset', 0.5)
let relative = get(a:opts, 'relative', 0)
" Use current window size for positioning relatively positioned popups
let columns = relative ? winwidth(0) : &columns
let lines = relative ? winheight(0) : (&lines - has('nvim'))
" Size and position
let width = min([max([8, opts.width > 1 ? opts.width : float2nr(columns * opts.width)]), columns])
let height = min([max([4, opts.height > 1 ? opts.height : float2nr(lines * opts.height)]), lines])
let width = min([max([8, a:opts.width > 1 ? a:opts.width : float2nr(columns * a:opts.width)]), columns])
let height = min([max([4, a:opts.height > 1 ? a:opts.height : float2nr(lines * a:opts.height)]), lines])
let row = float2nr(yoffset * (lines - height)) + (relative ? win_screenpos(0)[0] - 1 : 0)
let col = float2nr(xoffset * (columns - width)) + (relative ? win_screenpos(0)[1] - 1 : 0)
@@ -1106,17 +1082,9 @@ function! s:popup_bounds() abort
let row += !has('nvim')
let col += !has('nvim')
return { 'row': row, 'col': col, 'width': width, 'height': height }
endfunction
function! s:popup(opts) abort
let s:popup_opts = a:opts
call s:create_popup()
augroup fzf_popup_resize
autocmd!
autocmd VimResized * call s:resize_popup()
augroup END
call s:create_popup({
\ 'row': row, 'col': col, 'width': width, 'height': height
\ })
endfunction
let s:default_action = {