I've added these shortcuts to duplicate a line based on the :t command, where :t. duplicates the current line onto the next line (keeps cursor on the second of the pair of lines), and :t-1 duplicates the current line onto the previous line (keeps cursor on the first of the pair of lines).
nmap <leader>D :t-1<cr>
nmap <leader>d :t.<cr>
In both cases the command moves the cursor position to the beginning of the line that has been created. How can I keep the cursor in the same position it was on (e.g. 20 characters in from the start of the line) on the new line?
Easiest solution is to use
:set nostartofline
Makes ex commands retain cursor column when possible, see h:nosol
Here is a solution:
nmap <leader>D mayyp`a
nmap <leader>d mayyP`a
It starts by placing a mark called a (ma) on the current cursor position, then copy the current line (yy) and paste it below (p). After that, it goes back to the original cursor position with `a. The second mapping uses P instead of p to paste the line above the current one.
This should do what you’re expecting.
Related
I want to duplicate a line with Vim. Every time when I use yyp or any other command, I have to jump the cursor to the position where it was. Is there any trick to duplicate a line and jump the cursor to its position, like maybe using a macro to save current the cursor position, duplicate, and then jump to the required position?
The only solution I'd see to do what you want, given you only use it for yyp (i.e. copy currentline and paste it below), is to record in a macro:
mmyyp`mj
what that does is:
to record a mark m,
copy current line
paste it
jump to col+row location of the mark m
move the cursor one line down
ideally what you'd want is a jump to a column, not changing the row. I'm not sure if it's possible, I never needed that before.
Maybe you are looking for ctrl-o and ctrl-i to jump back and forth.
I like the Markdown style underlining, but I want it to line up with the above line.
So for example if I have this:
heading one
_
^ cursor here
I could (in normal mode) just type (something)i=<ESC><ESC>, and the result would be:
heading one
===========
^ cursor here
Does anyone know what I can use for (something)?
It doesn't really matter to me where my cursor is/ends up, so for example I could be on the last position of the heading one line and do some operation to achieve the same result. I'm picky, but not that picky.
If you use visual selections you can then use r to replace every character in said visual selection.
So if you start with your cursor on the "heading one" line type.
yypVr=
Would copy the line and then replace every character with an equal sign.
kyypv$r=j
go up one line
yank it
paste it below
visually select the line
replace every character with =
Turn it into a mapping if you ned it often:
nnoremap <key> kyypv$r=j
I'd suggest you do this on the line to underline itself and not on the line below, though:
nnoremap <key> yypv$r=
This question already has answers here:
How to yank the text on a line and paste it inline in Vim?
(4 answers)
Closed 8 years ago.
I couldn't find this answer anywhere. I cut some line in Vim with either dd or V+d and I want to paste it inside brackets let's say. How do I do that?
p is paste after, and P is paste before, but I want it to paste at my cursor position.
Edit: I want to cut from certain cursor position (not whole line) to end of line and paste to cursor position in another line.
When you use either of those methods for cutting, you get the newline at the end of the line. With the newline, vim has to either put the line before or after.
To get the behavior you want, you should delete using 0D instead to delete, and then use a normal p to put it into the cursor.
If you want to cut from current cursor position to the end of line and then paste it inside another line at cursor position, then navigate do the first line, do D to cut to end of line, then move your cursor to the place where you want to paste it and use p.
try this, do Y or dd as usually, and create this mapping:
nnoremap <leader>p :let #"=substitute(#","\n","","g")<cr>p
nnoremap <leader>P :let #"=substitute(#","\n","","g")<cr>P
when you press p/P it pastes in default way(with newline). when you press <leader>p /<leader>P it pastes "in-line".
This is not so clean, because it changed the #", next time you press p the newline is not there any longer. I was a bit lazy, put the sub() there, you can make a little function, remove the newline then paste, without touching (or restore after paste) the #". and in mapping call that function.
I don't know if you did a 10dd, what output do you want to have when you do an "in-line" paste. but you can do quite a lot thing in your function, to reach your needs.
EDIT,
I don't know how did you create the mapping, and "didn't work". here I put an animation:
You can do something like this:
v$d
(move to where you want to put what you just cut)
p or P
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.
To yank 7 lines downward without moving the cursor, I can 7yy. Is it possible to do the same upwards, not using macros or remapping?
You can use the :yank command with a range to accomplish this effect.
:.-6,.yank
The range explanation:
. or the dot means current line
.-6 means current line minus 6
.-6,. is current line minus 6 to the current line
This can be abbreviated .-6 to just -6 giving us -6,.yank
the current line is also assumed in the end of the range so -6,yank
the yank command can be shortened to just :y giving us -6,y
Final command:
:-6,y
For more help:
:h :yank
:h [range]
You could simply yank to a motion and then return the cursor to the position using either '[ or '].
The yank for 6 lines up, plus the current gives 7 in total:
y6u
Then, use some lesser known marks:
'[ -> to the first character on the first line of
the previously yanked text (or changed)
`[ -> to the first character of the previously yanked text
'] -> to the first character on the last line of yanked text
`] -> to the last character of the preciously yanked text
So:
y6u']
y6u`]
Are two solutions you could use depending on what exactly you want. The former moves the cursor back to the first character on the line your cursor was, and the latter moves to the last character on that line.
But there is another mark that might be handy: '^. It means the last position the cursor was when leaving insert mode.
'^ -> moves to the beginning of the last line when leaving insert mode.
`^ -> moves to the exact position where insert mode was last left.
Then here are two other solutions:
y6u'^
y6u`^
That's not the end! If you pretend to continue inserting text, you can use the gi command. It moves you to the `^ mark and enter insert mode. Then we have a fifth solution:
y6ugi
I hope one of these meets your needs!
You could do the following:
6yk6j
This is will yank the 6 preceding lines and the current one) but the courser will move. 6j jumps back to the previous position.