Vim: unindent multiple lines to the beginning - vim

Suppose I have something like this:
line 1 with text
line 2 with text
line 3 with text
line 4 with text
I want to unindent all of these lines to the beginning, like this:
line 1 with text
line 2 with text
line 3 with text
line 4 with text
Shift + V < gives me ONE level of un-indentation. How can I get them all to the beginning? Sorry, I'm having trouble phrasing this...

There are two different ways you could do this:
Visually select all of the lines, press <, and then press . as many times as you need until there is no indent left. Or if there are a specific number of lines you would like this on, you could do something like
5<< (unindent 5 lines)
<j (unindent this line and the next)
<ip (unindent inside this paragraph)
followed by as many . as you need.
Select all of the lines, and then type either :norm d^ or :s/^\s*
Also, Shift-V + V + < is basically the same as <<.

Related

convert vertical text to horizontal text in vim

I want to convert the vertical text in my file to horizontal. like
1
2
3
to
1 2 3
I can do this using the tr command tr '\n' ' ' <file
but I want to do this using vim
An easy one. Use a range from first line until last one and join them with an space between them:
:0,$join
Select the lines and join them with J.
From :h J :
*J*
J Join [count] lines, with a minimum of two lines.
Remove the indent and insert up to two spaces (see
below).
*v_J*
{Visual}J Join the highlighted lines, with a minimum of two
lines. Remove the indent and insert up to two spaces
(see below). {not in Vi}
And, just for the fun of it:
:{fromLine},{toLine}!tr '\n' ' '
Another way:
By replacing \n with
:{fromLine},{toLine}s/\n/ /g

What's the meaning of empty last line in jump list in Vim?

I saw the bottom jump list in Vim (ju in normal mode) could be in 2 different forms as below. The current pos (> sign) points to empty line in the first output, but not the case for the second output. I am wondering how to enter such state of jump list separately and what's the effect on navigation?
2 1 2 Some line in file
1 2 2 Another line in file
>
2 1 2 Some line in file
> 1 2 2 Another line in file
The > shows your current position in the jumplist.
The empty line means that the cursor is currently not at a position in the jumplist.
No empty line means that you jumped to some position in the list.

Vim: paste multiple lines after multiple lines

In vim, how can I paste multiple lines of code after every line of a visual block?
What I have is:
foo
bar
1
2
3
What I am trying to do is:
1
foo
bar
2
foo
bar
3
foo
bar
Is there a way to easily accomplish this?
You can cut it to the default register and do a global replacement for the rest of lines, like this:
Go to first column of first line of the file:
gg0
Cut data:
3dd
Do a global repeat for every line of the file and paste it:
:g/^/put
It yields:
1
foo
bar
2
foo
bar
3
foo
bar
assume that you want to copy and paste line number 1 2 3, run this command:
:g/^\S/1,3t.
then the text foo bar would be copied to right place. then you can remove the two lines.
You can also change the 1,3 to other range.
Not fully automated but almost there:
Visually highlight desired rows to copy with Shift+V
Delete with d
Move to first line ("1") and start recording with q followed by some letter, i.e., a.
Paste with p and then move down to the next line ("2"). Stop recording with q.
Now just repeat the last recorded command with ##, or + the designated letter, i.e., #a.

Vim: Replace n with n+1

How do I replace every number n that matches a certain pattern with n+1? E.g. I want to replace all numbers in a line that are in brackets with the value+1.
1 2 <3> 4 <5> 6 7 <8> <9> <10> 11 12
should become
1 2 <4> 4 <6> 6 7 <9> <10> <11> 11 12
%s/<\zs\d\+\ze>/\=(submatch(0)+1)/g
By way of explanation:
%s " replace command
"""""
< " prefix
\zs " start of the match
\d\+ " match numbers
\ze " end of the match
> " suffix
"""""
\= " replace the match part with the following expression
(
submatch(0) " the match part
+1 " add one
)
"""""
g " replace all numbers, not only the first one
Edit:
If you only want to replace in specific line, move your cursor on that line, and execute
s/<\zs\d\+\ze>/\=(submatch(0)+1)/g
or use
LINENUMs/<\zs\d\+\ze>/\=(submatch(0)+1)/g
(replace LINENUM with the actual line number, eg. 13)
In vim you can increment (decrement) the numeric digit on or after the cursor by pressing
NUMBER<ctrl-a> to add NUMBER to the digit
(NUMBER<ctrl-x> to substract NUMBER from the digit)
If only incrementing (decrementing) by one you don't need to specify NUMBER. In your case I would use a simple macro for this:
qaf<<ctrl-a>q
100<altgr-q>a
Here a brief explanation of the macro: It uses the find (f) commant to place the cursor on the opening < bracket. It is not necessary to position the cursor on the digit. When press the number on the cursor or the nearest number after the cursor will get incremented.
If you want an even shorter series of commands you can position your curser ONCE by pressing f<, increment the number with ctrl-a and then just repeatedly press ;.. The ; command repeats the last cursor movement i.e. the find command. The . command repeats the last text changing command.
Check out this link for further information or use the built in documentation: h: ctrl-a.

Delete lines based on character(s) in specific position on line

I'm working with a large text file and need to be able delete lines based on the value of the 25th character on the line, i.e. if it is equal to H, K or Z. Is this possible, either just by matching one of the letters and running 3 commands or (even better) by all 3 in one command? Any help greatly appreciated!
You can use global to find a regex and then execute a command on the line that regex was found.
In this case it looks for any character 24 times from the beginning of the line and if the character after it matches H, K, or Z delete that line. (d at the end of the command stands for delete).
:g/^.\{24\}[HKZ]/d
Edit: as Peter Ricker points out \%25c would also work.
:g/\%25c[HKZ]/d
\%25c matches the 25th column then preforms the regex from there.
You could also use \%v if you wanted to match virtual columns instead.
You can try following ex command:
:if match( "HKZ", strpart( getline("."), 24, 1) ) != -1 | delete | endif

Resources