Reputation: 12087
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:
4j
$
A
y
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
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
Reputation: 17843
Have you tried :{range}normal
? This should work:
:'<,'>normal $x
(The '<,'>
bit is filled in for you when you type :.)
Upvotes: 13
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
Reputation: 17521
$
C-v
4j
x
$
C-v
4j
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:
qa
$
x
j
q
Now apply our macro: 20@a
- will do the same you did while you was recording the macro, 20x.
Upvotes: 6