Humanity

Edit the world by your favorite way

neosnippet でプレースホルダがある場合は展開よりジャンプを優先させる

今週の Vim の細道見てて neosnippet で困った挙動があるのを思い出して、重い腰上げて help 見て設定したら解消した。 <Tab> にこんな感じで割り当ててたけど

imap <expr> <Tab> neosnippet#expandable_or_jumpable() ?
  \ "\<Plug>(neosnippet_expand_or_jump)" : "\<Tab>"
smap <expr> <Tab> neosnippet#expandable_or_jumpable() ?
  \ "\<Plug>(neosnippet_expand_or_jump)" : "\<Tab>"

これだとプレースホルダーがある時に <Tab> を押すとジャンプよりも展開を優先してしまう。 func<Tab> で展開した後、以下で <Tab> を押すと path が現在のファイルのパスに展開されてしまう (まだプレースホルダがある時は次のプレースホルダに移ってほしい)。

function! s:func(path<Tab>)
  <`0:TARGET`>
endfunction

そこで <Plug>(neosnippet_expand_or_jump) の代わりに <Plug>(neosnippet_jump_or_expand) 使うようにしたら次のプレースホルダへのジャンプを優先してくれるようになって便利。

imap <expr> <Tab> neosnippet#expandable_or_jumpable() ?
  \ "\<Plug>(neosnippet_jump_or_expand)" : "\<Tab>"
smap <expr> <Tab> neosnippet#expandable_or_jumpable() ?
  \ "\<Plug>(neosnippet_jump_or_expand)" : "\<Tab>"

Go とかでも同じように困ってて、 ok が定義されてるので以下で <Tab> を押すと

if v, ok := m["key"]; ok<Tab> {
  <`0:TARGET`>
}

以下のように展開されてしまっていた。

if v, ok := m["key"]; if !ok {
    
} {
    <`0`>
}

これは ok<Tab> が以下に展開されるため。

if !ok {
    <カーソル位置>
}

けどこれもちゃんと以下のようにジャンプを優先してくれるようになった。

if v, ok := m["key"]; ok {
    <カーソル位置>
}