Deleting to the beginning of line when line starts with whitespace characters - vim

I usually use
d^ to delete to the beginning of line.
But if the line starts with space or tabulations, the deletion does not go all the way to start of line.
Example:
foo foo
The line starts with two spaces, and the cursor is between the two "foo"
d^ deletes the first foo, but not the two spaces before it.
It is obviously useful most of the time, but what if I do want to delete everything?

You can use d0 to delete to the real beginning of the line.

as #GWW mention and:
use c0 to delete to real begginning of the line and go insert mode.
c^ - delete to first non-blank character and go insert mode.

You can also use | to goto column 0 of a line, which can be using in combination with d as d| to delete to column 0 of a line.
Source: http://hea-www.harvard.edu/~fine/Tech/vi.html

If the cursor in the middle of an empty space between beginning of line and the first character of the line, then you can delete the whole spaces with diw, that means: delete inner word. In this case word is the spaces.

Related

delete first 2 white spaces from start of line in gvim

I am reading a file which has 2 unwanted spaces in each line.
import uvm_pkg::*;
`include "uvm_pkg.svh"
And it continues till last line
How to delete first 2 white spaces in each line in gvim?
Enter :%s/^ //, which substituttes 2 leading whitespaces (^ ) with nothing (the nothing between the second and third /) on every line (%).
position cursor at line 1, column 1 (press gg0)
enter visual block mode (Ctrl+v)
select first two columns of all lines by moving the cursor to the bottom and one to the right (Gl)
delete selection (x)
:%s/^ //
substitutes the two first leading spaces on every line of the buffer with nothing, effectively deleting them.
Note that, in this case, you don't even need the replacement part because it is implied: :%s/^ .
See :help :s and :help :range for the %.

How do I delete from immediately AFTER cursor to first non-whitespace character in vim?

I'm looking for a command to delete from the position after the cursor to the first non-whitespace character on the same line. I've tried several possibilities, and nothing seems to work. d2w comes closest, but deletes the character under the cursor.
e.g. I want to change this code
$obj->
set('foo')->
and('bar');
(note the leading spaces!) to
$obj->set('foo')->and('bar');
So I place the cursor on the first >, hit d2w, and end up with $obj-set('foo')-> on a single line. Note the missing '>'.
What's the answer?
Thanks!
J joins the current line with next line, but with a space, but deletes leading spaces in next line.
gJ joins the current line with next line without space, but if second line contained leading space, it would be kept as it is. You can add a count before it to join n lines, like 3gJ
Example:
`3gJ` - join three consecutive lines without spaces.
In your case,
Jx - Join two lines with space and delete space
Give this command two times, like JxJx for your case.
You can't give 2Jx, since J and x are two operators and 2 will be taken only for J alone. Further, gJ won't work in your case if second line contains leading spaces.

How do I delete the last character in each line using vim

I have a file:
12345a
123456b
1234567c
12345678d
123456789e
How do I delete the last character in each line.
And the file will be
12345
123456
1234567
12345678
123456789
You could use :%s/.\{1}$// to delete 1 character off the end of each line.
:%normal $x
: puts you into command line mode
% is a range representing the entire file
normal says we're running a normal mode command
$x deletes the last character in the line
Some overlap with other answers, but to me this one reads most simply.
TLDR: :%s/.$//
For explanation and more examples read on.
:%s/.$//
deletes any character at the end of all lines (or better to say: replaces any character at the end with nothing)
s = substitute command
. = any character
if you want to delete . (not any character) use \.$ instead of .$
:'<,'>s/.$//g
deletes any character at the end of all lines of the current selection
'<,'> = current selection (you get this by SHIFT+V, then selecting the lines, then :)
:%s/;$//
deletes ; at the end of all line
useful if you copy & paste code from a language that needs ; to one that doesn't
Use :g command:
:g/^/norm $x
^ matches every line which will be operated on.
norm is shorthand for normal, going before the normal command you want to execute.
$x move to the end of a line, and delete a character in normal mode

Using gvim, to copy few lines and paste them at the start of each line [duplicate]

I’d like to merge two blocks of lines in Vim, i.e., take lines k through l and append them to lines m through n. If you prefer a pseudocode explanation: [line[k+i] + line[m+i] for i in range(min(l-k, n-m)+1)].
For example,
abc
def
...
123
45
...
should become
abc123
def45
Is there a nice way to do this without copying and pasting manually line by line?
You can certainly do all this with a single copy/paste (using block-mode selection), but I'm guessing that's not what you want.
If you want to do this with just Ex commands
:5,8del | let l=split(#") | 1,4s/$/\=remove(l,0)/
will transform
work it
make it
do it
makes us
harder
better
faster
stronger
~
into
work it harder
make it better
do it faster
makes us stronger
~
UPDATE: An answer with this many upvotes deserves a more thorough explanation.
In Vim, you can use the pipe character (|) to chain multiple Ex commands, so the above is equivalent to
:5,8del
:let l=split(#")
:1,4s/$/\=remove(l,0)/
Many Ex commands accept a range of lines as a prefix argument - in the above case the 5,8 before the del and the 1,4 before the s/// specify which lines the commands operate on.
del deletes the given lines. It can take a register argument, but when one is not given, it dumps the lines to the unnamed register, #", just like deleting in normal mode does. let l=split(#") then splits the deleted lines into a list, using the default delimiter: whitespace. To work properly on input that had whitespace in the deleted lines, like:
more than
hour
our
never
ever
after
work is
over
~
we'd need to specify a different delimiter, to prevent "work is" from being split into two list elements: let l=split(#","\n").
Finally, in the substitution s/$/\=remove(l,0)/, we replace the end of each line ($) with the value of the expression remove(l,0). remove(l,0) alters the list l, deleting and returning its first element. This lets us replace the deleted lines in the order in which we read them. We could instead replace the deleted lines in reverse order by using remove(l,-1).
An elegant and concise Ex command solving the issue can be obtained by
combining the :global, :move, and :join commands. Assuming that
the first block of lines starts on the first line of the buffer, and
that the cursor is located on the line immediately preceding the first
line of the second block, the command is as follows.
:1,g/^/''+m.|-j!
For detailed explanation of this technique, see my answer to
an essentially the same question “How to achieve the “paste -d '␣'”
behavior out of the box in Vim?”.
To join blocks of line, you have to do the following steps:
Go to the third line: jj
Enter visual block mode: CTRL-v
Anchor the cursor to the end of the line (important for lines of differing length): $
Go to the end: CTRL-END
Cut the block: x
Go to the end of the first line: kk$
Paste the block here: p
The movement is not the best one (I'm not an expert), but it works like you wanted. Hope there will be a shorter version of it.
Here are the prerequisits so this technique works well:
All lines of the starting block (in the example in the question abc and def) have the same length XOR
the first line of the starting block is the longest, and you don't care about the additional spaces in between) XOR
The first line of the starting block is not the longest, and you additional spaces to the end.
Here's how I'd do it (with the cursor on the first line):
qama:5<CR>y$'a$p:5<CR>dd'ajq3#a
You need to know two things:
The line number on which the first line of the second group starts (5 in my case), and
the number of lines in each group (3 in my example).
Here's what's going on:
qa records everything up to the next q into a "buffer" in a.
ma creates a mark on the current line.
:5<CR> goes to the next group.
y$ yanks the rest of the line.
'a returns to the mark, set earlier.
$p pastes at the end of the line.
:5<CR> returns to the second group's first line.
dd deletes it.
'a returns to the mark.
jq goes down one line, and stops recording.
3#a repeats the action for each line (3 in my case)
As mentioned elsewhere, block selection is the way to go. But you can also use any variant of:
:!tail -n -6 % | paste -d '\0' % - | head -n 5
This method relies on the UNIX command line. The paste utility was created to handle this sort of line merging.
PASTE(1) BSD General Commands Manual PASTE(1)
NAME
paste -- merge corresponding or subsequent lines of files
SYNOPSIS
paste [-s] [-d list] file ...
DESCRIPTION
The paste utility concatenates the corresponding lines of the given input files, replacing all but the last file's newline characters with a single tab character,
and writes the resulting lines to standard output. If end-of-file is reached on an input file while other input files still contain data, the file is treated as if
it were an endless source of empty lines.
Sample data is the same as rampion's.
:1,4s/$/\=getline(line('.')+4)/ | 5,8d
I wouldn't think make it too complicated.
I would just set virtualedit on
(:set virtualedit=all)
Select block 123 and all below.
Put it after the first column:
abc 123
def 45
... ...
and remove the multiple space between to 1 space:
:%s/\s\{2,}/ /g
I would use complex repeats :)
Given this:
aaa
bbb
ccc
AAA
BBB
CCC
With the cursor on the first line, press the following:
qa}jdd''pkJxjq
and then press #a (and you may subsequently use ##) as many times as needed.
You should end up with:
aaaAAA
bbbBBB
cccCCC
(Plus a newline.)
Explaination:
qa starts recording a complex repeat in a
} jumps to the next empty line
jdd deletes the next line
'' goes back to the position before the last jump
p paste the deleted line under the current one
kJ append the current line to the end of the previous one
x delete the space that J adds between the combined lines; you can omit this if you want the space
j go to the next line
q end the complex repeat recording
After that you'd use #a to run the complex repeat stored in a, and then you can use ## to rerun the last ran complex repeat.
There can be many number of ways to accomplish this. I will merge two blocks of text using any of the following two methods.
suppose first block is at line 1 and 2nd block starts from line 10 with the cursor's initial position at line number 1.
(\n means pressing the enter key.)
1. abc
def
ghi
10. 123
456
789
with a macro using the commands: copy,paste and join.
qaqqa:+9y\npkJjq2#a10G3dd
with a macro using the commands move a line at nth line number and join.
qcqqc:10m .\nkJjq2#c

Vim: How to delete between the cursor and the first character of the line?

How to delete till the first character of the line ? In the line below, for example, with the cursor near the end as indicated, delete backwards until the first $.
I have this line:
[space][space][space]$entity->setPositionBrand(count($qb->getResult())[my_cursor_here] + 1);
After deletion, I want this:
[space][space][space] + 1);
There is a standard vim motion that goes exactly to the first non-whitespace character on the line. It's ^
So you only need to type d^.
Obviously not as succinct as Vladimir's answer (which is a better solution), but for the record, here's how you could achieve the same with visual mode.
v0wx
v Enter visual mode.
0 Move to the beginning of the line.
w Move to first word.
x delete characters in visual selection.
Any amount of whitespace counts as a word.
If you want a general solution, you would probably need some sort of regex-based keybinding. But, you can accomplish what you want with these key combinations:
Put your cursor on the first $ sign.
d 12 e
The second key sequence deletes characters from the position of your cursor up to the end of the twelfth word, which will result in exactly the line you want.

Resources