Closed talovski closed 6 months ago
But I can't figure out how to replicate it in FzfLua? I am not fluent in fzf, so there might be an obvious way to implement this that I am missing.
There are a few ways to address what you’re after:
:FzfLua live_grep path_shorten=true
--keep-right
option (within fzf_opts
)--delimiter
and --with-nth
(man fzf
and search the issues and you’ll understand how to use these)@talovski May I ask your config to solve this ? I try to achieve the same behavior since I migrate from Telescope to FzfLua.
files = {
cwd_prompt = false,
previewer = false,
-- fd_opts = [[--color=never --type f --hidden --follow --exclude .git \
-- | awk -F'/' '{ print $NF, substr($0, 1, length($0)-length($NF)-1) }']],
fzf_opts = {
-- ["--delimiter"] = ("[%s]"):format(util.nbsp),
-- ["--with-nth"] = "-1,..-2",
},
fn_transform = function(entry)
local file_icon, path = unpack(vim.split(entry, util.nbsp))
local tail = vim.fs.basename(path)
local parent = vim.fs.dirname(path)
if parent == "." then
return ("%s%s%s"):format(file_icon, util.nbsp, tail)
end
return ("%s%s%s%s%s"):format(file_icon, util.nbsp, tail, util.nbsp, util.ansi_codes.grey(parent))
end,
},
Which is exact the display I want but when select an entry it doesn't open a file but a directory instead. The createdb.sql db/migration
entry above will open db/migration
instead of db/migration/createdb.sql
.
As you can see in my config I try fzf_opts
as well (uncomment and file_icons=false
) and the display is not what I expected but It opens the file correctly
@hieulw, instead of creating your own transformer, it’s better to use --delimiter
to split the string into virtual fields and then use --with-nth
to place the filename first, this way you’re just playing with formatting so everything continues to work as expected (opening files, previews, etc).
I’ve seen a post on Reddit about this recently you might find interesting (using the above technique): https://redlib.freedit.eu/r/neovim/comments/1c1id24/vscode_like_path_display_in_fzfluas_files_picker/
Wow, you so fast @ibhagwan. It works! I never think of -x printf "{}: {/} %s\n"
before.
Thank you so much!
Wow, you so fast @ibhagwan. It works! I never think of
-x printf "{}: {/} %s\n"
before. Thank you so much!
This seems so popular I’m thinking of adding this as a native functionality in fzf-lua (without the overhead of printing the path twice).
Wow, you so fast @ibhagwan. It works! I never think of
-x printf "{}: {/} %s\n"
before. Thank you so much!This seems so popular I’m thinking of adding this as a native functionality in fzf-lua (without the overhead of printing the path twice).
That would be great !
https://github.com/ibhagwan/fzf-lua/commit/0d09b75aa7a6ea39752c6cb21cbe28ce5e4de689
@hieulw, @towry, try out the latest commi, to enable set `formatter="path.filename_first" (hardcoded in globals):
require("fzf-lua").setup({
files = {
formatter = "path.filename_first"
}
})
Can also be sent directly in the call options, e.g:
:lua require("fzf-lua").live_grep({ formatter = "path.filename_first" })
:FzfLua lsp_finder formatter=path.filename_first
Currently the folder is hard color coded with terminal grey, when I get a chance I'll add a custom highlight for that (it's a bit more complex as it needs to be passed to the child process).
A nice "side effect", the new formatter can be combined with path_shorten
, for example:
FzfLua live_grep path_shorten=true formatter=path.filename_first
Note the folders are shortened to a single letter
How to change the highlight group of the path?
How to change the highlight group of the path?
Use fzf_colors.fg
, see man fzf
for all other color elements you can change.
Hi there 👋 😊 ,
i love this new "filename_first" functionality, but I also have problems with the color of the path. I am also working on a big colorscheme collection and I love FzfLua so this is important to me. :)
I tried to work with fzf_colors.fg
but fg
seem to affect the filename only and not the path. And I can't find in the Manual a fzf
which affects only the path.
This is what I currently got:
fzf_colors = {
-- I intentionally picked something colorful here
-- to illustrate my problem, that this color only affects the filename.
-- Normally its `Normal`
["fg"] = { "fg", "@conditional" },
-- ["fg"] = { "fg", "Normal" },
["fg+"] = { "fg", "CursorLineNr" },
["bg"] = { "bg", "NormalFloat" },
["hl"] = { "fg", "Comment" },
["bg+"] = { "bg", "Normal" },
["border"] = { "fg", "CursorLineNr" },
["hl+"] = { "fg", "Statement" },
["query"] = { "fg", "Statement" },
["info"] = { "fg", "PreProc" },
["label"] = { "fg", "CursorLineNr" },
["prompt"] = { "fg", "Conditional" },
["pointer"] = { "fg", "Exception" },
["marker"] = { "fg", "Keyword" },
["spinner"] = { "fg", "Label" },
["header"] = { "fg", "Comment" },
["gutter"] = { "bg", "NormalFloat" },
},
This results in this:
I don't know if this is a good idea or even possible from your end, but I would expected a dedicated highlight group in the same maner of FzfLuaPathColNr
& FzfLuaPathLineNr
. Something like FzfLuaPath
or something.
Currently the folder is hard color coded with terminal grey, when I get a chance I'll add a custom highlight for that (it's a bit more complex as it needs to be passed to the child process).
@nikbrunner, @PangPangPangPangPang - this is a new feature, I am planning on adding an hl group but haven’t gotten to it yet.
Alright thank you very much! 😊
@nikbrunner @PangPangPangPangPang
https://github.com/ibhagwan/fzf-lua/commit/e32f3dfb543c69fe3cc6a85b763f66b7ff98294e
The above commit defines a new highlight group FzfLuaDirPart
:
Can be linked to anything
:hi! link FzfLuaDirPart IncSearch
defined in
setup
require("fzf-lua").setup({ hls = { dir_part = "IncSearch" } })
Or sent directly in a call
:FzfLua live_grep formatter=path.filename_first hls.dir_part=ErrorMsg
Thank you so very much!!! Its working great. 😊
Thank you so very much!!! Its working great. 😊
Ty @nikbrunner!
I just set it up for myself as well :-)
Btw, if you want to do this for all pickers that contain path entries use global picker defaults in setup.defaults
:
require("fzf-lua").setup({
defaults = { formatter = "path.filename_first" },
-- rest of your setup
})
Thank you so very much!!! Its working great. 😊
Ty @nikbrunner!
I just set it up for myself as well :-)
Btw, if you want to do this for all pickers that contain path entries use global picker defaults in
setup.defaults
:require("fzf-lua").setup({ defaults = { formatter = "path.filename_first" }, -- If you're using `tags`, disable the formatter for `btags|tags` tags = { formatter = false }, btags = { formatter = false }, -- rest of your setup })
You are reading my mind. ❤️
You are reading my mind. ❤️
As the saying goes, I eat my own dogfood :-)
I just noticed something while trying this out. I can open an issue for that, if it even is an issue or just a miss-setting from my side. Ill just mention it here, because we just talked about it.
When I set the defaults = { formatter = "path.filename_first" }
and also have the fzf_colors.prompt
set, I will get an error:
15:21:05 │ [Fzf-lua] fzf error 2: invalid color specification: formatter:path.filename_first
I found this in the repo and I guessed it has something todo with the fzf colors.
I commented out every line in the fzf_colors
array and stopped at prompt
. If I comment it out I no longer get the error.
This is what my fzf_colors
array looks like, and behind that link is also the rest of my fzf-lua
config file:
https://github.com/nikbrunner/vin/blob/86389b98f870661d0390ae38e8fa8076873d1573/lua/vin/specs/fzf.lua#L235-L252
I also noticed that you have the default set, but the prompt
commented out in your nvim config: https://github.com/ibhagwan/nvim-lua/blob/b049e0571328ca28cdf66030fd900473aab9f9e2/lua/plugins/fzf-lua/setup.lua#L83
Thank you again. :) If you want me to open an Issue for that, please let me know.
Thank you again. :) If you want me to open an Issue for that, please let me know.
Sure, would be great, so we can track it as this is a different issue altogether unrelated to this issue.
Would also be helpful if you can post the output of the bugged out group, if the below returns a link to another group try to follow it until the definition and that will tell us what’s bugged.
lua vim.print(vim.api.nvim_get_hl(0,{name="Conditional"}))
I also noticed that you have the default set, but the prompt commented out in your nvim config:
Just a personal preference after testing, I suspect your group has a value the code doesn’t expect, if you change it to one of the other groups in your fzf_colors
it will probably work, this has nothing specific to do with prompt
.
Actually I just noticed this:
invalid color specification: formatter:path.filename_first
Might be related to the new formatted after, I’ll try to reproduce with prompt.
In the meantime can you run :FzfLua files debug=true _base64=false formatter=path.filename_first
and post the output from :messages
?
Also, if you run without the new formatter, do you still get an error (albeit different)?
I am just writing out the issue in the other window, but here you go. :)
This is the output of FzfLua files debug=true _base64=false formatter=path.filename_first
[Fzf-lua]: FZF_DEFAULT_COMMAND: VIMRUNTIME='/opt/homebrew/Cellar/neovim/0.9.5/share/nvim/runtime' '/opt/homebrew/Cellar/neovim/0.9.5/bin/nvim' -n --headless --clean --cmd 'lua loadfile([[/Users/nbr/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/libuv.lua]])().spawn_stdio({g = {_fzf_lua_server = "/var/folders/k5/jc_1pjxx7h781rvj5y3ysmth0000gp/T/nvim.nbr/GfPEDh/fzf-lua.1714918308.4081.1"}, _base64 = false, cmd = "fd --color=never --type f --hidden --follow --exclude .git", git_icons = true, formatter = "path.filename_first", color_icons = false, debug = true, file_icons = false},[==[return require("make_entry").file]==],[==[return require("make_entry").preprocess]==])' || true
[Fzf-lua]: fzf cmd: fzf --preview 'VIMRUNTIME='\''/opt/homebrew/Cellar/neovim/0.9.5/share/nvim/runtime'\'' '\''/opt/homebrew/Cellar/neovim/0.9.5/bin/nvim'\'' -n --headless --clean --cmd '\''lua loadfile([[/Users/nbr/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell_helper.lua]])().rpc_nvim_exec_lua({fzf_lua_server=[[/var/folders/k5/jc_1pjxx7h781rvj5y3ysmth0000gp/T/nvim.nbr/GfPEDh/fzf-lua.1714918308.4081.1]], fnc_id=3 , debug=true})'\'' -- {}' --bind 'ctrl-d:preview-page-down,f4:toggle-preview,ctrl-u:preview-page-up,ctrl-c:abort,ctrl-a:toggle-all,zero:execute-silent(mkdir '\''/var/folders/k5/jc_1pjxx7h781rvj5y3ysmth0000gp/T/nvim.nbr/GfPEDh/3'\'' && VIMRUNTIME='\''/opt/homebrew/Cellar/neovim/0.9.5/share/nvim/runtime'\'' '\''/opt/homebrew/Cellar/neovim/0.9.5/bin/nvim'\'' -n --headless --clean --cmd '\''lua loadfile([[/Users/nbr/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell_helper.lua]])().rpc_nvim_exec_lua({fzf_lua_server=[[/var/folders/k5/jc_1pjxx7h781rvj5y3ysmth0000gp/T/nvim.nbr/GfPEDh/fzf-lua.1714918308.4081.1]], fnc_id=4 , debug=true})'\'' -- ),f3:toggle-preview-wrap,ctrl-q:select-all+accept' --header ':: <^[[38;2;0;250;154mctrl-g^[[0m> to ^[[38;2;139;35;35mDisable .gitignore^[[0m' --preview-window 'nohidden:right:0' --height '100%' --no-info --border-label '[ Vin ]' --layout 'reverse' --no-scrollbar --keep-right --reverse --padding '0,3' --no-separator --ansi --prompt ' ' --multi --color 'header:#606a67,query:#998ed9,info:#998ed9,bg+:#e3e6e5,hl+:#998ed9,hl:#606a67,fg+:#4db290,gutter:#d6dbd9,fg:#313533,spinner:#998ed9,border:#4db290,marker:#7872c2,pointer:#998ed9,bg:#d6dbd9,label:#4db290' --print-query --expect 'ctrl-t,ctrl-v,ctrl-s,ctrl-y,alt-q,alt-l,ctrl-c,esc,ctrl-g,ctrl-q' --border 'none' > '/var/folders/k5/jc_1pjxx7h781rvj5y3ysmth0000gp/T/nvim.nbr/GfPEDh/5'
And yes. If I comment out the default option for the formatter, and comment in the fzf_colors.prompt
again, I don't get the error.
So this works.
defaults = {
-- formatter = "path.filename_first",
},
-- ...
fzf_colors = {
["fg"] = { "fg", "Normal" },
["fg+"] = { "fg", "CursorLineNr" },
["bg"] = { "bg", "NormalFloat" },
["hl"] = { "fg", "Comment" },
["hl+"] = { "fg", "Statement" },
["bg+"] = { "bg", "Normal" },
["border"] = { "fg", "CursorLineNr" },
["query"] = { "fg", "Statement" },
["info"] = { "fg", "PreProc" },
["label"] = { "fg", "CursorLineNr" },
["prompt"] = { "fg", "Conditional" },
["pointer"] = { "fg", "Exception" },
["marker"] = { "fg", "Keyword" },
["spinner"] = { "fg", "Label" },
["header"] = { "fg", "Comment" },
["gutter"] = { "bg", "NormalFloat" },
},
Ah and this is the output of lua vim.print(vim.api.nvim_get_hl(0,{name="Conditional"}))
:
{
bold = true,
cterm = {
bold = true,
italic = true
},
fg = 10063577,
italic = true
}
And yes. If I comment out the default option for the formatter, and comment in the fzf_colors.prompt again, I don't get the error.
Def related to the formatter, you can skip the issue if you want, I’ll take a look later when I’m no longer AFK, I’m a bit confused how the color spec gets into this mixed given the formatter is hidden inside a base64 string.
Okay thank you for the update! I hope you can figure it out. :)
Well was just done writing out the issue. I tried to append the gathered information about this in it. If you need anything more, please just ask.
Hello,
Is it expected that the formatter = 'path.filename_first'
option impacts the way search query is interpreted? Asking because with this option on I have to also type the filename first rather than start with any path segments in order to be able to find anything :)
Hello, Is it expected that the
formatter = 'path.filename_first'
option impacts the way search query is interpreted? Asking because with this option on I have to also type the filename first rather than start with any path segments in order to be able to find anything :)
Yes, once the line is transformed and sent to fzf it has no awareness of a “path”, just a string, I can look into changing the search order with --nth
.
@oshchyhol, unfortunately, that doesn't seem possible as --nth
only limits the search scope but does not change the search order, this would require a feature request upstream.
Gotcha, thanks for the quick response and for looking for workarounds!
@ibhagwan I also just noticed the way searching is changed if using path.filename_first
:)
What about adding the basename (filename) to the end of the string and then use --with-nth=..-2
.
Wouldn't that work more as expected?
I made an experimental PR to allow better search with filename_first
.
https://github.com/ibhagwan/fzf-lua/pull/1255
It's a bit of a hack, but works as intended:
ellipsis
to the empty stringhscroll
@ibhagwan If the query for 'a.txt foo/bar' is "foo bar a.txt" then it works as expected.
So is it possible to send "foo bar a.txt" to fzf if user input "foo/bar/a.txt" ?
@ibhagwan If the query for 'a.txt foo/bar' is "foo bar a.txt" then it works as expected.
So is it possible to send "foo bar a.txt" to fzf if user input "foo/bar/a.txt" ?
Unfortuntely not, I have no control over parsing the query outside of "live" pickers which would mean no fuzzy matching.
@towry, update to the latest commit and try:
:lua require("fzf-lua").files({ formatter={"path.filename_first",2} })
-- or
:FzfLua files formatter={"path.filename_first",2}
It will hide the highlighting when the match is on the hidden part but it will match the paths, see https://github.com/ibhagwan/fzf-lua/pull/1255#issuecomment-2163449012
Thanks, I will give it a try.
And I just find a solution for files
picker only, to replace path separator to space in query.
files = {
formatter = 'path.filename_first',
keymap = {
fzf = {
['/'] = [[transform-query(echo '{fzf:query} ')]],
},
},
},
And I just find a solution for files picker only, to replace path separator to space in query.
While this might work, playing with the query isn't something I would like to get into, has too many uninteded consequences.
When using :FzfLua files formatter={"path.filename_first",2}
I'm seeing the following with top level files Unable to stat file
. Then when I attempt to select it, it opens in an empty buffer
EDIT: Ah looks like this was fixed in https://github.com/ibhagwan/fzf-lua/issues/1304#issuecomment-2200500447
Info
nvim --version
: v0.10.0-dev-2156+g012cfced9-Homebrewfzf --version
: 0.46.0 (brew)fzf-lua configuration
```lua local actions = require("fzf-lua.actions") require("fzf-lua").setup({ actions = { files = { ["default"] = actions.file_edit, ["ctrl-_"] = actions.file_split, ["ctrl-v"] = actions.file_vsplit, ["ctrl-t"] = actions.file_tabedit, ["alt-q"] = actions.file_sel_to_qf, ["alt-l"] = actions.file_sel_to_ll, }, grep = { -- this action toggles between 'grep' and 'live_grep' ["ctrl-g"] = { actions.grep_lgrep }, ["default"] = actions.file_edit, ["ctrl-_"] = actions.file_split, ["ctrl-v"] = actions.file_vsplit, ["ctrl-t"] = actions.file_tabedit, ["alt-q"] = actions.file_sel_to_qf, ["alt-l"] = actions.file_sel_to_ll, }, }, fzf_opts = { ["--ansi"] = "", ["--info"] = "inline", ["--layout"] = "reverse-list", ["--no-separator"] = "", ["--height"] = "100%", ["--margin"] = "0", ["--padding"] = "1", ["--preview-window"] = ":rounded", ["--border"] = "none", }, previewers = { cat = { cmd = "cat", args = "--number", }, bat = { cmd = "bat", args = "--style=numbers,changes --color always", theme = "gruvbox-dark", -- bat preview theme (bat --list-themes) config = nil, -- nil uses $BAT_CONFIG_PATH }, }, files = { -- previewer = 'bat', prompt = "Files) ", multiprocess = true, git_icons = true, file_icons = true, color_icons = true, fd_opts = "--color=never --type f --hidden --follow --exclude .git --exclude node_modules", }, grep = { prompt = " Search) ", input_prompt = " Search) ", multiprocess = true, git_icons = true, file_icons = true, color_icons = true, rg_opts = "--column --line-number --no-heading --color=always --smart-case --hidden --follow --glob '!.git/*' --glob '!.node_modules/*' --glob '!pnpm-lock.yaml' --glob '!package.lock' --glob '!yarn.lock'", rg_glob = true, glob_flag = "--iglob", glob_separator = "%s%-%-", -- query separator pattern (lua): ' --' no_header = false, -- hide grep|cwd header? no_header_i = false, -- hide interactive header? }, }) ```Description
I am primarily working in a large monorepo. Large monorepo means long paths —
app/packages/package/src/components/component/ComponentName.tsx
Long paths means unreadably (worst case) or just ugly path when using
:FzfLua files
or:FzfLua live_grep
:Apart from changing the layout or increasing the size of the FzfLua floating window, is there a possibility to format the path from this:
pkgs/package/components/component/ComponentName.tsx
toComponentName.tsx — pkgs/package/components/component
?In Telescope, I managed to change the path display like this:
But I can't figure out how to replicate it in FzfLua? I am not fluent in
fzf
, so there might be an obvious way to implement this that I am missing.