how to insert text at specific lines in vim? - vim

I want to put cursor at specific lines that is:
AAA
BBB
CCC
I know how to edit those three lines using CTRL_V and then SHIFT_I, but my question is how do i edit the first and the last line and leave out the second line that is:
test_AAA
BBB
test_CCC
thanks in advance.

Vim doesn't have a built-in "multiple cursors" feature. If you want to do it the vanilla way, you can use :help .:
" cursor is on first A
> AAA
BBB
CCC
" do itest_<Esc>
> test_AAA
BBB
CCC
" move the cursor to CCC
test_AAA
BBB
> CCC
" press .
test_AAA
BBB
> test_CCC
or the almighty :help :global, which is the de-facto way to operate on non-contiguous line:
:g/^AA|^CC/s/^/test_
And there are many other ways.
Or you can ask your favourite engine to help you find the couple of plugins that replicate that feature: "vim multiple cursors".

You could use a reverse global command:
:v/^BBB/norm Itest_
Explanation:
The normal global command uses "g" instead of "v" which inverts the search, so, for each line that does not start with BBB use the normal command "I" (insert)

Related

Natural sorting in reverse?

I'm trying to sort a text file in this manner:
6 aaa
4 bbb
2 ccc
2 ddd
That is, each line sorted first in numeric descending order (the number indicates the number of occurrences of the word on the right), and if multiple words are repeated the same number of times, I'd like to have those words sorted alphabetically.
What I have:
6 aaa
4 bbb
2 ddd
2 ccc
When I try sort -nr | sort -V it kind of does what I want but in ascending order.
2 ccc
2 ddd
4 bbb
6 aaa
What's a clean way to accomplish this?
I think you just need to specify that the numeric reverse sort only applies to the first field:
$ sort -k1,1nr file
6 aaa
4 bbb
2 ccc
2 ddd
-k1,1[OPTS] means that OPTS only apply between the 1st and 1st field. The rest of the line is sorted according to global ordering options. In this case, since no other options were passed, this means the default lexicographic sort.
Maybe using tac? (not a shell expert here, just remembering uni days...
sort -nr | sort -V | tac

How to modify a line after every 6 lines in vim

I have a file with these lines:
aaa
aaa
aaa
aaa
aaa
aaa
bbb
bbb
bbb
bbb
bbb
bbb
ccc
ccc
ccc
ccc
ccc
ccc
ddd
ddd
ddd
ddd
ddd
ddd
i want to convert this into:
aaa;100;
aaa
aaa
aaa
aaa
aaa
bbb;100;
bbb
bbb
bbb
bbb
bbb
ccc;100;
ccc
ccc
ccc
ccc
ccc
ddd;100;
ddd
ddd
ddd
ddd
ddd
Is this possible in vim in one command ?
Yet another one
:g/^/ if !((line('.')-1)%6)|s/$/;100;
Breakdown
g/^/ Global command to apply next expression on each line
if !((line('.')-1)%6) If the modulus of the current line equals 0
s/$/;100; Replace the line ending with ;100;
That depends on what you mean by "one command", but you can do without manually repeating it for each item by using a macro:
Position your cursor on the first line
Start recording a macro named z: qz
Enter insert mode at the end of the line: <shift-A>
Enter the text you want: ;100;
Exit insert mode: <esc>
Jump down six lines: 6j
Stop recording the macro: q
Repeat the macro the right number more times: 3#z
Because the jumping down 6 lines is part of the macro, it will line up properly and loop through the file.
The relevant commands here are q# to start recording a macro, q to end the recording, and ## to play a recording back.
More information can be found in various places, such as the vim wiki: http://vim.wikia.com/wiki/Macros
If the lines are all the same until the change, this is a pretty nasty Vim solution:
/\v(.*)\n\zs\1#!
:%g//norm A;100;
Traditionally in Vim you craft a search first, then use :%s//replace to replace your last search with "replace". In one line it would be:
:%g/\v(.*)\n\zs\1#!/norm A;100;
I'm so sorry. This is what happens after years of Vim use. It's not pretty.
Explanation:
Essentially we're finding lines that AREN'T duplicated on the next line, and performing an action on them, in this case, adding some text.
:%g/ Perform an action on a pattern (same syntax as %s)
\v Very magic. Makes all special characters in Vim regexes special.
(.*)\n any text followed by a line break. Capture the text.
\zs Start highlighting the match here. This will put the cursor on the next line after the match, where we will perform the action.
\1 The capture group from above (.*), so a new line with the same text...
#! But negate it! So the cursor will go to any line that is NOT duplicated by the previous line.
/norm A;100; Peform the normal mode command A;100; which will execute keystrokes on each line as if you were in normal mode. Regular Vim here, just append (A) text.
:%s/\v(.*)(\n.*)(\n.*)(\n.*)(\n.*)(\n.*\n)/\1;100;\2\3\4\5\6/

How to put/insert multiple yanked/deleted lines in vim

A simple problem that I do not have the right terminology to google to.
I am in visual mode when I delete some lines:
aaa
eee
fff
bbb
ccc
ddd
ggg
hhh
from first whitespace in 'b' row I press $ to select to end of line and then down to 'd' line but when I put them in the slot after 'aaa' I get this:
aaa
bbb
ccc eee
ddd fff
ggg
hhh
I want 'e' and 'f' lines to push down, not out. I can do it by copy/paste using the mouse in insert mode but the mouse is not my friend so I would like to know another way of doing it.
It looks like you are using "visual-block mode" (<C-v>, or <C-q> if you source mswin.vim, which you shouldn't) instead of the correct "visual-line mode" (V).

In Vim, how to cut in block mode but paste in normal mode, inserting as new lines?

Every now and then I run into this type of editing problem in Vim.
I have text formatting in a table that I want to turn into a list.
Before:
AAA BBB
AAA BBB
AAA BBB
CCC DDD
CCC DDD
CCC DDD
After:
AAA
AAA
AAA
BBB
BBB
BBB
CCC
CCC
CCC
DDD
DDD
DDD
Of course not as trivial as this example. The blocks can have hairier contents, larger and inconsistent numbers of lines, etc.
The way I do it now seems to be a bit of a hack:
Select a block from the right column in block mode:
CTRL-q in the Windows version to select the top-left corner.
d to cut the block.
Note how many lines were in the block, then manually add that many blank lines.
Go to the top-left of the new blank area I created. SHIFT+p to paste the block into this area.
Step is the rough part.
Doing a normal non-block cut or copy will always paste into "new" lines. A kind of "insert" or "append" operation. Doing a block cut or copy will normally paste in a kind of "overwrite" mode.
Is there a better way to copy or cut in "block mode" but paste in "insert / append mode"?
The ex command :put will always paste a register line wise.
Cut the block of text with visual block mode like you have before then execute :put instead of p.
If you want to "cast" pastes in more ways then use #Ingo Karkat's plugin.
For more information see:
:h pu
you can block wise select the BBB part as how you did, and after cut by d for example, you run this command:
call setreg('"',#",'V')
then you can paste to target line, it will turn your block-wise "yank" into line-wise.
You can create a mapping if you do need to do this often.
My UnconditionalPaste plugin has a glp (go linewise paste) command that will paste the register contents as new lines, regardless of how they were yanked (e.g. in blockwise mode).
It also has several other helpful commands that affect the way the register is pasted.

How to select a jagged block in Vim?

For example, there are some text like this:
001 aaaaa
002 bbbbbbbb
003 ccc
I want to select
aaaaa
bbbbbbbb
ccc
and yank it. What should I do?
The following sequence should do the trick
ggw<C-v>G$
where
gg -- Goes to top of file
w -- skips one word
<C-v> -- starts visual block select
G -- selects until end of file
$ -- selects to end of each line
Switch to Visual Mode in Vim by pressing v in prompt
place the cursor in the column to select
Use ctrl+v to select a block to copy
Then the column alone will be selected and copy needed text alone and can yank it:)
Please refer the link here

Resources