Skip to content
Junegunn Choi edited this page Mar 30, 2024 · 22 revisions

Automatically install missing plugins on startup

autocmd VimEnter *
  \  if len(filter(values(g:plugs), '!isdirectory(v:val.dir)'))
  \|   PlugInstall --sync | q
  \| endif

H to open help docs

function! s:plug_doc()
  let name = matchstr(getline('.'), '^- \zs\S\+\ze:')
  if has_key(g:plugs, name)
    for doc in split(globpath(g:plugs[name].dir, 'doc/*.txt'), '\n')
      execute 'tabe' doc
    endfor
  endif
endfunction

augroup PlugHelp
  autocmd!
  autocmd FileType vim-plug nnoremap <buffer> <silent> H :call <sid>plug_doc()<cr>
augroup END

gx to open GitHub URLs on browser

Press gx to open the GitHub URL for a plugin or a commit with the default browser.

function! s:plug_gx()
  let line = getline('.')
  let sha  = matchstr(line, '^  \X*\zs\x\{7,9}\ze ')
  let name = empty(sha) ? matchstr(line, '^[-x+] \zs[^:]\+\ze:')
                      \ : getline(search('^- .*:$', 'bn'))[2:-2]
  let uri  = get(get(g:plugs, name, {}), 'uri', '')
  if uri !~ 'github.com'
    return
  endif
  let repo = matchstr(uri, '[^:/]*/'.name)
  let url  = empty(sha) ? 'https://github.com/'.repo
                      \ : printf('https://github.com/%s/commit/%s', repo, sha)
  call netrw#BrowseX(url, 0)
endfunction

augroup PlugGx
  autocmd!
  autocmd FileType vim-plug nnoremap <buffer> <silent> gx :call <sid>plug_gx()<cr>
augroup END

Browse help files and README.md

Requires fzf.

function! s:plug_help_sink(line)
  let dir = g:plugs[a:line].dir
  for pat in ['doc/*.txt', 'README.md']
    let match = get(split(globpath(dir, pat), "\n"), 0, '')
    if len(match)
      execute 'tabedit' match
      return
    endif
  endfor
  tabnew
  execute 'Explore' dir
endfunction

command! PlugHelp call fzf#run(fzf#wrap({
  \ 'source': sort(keys(g:plugs)),
  \ 'sink':   function('s:plug_help_sink')}))

A more sophisticated version with preview support:

function! s:plug_help_source()
  let lines = []
  let longest = keys(g:plugs)->map({_, v -> strlen(v)})->max()
  for [name, plug] in items(g:plugs)
    let matches = []
    for pat in ['doc/*.txt', 'README.md']
      let match = get(split(globpath(plug.dir, pat), "\n"), 0, '')
      if len(match)
        call add(lines, printf("%-"..longest.."s\t%s\t%s", name, fnamemodify(match, ':t'), match))
      endif
    endfor
  endfor
  return sort(lines)
endfunction

command! PlugHelp call fzf#run(fzf#wrap({
  \ 'source': s:plug_help_source(),
  \ 'sink':   { line -> execute('tabedit '..split(line)[-1]) },
  \ 'options': ['--reverse', '--delimiter=\t', '--with-nth=1..2', '--preview', 'bat --style=numbers --color=always {-1}']}))

Extra key bindings for PlugDiff

(suggested by @sodapopcan)

  • J / K to scroll the preview window
  • CTRL-N / CTRL-P to move between the commits
  • CTRL-J / CTRL-K to move between the commits and synchronize the preview window
function! s:scroll_preview(down)
  silent! wincmd P
  if &previewwindow
    execute 'normal!' a:down ? "\<c-e>" : "\<c-y>"
    wincmd p
  endif
endfunction

function! s:setup_extra_keys()
  nnoremap <silent> <buffer> J :call <sid>scroll_preview(1)<cr>
  nnoremap <silent> <buffer> K :call <sid>scroll_preview(0)<cr>
  nnoremap <silent> <buffer> <c-n> :call search('^  \X*\zs\x')<cr>
  nnoremap <silent> <buffer> <c-p> :call search('^  \X*\zs\x', 'b')<cr>
  nmap <silent> <buffer> <c-j> <c-n>o
  nmap <silent> <buffer> <c-k> <c-p>o
endfunction

augroup PlugDiffExtra
  autocmd!
  autocmd FileType vim-plug call s:setup_extra_keys()
augroup END

Plugin completion using VimAwesome

https://gist.github.com/junegunn/5dff641d68d20ba309ce