2

I know how to delete blank lines with commands.

We may visually select the text block first, and then run commands like s/^$/d to delete all blank lines or %s/^\(\s*\n\)\+/\r to keep only one blank lines.

Can I perform the above using motion, so that I can just press some keys to perform the "delete-motion" without having to enter command-line mode?

Community
  • 1
  • 1
ying17zi
  • 492
  • 6
  • 15
  • 1
    Well, you can make a key mapping to that ex-command. – doubleDown Jul 03 '13 at 07:42
  • 1
    `d/^.` will delete from here until the next non-blank line, or if you've already done that search before, then simply `dn`, but "here" needs to be a sensible value. Will that do? – sh1 Jul 04 '13 at 13:59
  • @sh1, Thank you! Then for deleting backwards `d/.$`! Probably I would have not asked this question if I knew `d/^.`. :) – ying17zi Jul 04 '13 at 14:11
  • @Hongying, unfortunately the reverse pattern seems to eat the last character of the non-empty line. I thought it would be `d?^\@!$`, but no such luck. – sh1 Jul 04 '13 at 14:19

4 Answers4

3

Creating a new operator for this is a good idea, but it can be tough to get right.

The operator-user plugin makes that task easy.

Once you have installed operator-user, all you need to do is add two lines to your vimrc, one to define the operator, and one to define your personal mapping to it:

call operator#user#define_ex_command('delete-blanks', 'g/^$/d')
map _ <Plug>(operator-delete-blanks)

This creates a new operator _. Change it to whatever you like best.

Now you can do _3} or _G or _23k to delete the blank lines contained in the motion. Text objects _a}, doubling of the operator 4__, and Visual mode V7j_ are all also supported, as befits a proper operator.

glts
  • 21,808
  • 12
  • 73
  • 94
2

You could use operatorfunc. For example:

Define a function like this in your .vimrc:

function! DeleteEmptyLines(type)
    if a:type == 'line'
        silent execute ".,'\"g/^$/d"
    endif
endfunction

And a mapping:

nnoremap <silent> ,d :set operatorfunc=DeleteEmptyLines<CR>m"g@

,d performs now just like an operator and accepts a (line-based) motion. You can, for example, insert ,d5j or ,dG in normal mode to delete empty lines in the next 5 lines or to the end of file.

You can find more information on how to extend this functionality here: http://learnvimscriptthehardway.stevelosh.com/chapters/33.html and of course::h operatorfunc and :h map-operator.

From :h map-operator:

"An operator is used before a {motion} command. To define your own operator you must create mapping that first sets the operatorfunc option and then invoke the g@ operator. After the user types the {motion} command the specified function will be called."

qzr
  • 722
  • 1
  • 6
  • 13
  • Thanks! It seems promising! (`,dG` works as we expect, but neither `,d` nor `,d5j` works. They just work like `d` and `d5j`.) – ying17zi Jul 04 '13 at 12:13
  • I probably had my jumplist mixed up when I was testing it. It seems like `10j` does not count as a "jump" and therefore can't be accessed by `'[` and `']`. You should be able to do it by setting a mark before executing `g@` and then using this mark in the range to the global command => see my updated post. – qzr Jul 04 '13 at 13:42
  • Ok, somehow it seems to work fine if the direction is upwards. Downwards movement doesn't work however. Maybe somebody else could help here. May this be a bug in vim? – qzr Jul 04 '13 at 15:12
1

well, using motions I don't think you can only delete blank lines.

But you can do it using a mapping:

:nmap <Leader>db :g/^$/d<CR>

The motions help you move one word, one paragraph away... And before the motion you use an operator (d, c...).

So what you'd want is to create a new operator that deletes blank lines within the given motion (or selection). What I gave you is close to that, but you'd have to invent a new operator (and I don't think there's many unbound keys left).

Other vimmers may correct me, but I think the easiest way to create such operators would be to define a map for each motion and bind it to a function.

zmo
  • 24,463
  • 4
  • 54
  • 90
  • How does Vim let motion and build in commands work together, e.g., `d}`? Couldn't we define some key strokes like that? – ying17zi Jul 03 '13 at 11:56
-1

There isn't a motion that can combine with a delete such that it only deletes blank lines. A motion denotes all the text between the initial and final position, without any gaps. That includes motions which search using regular expressions.

Kaz
  • 55,781
  • 9
  • 100
  • 149