僕のYak Shavingは終わらない

車輪の再発明をやめたらそこには壮大なYakの群れが

今しているneocomplcache + neosnippetの設定の自分的おすすめ

※この記事の最後の設定をすることによって以下が実現します。

  • neocomplcacheの出す補完候補をTABで送れる、Shift + TABで戻れる
  • 入力した文字に対してSnippetの候補がある場合はCtrl+kで展開できる(TABを押したときはスルーして下の候補に移る)
  • Snippet展開後はTABを使って次の入力タグへジャンプできる
  • Snippet展開中において、一度インサートモードから抜けてから、
再びインサートモードになったときでも、未入力のタグがあるならTABでそこまで移動できる
  • 特に移動するタグがない場合は、インサートモード時に入力したTABは普通にインデントを挿入するためのTABとして振る舞う

neosnippet#expandable() の仕様が変わってた - 永遠に未完成
であるようにneosnippetの関数の仕様が変わっていたため
Vimのsnippetについてあまり知らなかったので設定してみたら便利過ぎてつらい - 僕の車輪の再発明
にある設定も書き換えました。

また本家のREADMEもすでに以下のように修正されているようです。
Shougo/neosnippet · GitHub

" Plugin key-mappings.
imap <C-k>     <Plug>(neosnippet_expand_or_jump)
smap <C-k>     <Plug>(neosnippet_expand_or_jump)

" SuperTab like snippets behavior.
imap <expr><TAB> neosnippet#expandable() <Bar><bar> neosnippet#jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : pumvisible() ? "\<C-n>" : "\<TAB>"
smap <expr><TAB> neosnippet#expandable() <Bar><bar> neosnippet#jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"

" For snippet_complete marker.
if has('conceal')
  set conceallevel=2 concealcursor=i
endif

で、ここからが本題なのですが自分としては、neocomplcacheに関して以下のような設定をしていました。

" <TAB>: completion.                                         
inoremap <expr><TAB>  pumvisible() ? "\<C-n>" : "\<TAB>"   
inoremap <expr><S-TAB>  pumvisible() ? "\<C-p>" : "\<S-TAB>" 

つまり補完候補が出ているときにTABを押すことによって次の候補の選択ができるという感じです。

で、このようにしている場合は、以下のようにSnippetの候補があると、出てきた一番最初の候補をいきなり展開してしまうことになります。
f:id:kazuph1986:20130119192804p:plain

これを避けるにはCtrl+nで移動するようにしないといけないのですが、正直めんどうです。

今までの用にTABによって上下の移動を行いたい。

ということで、neosnippetの設定を以下のように修正しました。

" <TAB>: completion.                                         
" inoremap <expr><TAB>  pumvisible() ? "\<C-n>" : "\<TAB>"   
inoremap <expr><S-TAB>  pumvisible() ? "\<C-p>" : "\<S-TAB>" 

" Plugin key-mappings.
imap <C-k> <Plug>(neosnippet_expand_or_jump)
smap <C-k> <Plug>(neosnippet_expand_or_jump)

" SuperTab like snippets behavior.
imap <expr><TAB> neosnippet#jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : pumvisible() ? "\<C-n>" : "\<TAB>"
smap <expr><TAB> neosnippet#jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"

" For snippet_complete marker.
if has('conceal') set conceallevel=2 concealcursor=i
endif

こうすることによって、snippetの候補間をTABで移動し、展開したい場合はCtrl+kで展開し、スニペットのジャンプはTABで移動できるようになりました。

追記(2013/06/02)

そういえば未入力のタグがある状態で、neoconの補完候補が出てるときにを押してしまうと次のタグへ飛んでしまって、Ctrl+nしないといけなくてめんどくさいなぁ、って思ってたら以下のように変更したらできたので、これで割りと満足。

" <TAB>: completion.
" inoremap <expr><TAB>  pumvisible() ? "\<C-n>" : "\<TAB>"
inoremap <expr><S-TAB>  pumvisible() ? "\<C-p>" : "\<S-TAB>"

" Plugin key-mappings.
imap <C-k>     <Plug>(neosnippet_expand_or_jump)
smap <C-k>     <Plug>(neosnippet_expand_or_jump)

" SuperTab like snippets behavior.
" imap <expr><TAB> neosnippet#jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : pumvisible() ? "\<C-n>" : "\<TAB>"
imap <expr><TAB> pumvisible() ? "\<C-n>" : neosnippet#jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"
smap <expr><TAB> neosnippet#jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"

" For snippet_complete marker.
if has('conceal')
  set conceallevel=2 concealcursor=i
endif