vim - multiple commands on same line mapping failure - vim

I am pretty new to vim/gvim. This is my first attempt at modifying the ~/.vimrc file.
I am trying to map F11 to multiple commands.
What I am trying is
inoremap jj <ESC>
map <F11> h e a , jj && l && x
While manually entering h e a , jj l x is working for me, using F11 key is not.
What I am trying to achieve is-
1. get to the end of the current word
2. append ','
3. move right one place and delete that space between ',' and the start of next word.
I do not understand what's wrong with my mapping.
Please help me here.

First, let's build a proper representation of your macro
get to the end of the current word
e
append ','
ea,<Esc>
move right one place…
ea,<Esc>l
… and delete that space between ',' and the start of next word.
ea,<Esc>lx
Second, let's use it in the right-hand part of a proper non-recursive mapping:
nnoremap <F11> ea,<Esc>lx
Of note:
<Space> is a legitimate normal mode command so any <Space> in your macro is interpreted as "move the cursor one cell to the right", see :help l.
& is also a legitimate normal mode command, see :help &.
In a macro, every character is meaningful so h e a , jj && l && x is interpreted as:
move the cursor one cell to the left,
move the cursor one cell to the right,
move the cursor to the end of the current word,
move the cursor one cell to the right,
append a space, a comma, a space,
move the cursor one cell to the right,
repeat last substitution,
repeat last substitution,
move the cursor one cell to the right,
move the cursor one cell to the right,
move the cursor one cell to the right,
repeat last substitution,
repeat last substitution,
move the cursor one cell to the right,
cut the character under the cursor.
Your jj insert mode mapping provides zero value over plain <Esc> so there is no reason to use it in any mapping.
Your mapping thus becomes a non-recursive mapping so nmap becomes nnoremap.

Related

Pasting with overwrite in Vim

