藻ログ

都会でOLをしています

unite.vim, ctrlp.vim から neovim と denite.nvim へ引越した

だいぶ前に以下の環境を denite.nvim で統一するように引越した.
wakame.hatenablog.jp
プラグインマネージャはdein.vim に引越した.
wakame.hatenablog.jp

neovim

https://neovim.io/

install

各OSへの入れ方は以下.
Installing Neovim · neovim/neovim Wiki · GitHub

python3 support

dein/deoplete など一部のプラグインは python3 に依存しているので,python3 のパスと pipのneovim パッケージが必要になる.
:echo has('python3') で 1 が返ってくれば python3 が見えている.:CheckHealth すれば,今のpython3 周りの環境がどうなっているか確認できる.
nvimから読むpython3のパスを指定したいときは

let g:python3_host_prog = '/path/to/python3'

の設定を追加しておく.後は,

$ pip3 install neovim

ののち,nvimで以下を実行する.

:UpdateRemotePlugins

切替え先のpythonごとにpipでneovimを入れたりpython3がないといか言われるのは辛いので,
pyenvなどでpythonを切り替える場合は python3_host_prog を設定しておく.

config ファイル

nvim では ~/.config 以下*1に設定ファイルを置くようになっている.

~/.vimrc ~/.config/nvim/init.vim
~/.vim/ ~/.config/nvim/

とりあえずvimの設定を維持しつつ以下のような感じに.

~/.config/nvim
├── colors
├── dein
├── init.vim # vimrc
├── snippets # 自分のスニペット入れ
└── userautoload # 自分の設定ファイル
    ├── dein #deinの設定
    ├── init 
    └── plugins

if has('nvim') で分岐させることもできるが,自分はvimとneovimの設定ファイルは完全に分けている*2.

denite.nvim

github.com

Dark powered asynchronous unite all interfaces for Neovim/Vim8

暗黒の力を手にいれた unite らしい.ドキュメントはあまりないので,:h denite してちょっとずつ調べる.

plugins.toml

[[plugins]]
repo = 'Shougo/denite.nvim'
on_cmd = 'Denite'
if = 'has("nvim")'
hook_source = 'source ~/.config/nvim/userautoload/plugins/plugins-denite.vim'

plugins-denite.vim

見た目をちょっと変更

デフォルトが # なのがちょっと落ち着かないので>へ変更.

call denite#custom#option('default', 'prompt', '>')
unite っぽいキーバインドに近づける
" denite/insert モードのときは,C- で移動できるようにする
call denite#custom#map('insert', "<C-j>", '<denite:move_to_next_line>')
call denite#custom#map('insert', "<C-k>", '<denite:move_to_previous_line>')

" tabopen や vsplit のキーバインドを割り当て
call denite#custom#map('insert', "<C-t>", '<denite:do_action:tabopen>')
call denite#custom#map('insert', "<C-v>", '<denite:do_action:vsplit>')
call denite#custom#map('normal', "v", '<denite:do_action:vsplit>')

" jj で denite/insert を抜けるようにする
call denite#custom#map('insert', 'jj', '<denite:enter_mode:normal>')

なんとなく雰囲気がわかってきた....*3
あとは以下の環境を順番に引越したい.
vimでソースをもりもり読む - 藻ログ

内部で高速 grep を使う

unite のときは ag を呼び出していたが,最近はたくさん高速grepが出ていてどれが良いのかわからなくなってきた *4.

高速 grep シリーズ

ag https://github.com/ggreer/the_silver_searcher
highway https://github.com/tkengo/highway
ripgrep https://github.com/BurntSushi/ripgrep
sift https://github.com/svent/sift
pt https://github.com/monochromegane/the_platinum_searcher
ucg https://github.com/gvansickle/ucg

とりあえず,ag よりかなり速いらしい ripgrep を使うようにしてみた*5
ripgrep is faster than {grep, ag, git grep, ucg, pt, sift} - Andrew Gallant's Blog

