New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FZF Support? #106
Comments
That's a cool idea 👍 . Just quickly looked at the code and I am not sure how much would be involved but definitely would like to try at some point 😄 Thanks |
👍 |
I really like this idea and have wanted this for a while as well. I think that the only way to achieve this is create a custom FZF source that appends the correct file icons in front of the filenames. The problem with this approach is that we limit the user to using a specific FZF custom source and not have the devicons in all there already defined sources. I'm willing to take this up and look into this further. |
Ok so I've investigated it some more, and what I found so far is: nonetheless altough it took me a full afternoon (I'm a vimscript novice) I got it done (adding icons to fzf) see below screenshot: The only part left is getting FZF to actually edit the file because now it tries to edit (icon + filename) as a path. |
@alexanderjeurissen Nice! Very cool. So this is for FZF in the terminal (executable)? Your previous comment I thought it was just the vim plugin of FZF.
Ah yup, I had a similar struggle with CtrlP (eventually sending a PR to more easily do some things). Not sure if it will be of any help to your particular case but this is how I was stripping out the glyphs for CtrlP: https://github.com/ryanoasis/vim-devicons/blob/master/plugin/webdevicons.vim#L505-L509 |
@ryanoasis DONE. code: " Files + devicons
function! Fzf_dev()
function! s:files()
let files = split(system($FZF_DEFAULT_COMMAND), '\n')
return s:prepend_icon(files)
endfunction
function! s:prepend_icon(candidates)
let result = []
for candidate in a:candidates
let filename = fnamemodify(candidate, ':p:t')
let icon = WebDevIconsGetFileTypeSymbol(filename, isdirectory(filename))
call add(result, printf("%s %s", icon, candidate))
endfor
return result
endfunction
function! s:edit_file(item)
let parts = split(a:item, ' ')
let file_path = get(parts, 1, '')
execute 'silent e' file_path
endfunction
call fzf#run({
\ 'source': <sid>files(),
\ 'sink': function('s:edit_file'),
\ 'options': '-m -x +s',
\ 'down': '40%' })
endfunction |
as I said the only downside of this approach is that people have to use this function.. as we require control over the this function however doesn't include buffer files and MRU, not sure if that's a deal breaker for a lot of people. We could add them ofc but then we have to offer multiple variants or options ;) And to answer your question: Yes this is only for using fzf in vim, the standalone fzf.vim plugin isn't required though. |
I'll tackle some of the problems mentioned in my previous comment and refine the code. Expect a PullRequest somewhere this weekend. In the mean time people like ( @mhartington ) can use the snippet above ;-) |
@alexanderjeurissen Any movement on this by chance? |
@michaelmior the code snippet that i shared in a previous comment still works. However it is required that the user specifies this in their vimrc. I so far haven't found time to work on implementing this in the devicons vim plugin. I don't expect to have spare time to work on this till september. So if people think it's a high priority feature, they can use the code I provided as a starting point for the implementation. |
Another fzf user here. I tried the snippet from @alexanderjeurissen without much success. Anything else needed to get it working? |
@dvcrn @alexanderjeurissen's snippet works on my setup. Just calling |
If you want preview you can install the rouge gem: " Files + devicons
function! Fzf_dev()
let l:fzf_files_options = '--preview "rougify {2..-1} | head -'.&lines.'"'
function! s:files()
let l:files = split(system($FZF_DEFAULT_COMMAND), '\n')
return s:prepend_icon(l:files)
endfunction
function! s:prepend_icon(candidates)
let l:result = []
for l:candidate in a:candidates
let l:filename = fnamemodify(l:candidate, ':p:t')
let l:icon = WebDevIconsGetFileTypeSymbol(l:filename, isdirectory(l:filename))
call add(l:result, printf('%s %s', l:icon, l:candidate))
endfor
return l:result
endfunction
function! s:edit_file(item)
let l:pos = stridx(a:item, ' ')
let l:file_path = a:item[pos+1:-1]
execute 'silent e' l:file_path
endfunction
call fzf#run({
\ 'source': <sid>files(),
\ 'sink': function('s:edit_file'),
\ 'options': '-m ' . l:fzf_files_options,
\ 'down': '40%' })
endfunction |
@dkarter great solution! There is a simple way to use the 'internal' fzf.vim preview ( |
I've tried using the two |
Follow-up: looks like installing |
I use
AgIf you want the same setup install via homebrew (macOS): brew install the_silver_searcher and add this to your let $FZF_DEFAULT_COMMAND = 'ag --hidden -l -g ""' RipGrepIf you want it to be even faster - use ripgrep brew install ripgrep and add this to your let $FZF_DEFAULT_COMMAND = 'rg --hidden -l ""' Compared with |
@dkarter Good solution. The preview command can be simplified into this: let l:fzf_files_options = '--preview "rougify {2..} | head -'.&lines.'"' Here |
@dkarter These lines in let l:parts = split(a:item, ' ')
let l:file_path = get(l:parts, 1, '') Suggest replacing it by the following: let l:pos = stridx(a:item, ' ')
let l:file_path = a:item[pos+1:] |
Thanks @wfxr! I've updated my comment above to include your improvements. |
@dkarter also, to remove the dependency of the let l:fzf_file_options = '--preview "[[ \$(file --mime {2..-1}) =~ binary ]] && echo {2..-1} is a binary file || (highlight -O ansi -l {2..-1} || coderay {2..-1} || rougify {2..-1} || cat {2..-1}) 2> /dev/null | head -'.&lines.'"' which tries the different supported highlighting programs and finally defaults to cat. |
You can take advantage of the neovim async api with the following: function! Fzf_dev(no_git) abort
let s:file_list = ['']
let s:callbacks = {
\ 'on_stdout': 'OnEvent',
\ 'on_exit': 'OnExit'
\ }
if !a:no_git
call jobstart([ 'rg', '--files' ], s:callbacks)
else
call jobstart([ 'rg', '-L', '-i', '--no-ignore', '--files' ], s:callbacks)
endif
function! OnEvent(job_id, data, event)
let s:file_list[-1] .= a:data[0]
call extend(s:file_list, a:data[1:])
endfunction
function! OnExit(job_id, data, event)
call fzf#run({
\ 'source': s:prepend_icon(s:file_list),
\ 'sink': function('s:edit_file'),
\ 'options': '-m',
\ 'down': '40%'
\ })
endfunction
function! s:prepend_icon(candidates)
let l:result = []
for l:candidate in a:candidates
let l:filename = fnamemodify(l:candidate, ':p:t')
let l:icon = WebDevIconsGetFileTypeSymbol(l:filename, isdirectory(l:filename))
call add(l:result, printf('%s %s', l:icon, l:candidate))
endfor
return l:result
endfunction
function! s:edit_file(item)
let l:pos = stridx(a:item, ' ')
let l:file_path = a:item[l:pos+1:-1]
execute 'silent e' l:file_path
endfunction
endfunction Then it can be called with a |
Used @dkarter's comment as a starting point, and made some performance improvements and added some git diff support as well. TLDR: Wrote a tool to do the devicon lookup in Rust (so it actually doesn't depend on this repo at all), and used You can install both with cargo install bat
cargo install devicon-lookup And here is the VIM config (also includes support for emulating " Files + devicons
function! Fzf_files_with_dev_icons(command)
let l:fzf_files_options = '--preview "bat --color always --style numbers {2..} | head -'.&lines.'"'
function! s:edit_devicon_prepended_file(item)
let l:file_path = a:item[4:-1]
execute 'silent e' l:file_path
endfunction
call fzf#run({
\ 'source': a:command.' | devicon-lookup',
\ 'sink': function('s:edit_devicon_prepended_file'),
\ 'options': '-m ' . l:fzf_files_options,
\ 'down': '40%' })
endfunction
function! Fzf_git_diff_files_with_dev_icons()
let l:fzf_files_options = '--ansi --preview "sh -c \"(git diff --color=always -- {3..} | sed 1,4d; bat --color always --style numbers {3..}) | head -'.&lines.'\""'
function! s:edit_devicon_prepended_file_diff(item)
echom a:item
let l:file_path = a:item[7:-1]
echom l:file_path
let l:first_diff_line_number = system("git diff -U0 ".l:file_path." | rg '^@@.*\+' -o | rg '[0-9]+' -o | head -1")
execute 'silent e' l:file_path
execute l:first_diff_line_number
endfunction
call fzf#run({
\ 'source': 'git -c color.status=always status --short --untracked-files=all | devicon-lookup',
\ 'sink': function('s:edit_devicon_prepended_file_diff'),
\ 'options': '-m ' . l:fzf_files_options,
\ 'down': '40%' })
endfunction
" Open fzf Files
map <C-f> :call Fzf_files_with_dev_icons($FZF_DEFAULT_COMMAND)<CR> " :Files
map <C-d> :call Fzf_git_diff_files_with_dev_icons()<CR> " :GFiles?
map <C-g> :call Fzf_files_with_dev_icons("git ls-files \| uniq")<CR> " :GFiles See my blog post for the long form write up! https://coreyja.com/blog/2018/11/17/vim-fzf-with-devicons.html |
@coreyja Looks great, but all icons show up as question marks. Any idea why? |
@jonasstenberg hmm do you have a nerd font compatible font installed? And do you see Dev icons elsewhere, assuming you have this, vim-devicons, plugin installed? |
This was taken from here: ryanoasis/vim-devicons#106 The implementation I went with was from coreyja. Unfortunately this doesn't work with ag, but perhaps this could be adapted.
@coreyja this is very cool, but it seems to fail for |
@mellery451 ahh sorry you are running into issues. From your description of what happens it sounds like the code that is supposed to chop off the dev char is also chopping off some of your file name. Which is part of the vim script. Are you seeing this with the standard files view or with the git changed files version? Also I might move this little script to a repo, so that we could use the issue tracker and stop using this comment thread! |
@coreyja I've only used the standard files view. I think part of the issue might be: https://github.com/coreyja/devicon-lookup/blob/master/src/main.rs#L103 which looks like it returns a single width char (x65 'e') for `txt' which confuses the strip-leading-widechar part of this vim code. Happy to move this discussion to another repo as you suggest. Thanks. |
@mellery451 Sorry for the delayed response! I created an issue over on my rust repo, and tagged you in a potential workaround (which I took from @dkarter in this thread)! Here is a link to that issue: coreyja/devicon-lookup#2 |
Nice ty..glad I found this was really helpful. Noticed that the fzf default_actions (ctrl+x, ctrl+v) weren't working. Seems that is possible to just precall fzf#wrap({}), store the sink function and then modify the returned object. I also needed to change the split file_path index from 1 to 2, could just be me though. modified @dkarter's code :
|
I've continued on the work of @TaDaa and the others. What i have now supports devicons, multiselect, preview with highlighting by bat, ctrl-d and ctrl-u for navigating preview up/down, ctrl-x,v,t bindings. I'm not a big fan of how we are bending fzf to work with the custom sink calling the default sink this way. It feels very fragile. But i'm a total viml noob, so if anyone have a better solution i'm all ears. function! FZFWithDevIcons()
let l:fzf_files_options = ' -m --bind ctrl-d:preview-page-down,ctrl-u:preview-page-up --preview "bat --color always --style numbers {2..}"'
function! s:files()
let l:files = split(system($FZF_DEFAULT_COMMAND), '\n')
return s:prepend_icon(l:files)
endfunction
function! s:prepend_icon(candidates)
let result = []
for candidate in a:candidates
let filename = fnamemodify(candidate, ':p:t')
let icon = WebDevIconsGetFileTypeSymbol(filename, isdirectory(filename))
call add(result, printf("%s %s", icon, candidate))
endfor
return result
endfunction
function! s:edit_file(items)
let items = a:items
let i = 1
let ln = len(items)
while i < ln
let item = items[i]
let parts = split(item, ' ')
let file_path = get(parts, 1, '')
let items[i] = file_path
let i += 1
endwhile
call s:Sink(items)
endfunction
let opts = fzf#wrap({})
let opts.source = <sid>files()
let s:Sink = opts['sink*']
let opts['sink*'] = function('s:edit_file')
let opts.options .= l:fzf_files_options
call fzf#run(opts)
endfunction |
bump |
The biggest challenge here is to have the prepend icon runs asynchronously. |
I customised @micke's snippet to use @coreyja's devicon-lookup which results in significantly faster response for me. function! FZFWithDevIcons()
let l:fzf_files_options = ' -m --bind ctrl-d:preview-page-down,ctrl-u:preview-page-up --preview "bat --color always --style numbers {2..}"'
function! s:files()
let l:files = split(system($FZF_DEFAULT_COMMAND.'| devicon-lookup'), '\n')
return l:files
endfunction
function! s:edit_file(items)
let items = a:items
let i = 1
let ln = len(items)
while i < ln
let item = items[i]
let parts = split(item, ' ')
let file_path = get(parts, 1, '')
let items[i] = file_path
let i += 1
endwhile
call s:Sink(items)
endfunction
let opts = fzf#wrap({})
let opts.source = <sid>files()
let s:Sink = opts['sink*']
let opts['sink*'] = function('s:edit_file')
let opts.options .= l:fzf_files_options
call fzf#run(opts)
endfunction |
Is there a way to make this work with open buffers as well? |
- FZF wired up to work with the silver searcher and added nerd fonts dev icons next to files in the fuzzy search list. Source found in a github issue ryanoasis/vim-devicons#106 - Tinkering with custom gitgutter signs
@waigx could we maybe use this for async? https://github.com/tpope/vim-dispatch |
@chris-fran - I am using external devicon-lookup pipeline as suggested above. |
Is there a way to add devicons to :Ag search results (in fzf-vim plugin)? I am very satisfied with files searchinng with BAT but the last thing i wanna do is to search inside files with some BAT preview and devicons |
@roszczypalam There is now 🙃 I'm back in this thread to announce a The new plugin is fzf.devicon.vim 🎉 This plugin is a fork of One of the new things is actually the grep support. I added Besides the grep results, the functionality is pretty much the same as the other versions that have been shared here previously (so thanks to everyone for their contributions in this thread!). It supports all the the different Let me know what you guys think! Thanks! |
Why not PR the main project? |
@blayz3r I thought about it and might still. The main reason I didn't is that it doesn't actually I wasn't sure this was in the spirit of this original repo, and I don't think maintaining a full Another reason is that it requires an external tool to function (even besides But if @ryanoasis (and/or other maintainers) would like to include this in the original repo, I am MORE than happy to contribute it and help maintain it in this repo! |
Makes sense I was imagining something like this https://github.com/kristijanhusak/defx-icons/blob/master/README.md. |
hey all, sorry for the delay in chiming in. 👋 lots of good solutions here, I am open to any PRs and also very cool with people just creating their own forks or projects (that's what's cool about OSS right?). That said I would love it was supported out of the box and it looks like others have posted possible solutions here already.. |
@ryanoasis Thanks for the reply! So right now my solution (plus most of the others here that I am aware of) here don't really 'insert' icons into the original I decided to rename my commands so as to not 'shadow' the original ones. If you (@ryanoasis) are ok with maintaining (with help of course 🙃 ) my implementation (potentially with a shim to not need |
While we don't yet have full support for devicons, we are working on a plugin that provides various resources for FZF. It uses Vim script and ripgrep to apply the devicons. |
Any update? |
Hey, it’s been 5 years people have been asking for this. I’m pretty sure lots of people would contribute to provide all the patches listed above. What’s your take on this @ryanoasis? |
FZF has a vim interface for fast file searching.
https://github.com/junegunn/fzf
Similar to ctrlp/unite.
Would be interested in have some icons in there too 😁
The text was updated successfully, but these errors were encountered: