none
none

Reputation: 12087

delete from end of lines using block select in vim

I'm getting an unusual behavior when I try to delete from end of lines using block selection in vim.

So let's say I have a text as such:

delete this char:x
and this:x
also this:x
and then this:x
lastly this:x

If I want to append y to every line I can:

in order to get:

delete this char:xy
and this:xy
also this:xy
and then this:xy
lastly this:xy

but if I try to delete x in the last step instead of appending I would expect to get:

delete this char:
and this:
also this:
and then this:
lastly this:

although I end up with:

delete this char:
and this:x:
also this:x:
and then this:x:
lastly this:x:

As far as I understand it appends the last char in the first line to all other lines (in this case :) rather than deleting the missing ones (in this case x).

I can do this with macros or substitutes but I don't quite understand the rationale behind such behavior. Is there a way I can do this with block selection?

Upvotes: 12

Views: 4678

Answers (4)

Peter Rincker
Peter Rincker

Reputation: 45087

If I have a small number of lines I typically do Abackspaceesc. Then repeatedly do j. until done. Not the fastest way but easy to remember.

For a large amount of lines I typically visually select the lines via V then do a substitution or a normal command on the range.

:'<,'>s/.$//
:'<,'>norm $x

Note: you do not have to type '<,'>. It will be inserted automatically when you start a command when some text is visually selected.

The substitution command is pretty simple, match the last character (.$) and then replace it with nothing.

The normal command is just how you would delete the last character in normal mode via $x for a single line except it will apply it to each line in the range.

For more help see:

:h range
:h :s
:h :norm

Upvotes: 7

dash-tom-bang
dash-tom-bang

Reputation: 17843

Have you tried :{range}normal? This should work:

:'<,'>normal $x

(The '<,'> bit is filled in for you when you type :.)

Upvotes: 13

Kent
Kent

Reputation: 195029

as you said yourself, to achieve your goal, there are other ways, in fact better ways to go. :s or q(macro) or :g/.../norm $x. :s/.$//g is pretty straightforward.

Ctrl-V is not suitable for this job. As for its name: Visual BLOCK. You want to remove the last x, and they (only x) are not in a block.

However if you really want to stick with ctrl-v, you have to do some extra work, to make those 'x' in a block. If you have Align plugin installed, you could :

Select (V) all lines you want to do the trick,

<leader>t:

then your text looks like:

delete this char : x
and this         : x
also this        : x
and then this    : x
lastly this      : x

Ctrl-V to remove x, you should know how to do it.

then

:%s/ *:/:/g

to remove padded spaces before ':'

However I don't think it is a good way to go.

Upvotes: 2

user823738
user823738

Reputation: 17521

$ C-v 4j x

  1. go to end of line with $
  2. toggle visual block C-v
  3. go down (in your case 4x) 4j
  4. delete that stuff with x

Edit: (reacting on your comment for arbitrary indentation)

That can be done with simple macro. Macros are not so hard as you can think:

  1. start recording a macro, we will name it 'a', so qa
  2. go to the end of line $
  3. delete one character x
  4. go down by one line with j
  5. end our macro q

Now apply our macro: 20@a - will do the same you did while you was recording the macro, 20x.

Upvotes: 6

Related Questions