3

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.

2 Answers 2

8

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{"
7
  • 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, 2014 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, 2014 at 8:12
  • @JeffTerrellPh.D. please see my edit.
    – romainl
    Nov 7, 2014 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, 2014 at 15:15
  • You currently have two questions on superuser which should have been asked together.
    – romainl
    Nov 7, 2014 at 15:23
1

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('$'))))
      else
        call cursor(1, 1)
      endif
      break
    endif
    call cursor(l:currentLine, 0)
  endwhile
endfunction

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .