DEV Community

Zanets
Zanets

Posted on

Fancy fzf on neovim

After neovim 4.0 and vim 8.1, both of them have an amazing feature: popup window.
That's take a look how it makes fzf better.

This is how fzf looks in terminal buffer.
Alt Text

This is how fzf looks in popup window.
Alt Text

There are two reason why I prefer popup window.

  1. The position of cursor doesn't move.
  2. Looks more like a "menu".

Configure fzf to use popup window

Thanks to the author of fzf, fzf has supported the popup window.

let g:fzf_layout = { 'window': { 'width': 0.8, 'height': 0.5, 'highlight': 'Comment' } }
Enter fullscreen mode Exit fullscreen mode

When the window entry is a dictionary, fzf will treat the value as the attribute of popup window. Here are some attributes you can set

Required

  • width: float range [0 ~ 1]
  • height: float range [0 ~ 1]

Optional

  • yoffset: float default 0.5 range [0 ~ 1]
  • xoffset: float default 0.5 range [0 ~ 1]
  • highlight: [string]: Highlight group for border
  • border: [string default rounded]: Border style

Avaliable Border Style: rounded: / sharp / horizontal / vertical / top / bottom / left / right

Customize the colors

If you have set colors in FZF_DEFAULT_OPTS, then you don't have to worry this. If not, you can set in shell or neovim.

You can find those elements which can be customized here: https://github.com/junegunn/fzf/blob/a9fba1c8496f7352de55b9fe5f36f23872e5a364/README-VIM.md#L140

shell

export FZF_DEFAULT_OPTS='
    --color fg:14,fg+:3,hl:5,hl+:5,bg:-1,bg+:-1
    --color info:6,prompt:6,spinner:1,pointer:3
'
Enter fullscreen mode Exit fullscreen mode

Well, yes, pass two '--color' to fzf is legal.

neovim
It's a little harder than in shell. You need to set g:fzf_colors

let g:fzf_colors =
  \ { 'fg+':     ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
  \ 'bg+':     ['bg', 'CursorLine', 'CursorColumn'] }

Enter fullscreen mode Exit fullscreen mode

Uh...what are them ?

For example

'bg+':     ['bg', 'CursorLine', 'CursorColumn']
Enter fullscreen mode Exit fullscreen mode

The logic is

  1. FZF will color 'bg+' with the 'bg' of highlight group 'CursorLine'.
  2. If 'CursorLine' doesn't have 'bg', then find in 'CursorColumn' and so on.
  3. If none of them have 'bg', use default value.

If you don't like to use an unrelated highlight group like me, you can create new ones for fzf.

hi! fzf_fg ctermfg=14                                                                                                                                                       
hi! fzf_fgp ctermfg=3                                                                                                                                                       
hi! fzf_hl ctermfg=5                                                                                                                                                        
hi! fzf_hlp ctermfg=5                                                                                                                                                       
hi! fzf_info ctermfg=6                                                                                                                                                      
hi! fzf_prompt ctermfg=6                                                                                                                                                    
hi! fzf_spinner ctermfg=6                                                                                                                                                   
hi! fzf_pointer ctermfg=3
Enter fullscreen mode Exit fullscreen mode
let g:fzf_colors = {                                                                                                                                                        
  \ 'fg':      ['fg', 'fzf_fg'],                                                                                                                                            
  \ 'hl':      ['fg', 'fzf_hl'],                                                                                                                                            
  \ 'fg+':     ['fg', 'fzf_fgp'],                                                                                                                                           
  \ 'hl+':     ['fg', 'fzf_hlp'],                                                                                                                                           
  \ 'info':    ['fg', 'fzf_info'],                                                                                                                                          
  \ 'prompt':  ['fg', 'fzf_prompt'],                                                                                                                                        
  \ 'pointer': ['fg', 'fzf_pointer'],                                                                                                                                       
  \ 'spinner': ['fg', 'fzf_spinner'] }
Enter fullscreen mode Exit fullscreen mode

By the way, you can also do this to the highlight attribute of g:fzf_layout.

FZF will generate the color setting from g:fzf_colors. To check the generated result, use this vim command

:echo fzf#wrap()
Enter fullscreen mode Exit fullscreen mode

If enerything is good, fzf will trans g:fzf_colors to the format of FZF_DEFAULT_OPTS

{'options': '''--color=info:6,spinner:6,hl:5,fg:14,fg+:3,pointer:3,prompt:6,hl+:5''  --expect=ctrl-v,ctrl-x,ctrl-t', 'sink*': func
tion('283'), 'window': {'highlight': 'fzf_popup', 'width': 0.8, 'height': 0.5}, '_action': {'ctrl-v': 'vsplit', 'ctrl-x': 'split',
 'ctrl-t': 'tab split'}}
Enter fullscreen mode Exit fullscreen mode

More

Well, how do I know the color number ?

If you use 256 color, you can reference this cheat sheet: https://jonasjacek.github.io/colors/

Or this tiny script

for i in {0..255}; do
    printf "\x1b[38;5;${i}m%-9s\x1b[0m" "colour${i}"
    if (( $i % 5 == 0 )); then                            
        printf "\n"                                   
    else                                                  
        printf " "                                    
    fi                                                    
done       
Enter fullscreen mode Exit fullscreen mode

Reference

https://github.com/junegunn/fzf/blob/a9fba1c8496f7352de55b9fe5f36f23872e5a364/README-VIM.md#L140
https://jonasjacek.github.io/colors/

Top comments (1)

Collapse
 
ston1x profile image
Nicolai Stoianov

While setting up yet another MacBook Pro, I saw this floating window and I thought it was something wrong with my config files, wanted to go back to the terminal buffer mode. When I finally found this post, I agreed that it's cooler to have popup windows since the cursor doesn't move.. So I'll use it.
Thanks for keeping people up-to-date and not afraid of new things!