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.

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{"
  • 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 }. – Jeff Terrell Ph.D. 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! – Jeff Terrell Ph.D. 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
0

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>

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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