Candidates listing engine for vim/nvim built on yaegi on golang.


Keywords
vim, vim-plugin
Install
go get github.com/hrsh7th/vim-candle

Documentation

vim-candle

Any candidates listing engine for vim/nvim built on yaegi.

Status

  • Works
  • Not documented
  • APIs aren't stable
  • Tested only in mac

Requirements

  • vim

    • exists('*win_exeute')
  • nvim

    • exists('deletebufline')

Concept

Performance

  • filtering written in golang.
  • virtual scroll.

Works on vim/neovim

  • use job API only.

Use function

  • because the commands can't pass complex object.

Setting

augroup vimrc
 autocmd!
augroup END

"
" global mapping
"
nnoremap <silent> <Leader>k :<C-u>call candle#mapping#toggle()<CR>
nnoremap <silent> <Leader>n :<C-u>call candle#mapping#action_next('default')<CR>
nnoremap <silent> <Leader>p :<C-u>call candle#mapping#action_prev('default')<CR>

"
" mapping for candle buffer
"
autocmd vimrc User candle#start call s:on_candle_start()
function! s:on_candle_start()
  nnoremap <silent><buffer> k     :<C-u>call candle#mapping#cursor_move(-1)<CR>
  nnoremap <silent><buffer> j     :<C-u>call candle#mapping#cursor_move(1)<CR>
  nnoremap <silent><buffer> K     :<C-u>call candle#mapping#cursor_move(-10)<CR>
  nnoremap <silent><buffer> J     :<C-u>call candle#mapping#cursor_move(10)<CR>
  nnoremap <silent><buffer> gg    :<C-u>call candle#mapping#cursor_top()<CR>
  nnoremap <silent><buffer> G     :<C-u>call candle#mapping#cursor_bottom()<CR>
  nnoremap <silent><buffer> -     :<C-u>call candle#mapping#toggle_select()<CR>
  nnoremap <silent><buffer> *     :<C-u>call candle#mapping#toggle_select_all()<CR>
  nnoremap <silent><buffer> i     :<C-u>call candle#mapping#input_open()<CR>
  nnoremap <silent><buffer> a     :<C-u>call candle#mapping#input_open()<CR>
  nnoremap <silent><buffer> <Tab> :<C-u>call candle#mapping#choose_action()<CR>
  nnoremap <silent><buffer> <C-l> :<C-u>call candle#mapping#restart()<CR>

  nnoremap <silent><buffer> <CR>  :<C-u>call candle#mapping#action('default')<CR>
  nnoremap <silent><buffer> s     :<C-u>call candle#mapping#action('split')<CR>
  nnoremap <silent><buffer> v     :<C-u>call candle#mapping#action('vsplit')<CR>
  nnoremap <silent><buffer> d     :<C-u>call candle#mapping#action('delete')<CR>
endfunction

"
" mapping for candle.input buffer
"
autocmd vimrc User candle#input#start call s:on_candle_input_start()
function! s:on_candle_input_start()
  cnoremap <silent><buffer> <Tab> <Esc>:<C-u>call candle#mapping#choose_action()<CR>
  cnoremap <silent><buffer> <C-y> <Esc>:<C-u>call candle#mapping#action('default')<CR>
  cnoremap <silent><buffer> <C-p> <Esc>:<C-u>call candle#mapping#cursor_move(-1) \| call candle#mapping#input_open()<CR>
  cnoremap <silent><buffer> <C-n> <Esc>:<C-u>call candle#mapping#cursor_move(+1) \| call candle#mapping#input_open()<CR>
endfunction

Recipes

mru files

Recently opened files (and exclude displayed files).

nnoremap <silent>mru_file :<C-u>call candle#start({
\   'mru_file': {
\     'ignore_patterns': map(range(1, tabpagewinnr(tabpagenr(), '$')), { i, winnr ->
\       fnamemodify(bufname(winbufnr(winnr)), ':p')
\     })
\   }
\ })<CR>

mru projects

Recently projects (When choose one project, listing all files).

  nnoremap <silent><Leader>mru_project :<C-u>call candle#start({
  \   'mru_dir': {},
  \ }, {
  \   'action': {
  \     'default': { candle -> [
  \       execute('quit'),
  \       win_gotoid(candle.prev_winid),
  \       candle#start({
  \         'source': 'file',
  \         'params': {
  \           'root_path': candle.get_action_items()[0].path,
  \           'ignore_patterns': ['.git/', 'node_modules'],
  \         }
  \       })
  \     ] }
  \   }
  \ })<CR>

files

All files under specified root.

nnoremap <silent>file :<C-u>call candle#start({
\   'file': {
\     'root_path': 'path to root dir',
\     'ignore_patterns': ['.git/', 'node_modules'],
\   }
\ })<CR>

grep

Invoke ripgrep/ag/pt/jvgrep/grep.

You can specify your custom grep command.

nnoremap <silent>grep :<C-u>call candle#start({
\   'grep': {
\     'root_path': 'path to root dir',
\     'pattern': input('PATTERN: '),
\     'command': [
\       'rg',
\       '-i',
\       '--vimgrep',
\       '--no-heading',
\       '--no-column',
\     ] + map([
\       '.git',
\       '.svn',
\       'image/',
\       'vendor/',
\       'node_modules/',
\     ], { _, v -> printf('--glob=!%s', v) }) + [
\       '-e',
\       '%PATTERN%',
\       '%ROOT_PATH%',
\     ]
\   }
\ })<CR>

grep + vim-qfreplace

Modify grep results with qfreplace.

function! s:qfreplace_accept(candle) abort
  return len(filter(a:candle.get_action_items()), { _, item ->
  \   !has_key(item, 'path') || !has_key(item, 'lnum') || !has_key(item, 'text')
  \ }) == 0
endfunction

function! s:qfreplace_invoke(candle) abort
  call setqflist(map(a:candle.get_action_items(), { _, item -> {
  \   'filename': item.path,
  \   'lnum': item.lnum,
  \   'text': item.text
  \ } }))
  call qfreplace#start('')
endfunction

call candle#action#register({
\   'name': 'qfreplace',
\   'accept': function('s:qfreplace_accept'),
\   'invoke': function('s:qfreplace_invoke'),
\ })

menus

Your custom menu.

nnoremap <silent>menu :<C-u>call candle#start({
\   'item': [{
\     'id': 1,
\     'title': 'PlugUpdate',
\     'execute': 'PlugUpdate'
\   }, {
\     'id': 2,
\     'title': 'Open .vimrc',
\     'execute': 'vsplit $MYVIMRC'
\   }]
\ }, {
\   'action': {
\     'default': { candle -> execute(candle.get_cursor_item().execute) }
\   }
\ })<CR>