Difference between cutting lines with 10dd and d9 in vim? - vim

If I understand correctly both commands cut 10 lines and allow you to paste them anywhere.
Are they both the same as (n-1)dd and dn+enter where n is the number of lines to be cut?

The two relevant help section are copied below.
d
["x]d{motion} Delete text that {motion} moves over [into register
x]. See below for exceptions.
dd
["x]dd Delete [count] lines [into register x] linewise.
10dd is the second one which deletes 10 lines from you current position.
d9 does nothing. d9j (or d9<CR>) is delete from the cursor to where the cursor ends up (which is9j) is nine lines below the current one. However the j or <CR> makes it linewise so the same thing is deleted.
Both of these commands delete 10 lines. so ndd is equivalent to d(n-1)j.
d9j might be easier to type than 10dd if you have set relativenumber turned on because the difference between the line you are on and the line you want to delete to are on the left hand side of your screen.
You can use d9k to delete 10 lines up from your cursor line which you can't do with dd. Or you can use dfa to delete upto and including the next a. d{motion} is more powerful than dd because it isn't restricted to only linewise deletions.
Which one you use is up to you but certain combinations are easier depending on where your cursor is.

Related

How to append each line from 11-20 to each line from 1-10 in VIM

I have a file in which first 10 lines are the columns of a table and the rest 10 lines are the values of each column.
How can I use norm in VIM to append the values after each column names like this:
column1
...
column10
value1
...value10
-->
column1: value1
...
column10: value10
It is a little similar with this(Vim - Copy Nth word of each line, from line 10-100, to end of line), but I don't know how to go to line 1:10 and append the copied lines.
Any idea will be appreciated!
Fairly naive and crude way to do this, but:
:1,10norm! 10j0d$10kA: ^[p
Explanation:
1,10norm!: for lines 1 to 10, do the following (the ! means any custom mapping you have will be ignored, thanks to D. Ben Knoble for reminding of this):
10j: move down 10 lines
0d$: delete the whole line (not including newline)
10k: move back up 10 lines
A:: append (at the end of the line) ': ' (note the trailing space)
^[: input escape character, going back to normal mode. This (^[) is a single character and is inputted by typing Ctrl-v then escape, not by typing ^[.
p: paste the line deleted in step 3
Another (copy-pastable) way, (ab)using the substitute command:
:1,10s/\v(.*)\ze(.*\n){10}(.*)/\1: \3/ | 11,20d
which does:
1,10s/: for lines 1 to 10, execute the following substitution:
\v: use very-magic regex mode (see :help \v)
(.*): capture the entire current line (eg column1)
\ze: signal the end of the match. This way everything read (and captured) afterwards will not be affected (but can still be read)
(.*\n){10}: skip 10 (including current) lines, ie skip selector to 10 lines below
(.*): capture the line (eg value1)
/: end the 'select' part of the substitute command
\1: \3: replace with captured groups (eg column1: value1)
|: command separator
11,20d: delete lines 11 to 20
Use blockwise-visual mode to perform the operations.
You can enter visual block mode with Ctrl-V and it allows you to select and operate on columns. It also allows you to perform the same action on a block, which you can use to add the : to the lines with the column names.
I'll use normal Vim syntax for keystrokes in my examples, <C-v> means Ctrl-V.
Start by deleting the values into the default register, using a visual block:
11G<C-v>9j$d
Then Add the : to the column lines, also using a visual block:
1G<C-v>9j$A: <Esc>
Then add some more spaces to the first line, to ensure there's room for all the column names to fit:
A <Esc>
Finally, put the visual block at the end of the first line:
$p
It will actually put it on all lines all the way to the end.
This is slightly different from what you specified, since the values are all aligned on the same column. If you want different spacing, you can perhaps use a :s operation to fix spacing.
10:s/: */: /<cr>
Depending on where you pasted (if some column names had more trailing spaces than the first one), you might have some trailing spaces after the pasted values to fix as well, but that should be easy to do using a similar procedure.
Visual block operations are really powerful, it's a great feature to learn and keep in your "toolbox" in Vim. They're really handy with this kind of problem where thinking in "columns" makes the most sense.

VIM column operation

Intro
In gVim under Windows i have to replace insert and mod in each string of file some character in a specifics position.
Example
QWAER;PA 0X000055;123WAAAA
TYUIO;PA 0Y000056;123VAAAA
need to become
QWAE#;PAX000055;123;WAAAA
TYUI#;PAY000056;123;VAAAA
modify char 5 in #
delete char 9,10
insert ; in original pos 22 or after delete in pos 20
More Info
Usually I do
Put cursor and beginning of text to select
Press CTRL-V (CTRL-Q in gVim) to begin select of the column
keep press SHIFT and selecte the interested area
the go at the end of file
then do the replace insert or modification.
(This is where I learn about Keyboard-only column block selection in GVim Win32, or why does Ctrl-Q not emulate Ctrl-V when mswin.vim is included?
and here i learn how to do the insert(http://pivotallabs.com/column-edit-mode-in-vi/)
It's not a correct way to do the things.
In vim i can do the replaceof a fange of rows, and so on using commands.
I think that should be possible to use commands to replace a portion of each string but i have no Knoledge about those command.
this is the main idea
Replacing alternate line in vi text file with a particular string
Question
Is there a way to do the operations using commands with absolute position and not selection.
Thanks
:{range}normal 5|r#9|2x20|i;
Does what you want on the lines covered by {range}:
5|r# " go to column 5 and replace the character with #
9|2x " go to column 9 and cut 2 characters
20|i; " go to column 20 and insert a ; to the right
So…
:5,25norm 5|r#9|2x20|i; would apply that transformation to lines 5 to 25,
:.,$norm 5|r#9|2x20|i; would apply that transformation from the current line to the last,
:'<,'>norm 5|r#9|2x20|i; would apply that transformation to the current (or last) visual selection,
:'{,'}norm 5|r#9|2x20|i; would apply that transformation to the current "paragraph",
:%norm 5|r#9|2x20|i; would apply that transformation to the whole buffer,
and so on…
You could also record it, let's say in register q:
qq
5|r#
9|2x
20|i;<Esc>
q
and play it back on {range}:
:{range}#q
Or spend 30 minutes trying to come up with the right :s// command…
Reference:
:help range
:help :normal
:help |
:help r
:help x
:help i
:h recording

How can I highlight multiple lines in gVim without using the mouse?

Vim noob here. I am trying to select multiple lines of code to copy and paste in other areas. Is there a way to do this without using the mouse?
A few other ways that don't use visual mode at all:
using marks
leave a mark somewhere with ma
move somewhere else
yank from here to there with y'a
using search motions
localize some unique token at the end of the part you want to yank
yank from here to there with y/foo<cr> (forward search) or y?bar<cr> (backward search)
using text-objects
determine what text-object would map to what you want to yank:
inner/outer word, iw/aw
inner/outer pair, i'"([{</a'"([{<
inner/outer html tag, it/at
sentence, s
paragraph, p
"block", ]
…
yank that text-object with, say, yip
using other motions
yank to end of function: y]}
yank to end of file: yG
all of the above solutions with visual mode
V'ay
V/foo<cr>y
V?bar<cr>y
Vipy, etc.
V]}y
VGy
:h motion.txt will hopefully blow your mind, like it did to mine.
You can place your cursor in the first line you want to copy and then type nyy where n is the number of lines you want to copy. For example, type 2yy to copy the two lines under the cursor.
Then, you can paste them using p.
You can also select multiple lines by placing your cursor somewhere and keeping Shift pressed. Move your cursor to the end of the desired selection and stop pressing Shift. Then copy using just y (and not yy) and paste with p.
Yep, in normal mode type V[direction] and you will highlight multiple lines. If you don't want whole lines, use v instead of V. To copy it, hit y and move to the area which you want to paste in and hit p. To delete it, instead of y use x.
Alternatively, you can simply use [number of lines]yy to yank some number of lines or [number of lines]dd to cut some number of lines. In this case pasting is the same.

Cut and paste multiple lines in vim

I'm running vim 7.3 on a Mac 10.7.2 and I'm having some trouble cutting and pasting several lines.
On my old Linux setup (which was stolen so I don't know versions), I could type "dd" multiple times and then "p" would yank all of them back. For example: type: "dd dd" and two lines would be deleted. Now type "p" and both lines are pasted back into the buffer.
I know I can accomplish what I want by typing "2dd", and then "p" - but I would like to be able to "dd"-out lines without counting the number of lines ahead of time.
Any ideas?
Have you considered using visual mode?
You could just go:
Press V
Select everything you want to cut without counting
Press d
Go to where you want to paste
Press p
This should yield approximately half as many keystrokes as the dd method since you press one key per line rather than two. Bonus points if you use 5j (or similar) to select multiple lines at a time.
You could type:
d<n>d
where <n> is the number of lines that you want to cut, and then you could paste them with:
p
For example, to cut and paste 3 lines:
d3d
p
To cut and paste by line numbers (do :set number to see the line numbers), for lines x to y do:
:x,yd
or if your cursor is already on line x, do
:,yd
Then go to where you want to paste and press p
Not sure if this is close enough to what you're trying, but one thing you could do is use a specific register, and capitalize your register name. That tells vim to append to the register rather than replace it, so if you have the lines:
one
two
three
you can enter
"qdd
"Qdd
"Qdd
and then subsequently if you enter
"qp
it will paste back the original lines
To copy and paste 4 lines:
y4y (with the cursor on the starting line you wanna copy)
p (with cursor on the line you wanna paste after)
I agree with #Ben S. that this is the preferred way to accomplish this but if you are just looking to replicate your old behavior you can remap dd to append to a specified register, and then map p to paste from that register and clear it.
This will have the disadvantage of causing p to only work with things deleted using dd (using d} to delete to the end of the paragraph would not put the text in the correct register to be pasted later).
Add the following to your vimrc
noremap dd "Ddd "Appends the contents of the current line into register d
noremap p "dp:let #d=""<CR> "Pastes from register d and then clears it out
if you don't want pasting to clear out the contents of the register
noremap p "dp "Paste from register d
but this will cause that register to grow without ever clearing it out

Difference between :d[count] and d[count]

As a novice vim user, I used d[count]<Enter> to delete lines.
It striked me as odd that there were always count+1 lines deleted.
If I wanted to delete 2 lines, I typed d1, 3 lines took d2, ...
I finally took the time trying to understand why and it appears I should have been using :d<count>.
That does beg for the question though, why is :d1<Enter> <> d1<Enter>
d<count> in normal mode doesn't do anything, because the count isn't followed by a motion. So presumably you've been hitting d<count><Enter>, in which case the motion associated with d is <count><Enter>, which moves <count> lines downward. Since <Enter> is a linewise motion, the d will also be linewise, deleting all lines from the current one to the line <count> downward, inclusive.
The command you actually wanted is <count>dd.
d{motion} deletes the text that {motion} moves over. When you type 3<ENTER>, the cursor moves 3 lines below the current and therefore d3<ENTER> deletes that area.
:d[count] simply deletes [count] lines.
The difference is that {motion} is not the same as count.
To get around that, you could use the visual mode and select what you're going to delete and then simply press d.

Resources