関係ないけどインタラクティブフィルタシリーズもたくさんあってわかんなくなってきた.自分はpercolだったけど最近pecoに乗り換えた.
おい、peco もいいけど fzf 使えよ - Qiita

grep と ファイル検索をrgで置き換えるように.

if executable('rg')
  call denite#custom#var('file_rec', 'command',
        \ ['rg', '--files', '--glob', '!.git'])
  call denite#custom#var('grep', 'command', ['rg'])
endif

ファイル絞り込み検索

もともと unite でなく ctrlp.vim を使っていたが,denite.nvim はかなり高速になっているという話があったので,ctrlpをやめて全部deniteにすることにした.

" ctrlp
nnoremap <silent> <C-p> :<C-u>Denite file_rec<CR>

:Denite file_rec ${dir} で引数なしだとカレントディレクトリ以下の再帰検索を絞り込みながら行える.
検索除外したいパターンを matcher_ignore_globs を上書きして登録しておく.denite のmatcher は matcher_fuzzy (あいまい検索)で,複数単語での検索に便利.matcherについては denite のヘルプが詳しい

" customize ignore globs
call denite#custom#source('file_rec', 'matchers', ['matcher_fuzzy','matcher_ignore_globs'])
call denite#custom#filter('matcher_ignore_globs', 'ignore_globs',
      \ [
      \ '.git/', 'build/', '__pycache__/',
      \ 'images/', '*.o', '*.make',
      \ '*.min.*',
      \ 'img/', 'fonts/'])

高速 grepシリーズ 以外に 高速matcher シリーズもある.denite では matcher_cpsm が使える.
mattn.kaoriya.net

全文検索

諸事情あって手元では unite と denite がまだ共存してるので,uniteを, deniteを; にしている.

" カーソル以下の単語をgrep
nnoremap <silent> ;cg :<C-u>DeniteCursorWord grep -buffer-name=search line<CR><C-R><C-W><CR>
" 普通にgrep
nnoremap <silent> ;g :<C-u>Denite -buffer-name=search -mode=normal grep<CR>

その他

ふつうの検索

ためしにファイル内検索を denite のに置き換えた. /をmapするのは激しいが慣れれば意外と快適だった.普通の検索で順番にsearch するのではなく,絞り込みながらsearchできる.

" search
nnoremap <silent> / :<C-u>Denite -buffer-name=search -auto-resize line<CR>

閉じたバッファまた開く

" resume previous buffer
nnoremap <silent> ;r :<C-u>Denite -buffer-name=search -resume -mode=normal<CR>

vimrc検索する

:vs が.....

nnoremap <silent> ;v :<C-u>Denite -buffer-name=search file_rec:~/.config/nvim/<CR>

タグジャンプ

最近denite-gtags が出てた.
https://github.com/ozelentok/denite-gtags

noremap [denite-gtags]  <Nop>
nmap ,t [denite-gtags]
nnoremap [denite-gtags]d :<C-u>DeniteCursorWord -buffer-name=gtags_def -mode=normal gtags_def<CR>
nnoremap [denite-gtags]r :<C-u>DeniteCursorWord -buffer-name=gtags_ref -mode=normal gtags_ref<CR>
nnoremap [denite-gtags]c :<C-u>DeniteCursorWord -buffer-name=gtags_context -mode=normal gtags_context<CR>

05/08 追記

global --from-here (contextでのref/defジャンプ)が早速実装されていました(感謝)

まとめ(でもない)

ドキュメントが少なくて難しかった.最近はgithubから検索オプションを駆使して他人のソース読んでることが多い.

*1:$XDG_CONFIG_HOME/nvim 以下,が正しい

*2:なんとなく生まれ変わったきもちで

*3:ドキュメントが少なくてdocを延々と読んでいた

*4:全部試せばいいといえばそうなのだが...

*5:まともなベンチマークは取ってないが,手元では確かにagよりかなり速い