Closed Marskey closed 3 weeks ago
ATM, this is not possible, it’s an interesting idea might be worth exploring.
+1 on this feature request. I use this feature a lot and would be nice to have it supported in fzf-lua.
If you're on Neovim >= 0.10, then you can use the keymap below to toggle any floating window.
local function toggle_floats()
local floats = {}
local any_hidden = false
for _, win in ipairs(vim.api.nvim_list_wins()) do
local config = vim.api.nvim_win_get_config(win)
if config.relative ~= "" then
floats[win] = config
if config.hide then
any_hidden = true
end
end
end
for win, config in pairs(floats) do
config.hide = not any_hidden
vim.api.nvim_win_set_config(win, config)
end
end
vim.keymap.set({ "n", "t" }, "<c-;>", toggle_floats)
Edit: this doesn't really work as intended though, since focus would still be on the hidden fzf window :)
I've been using a similar to folke's solution with nvim >= 0.10 for some time, and in general it works fine (see the video example) - it switches the focus to the buffer, and restores the cursor position in the next fzf search
my workflow:
<enter>
to go to the selected entry - it'll hide the current search float window to resume laterreferences to the actual config:
demo:
https://github.com/ibhagwan/fzf-lua/assets/11135392/32f974b0-9aac-4744-9824-2fb5c1e84efc
fzf-lua action example
{
'ibhagwan/fzf-lua',
keys = function()
local fzf = require('fzf-lua')
local actions = require('fzf-lua.actions')
return {
utils.cmd_shift('f', {
function()
local tf = require('lttb.dev.toggle_floats')
if tf.is_hidden('fzf') then
tf.toggle_floats('fzf')
return
end
fzf.grep_project({
actions = {
['enter'] = {
function(selected, opts)
tf.toggle_floats('fzf', function()
actions.file_edit(selected, opts)
end)
end,
actions.resume,
},
},
})
end,
desc = 'fzf: search',
}),
}
end,
},
toggle_floats.lua
local M = {}
local registry = {}
function M.is_hidden(name)
local reg = registry[name]
return reg and #reg.hidden_w > 0
end
function M.toggle_floats(name, callback)
registry[name] = registry[name] or { hidden_w = {}, last_w = nil }
local reg = registry[name]
local wins = vim.api.nvim_list_wins()
if #reg.hidden_w > 0 then
for _, w in ipairs(reg.hidden_w) do
vim.api.nvim_win_set_config(w, { hide = false })
end
if reg.last_w then
vim.api.nvim_set_current_win(reg.last_w)
vim.schedule(function()
vim.api.nvim_feedkeys('i', 'n', false)
end)
end
reg.hidden_w = {}
reg.last_w = nil
return
end
reg.last_w = vim.api.nvim_get_current_win()
for id, w in ipairs(wins) do
local win_config = vim.api.nvim_win_get_config(w)
if
win_config.relative == 'editor'
-- ignore mini map (TODO: find a better detection way)
and win_config.zindex ~= 10
then
vim.api.nvim_win_set_config(w, { hide = true })
table.insert(reg.hidden_w, w)
end
end
vim.opt.eventignore:append('WinLeave')
vim.opt.eventignore:append('BufLeave')
vim.api.nvim_set_current_win(1000)
vim.schedule(function()
if callback then
callback()
end
vim.opt.eventignore:remove('WinLeave')
vim.opt.eventignore:remove('BufLeave')
end)
end
return M
I also thought about the new float hide in neovim 0.10 but this provides a solution only for users with 0.10 and only using floats, there are also users using splits or fzf-tmux.
In general, I’m not too happy with the current state of the window class code since it had many iterations and is a bit messy, it started by only making a window for fzf with no preview buffer (at first, only native previewers were supported, like fzf.vim), then the “builtin” neovim buffer preview, splits, and fzf-tmux.
I’d hate to continue contributing to this mess without first splitting the window class to a base object and having a class for each FzfLuaFloat
, FzfLuaSplit
, etc, each having their own :hide()
callback (which may or may not be supported, e.g. fzf- tmux), that will also open up the window creation for other frameworks like nui.nvim, etc.
That said, this change is a “luxury” change since everything is pretty much working so I need to get inspired to find the time for this :)
See #1371 for more info, default bind set to <A-Esc>
.
Forgot to mention how this addresses the issue of replacing the default <esc>
with hide:
require("fzf-lua").setup({
keymap = {
builtin = {
true, -- inherit all other default binds
["<Esc>"] = "hide",
}
}
})
Can also be set for a single call:
:FzfLua files keymap.builtin.<esc>=hide
Or for a specific picker (or picket "set", e.g. grep
):
:lua require("fzf-lua").setup({ files = { keymap = { builtin = { ["<Esc>"] = "hide" } } } })
The feature didn't work as I expected. It should be like what @lttb posted: hide the window and then resume, including the cursor position.
@Marskey I haven't tried @lttb's solution, but I tested the latest version of Fzf-Lua and I think it works as expected (by me). Attaching a screen record for how it behaves for me:
The feature didn't work as I expected. It should be like what @lttb posted: hide the window and then resume, including the cursor position.
Can you try with the default keybind alt-escape
?
Perhaps your key mapping isn’t working or mapped to something else, one way to check if your window is actually hidden is to run :FzfLua unhide
, with “unhide” it won’t fall back to resume, if unhide yields nothing your window wasn’t hidden.
Also can you press F1
and see if your mapping worked? My F1
(with the default) below:
My bad, my config did not inherit the default keybind. nice work~ you are awosome!
Ty @Marskey for the confirmation.
Note that it’s not meant to simply “restore the cursor” (not only at least), the new functionality sends the fzf process to the background so if you have a long running fd in a large project you can send it to background and come back to it when the enumeration finishes.
@ibhagwan after I resumed, then I use fzf.buffers will occurd follwing error
Error executing vim.schedule lua callback: ...key/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell.lua:313: vim/shared.lua:0: t: expected table, got nil
stack traceback:
[builtin#36]: at 0x010523481c
...key/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell.lua:313: in function 'fn'
...key/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell.lua:77: in function <...key/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell.lua:76>
@ibhagwan after I resumed, then I use fzf.buffers will occurd follwing error
Error executing vim.schedule lua callback: ...key/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell.lua:313: vim/shared.lua:0: t: expected table, got nil stack traceback: [builtin#36]: at 0x010523481c ...key/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell.lua:313: in function 'fn' ...key/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell.lua:77: in function <...key/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell.lua:76>
Can you help me reproduce this? Does this happen all the time with buffers (I assume not)? Is a certain sequence required to trigger this bug? Does this happen on selection / up/down / ctrl-x?
@ibhagwan my config
local actions = require("fzf-lua").actions
require("fzf-lua").setup {
"telescope",
defaults = { formatter = "path.filename_first" },
winopts = {
height = 0.90,
width = 0.77,
preview = {
wrap = "wrap",
layout = "vertical", -- horizontal|vertical|flex
vertical = "down:50%", -- right|left:size
hidden = "hidden", -- hidden|nohidden
},
},
fzf_opts = { ["--layout"] = "reverse", ["--marker"] = "+" },
fzf_colors = {
["gutter"] = "-1",
},
hls = {
cursorline = "CursorLine",
cursorlinenr = "CursorLineNr",
},
grep = {
rg_opts = "--column --line-number --no-heading --color=always -L --smart-case --max-columns=4096 -e",
},
keymap = {
builtin = {
["<Esc>"] = "hide",
["<F1>"] = "toggle-help",
["<c-n>"] = "toggle-fullscreen",
-- Only valid with the 'builtin' previewer
["<F3>"] = "toggle-preview-wrap",
["<c-p>"] = "toggle-preview",
["<F5>"] = "toggle-preview-ccw",
["<F6>"] = "toggle-preview-cw",
["<C-d>"] = "preview-page-down",
["<C-u>"] = "preview-page-up",
["<S-left>"] = "preview-page-reset",
},
fzf = {
["ctrl-z"] = "abort",
["ctrl-f"] = "forward-char",
["ctrl-b"] = "backward-char",
["ctrl-a"] = "beginning-of-line",
["ctrl-e"] = "end-of-line",
["alt-a"] = "toggle-all",
-- Only valid with fzf previewers (bat/cat/git/etc)
["f3"] = "toggle-preview-wrap",
["f4"] = "toggle-preview",
["ctrl-d"] = "preview-page-down",
["ctrl-u"] = "preview-page-up",
},
},
actions = {
files = {
["default"] = actions.file_edit_or_qf,
["ctrl-s"] = actions.file_split,
["ctrl-v"] = actions.file_vsplit,
["ctrl-t"] = actions.file_tabedit,
},
},
}
I figure out that ["<Esc>"] = "hide",
is the reason cause this error. after opening fzf.files
, press esc
to hide it, then use fzf.buffers
. It happended 100%
Does the interface open at all? What happens if you :FzfLua buffers previewer=false
?
after :FzfLua buffers previewer=false
Ty @Marskey, I have a good idea now where this might come from.
If I use <M-esc>
It will work normally
@Marskey, should work as expected after https://github.com/ibhagwan/fzf-lua/commit/19c52910dce1a95f01fc2dc3c7c7458ad425b887.
Have you RTFM'd?
Feature Request
This way, I can resume my last search status exactly where I left off. The current resume feature only redoes the search with the same query, which causes the previous search state to be lost.