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' } }

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
'

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'] }

Uh...what are them ?

For example

'bg+':     ['bg', 'CursorLine', 'CursorColumn']

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
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'] }

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()

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'}}

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       

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!