How do I start inserting text between two methods, with spacing? - vim

Let's say I have this code:
01 int function1(){
02 //do something
03 }
04
05 int function2(){
06 //do something
07 }
And I want to insert a new function between function1 and function2.
Currently, I would put the cursor in line 03, press o, then Enter, so there's an empty line before, and another one after the line I'm editing.
Is there a simpler way? I do this often enough that I want to know if there's a faster way.

vim can edit key commands in any mode.
For example, Put in .vimrc:
imap <C-Enter> <Enter><C-W>
In insert mode, press Ctrl-Enter to avoid auto indentation when inserting a new line.
Or this:
nmap <C-Enter> o<Enter><C-W>
In normal mode, press Ctrl-Enter to simulate pressing o, then press enter, and finally remove the auto indentation.

Related

How to switch modes when operating on multiple selected lines

I have created a line selection in Vim by Shift+V and followed by jjjj.
I can do something against all lines separately like :normal ^i//, which moves the cursor to the beginning of each line and enter insert mode, then insert two /.
Is it possible to switch back to normal mode after this?
The example in the question is just to demonstrate the problem and I only want to discuss the Vim usage skills.
I tried :normal ^i//<Esc>A// in the hope of adding two / to the end of each line, but it didn't work.
Is this possible?
The :normal command does not interpret special characters. In your last try, all the chars after i would be interpreted as normal text then inserted at the beginning of each selected line: //<Esc>A//.
The Esc character is a special char (actually the ASCII code 27), so you have to ask Vim to insert this char in a different way (because hitting Esc would escape the command line).
In order to do this (either in Command mode or Insert mode), press Ctrl + V then the wanted key, e.g. Esc. This will insert the real <esc> character in you flow, then perform the desired behaviour.
To summarize:
Press Shift + V followed by jjjj...
Type :normal ^i//Ctrl + VEscA//
Hit Return to validate the command

Vim: Recording a macro with an escape key press does not work correctly