I want to be able to paste something from the buffer (probably using p), but instead of inserting it into the text, I want to replace whatever was there before (just like the R command). I've searched Google, vim documentation, and Stack Overflow but could not find anything on the issue. I imagine that it's just a command that I don't know about. Any help would be appreciated.
That's all I need to know, but if you want to know my specific problem:
Essentially I'm just trying to create a short script for documentation headers. At the beginning of every function I put the following:
// FunctionName <><><><><><><><><><><><><><><><><><><><>
However adding all those <> gets annoying. I want to be able to place my cursor on a function name, press the F6 key and it produce the above. The problem, of course, is that function names are not constant sizes and it would make the "chain" look weird. So I just want to paste OVER a bunch of pre-made chain so that the whole thing will always be a constant number of characters. i.e.:
start with
//<><><><><><><><><><><><><><><><><><><><><><><><><><><>
Paste " FunctionName " and end with
// FunctionName <><><><><><><><><><><><><><><><><><><><>
I found a much better solution
R Enter Replace mode: Each character you type replaces an existing character, starting with the character under the cursor.
So R <ctrl-r>" will do what you want. Note there is a space before and after <ctrl-r>".
OLD ANSWER
You can do this with a macro pretty easily
qhmhA <esc>a<><esc>40.80|D`hq
qh start macro
mh set mark
A <esc> insert a space after the existing text
a<><esc> insert '<>'
40. repeat last command 40 times
80| move to column 80
D delete to the end of the line
`h jump back to mark
q end macro
The macro can then be repeated with #h. You probably want to save this to your .vimrc like so
let #h = 'mhA ^[a<>^[40.80|D`h'
Note that the ^[ are supposed to be one character entered by pressing <ctrl-V><esc>
You can use visual selection.
Vp select the whole line and overwrite with buffer
viwp select the word under cursor and overwrite with buffer content.
vi(p overwrite what is in between parenthesis.
I particularly like that it highlights what should be overwritten, which
makes it easier to verify.
You can do it with this:
:exe "normal ".strlen(#p)."x\"pP"
It deletes the right number of chars, and then paste the content of register p.
Short answer
Simply do R and <C-r>0 or the 'register' you are trying to yank. If in doubt, check :reg
Long answer
From :help i_CTRL-R:
Insert the contents of a register. Between typing CTRL-R and
the second character, '"' will be displayed to indicate that
you are expected to enter the name of a register.
The text is inserted as if you typed it, but mappings and
abbreviations are not used. If you have options like
'textwidth', 'formatoptions', or 'autoindent' set, this will
influence what will be inserted. This is different from what
happens with the "p" command and pasting with the mouse.
Special registers:
'"' the unnamed register, containing the text of
the last delete or yank
'%' the current file name
'#' the alternate file name
'*' the clipboard contents (X11: primary selection)
'+' the clipboard contents
'/' the last search pattern
':' the last command-line
'.' the last inserted text
'-' the last small (less than a line) delete
*i_CTRL-R_=*
'=' the expression register: you are prompted to
enter an expression (see |expression|)
Note that 0x80 (128 decimal) is used for
special keys. E.g., you can use this to move
the cursor up:
CTRL-R ="\<Up>"
Use CTRL-R CTRL-R to insert text literally.
When the result is a |List| the items are used
as lines. They can have line breaks inside
too.
When the result is a Float it's automatically
converted to a String.
When append() or setline() is invoked the undo
sequence will be broken.

Vim: cut line from cursor position and paste it to another cursor position [duplicate]

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

vi/vim editor, copy a block (not usual action)

In vi/vim editor, I need to copy a block. There are many ways, but one way is very quick.
label the first line by some way,
then label the end line by some way,
then put some command to copy the labeled lines.
then copy, may using 'p', but not sure.
Anybody know the commands (not yy or 10yy)?
just use V to select lines or v to select chars or Ctrlv to select a block.
When the selection spans the area you'd like to copy just hit y and use p to paste it anywhere you like...
Their Documentation says:
Cut and paste:
Position the cursor where you want to begin cutting.
Press v to select characters (or uppercase V to select whole lines).
Move the cursor to the end of what you want to cut.
Press d to cut (or y to copy).
Move to where you would like to paste.
Press P to paste before the cursor, or p to paste after.
Copy and paste is performed with the same steps except for step 4 where you would press y instead of d:
d = delete = cut
y = yank = copy
Another option which may be easier to remember would be to place marks on the two lines with ma and mb, then run :'a,'byank.
Many different ways to accomplish this task, just offering another.
I found the below command much more convenient. If you want to copy lines from 6 to 12 and paste from the current cursor position.
:6,12 co .
If you want to copy lines from 6 to 12 and paste from 100th line.
:6,12t100
Source: https://www.reddit.com/r/vim/comments/8i6vbd/efficient_ways_of_copying_few_lines/
It sounds like you want to place marks in the file.
mx places a mark named x under the cursor
y'x yanks everything between the cursor's current position and the line containing mark x.
You can use 'x to simply move the cursor to the line with your mark.
You can use `x (a back-tick) to move to the exact location of the mark.
One thing I do all the time is yank everything between the cursor and mark x into the clipboard.
You can do that like this:
"+y'x
NOTE: In some environments the clipboard buffer is represented by a * in stead of a +.
Similar questions with some good answers:
How to copy/paste text from vi to different applications
How to paste from buffer in ex mode of vim?
Keyboard shortcuts to that are:
For copy: Place cursor on starting of block and press md and then goto end of block and press y'd. This will select the block to paste it press p
For cut: Place cursor on starting of block and press ma and then goto end of block and press d'a. This will select the block to paste it press p
You can do it as you do in vi, for example to yank lines from 3020 to the end, execute this command (write the block to a file):
:3020,$ w /tmp/yank
And to write this block in another line/file, go to the desired position and execute next command (insert file written before):
:r /tmp/yank
(Reminder: don't forget to remove file: /tmp/yank)

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.

copy partial lines in VI

There are a lot of different ways in which one can yank complete single/multiple lines. Is there a way in which we can copy partial lines in vi, like just 10 characters of the line.
I would guess the most common partial yanks are:
yaw: yank the word the cursor is currently in
2yaw: yank the word the cursor in currently in and the next (2 words total)
ya(: yank the matched parentheses containing the cursor
yf.: yank from the cursor to the next .
y$: yank from the cursor to the end of the line
Any movement keys can be used.
Cut and paste:
Position the cursor where you want to begin cutting.
Press v to select characters (or uppercase V to select whole lines).
Move the cursor to the end of what you want to cut.
Press d to cut (or y to copy).
Move to where you would like to paste.
Press P to paste before the cursor, or p to paste after.
Copy and paste is performed with the same steps except for step 4 where you would press y instead of d:
d = delete = cut
y = yank = copy
Resource:
vim.wikia.com: Copy, cut and paste
You can do yMovement, so for 10 characters: y10l yanks 10 characters from (and including) the current cursor position
I prefer just pressing the v key, then using the cursor keys to move your selection. Then press the y key when you satisfied to yank the selection.
you can also do
yt<char> - yank 'till char - i use that a lot
or y/<pattern>/ - yank until pattern
Sure, with the cursor at the beginning of the line, type:
y10l
This yanks 10 characters to the right. If you need to do this repeatedly for some reason, just add this temporary kep mapping:
:noremap ,m ^y10l
Which will yank the first 10 chars of any line every time you press ,m
If you have multiple lines to copy, try visual block mode,
" beginning of line
C-v
" up-down move 10j or 5k
10l
" copy & paste
y
p
more detail, see wiki
This is one place mouse may actually beat keyboard, especially if the current mouse cursor is far from your copy target, or if you want to select multiple lines with partial start line or end line.
Use :set mouse=a to enable mouse support. Then select whatever irregular text blocks with mouse, and then press y

Resources