I'm trying to do two things involving blank lines (empty lines or lines with only white-space on them).

  1. Move to the next blank line (or EOF if none)
  2. Filter (using !) to the next blank line (or EOF if none)

Number 1 is similar to }, but allows for lines with only white-space. I thought number 2 would be easy if I could do number 1. But unfortunately, reality has intervened.

Here is the .vimrc that I have so far to test my mapping (using nl -ba as a test filter):

set nocompatible
set list       " to distinguish empty lines from blank lines
map } :<C-u>call search('^\s*$\\|\%$', 'W')<CR>
map - !}nl -ba<CR>}

Creating a test file with some data, some empty lines and some white-space only lines, I notice the following:

  1. My new } motion command seems to work just as I would like.
  2. The filter command (-) works fine, except if the last line of the file has only a single character on it, which is treated as its own independent "paragraph" and not included along with the previous lines. This is unlike the way the } motion command works.
  3. However, the filter command hangs for many seconds (or indefinitely?) on some machines which are running different versions of vim 7.4 (I never did get an opportunity to isolate this hanging issue and it ended up disappearing in my solution below).

I've tried various combinations of map, noremap, etc. but that doesn't seem to help, except to prevent my } motion mapping from being recognized inside the filter mapping, which is obviously not what I want.

So, how can I map } to also find blank lines and still use it properly in a filter (!) command. Hopefully the changes will also avoid the hanging that I'm experiencing on some machines (which obviously makes those solutions unusable). Lacking the ability to make } work reliably inside filter commands, I would be willing to use something else in those filter commands that would accomplish what I'm looking for.

  • I think (but haven't tried) you merely need to add a v to this map: map - !v}nl -ba<CR>}. map - !V}nl -ba<CR>} should also work
    – Mass
    Commented Jul 25, 2018 at 14:11

2 Answers 2


I ended up using something like this solution:

map } :<C-u>call search('^\s*$\\|\%$', 'W')<CR>
map - mx}!'x nl -ba<CR>}
map = mx}my!'x nl -ba<CR>'y

Note: These two solutions use different ways of moving the cursor after the operation. Different commands may need different techniques, depending on how the external command in question modifies the block of lines being filtered through it (e.g. does it return fewer lines than it was given as input?).

I ended up exploring different motion commands, based on the suggestion from @Mass in his comments to the question. The relevant information is in the motion.txt help page.


You should also be able to do this in command mode where it might be more readable:

nnoremap - /\v^\s*$<BAR>%$<CR>
nnoremap = :.,/\v^\s*$<BAR>%$/ ! nl -ba<CR>
  • The movement command works just fine, but the filter doesn't also move the cursor past the filtered data (so I can filter the next paragraph).
    – jrw32982
    Commented Jul 26, 2018 at 11:26
  • Does an additional '] at the end fix it?
    – Lucas
    Commented Jul 26, 2018 at 12:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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