I love vim's { and } motions, which jump to the next/previous empty line.

I've recently been using folding more, and while that's a great feature, it doesn't do what I would expect with respect to the { and } motions. If there is an empty line in the fold, then { and } will land there, thus opening the fold.

Is there a way to remap { and } to skip folds altogether? That is, even if there were empty lines inside a fold, { and } would not stop there but would seek the next unfolded empty line? This would fit better with what I would expect.


First question:

You must remove block from the default value of 'foldopen':

set foldopen-=block

See :help 'foldopen'.

Second question:

You can try these mappings

nnoremap <expr> } foldclosed(search('^$', 'Wn')) == -1 ? "}" : "}j}"
nnoremap <expr> { foldclosed(search('^$', 'Wnb')) == -1 ? "{" : "{k{"
  • This is much better, thanks! But it's not quite what I asked. I want to skip folds altogether, such that even if there is an empty line, the cursor doesn't stop there upon a { or }. Nov 7 '14 at 3:51
  • My answer addressed your first question. If you have multiple questions ask them separately. If they are all linked by a common subject, ask about that subject instead.
    – romainl
    Nov 7 '14 at 8:12
  • @JeffTerrellPh.D. please see my edit.
    – romainl
    Nov 7 '14 at 8:55
  • Thanks for the followup. The nnoremap commands make fewer folded empty lines catch the cursor, but if there are two empty lines in a single fold, the second will still catch the cursor. I want to skip all folded empty lines, not just some. Also, I only ever intended to ask one question. The second question above was intended to clarify the intent of the first question, not pose a new question. Thanks! Nov 7 '14 at 15:15
  • You currently have two questions on superuser which should have been asked together.
    – romainl
    Nov 7 '14 at 15:23

This method takes into account multiple consecutive folds.

function! s:SkipFold(direction) abort
  let l:currentLine = line('.')
  while foldclosed(l:currentLine) != -1
    let l:currentLine = search('^$', (a:direction ? 'Wn' : 'Wnb'))
    if l:currentLine == 0
      if a:direction
        call cursor(line('$'), strlen(getline(line('$'))))
        call cursor(1, 1)
    call cursor(l:currentLine, 0)

nnoremap <silent>} }:call <SID>SkipFold(1)<cr>
nnoremap <silent>{ {:call <SID>SkipFold(0)<cr>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.