Skip to content

Commit

Permalink
refactor(win): native fzf flex layout
Browse files Browse the repository at this point in the history
Use alternative preview layout instead of using a "transform",
simpler, and we don't need to take into account the hidden state of
the preview as well as decrease the minimum fzf version for native
fzf flex layout to 0.31 (instead of 0.46).

Has known issue upstream where if the layout changes upon resize
the hidden state of the preview is lost:
junegunn/fzf#4100

Closes #1527
  • Loading branch information
ibhagwan committed Nov 19, 2024
1 parent 2a7eb32 commit 8c59894
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 165 deletions.
7 changes: 4 additions & 3 deletions OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,13 @@ Preview border for native fzf previewers (i.e. `bat`, `git_status`), set to `nob

Type: `string`, Default: `flex`

Preview layout, possible values are `horizontal|vertical|flex`, when set to `flex` neovim width is
tested against `winopts.preview.flip_columns`, when <= `vertical` is used, otherwise `horizontal`.
Preview layout, possible values are `horizontal|vertical|flex`, when set to `flex` fzf window
width is tested against `winopts.preview.flip_columns`, when <= `vertical` is used, otherwise
`horizontal`.

#### globals.winopts.preview.flip_columns

Type: `number`, Default: `120`
Type: `number`, Default: `100`

Auto-detect the preview layout based on available width, see above note in `winopts.preview.layout`.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ require'fzf-lua'.setup {
vertical = 'down:45%', -- up|down:size
horizontal = 'right:60%', -- right|left:size
layout = 'flex', -- horizontal|vertical|flex
flip_columns = 120, -- #cols to switch to horizontal on flex
flip_columns = 100, -- #cols to switch to horizontal on flex
-- Only used with the builtin previewer:
title = true, -- preview border title (file/buf)?
title_pos = "center", -- left|center|right, title alignment
Expand Down
8 changes: 4 additions & 4 deletions doc/fzf-lua-opts.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*fzf-lua-opts.txt* For Neovim >= 0.8.0 Last change: 2024 September 26
*fzf-lua-opts.txt* For Neovim >= 0.8.0 Last change: 2024 September 27

==============================================================================
Table of Contents *fzf-lua-opts-table-of-contents*
Expand Down Expand Up @@ -405,14 +405,14 @@ globals.winopts.preview.layout *fzf-lua-opts-globals.winopts.preview.layout*
Type: `string`, Default: `flex`

Preview layout, possible values are `horizontal|vertical|flex`, when set to
`flex` neovim width is tested against `winopts.preview.flip_columns`, when <=
`vertical` is used, otherwise `horizontal`.
`flex` fzf window width is tested against `winopts.preview.flip_columns`, when
<= `vertical` is used, otherwise `horizontal`.



globals.winopts.preview.flip_columns*fzf-lua-opts-globals.winopts.preview.flip_columns*

Type: `number`, Default: `120`
Type: `number`, Default: `100`

Auto-detect the preview layout based on available width, see above note in
`winopts.preview.layout`.
Expand Down
60 changes: 30 additions & 30 deletions lua/fzf-lua/core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -376,28 +376,6 @@ M.fzf = function(contents, opts)
if opts.__FZF_VERSION and opts.__FZF_VERSION >= 0.40 and previewer.zero then
utils.map_set(opts, "keymap.fzf.zero", previewer:zero())
end
if opts.__FZF_VERSION
and opts.__FZF_VERSION >= 0.46
and opts.winopts.preview.layout == "flex"
and tonumber(opts.winopts.preview.flip_columns) > 0
-- Only enable flex layout native rotate if zero event wasn't
-- set as it's most likely set by the default builtin previewer
and (not previewer.zero
-- or when using split mode for the background "empty previewer"
-- do not use when starting with a hidden previewer as this will
-- display the empty previewer when resizing (#1130)
or opts.winopts.split and opts.winopts.preview.hidden ~= "hidden")
then
local transformer = string.format(utils.__IS_WINDOWS
and "IF %%FZF_COLUMNS%% LEQ %d (echo change-preview-window:%s) "
.. "ELSE (echo change-preview-window:%s)"
or "[ $FZF_COLUMNS -le %d ] && echo change-preview-window:%s "
.. "|| echo change-preview-window:%s",
tonumber(opts.winopts.preview.flip_columns),
opts.winopts.preview.vertical,
opts.winopts.preview.horizontal)
utils.map_set(opts, "keymap.fzf.resize", string.format("transform(%s)", transformer))
end
if type(previewer.preview_window) == "function" then
-- do we need to override the preview_window args?
-- this can happen with the builtin previewer
Expand Down Expand Up @@ -436,7 +414,7 @@ M.fzf = function(contents, opts)
-- convert "exec_silent" actions to fzf's `execute-silent` binds
opts = M.convert_reload_actions(opts.__reload_cmd or contents, opts)
opts = M.convert_exec_silent_actions(opts)
local selected, exit_code = fzf.raw_fzf(contents, M.build_fzf_cli(opts),
local selected, exit_code = fzf.raw_fzf(contents, M.build_fzf_cli(opts, fzf_win),
{
fzf_bin = opts.fzf_bin,
cwd = opts.cwd,
Expand Down Expand Up @@ -488,11 +466,33 @@ end

---@param o table
---@return string
M.preview_window = function(o)
local hsplit = win:preview_splits_horizontally(o.winopts, 0)
local split = hsplit and o.winopts.preview.horizontal or o.winopts.preview.vertical
return ("%s:%s:%s:%s"):format(
o.winopts.preview.hidden, o.winopts.preview.border, o.winopts.preview.wrap, split)
M.preview_window = function(o, fzf_win)
local layout
if o.__FZF_VERSION
and o.__FZF_VERSION >= 0.31
and o.winopts.preview.layout == "flex"
and tonumber(o.winopts.preview.flip_columns) > 0
then
-- Fzf's alternate layout calculates the available preview width in a horizontal split
-- (left/right), for the "<%d" condition to trigger the width should be test against a
-- calculated preview width after a horizontal split (and not vs total fzf window width)
-- to do that we must substract the calculated fzf "main" window width from `flip_columns`.
-- NOTE: sending `true` as first arg gets the no fullscreen width, otherwise we'll get
-- incosstent behavior when starting fullscreen
local columns = fzf_win:columns(true)
local fzf_prev_percent = tonumber(o.winopts.preview.horizontal:match(":(%d+)%%")) or 50
local fzf_main_width = math.ceil(columns * (100 - fzf_prev_percent) / 100)
local horizontal_min_width = o.winopts.preview.flip_columns - fzf_main_width + 1
if horizontal_min_width > 0 then
layout = string.format("%s,<%d(%s)",
o.winopts.preview.horizontal, horizontal_min_width, o.winopts.preview.vertical)
end
end
if not layout then
layout = fzf_win:fzf_preview_layout_str()
end
return string.format("%s:%s:%s:%s",
o.winopts.preview.hidden, o.winopts.preview.border, o.winopts.preview.wrap, layout)
end

-- Create fzf --color arguments from a table of vim highlight groups.
Expand Down Expand Up @@ -621,7 +621,7 @@ end

---@param opts table
---@return string[]
M.build_fzf_cli = function(opts)
M.build_fzf_cli = function(opts, fzf_win)
opts.fzf_opts = vim.tbl_extend("force", config.globals.fzf_opts, opts.fzf_opts or {})
-- copy/merge from globals
for _, o in ipairs({ "fzf_colors", "keymap" }) do
Expand Down Expand Up @@ -681,7 +681,7 @@ M.build_fzf_cli = function(opts)
end
end
if opts.fzf_opts["--preview-window"] == nil then
opts.fzf_opts["--preview-window"] = M.preview_window(opts)
opts.fzf_opts["--preview-window"] = M.preview_window(opts, fzf_win)
end
if opts.fzf_opts["--preview-window"] and opts.preview_offset and #opts.preview_offset > 0 then
opts.fzf_opts["--preview-window"] =
Expand Down
2 changes: 1 addition & 1 deletion lua/fzf-lua/defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ M.defaults = {
vertical = "down:45%",
horizontal = "right:60%",
layout = "flex",
flip_columns = 120,
flip_columns = 100,
title = true,
title_pos = "center",
scrollbar = "border",
Expand Down
Loading

0 comments on commit 8c59894

Please sign in to comment.