cafegale(LeafCage備忘録)

LeafCage備忘録(はてなダイアリー)と統一しました。

zj zk を少しは使える子にする

折り畳みコマンドの中で、使えるか使えないか微妙な位置にあるバインドにzj zk (次の折り畳み・前の折り畳みへジャンプ)がある。
どの辺が微妙かというと、移動コマンドにがあって、それで十分だからだ。
折り畳みのブラウジングに取り立ててzj zk を使うほどでもない。
あと、zj zk でジャンプすると一体自分が今どこに跳んだのか軽く迷子になることも多い。

そんなわけでzj zkは要らない子疑惑が出ているのだが、もしかして]z [zの役割も持たせたら少しは使えるのではないかということで改造してみた。
(ちなみに]z [z は大きな折り畳みの中で移動したい時に使うバインドで、zj zk に比べると遙かに役に立つ)

nnoremap <silent>zj :<C-u>call <SID>smart_foldjump('j')<CR>
nnoremap <silent>zk :<C-u>call <SID>smart_foldjump('k')<CR>

function! s:smart_foldjump(direction) "{{{
  if a:direction == 'j'
    let [cross, trace, compare] = ['zj', ']z', '<']
  else
    let [cross, trace, compare] = ['zk', '[z', '>']
  endif

  let i = v:count1
  while i
    let save_lnum = line('.')
    exe 'keepj norm! '. trace
    let trace_lnum = line('.')
    exe save_lnum

    exe 'keepj norm! '. cross
    let cross_lnum = line('.')
    if cross_lnum != save_lnum && eval('cross_lnum '. compare. ' trace_lnum')
      \ || trace_lnum == save_lnum
      let i -= 1
      continue
    endif

    exe trace_lnum
    let i -= 1
  endwhile
  mark `
  norm! zz
endfunction
"}}}

これでzj zkには本来の役割である次/前の折り畳みにジャンプすることに加えて、現在折り畳み内の末尾/先頭にジャンプする機能が追加された。
あと、おまけでジャンプ後に常にzzされることで周辺を見渡せて少しは迷子になる要素を減らした。
これでもしかしたら少しは使える子になるかも知れない。