In Vim normal mode, you can press ctrl+e and ctrl+y to scroll down and up, respectively. I'm trying to make a key-bind that lets me do this from insert mode as well. This is what I've got:
" Scroll up and down while in insert mode.
inoremap <C-e> <C-o><C-e>
inoremap <C-y> <C-o><C-y>
This works like expected, but it has a big flaw. It leaves insert mode, scrolls, then re-enters insert mode. This is relevant when it comes to undo, repeat command etc. and I would like to be able to scroll up and down without leaving insert mode. Thoughts?
You could take a look at :h i_CTRL-X_CTRL-E, which is a built-in insert-mode mapping to scroll:
*i_CTRL-X_CTRL-E*
CTRL-X CTRL-E scroll window one line up.
When doing completion look here: |complete_CTRL-E|
*i_CTRL-X_CTRL-Y*
CTRL-X CTRL-Y scroll window one line down.
When doing completion look here: |complete_CTRL-Y|
So in your case, this would probably do the trick:
inoremap <C-e> <C-x><C-e>
inoremap <C-y> <C-x><C-y>
undojoin fixes the undo part of it:
ino <C-E> <Space><BS><ESC><C-E>:undojoin<CR>gi
The <Space><BS> sequence makes sure there's an undo block to join with.
Surprisingly (to me) this doesn't help with the . breakage, so this might leave you in just as annoying a spot as you're in now...
Related
I normally don't write tabs, so I mapped <TAB> to <ESC> in insert mode so that it's faster to leave insert mode. However, when I accidentally press TAB in normal mode, it jumps to some location in the file, without saving the jump location. I first suspected that a plugin is doing that, but I find no mapping for TAB in normal mode. Even explicitly unmapping it doesn't help, so it must be a built-in command. What does it do, why isn't this jump saved to history, and how do I disable it?
You're seeing the built-in :help CTRL-I; <C-I> and <Tab> are the same in (G)Vim. That command is the opposite of <C-O>; it goes to a newer position in the jump list. You don't see the "saving to history", because it operates on existing jumps.
If you don't want any action on Tab in normal mode, just put
:nnoremap <Tab> <Nop>
into your ~/.vimrc; :help <Nop>.
What does it do, why isn't this jump saved to history, and how do I disable it?
"Tab" (or <C-I>, which is really the same thing) goes forward through the jumplist ("undo" for <C-O>), so it's either no-op, or still there's nothing to save ;-) To see the embedded help topic use :h <tab>
If you really want to disable it, just remap it:
nnoremap <tab> <nop>
I want to be able to save a file in vim while in the insert mode. I thought of using the following shortcut:
inoremap <leader>w <Esc>:w<cr>
While the shortcut saves the file in the insert mode, it leaves the cursor one spot ahead of where the cursor would be if I physically typed out the keys
Esc :w followed by Enter. This is a problem because when I use the shortcut whenever I am at the end of a line, it takes me to the next line, and I have to then come back to the spot where I initiated the save.
Any help would be appreciated on how I can map <leader>w to the exact actions that occur in Vim when I physically type out the Esc :w followed by Enter key sequence.
I should add that if I instead use the following key-mapping, things work exactly as I want:
inoremap <C-s> <esc>:w<CR>
However, I would like to avoid pressing CTRL and s at the same time. It is possible there is some problem with the <leader>, but I cannot figure out what it is (I am using , as my leader key).
Though one could discuss the suitability of your insert-mode mapping, the root cause of your problem is a trailing space in the mapping definition; i.e. Vim reads this as follows:
inoremap <leader>w <Esc>:w<cr><Space>
You'll even see this in the :imap <Leader>w output! <Space> in normal mode advances the cursor one to the right (like l); that explains the unexpected move.
Try this instead:
inoremap <silent> <leader>w <C-o>:w<CR>
The idea is Ctrl-o can be used to run commands directly from insert mode. See :help i_CTRL-O for details.
Why not simply doing
inoremap <leader>w <Esc>h:w<cr>
(not the additional h for going back one character)?
There is nothing I hate more than phantom touchpad clicks causing my text to get entered somewhere random. I would almost rather have the typing be interpreted as random Vim commands. At any rate, I do have configuration that makes leaving insert mode highly conspicuous visually, so that shall be a non-issue.
How should I do this? I don't think there's a way to map or intercept mouse events in Vim. I am hoping maybe there is an autocmd of some sort that fires on clicks?
I am only talking about command line Vim here. Not MacVim or some such.
You can also map the mouse to do nothing at all:
inoremap <LeftMouse> <Nop>
Edit by OP: This little bit of insight was the perfect solution to the problem.
I prefer to make damn sure the left click is ignored when in insert mode. The reason that I like this answer so much is that it delivers the one-two punch of not only preventing the movement of the cursor (to cause my text to appear where i randomly phantom-clicked), but it also prevents Vim from causing those keys i was in the middle of typing to be interpreted as Vim commands, which is what would happen when left click is bound to <ESC>.
However I found sometimes I would stubbornly keep hammering on the mouse to change window while still in insert mode even though I set my entire status bar to change color in insert mode, mostly because I'm stupid, and the default bindings of double, triple, and quad left clicks can still trigger despite the single click map, because in this sort of situation I just mash the button I was hitting (in this case left mouse) instinctively, a behavior ingrained by flaky/laggy network connections (which actually still doesn't make any sense considering how TCP functions...)
So, to address that issue and configure Vim so that it will force me to realize that I'm in insert mode, here is an even more bulletproof set of binds. It clears out all the default functionality of left clicks causing various visual mode selections to go into effect (which if I go on to cancel will still drop me back in insert mode somewhere else, the original behavior I intended to correct):
inoremap <LeftMouse> <Nop> "normally causes visual selection mode
inoremap <2-LeftMouse> <Nop> "normally causes visual word selection mode
inoremap <3-LeftMouse> <Nop> "normally causes visual line selection mode
inoremap <4-LeftMouse> <Nop> "normally causes visual block selection mode
With :set mouse=a (or at least :set mouse=i), you can use the following mapping:
inoremap <LeftMouse> <Esc>
See :help mouse and :help mouse-using for more information.
I used Nikita Kouevda's version but with a small tweak to avoid clicking more than once:
inoremap <LeftMouse> <Esc><LeftMouse>
This takes you out and then performs the default action. As with his the mouse mode needs to be:
:set mouse=a
Background:
Sometimes when editing in vim it is possible to have extra characters in a file that the user did not expect to be there because he was in "insert mode" when in a hurry and rushing to get something finished.
Fortunately, even if the user is rushing, pressing ESC a couple of times is always sufficient to get them out of insert mode and into normal mode, with no surprises.
Question:
Is there a key binding that works the same way for insert mode? Pressing "i" can get you into insert mode, but if you press it multiple times, you will start inserting the letter "i" into the file.
Goal:
The goal is to have some key binding for getting back into insert mode that the user can even press multiple times with eyes closed, and still not worry about "surprises" of unexpected characters being put into the file.
<C-o>i should do the trick. <C-o> gets you temporarily to normal mode, but for only one command, if that command is "go to insert mode" than well, you simply return there.
Edit: I could reproduce your error message now, and it seems the easiest thing to do is this:
:nmap <C-i> i
:imap <C-i> <C-o>i
If do not map <C-i> in insert mode, but in normal mode only, then repeatedly hitting <C-i> will be idempotent.
Thanks to Benoit for mentioning that <C-i> inserts a tab in insert mode.
You should do a mapping that behaves differently in the distinct modes:
:inoremap <F1> <NOP>
:nnoremap <F1> i
:vnoremap <F1> <esc>i
:cnoremap <F1> <C-C>i
:onoremap <F1> <esc>i
Hitting F1 will go to insert mode then.
You can also toggle the 'insertmode' setting (:set insertmode): in this mode, the Insert mode is the default mode (to which you switch with Escape, and you go to normal mode with CTRL-L.
The answer given by bitmask works, but it apparently has the side-effect of producing the error message:
E37: No write since last change (add ! to override)
Unless you have configured your vimrc to turn that message off.
But another alternative that seems to work without producing error messages:
CTRL-C i
Which seems to work on standard vim.
One of the things that bugs me the most about VIM is having to move while in insert mode. With any other programs I can use the arrow keys to move around but with VIM I have learned to use h/j/k/l and in order to enter that mode I have to press escape then I again, Is there a quicker way to do that?
I have my escape button mapped to jj.
imap jj <ESC>
That way when I want to enter normal mode fast I double tap jj and my fingers are in a good position to start navigating.
It may seem awkward to begin with but once you get muscle memory it will be like lightening.
You can temporarily drop out of insert mode by typing ^O to navigate. Useful to get past auto inserted closing brackets.
Most of the time vim understands the page movement buttons if your terminal is known to it. The original vi did not, and this command has always been there.
Useful muscle memory:
^Oo - stop and open line below, capital O is above
^OA - go to the end of the line and carry on inserting
^OI - Start inserting at beginning of line
As an aside:
I used to use vi on system V way back, at least 23 years ago. Personally find the idea of vi having a philosophy very funny. It was a pragmatic replacement for ex written by a lone coder in a hurry. Its pragmatism is why it survived because it was easy to port to any Unix. To get the best you should learn how to use f, t, comma and semicolon - they can save you a lot of effort when you use them with c.
use CTRL-[
here's a suggestion (probably from Bram) in the insert.txt helpfile for :h i_CTRL-[
"Note: If your key is hard to hit on your keyboard, train yourself to use CTRL-[."
You can use Ctrl+C to exit from the insert mode. Adding things to your vimrc file has a caveat: they don't work if you're on a remote server.
If you have a line in your vimrc file that looks like set term=ansi, comment it out. Once I did that I was able to navigate insert mode with arrow keys no problem.
If you want to move more than ONE or TWO positions...
...the best choice is to hit ESC, move around, and get back to insert mode again.
There's no point on create mappings like <C-h> to move left and then start hitting it too many times... as a vim user you're not supposed to hit the same key multiple times to achieve a smart movement.
(If the ESC key isn't close to your fingers, it would be a good option to create a mapping for it.)
If you want to move ONE or TWO posistions on insert mode...
...a good choice would be to define some movements using your <Leader> key:
(I use , as <Leader> key since it's feels close and confortable to my fingers)
noremap! <Leader>h <left> "move cursor left
noremap! <Leader>j <down> "move cursor down
noremap! <Leader>k <up> "move cursor up
noremap! <Leader>l <right> "move cursor right
noremap! <Leader>w <esc>wi "move one word forward
noremap! <Leader>e <esc>ei "move forward to the end of word
noremap! <Leader>b <esc>bi "move one word backward