I have recorded a macro to the o register to indent and remove a space for a line, then move to the start of the next line.
The original line:
a : 1,
Keystrokes used:
qii<tab><esc>f<space>x+q
Result is exactly what I wanted:
a: 1,
The following key strokes are recorded to the regiser: i^I^[f x+
Running the macro on the line (after undoing changes) results in this:
æ x+a : 1,
A few more tests reveal the following:
"i i^I^[+
"o i^I^[f x+
"p i^I^[llx+
Register i works as expected.
Register p fails similar to o with the result looking like this:
ìlx+a : 1,
Seems that an escape key press recorded as ^[ does not exit insert mode when executing the macro.
I am on osx sierra and using vim with the terminal app.
Any ideas whats going on here and how to fix it?
Cause:
The following in my .vimrc caused the problem
" fix meta-keys which generate <Esc>a .. <Esc>z
let c='a'
while c <= 'z'
set <M-".c.">=\e".c
imap \e".c." <M-".c.">"
set <M-".toupper(c).">=\e".toupper(c)
imap \e".toupper(c)." <M-".toupper(c).">"
let c = nr2char(1+char2nr(c))
endw
The above allows me to use the <option/alt> key in OSX as the vim <Meta> key. Vim is interpreting an <Esc> key press followed by a letter in the macro as a meta keypress.
Solution:
I got around the issue by remapping <Esc> to <C-c> in insert mode so it now generates ^C^C in macros when exiting insert mode rather then ^[.
inoremap <Esc> <C-c>
The main draw back is that it breaks arrow keys in insert mode, but since I use hjkl i'm fine with that.
Here are some other resources that attempt to deal with this issue:
https://github.com/vim-utils/vim-alt-mappings
https://github.com/sunaku/.vim/blob/config/plugin/escape.vim

Switch automatically between normal and insert mode in vim

I am new to vim and have installed oh-my-vim and learnt these keybindings by googling:
Jump forward by word - w
Jump forward by word - b
Jump to end of sentence - A
Close current file without exiting - bd
Undo is u
Execute shell command with ! (bang)
of these typing Shift + a in Normal mode allows me to jump to end of sentence and also goes into insert mode soon as I start typing after it. I tried out Shift + w and Shift + b and
it also shows similar behaviour of going to insert mode as soon as I start typing after I use that keybinding.
What are the equivalents for these keybindings where I am not using a letter?
Jump to start of sentence - 0
Redo is Ctrl + R
Jump to previous line - ``
Hope I am clear in describing. Thanks!
I'm also a beginner and I am getting used to Vim recently.
Well, regarding your question, to switch from Normal to Insert, you could press:
i to insert (the cursor stays, effectively inserting to the left)
a to append (the cursor jumps after the character you were on)
I to insert from the beginning of the line. This is equivalent to pressing 0 in Normal mode, and then pressing i to enter Insert mode.
A to append to the end of the line. This is equivalent to pressing $ in Normal mode to get to the end of the line, and then pressing a to append in Insert Mode.
For Insert to Normal:
press <Esc> to get to Normal mode.
press <Ctrl-[> to get to Normal mode.
press <Ctrl-O> to temporarily enter Normal mode for one command. Upon execution it will automatically return to Insert mode.
Personally, to shift between Normal mode, I use <Ctrl-[> for consecutive commands in Normal mode and <Ctrl-O> if it's a one time deal. <Esc> is too far for my pinky :)
It's not entirely clear what you are asking. Shift+W and Shift+B do not automatically enter insert mode, instead they go back and forth on WORDS (vs words).
If you want to enter insert mode, just hit i. You could hit wi to insert after a word.
You mention 0, which goes to the beginning of a line. You can hit I (shift+I) to insert at the beginning of a line. Note that this inserts after the initial whitespace on the line, it is the same as hitting ^i. If you want to insert at the very beginning of the line, you'll need to use 0i.

Mapping leader key to execute something without having to press enter

I mapped leader lf to LustyFileSystemExplorer and it works properly. I press leader lf and it shows the explorer, however when I change it to any other key binding, pressing leader lf shows :LustyFileSystemExplorer and I've to press enter to use it.
Add a carriage return to your mapping:
map <Leader>lf :LustyFileSystemExplorer<CR>
And you're done!

Repeating characters in VIM insert mode

Is there a way of repeating a character while in Vim's insert mode? For example, say I would like to insert 80 dashes, in something like emacs I would type:
Ctrl+U 8 0 -
The only way I know how to do it in VIM is to exit normal mode for the repeat argument, then go back into insert mode to type the dash, then exit to insert the actual dashes, AND then go back into insert mode to carry on typing. The sequence is a really long:
Esc 8 0 a - Esc a
It would be nice not to switch in and out of modes.
If you are OK with leaving INSERT mode only once (at the end), this sequence works:
Ctrl+o 80i- Esc
Ctrl+o is used to issue normal commands without leaving INSERT mode,
80 the repetition,
i to insert,
- the character you want to insert,
Esc to leave INSERT mode.
Another one without EVER leaving INSERT mode:
Ctrl+o :norm 8ia Return
Esc nic Esc .
E.g. Esc 4iJ Esc will output JJJJ.
Through single repeat:
Press: i to enter into Insert mode
Press: -
Press: Esc
Press: 80.
It will output: 81 -, like this:
---------------------------------------------------------------------------------
More details about single repeat: :help .
Slightly different version of Eelvex's solution:
function! Repeat()
let times = input("Count: ")
let char = input("Char: ")
exe ":normal a" . repeat(char, times)
endfunction
imap <C-u> <C-o>:call Repeat()<cr>
<ESC>
<the number of times you want to repeat>
i
<the char you want to repeat>
<ESC>
for example: <ESC>12ia<ESC> will insert 12 a's.
You can also do,
Escnihello there EscEsc
where,
n is the number of repeats.
e.g.,
Esc5ihello there EscEsc
I'm surprised no one has suggested this yet:
In Insert mode, use <C-r>=repeat('-', 80)<CR>
That is:
Press Ctrl-r=
At the resulting prompt, enter repeat('-', 80)
Press Enter
Works for repeating any character any number of times.
This uses more keystrokes than #romainl's answer, but does not leave Insert mode at all.
There are many other ways but AFAIK the one you describe is the shortest one. In vim you are mostly supposed to spend your time in command mode, so that would be just 3 keystrokes + the number of repeats (80i-).
However, if you find that you very often use this repeat thing, you can make yourself a function or macro to that end; maybe something like:
:function Repeat(char)
: let counter = input("How many times?: ")
: call feedkeys("i")
: call feedkeys(repeat(a:char,counter))
:endfunction
:imap <C-U> <ESC>h"ryl :call Repeat(#r)<CR>
You said it would be 'nice' to stay in 'Insert' mode, however in Command Mode the following method would avoid your 2nd ESC :-
While I know this post is old, it seems a shame to miss the obvious 'Cut/Copy and Paste' option...
x ...cut
80 ...number of copies
p Paste
Note : This is similar to the method suggested by Martin Beckett, however I get a delay when issuing that command, perhaps because it switches modes several times, this command executes instantly.
Late answer but for what it's worth, if you wanna hand spam it, you can use the
"repeat last command" command: .
i "Phrase" Esc - i to insert, enter phrase/character, esc to go normal mode
. - Spam till you are satisfied. Will repeatedly input the phrase you typed (it repeats your last command).
I find this especially useful when I don't know exactly how many repeats I want to do, but know visually how long I want it to be. Basically blast the . till my eyes are content.
In addition to writing function that will repeat text multiple times, you could use <C-x><C-l>: if you already have line that contains 80 dashes, writing a few dashes at the start of new line and then pressing <C-x><C-l> will complete lines which start with these few dashes which will be likely that line with 80 dashes. I used to write horizontal lines (78 dashes) in help files in a such way.
For such an easy task abbreviation should do the trick. Add the following to your .vimrc
iab <expr> -- repeat('-', 80)
and from now, when you type -- followed by a space (while you are in insert mode), the -- will be automatically converted to - 80 times.
By using the function repeat you are able to repeat the string as many time you want.
Note that you can test it before updating the .vimrc by entering in command mode then issuing the following :iab <expr> -- repeat('-', 80)
I did this without exiting the INSERT mode using the below steps.
Enable INSERT mode.
Type one dash "-".
Ctrl + O
lowercase 'v' (to enter -- (insert) VISUAL -- mode)
lowercase 'y' (to copy)
Ctrl + O
Type 80
Then, followed by lowercase 'p' (for paste).
i - Ctrl+o v y Ctrl+o 80 p
This will print all the dashes horizontally in a single line.

Resources