gitneovimfzfneovim-pluginvim-fzf

fzf.vim - How to create git branch command with git log preview?


I'm trying to create neovim fzf command FzfGBranches to use git branch -a as input, and use git log --oneline as fzf preview:

command! -bang -nargs=0 FzfGBranches
            \ call fzf#vim#grep(
            \ "git branch -a", 1,
            \ fzf#vim#with_preview({
            \   'options': [
            \       '--prompt', '*Branches> ',
            \       '--bind', 'ctrl-d:page-down,ctrl-u:page-up',
            \   ],
            \   'placeholder': "echo {} | rev | cut -d'*' -f1 | rev | git log --oneline --graph --date=short --color=always --pretty=\"format:%C(auto)%cd %h%d %s\"",
            \ }), <bang>0)

When call FzfGBranches command, it show up and seems good, but when I press up/down keys, the preview (on the right side) does not refresh. See below screenshot:

enter image description here

How should I specify the --preview option in fzf.vim?


Solution

  • tl;dr

    1. Simplify this with fzf#run
    2. Make your git log command accept the branch selected from FZF

    Deets

    First off, placeholder is undocumented, so I didn't spend time down this path. Conceptually, this is possible, so there has to be a simpler way. Enter fzf#run. This is a thin wrapper around the actual FZF tool. It only requires a source, sink, and options. Most of the magic would be happening in your options string.

    Secondly, your last segment in the placeholder — to show a log of the changes in the branch — will always show the log of the branch you're currently on.

    git log
      \ --oneline
      \ --graph
      \ --date=short
      \ --color=always
      \ --pretty=\"format:%C(auto)%cd %h%d %s\"
    

    What you want to do is to pipe the current branch highlighted in FZF through to your git log command. Something along the lines of

    [alias]
      branch-name = rev-parse --abbrev-ref HEAD
      smart-log = !git log {1:-$(git branch-name)}
    

    Now, we can pipe the branch name from stdin into the git command.

    $ echo your-branch-name | git smart-log
    

    With this working, we are ready to build a working command in Vim

    command! -bang -nargs=0 FzfTBranches
                \ call fzf#run({
                \   'source': "git branch -a",
                \   'sink': 'git checkout',
                \   'down': '40%',
                \   'options': '--prompt="*Branches> " --bind="ctrl-d:page-down,ctrl-u:page-up" --preview="echo {} | sed \"s/\*//\" | sed \"s/^ *//;s/ *$//\" | xargs git smart-log"'
                \ })
    

    Breaking down the --preview segments…