Vim Tips Wiki
(Undo revision 37690 by 84.27.178.37 (talk) Edit did not fix all jj and no need to swap jj/jk.)
(48 intermediate revisions by 24 users not shown)
Line 1: Line 1:
{{Duplicate|75|136|166|1083}}
 
{{review}}
 
 
{{TipImported
 
{{TipImported
 
|id=285
 
|id=285
 
|previous=284
 
|previous=284
 
|next=286
 
|next=286
|created=July 22, 2002
+
|created=2002
 
|complexity=basic
 
|complexity=basic
|author=David A. Rogers
+
|author=
|version=5.7
+
|version=6.0
 
|rating=599/236
 
|rating=599/236
 
|category1=Map
 
|category1=Map
 
|category2=Usage
 
|category2=Usage
 
}}
 
}}
  +
This tip discusses how to exit from insert mode without needing to press Esc. The Vi editor was originally written on an ADM-3A terminal, which had the Escape key positioned where the Tab key occurs on most modern keyboards. Many touch typists appreciate the fact that they can leave their hands on the keyboard home row while using Vim, so there are several ideas for avoiding the Esc key at its current location (pressing Esc generally requires stretching to the top of the keyboard).
Vim is a dream for touch typists. Until you want to switch from insert mode to normal mode. Then you've got to reach way up to whack the escape key.
 
   
  +
No utility programs or operating system tweaks are required for this tip. For other suggestions involving mapping keys with the operating system or utilities, see [[VimTip166|Map caps lock to escape in XWindows]] (for Unix-based systems), or [[VimTip75|Map caps lock to escape in Windows]] (for Windows). Some of the suggestions involve more than avoiding escape; topics also discussed include using the CapsLock key for Ctrl, and avoiding irritations from accidental use of CapsLock.
Or at least that's what I was doing until I realized that Esc is equivalent to Ctrl-[ (control key plus left square bracket key).
 
   
  +
==Avoiding the Esc key==
That little bit of knowledge, plus mapping my caps lock to another control key, was what turned my fascination with Vim into true love. You never have to lose track of the home row again!
 
  +
If you have an American English keyboard, pressing Ctrl-[ (control plus left square bracket) is equivalent to pressing Esc. This provides an easy way to exit from insert mode.
   
  +
If you have a keyboard where the bracket is already mapped to Alt Gr-something (like the spanish keyboard), press Ctrl-c to quit insert mode (however, Ctrl-c does not expand abbreviations). {{help|i_CTRL-C}}
For Xfree86 users - you can make the capslock key another control key by adding
 
<pre>
 
Option "XkbOptions" "ctrl:nocaps"
 
</pre>
 
   
  +
==Use Alt/Meta In a Terminal==
to the InputDevice section of your XF86Config file.
 
  +
''[[wikipedia:Alt key|Alt keys]] appear on most PC keyboards. [[wikipedia:Meta key|Meta keys]] were used on some old systems.''
   
  +
If you use Vim in a terminal, simply press alt/meta+normal_mode_key. Most terminals send an escape character followed by the normal_mode_key that you pressed, removing the need to press escape yourself.
For Windows, see [[VimTip75]].
 
   
  +
The terminals konsole and gnome terminal send the escape by default when you press alt/meta+normal_mode_key. For Xterm you can ctrl+click and select the option "Meta sends escape" or "Alt sends escape". [http://xibur.blogspot.com/2012/02/vim-and-xterm-how-to-meta-escape.html]
For Unix, see [[VimTip166]].
 
   
  +
Thus in insert mode pressing alt+h alt+j alt+k alt+l all take you to normal mode and move in the expected direction. You can hold down alt when moving even while in normal mode since the additional ESC that is sent does no harm.
For Mac OS X, you can change this via the "Modifier Keys" button on the "Keyboard" section of the "Keyboard & Mouse" preference pane.
 
   
  +
The advantage of using this scheme is that you can use the alt/meta+key combination with any normal mode key, e.g.
===Related tips===
 
  +
*Alt+o opens a new line below the one you are currently editing,
*[[VimTip75|Tip 75 Remap CAPSLOCK key in Windows 2000 Professional and NT4.0]]
 
  +
*Alt+A appends to the end of the current line,
*[[VimTip136|Tip 136 Remapping Alt, Ctrl and Caps in Win2k]]
 
  +
*Alt+p pastes at the current insert location.
*[[VimTip166|Tip 166 Mapping caps lock to esc in XWindows]]
 
  +
*Alt+k moves up
*Tip 285 Avoid the escape key ''(this tip)''
 
*[[VimTip314|Tip 314 Insert and back]]
 
*[[VimTip327|Tip 327 Key mappings]]
 
*[[VimTip342|Tip 342 Remap the Escape key]]
 
*[[VimTip353|Tip 353 Swap caps-lock and control keys using MS Windows Registry]]
 
*[[VimTip377|Tip 377 Microsoft Natural Multimedia Keyboard Scancodes]]
 
*[[VimTip459|Tip 459 Use Ctrl-O instead of Esc in insert mode mappings]]
 
*[[VimTip770|Tip 770 Toggle normal-insert modes without Escape]]
 
*[[VimTip775|Tip 775 Remapping Caps to Shift]]
 
*[[VimTip783|Tip 783 Use the return key to get out of insert mode]]
 
*[[VimTip1083|Tip 1083 Map CapsLock key to Esc]]
 
*[[VimTip1117|Tip 1117 Use tab instead of escape]]
 
*[[VimTip1183|Tip 1183 Insert-mode only Caps Lock]]
 
*[[VimTip1275|Tip 1275 Toggle between insert and normal mode with Esc]]
 
*[[VimTip1324|Tip 1324 Alternative to hitting Esc]]
 
   
  +
Thus using vim via a terminal gives you these short cut powers on any stock standard system without the need to edit each systems vim mappings.
{{Todo}}
 
Some of the above tips should be merged. Need one tip for using the operating system to remap the keyboard (perhaps one for each OS), and another for using Vim to map some key to Escape.
 
   
==Comments==
+
==Mappings==
  +
It can be convenient to use a mapping so that pressing a key, or sequence of keys, generates Escape. The <code>:imap</code> command is used to create the mapping so that it only applies while in insert mode.
Simple map to use backtick as Esc, when in insert mode:
 
  +
  +
For example, the following allows you to press <code>jj</code> to exit from insert mode:
 
<pre>
 
<pre>
:imap ` <Esc>
+
:imap jj <Esc>
 
</pre>
 
</pre>
   
  +
To generate Escape, <code>jj</code> has to be typed quickly. {{help|'timeout'}}
----
 
I've always had situations where I had to "make a quick insert" - go into insert mode, insert a quick word, then come out into normal mode, and navigate elsewhere. To make a long story short, this is the solution that I came up with -
 
:map! &lt;S-space> <Esc>
 
   
  +
A problem with mapping a sequence like <code>jj</code> is that Vim will pause whenever you type <code>j</code> in insert mode (it is waiting for the next key to determine whether to apply the mapping). The pause is merely a visual distraction which you may not notice, and it does not slow down typing.
or even
 
:map! &lt;S-space>&lt;S-space> <Esc>
 
if you find the first mapping getting in the way of your typing
 
   
  +
For simplicity, we will show <code>:imap</code> but careful Vimmers are in the habit of using <code>:inoremap</code> which does not attempt to interpret the result of the mapping (with the <code>:imap</code> command, the result is scanned to see whether it contains another mapping).
With this quick combo ("Shift", + <Space>), one can easily (and might I add, intuitively) go into and come out of insert mode. I guess I always thought the <Space> would be a good way to do this sort of thing, since it is after all, so intuitive in the typing process. So why not make it such that it can "escape" you out into normal mode as well? Just type 'i', to go into insert mode, type in your stuff, and once you're done, hit Shift-space!
 
   
  +
If you are considering putting this map in your .vimrc be careful to not put any comments after it, imap will try to interpret the blank spaces after <Esc> producing random jumps after entering normal mode.
(note: I havent automated 'i' into the whole process yet, but does anybody think that it would be possible? I would certainly like to hear about it if you do work out something)
 
   
  +
===Alternative mappings===
----
 
  +
Here are some alternative suggestions:
I changed my CapsLock key to Escape under XFree86 with the following lines in my ~/.Xmodmap:
 
 
<pre>
 
<pre>
  +
" Can be typed even faster than jj.
! Esc on caps lock
 
  +
:imap jk <Esc>
remove Lock = Caps_Lock
 
  +
" Press i to enter insert mode, and ii to exit.
keysym Caps_Lock = Escape
 
  +
:imap ii <Esc>
</pre>
 
  +
" Use backtick.
 
  +
:imap ` <Esc>
In my ~/.xinitrc, xmodmap is called to set the mapping:
 
  +
" Two semicolons are easy to type.
<pre>
 
  +
:imap ;; <Esc>
if [ -f ~/.Xmodmap ]; then
 
  +
" Press Shift-Space (may not work on your system).
xmodmap ~/.Xmodmap
 
  +
:imap <S-Space> <Esc>
fi
 
  +
" Try the following so Shift-Space also enters insert mode.
  +
:nmap <S-Space> i
  +
" Or just Space to enter insert mode.
  +
:nmap <Space> i
  +
" In Mac OS X, mapping <S-space> does not work, but the following
  +
" is better (press the "apple" key and the space key).
  +
" Note that this will conflict with the spotlight shortcut
  +
:imap <D-space> <Esc>
  +
" On gvim and Linux console Vim, you can use Alt-Space.
  +
:imap <M-Space> <Esc>
 
</pre>
 
</pre>
   
  +
===Using the Tab key===
----
 
  +
:''If using MacVim under Mac OS X, see [[#Tab key under Mac OS X|below]] for a working procedure.''
I have a better tip. You can use some useful 'imap' keymaps for inserting mode. For example:
 
  +
It is possible to map the Tab key but that is not desirable because Ctrl-o and Ctrl-i (Tab) are very useful for [[jumping to previously visited locations]].
   
  +
With the following in your [[vimrc]], you can press Tab to return to normal mode:
 
<pre>
 
<pre>
<C-j> <Esc>lji
+
nnoremap <Tab> <Esc>
<C-k> <Esc>lki
+
vnoremap <Tab> <Esc>gV
<C-u> <Esc>i
+
onoremap <Tab> <Esc>
<C-l> <Esc> l
+
inoremap <Tab> <Esc>`^
  +
inoremap <Leader><Tab> <Tab>
 
</pre>
 
</pre>
   
  +
In normal mode, you can press prefix keys before a command (for example, 12 for a count). The <code>nnoremap</code> causes Tab to cancel any prefix keys.
<C-h> is crash with scancode of Insert key. so I use <C-u> keymap
 
   
  +
The <code>vnoremap</code> causes Tab to cancel any selection (<code>gV</code> is required to prevent automatic reselection).
----
 
Since on the french canadian keyboard the key combination Ctrl-[ is performed with Ctrl+AltCar+"the cedilla key" it's not very convenient.
 
   
  +
The <code>onoremap</code> causes Tab to cancel any operator-pending command (for example, <code>y</code>).
But the tip of using CTRL-C key combination work well on any keyboard mapping. It doesn't required you to modify any keymap, so it will work on any vanilla installation. From my point of view (switching from PC with English_US and Frech_CA keyboard layout) using CTRL-C instead of the hard to reach ESC key is the real TIP here.
 
   
  +
The first <code>inoremap</code> causes Tab to exit insert mode, and the <code>`^</code> restores the cursor position so exiting insert does not move the cursor left.
----
 
I have tried mapping "qq" and "jf" to <Esc> but I'm going to try to shift-space.
 
   
  +
The second <code>inoremap</code>, assuming the default leader key, allows you to press <code>\</code> then Tab to insert a tab character. You may prefer an alternative mapping to make it easier to insert a tab. For example, on some systems, you may be able to use Alt-Tab to insert a tab character with:
Incidentally, I mapped the space bar to i. So I will press <Space> to get into insert mode and &lt;S-space> to get out.
 
 
----
 
 
<pre>
 
<pre>
  +
inoremap <M-i> <Tab>
:map &lt;S-space> i
 
:imap &lt;S-space> <Esc>
 
 
</pre>
 
</pre>
   
  +
Some plugins may remap the Tab key. To remap them back from <code>.vimrc</code>, use <code>autocmd</code>:
From command mode &lt;S-space> takes you to insert mode, from insert mode &lt;S-space> takes you to command mode.
 
 
----
 
You can also remap the Caps Lock key to Control in Win9x using Microsoft's Windows 95 Kernel Toys (find them at http://www.microsoft.com/windows95/downloads/contents/WUToys/W95KernelToy/Default.asp); one of them ("keyboard remap") will let you do this. Despite their saying they're Win95 only, I've used this utility under Win98 and Win98SE without problems.
 
 
----
 
> I cannot get 'map! &lt;S-space> <Esc>' to work for me.
 
   
Since you are in INSERT mode when you want to press escape, it should be:
 
 
<pre>
 
<pre>
imap &lt;S-space> <Esc>
+
au VimEnter * map <Tab> <Esc>
  +
au VimEnter * imap <Tab> <Esc>
  +
au VimEnter * vmap <Tab> <Esc>
 
</pre>
 
</pre>
   
  +
Due to the way that Vim read keys, Ctrl-i is the same as Tab. Therefore, you cannot map Tab to generate Escape, ''and'' map Ctrl-i to do something different.
----
 
On Mac OS X:
 
   
  +
When adjusting indents, you can avoid tabs altogether:
I, too, am having problems getting the imap &lt;S-space> <Esc> scheme to work. I've noticed some really funky stuff. First, it doesn't work at all using App Terminal version of Vim, nor does it work using the GUI version for Jaguar either. Where the story gets strange is that it DOES work using the X-Windows version of gvim (via Apple X11) but not the xterm version.
 
  +
*In normal mode: Type <code><<</code> to shift the line left one 'shiftwidth', or <code>>></code> to shift right (and press <code>.</code> to repeat).
 
  +
*In insert mode: Press Ctrl-d to shift left, or Ctrl-t to shift right.
To sum up, it ONLY works on gvim via Apple's X11.
 
 
Hopefully someone can help us figure out what's going on here.
 
 
----
 
Well, <tt>map! &lt;S-space> <Esc></tt> doesn't work for me either on xterm, eterm or whatever. For
 
those with a 'normal' pc keyboard, you probably have the 'windows' key on the bottom row. Just
 
use it. Type the following on the commandline or put it in your .bash_profile or .xinitrc :
 
xmodmap -e "keysym Super_L = Escape
 
 
----
 
Okay a solution. Get the shareware utility "Keyboard Maestro". It allows you to remap keystrokes for all sorts of tasks. You can add a general remap for the Esc key to what ever you like, S-Space, or Ctrl-space, etc. Not exactly elegant via Vim, but it works.
 
 
----
 
Try:
 
map! &lt;S-Enter> <Esc>
 
instead of &lt;S-Space>
 
 
works a lot better and won't get pressed accidentally.
 
 
----
 
If you're having trouble getting <C-space> to map in Vim, it may be that <C-space> is being mapped to another keystoke. My keyboard was using <Nul> for <C-space>. So, you could put in your vimrc:
 
   
  +
====Tab key under Mac OS X====
  +
If you are using MacVim under Mac OS X, there is a good method to use the Tab key for Escape. The tool KeyRemap4MacBook can configure the Tab key to act as an Esc key in MacVim only (leaving the rest of the system untouched). Then you can press Ctrl-i to insert a tab character, and can press the Tab key to send Escape to MacVim. To do this, add the following to your <code>private.xml</code> file:
 
<pre>
 
<pre>
  +
<!-- TAB key changed to act as ESC, for MacVim only -->
" Map <C-space> to <Esc>. CTRL-@ will also be mapped to <Esc>
 
map <Nul> <Esc>
+
<appdef>
  +
<appname>MACVIM</appname>
  +
<equal>org.vim.MacVim</equal>
  +
</appdef>
  +
<item>
  +
<name>Change Tab to Esc in MacVim</name>
  +
<identifier>private.macvimdef</identifier>
  +
<only>MACVIM</only>
  +
<autogen>--KeyToKey-- KeyCode::TAB, KeyCode::ESCAPE</autogen>
  +
</item>
 
</pre>
 
</pre>
   
  +
===Using the Enter key===
To get the <> value for a particular keystroke, try pressing CTRL-K before the keystroke, while in insert mode.
 
  +
It's very easy to exit insert mode using the Enter key:
 
----
 
imap <Nul> <C-p>
 
This is really works.
 
But what is <Nul>? Is it keyboard or X11 defines it?
 
 
----
 
For Win2k and WinXP users, KeyTweak is probably your best bet, since it automates the registry access. I just downloaded it to swap my escape and capslock keys and it works great.
 
 
http://webpages.charter.net/krumsick/
 
 
----
 
And for those of us who prefer the console:
 
 
Alt-[key] is usually actually sent as <Esc>[key], and generally if you're coming out of insert mode it's because you want to execute a normal mode command, so:
 
 
Instead of <Esc>: to start an Ex command from insert mode, just press Alt-:. Sim. for everything else.
 
 
----
 
It's a good idea to use <ctrl-c> to get back to normal mode. these shift-space-things aren't easier to use and are user defined, so if you use another Vim installation, you have to define these two mappings first. so why not using <ctrl-c> instead? however, the only difference between <ctrl-c> and ESC is that incomplete abbreviations won't be expanded.
 
 
----
 
Get a Linux 101 keyboard from http://www.pckeyboards.com. Not only are the CTRL and ALT keys more convenient but the ESC key is where your little finger can hit it.
 
 
----
 
I use ":imap ;; <Esc>"
 
 
The ";" key is right at the fingertips, and I almost never actually need to type ";;". The &lt;s-space> is good too but it doesn't work when I use vi in a terminal (with putty).
 
 
----
 
How about remapping one of those irrelevant and annoying Windows-specific keys that are on every standard 104 key keyboard: the windows key and the context-menu key? They aren't used for anything on any of the Linux systems I've ever used.
 
 
This command turns the left Windows key into another Esc key. Just add it to your ~/.bashrc to make the change permanent.
 
 
 
<pre>
 
<pre>
  +
:inoremap <CR> <Esc>
xmodmap -e 'keysym Super_L = Escape'
 
 
</pre>
 
</pre>
   
  +
An example of using the above would be to type <code>ce</code> to change to the end of a word, then type new text, then press Enter to return to normal mode.
----
 
The following .Xmodmap swaps the CapsLock and Esc Keys:
 
<pre>
 
remove Lock = Caps_Lock
 
add Lock = Escape
 
keysym Caps_Lock = Escape
 
keysym Escape = Caps_Lock
 
</pre>
 
   
  +
When you want to enter a newline, you may find that Shift-Enter or Ctrl-Enter works (it should always work in gvim, but might not in a terminal, depending upon your system). If your Shift-Enter or Ctrl-Enter works, and you can get used to it, the above might be all you need.
----
 
Yet another way to remap the Caps Lock key to be Escape (i.e. helpful if you don't have root priv).
 
   
  +
An alternative would be to map Shift-Enter to generate Escape:
 
<pre>
 
<pre>
  +
:inoremap <S-CR> <Esc>
% xmodmap -pk | grep -i caps
 
66 0xffe5 (Caps_Lock)
 
% xmodmap -e 'keycode 66 = Escape'
 
 
</pre>
 
</pre>
   
  +
Then Enter will always work as expected, and Shift-Enter will always exit insert mode. If Shift-Enter does not work on your system, you might find that Ctrl-Enter (<code><C-CR></code>) does.
----
 
For Windows users:
 
   
  +
Another, more elaborate, alternative is:
Remap whatever you want any way you want: Use Autohotkey (www.autohotkey.com, an open source project)! You can map single keys to key combinations, you can map key combinations to single keys, you can even map double key strokes to single keys (e.g. double CAPS to ESC). But it's still much more. It's an extended, extremely powerful scripting language. There are scripts that allow the "command mode" style navigation everywhere in windows! Plus you can always write scripts yourself.
 
 
----
 
Why not use:
 
 
<pre>
 
<pre>
  +
function! ToggleEnterMapping()
map! ii <Esc>
 
  +
if empty(mapcheck('<CR>', 'i'))
  +
inoremap <CR> <Esc>`^
  +
return "\<Esc>"
  +
else
  +
iunmap <CR>
  +
return "\<CR>"
  +
endif
  +
endfunction
  +
call ToggleEnterMapping()
  +
inoremap <expr> <S-CR> ToggleEnterMapping()
  +
" Optional (so <CR> cancels prefix, selection, operator).
  +
nnoremap <CR> <Esc>
  +
vnoremap <CR> <Esc>gV
  +
onoremap <CR> <Esc>
 
</pre>
 
</pre>
   
  +
;Features
This allows the use of the same key to both enter and exit insert mode. It's also extra handy for dvorak users, since we can mash the i with the left index finger. And outside of roman numerals, how often does anyone need to type two consecutive i's?
 
  +
*Initially, pressing Enter returns to normal mode.
  +
*In insert mode, pressing Shift-Enter enters "multiline" mode, meaning that pressing Enter will insert a newline.
  +
*In insert mode, after pressing Shift-Enter to enter "multiline" mode, pressing Shift-Enter again exits (returns to normal mode).
   
  +
;Explanation
----
 
  +
The <code>mapcheck()</code> function returns the current insert-mode mapping for <code><CR></code> (Enter). The <code>empty()</code> function returns nonzero (true) if there is no such mapping.
I use AutoHotkey. The following script will map CapsLock to Ctrl in PuTTY. Every other app will use CapsLock like normal.
 
<pre>
 
classname = ""
 
keystate = ""
 
   
  +
The <code>inoremap <expr></code> command maps Shift-Enter to generate the expression returned by calling <code>ToggleEnterMapping()</code> (the code for either Escape or Enter). Calling the function toggles the insert-mode mapping for Enter: if it is mapped, it is unmapped; otherwise it is mapped to <code><Esc>`^</code> (generate Escape then go to the <code>^</code> mark).
*CapsLock::
 
WinGetClass, classname, A
 
if (classname = "PuTTY")
 
send,{Ctrl down}
 
else
 
GetKeyState, keystate, CapsLock, T
 
if (keystate = "D")
 
SetCapsLockState, Off
 
else
 
SetCapsLockState, On
 
return
 
   
  +
===Toggling insert mode===
*CapsLock up::
 
  +
Press Ctrl-Space to start and to stop insert mode (the same suggestion using Shift-Space is [[#Alternative mappings|above]]):
WinGetClass, classname, A
 
  +
<pre>
if (classname = "PuTTY")
 
  +
nnoremap <C-space> i
send,{Ctrl up}
 
  +
imap <C-space> <Esc>
return
 
 
</pre>
 
</pre>
   
  +
Or you may prefer to map Ctrl-Space to <code>a</code> rather than <code>i</code> so that repeatedly pressing Ctrl-Space does not move the cursor back (remember that pressing <code>I</code> allows you to insert a character at the beginning of the line):
I prefer this over losing the CapsLock key alltogether. Also this method is easily adaptable and I was already using AutoHotkey anyway.
 
 
----
 
If you have <tt>:set insertmode</tt>, then CTRL-L moves you from INSERT mode to NORMAL mode
 
 
----
 
Mapping ii to <Esc> is cool!
 
 
I have quite long fingers, therefore the upper keys (like numbers, even function keys) are somewhat easier to reach as the lower keys (like ctrl).
 
So mapping <F5> to <Esc> is very helpful to me (maybe <F9> too, for the right hand).
 
 
in .vimrc:
 
imap <F5> <Esc>
 
 
----
 
The answer is
 
 
<pre>
 
<pre>
  +
nnoremap <C-space> a
--contents of file .Xmodmap
 
  +
imap <C-space> <Esc>
remove Lock = Caps_Lock
 
remove Mod1 = Alt_R
 
remove Mod5 = Scroll_Lock
 
 
keycode 43 = h H Left
 
keycode 44 = j J Down
 
keycode 45 = k K Up
 
keycode 46 = l L Right
 
keycode 56 = b B BackSpace
 
keycode 64 = Alt_L
 
keycode 66 = Mode_switch
 
keycode 113 = Caps_Lock
 
 
add Lock = Caps_Lock
 
add Mod1 = 0x007D 0x009C Alt_L Alt_L
 
add Mod4 = 0x007F 0x0080
 
add Mod5 = Mode_switch ISO_Level3_Shift
 
 
</pre>
 
</pre>
  +
In the terminal <C-space> doesn't work, but <C-@> worked out (at least for me).
   
  +
An alternative follows. It uses <code>/i</code> to toggle insertion at the cursor, and <code>/a</code> to toggle insertion at the end of the line. If you use <code>/i</code> (or <code>/a</code>) to insert, you must <code>/i</code> (or <code>/a</code>) to exit (not Esc).
 
<pre>
 
<pre>
  +
nnoremap <silent> /i :let &insertmode=1-&insertmode<CR>
xmodmap .Xmodmap
 
  +
inoremap <silent> /i <Esc>:let &insertmode=1-&insertmode<CR>
  +
nnoremap <silent> /a :let &insertmode=1-&insertmode<Bar>if &insertmode<Bar>:startinsert!<Bar>endif<CR>
  +
inoremap <silent> /a <Esc>:let &insertmode=1-&insertmode<Bar>if &insertmode<Bar>:startinsert!<Bar>endif<CR>
 
</pre>
 
</pre>
   
  +
;References
Now in insert mode I use CAPS-{hjkl} to move around and CAPS-b to do a delete (BTW it works for all the X apps ALSO while writting this message)
 
  +
*{{help|'insertmode'}}
If someone would make a key below the spacebar to map to ESC I wouldn't have to move my fingers anymore.
 
  +
*{{help|:startinsert}}
   
  +
;Comment
to do the same thing in console mode use this map
 
  +
Probably can use <code>:set insertmode!</code> to toggle.
  +
  +
The <code>/</code> is easy to type, but did you mean to use <code><Leader></code>? Also, why toggle <code>'insertmode'</code>? Why not the following (and similar for append):
 
<pre>
 
<pre>
  +
nnoremap <Leader>i i
--contents of file map
 
  +
inoremap <Leader>i <Esc>
keycode 58 = Alt
 
keycode 125 = Caps_Lock
 
alt keycode 35 = Left
 
alt keycode 36 = Down
 
alt keycode 37 = Up
 
alt keycode 38 = Right
 
alt keycode 48 = Delete
 
 
</pre>
 
</pre>
   
  +
===Improving the Esc key===
  +
You may not find attempts to replace the Esc key satisfactory. However, if you don't like the cursor moving left when you exit from insert mode, you may want to try this variation from the Tab key section above:
 
<pre>
 
<pre>
  +
inoremap <Esc> <Esc>`^
loadkey map
 
 
</pre>
 
</pre>
   
  +
The above trick means that the cursor will not move if you press <code>i</code> to enter insert mode, then press Esc to exit. However, pressing <code>a</code> (append) then Esc ''will'' move the cursor, so this "improvement" may not satisfy you.
The problem as usual is in RTFM from xmodmap documention
 
   
  +
===Command-line mode===
The list of keysyms is assigned to the indicated keycode (which may be specified in decimal, hex or octal and can be determined by running the xev program). Up to eight keysyms may be attached to a key, however the last four are not used in any major X server implementation. The first keysym is used when no modifier key is pressed in conjunction with this key, the second with Shift, HERE--> the third when the Mode_switch key is used with this key and the fourth when both the Mode_switch and Shift keys are used <---
 
  +
If you want to map another key to Esc in command-line mode, if you attempt a mapping like
   
----
 
I didn't read all the comments, but in my enviro I have caps lock remapped to escape.
 
This is a bit faster than caps-lock being a Ctrl key. :)
 
 
My home directory contains a .xmodmaprc file which contains the two lines:
 
 
<pre>
 
<pre>
  +
cmap <C-space> <Esc>
clear lock
 
keycode 66 = Escape
 
 
</pre>
 
</pre>
   
  +
the resulting mapping will submit the command-line as if pressing Return rather. To create a mapping to act like Esc in command-line mode, you must map to <code>&lt;C-c&gt;</code> instead.
And after that you can run xmodmap ~/.xmodmaprc I'm unsure how to do this in text mode however.
 
   
  +
<pre>
----
 
  +
cmap <C-space> <C-c>
I am forced to use Windows at work, I tried www.autohotkey.com (the open source project for remapping keys) and it rocks!
 
  +
</pre>
   
  +
===Mapping problems===
To make Capslock work just like Escape, just add this to their default script:
 
  +
Vim runs on many different hardware and software platforms. Therefore some key sequences may not be available. For example, you may be able to map Shift-Space in a GUI Vim, but not in a terminal Vim (and even if you could, if you were running via PuTTY, for example, Vim might not receive the key code).
Capslock::Esc
 
   
  +
''For Shift-Space in terminal Vim, I used "URxvt.keysym.S-space: \033" in .Xresources.'' (for the rxvt-unicode terminal emulator).
----
 
I think it should be pointed out that xmodmap only works for people running X. It's not a solution for users of any other windowing system. And besides, I just want an easier keystroke than <Esc> for going into normal mode. I don't want to remap the CapsLock key for the entire operating system.
 
   
  +
To test your system, enter insert mode then press Ctrl-K followed by the key of interest (for example, press Ctrl-K then Shift-Space). {{help|i_CTRL-K}}
As for the shift+space problem, PuTTY seems to refuse to send the shift key along with space (or with enter, for that matter). I don't know why, but I'm hoping that "imap ii <Esc>" will suffice. As someone noted, shift+space does work in Gvim (even on Windows XP :) ) Unfortunately, that doesn't allow me to edit files on the server where I work, which is where I do most of my vimming.
 
   
  +
===Related tips===
----
 
  +
The following advises using <code><C-o></code> instead of <code><Esc></code> in insert mode mappings.
> This is not a good tip if you have e.g. norwegian <br/>
 
  +
*[[VimTip459|459 Use Ctrl-O instead of Esc in insert mode mappings]]
> keyboard layout. ctrl [ for me is pressing CTRL+Alt Gr + 9 <br/>
 
> [...] <br/>
 
> Since on the french canadian keyboard the key combination <br/>
 
> Ctrl-[ is performed with CTRL+AltCar+"the cedilla key" it's <br/>
 
> not very convenient.
 
   
  +
The following are not related to the Esc key. They try to avoid CapsLock applying in normal mode (so you can insert text in uppercase when needed, but ''not'' type in uppercase after exiting insert mode).
I don't know about norwegian or french keyboard layout, but I just found out this: On german keyboard layout the [ is also AltGr + 9, but ANYWAY: using CTRL+ the key where [ is on english keyboard layout has the same effect! Although there is another character mapped to the key right to 'p' than [ (which is [ in english keyboard layout) this shortcut has the effect of ESC!!
 
  +
*[[VimTip1183|1183 Insert-mode only Caps Lock]]
  +
*[[VimTip1519|1519 Making CapsLock work in Vim]]
   
  +
==Comments==
It works here in windows on german keyboard layout. Does it work for norwegian keyboard layout as well? Does it work in Linux?
 
  +
'''Use META + <next action>'''
   
  +
Depending on your terminal and vim settings it is possible that ^[ is sent firstly while you are pressing META(Alt)+<key>. So during Insert mode you can press META+j to finish editing, return to Normal mode and move to the next line.
----
 
I have been using
 
imap &lt;S-space> <Esc>
 
for a while. But this doesn't work in Mac OSX. Instead I found
 
imap <D-space> <Esc>
 
works even better in Mac! <D-space> means the "apple" key and the space key. Have fun!
 
   
  +
'''Remap Bash Shell's Escape Key for Readline VI mode'''
I tried to find a similar way in Cygwin, but no luck.
 
   
  +
Although slightly off-topic here, you can also remap the ESC key for Bash's Readline VI emulation mode to another key sequence.
----
 
Very useful for me was [http://sudan.ubuntuforums.com/showthread.php?t=106209].
 
   
  +
Create or modify your $HOME/.inputrc:
In brief: type
 
 
<pre>
 
<pre>
  +
# Remap ESC to use my double 'i' keypress to toggle insert or movement
xev
 
  +
# mode.
  +
$if mode=vi
  +
set keymap vi-command
  +
"ii": vi-insertion-mode
  +
set keymap vi-insert
  +
"ii": vi-movement-mode
  +
$endif
 
</pre>
 
</pre>
in the terminal, then press the button you want to remap for "Escape". I pressed left WinKey and the program displayed "keycode 115". After it I executed the command:
 
<pre>
 
xmodmap -e "keycode 115 = Escape"
 
</pre>
 
Now it WORKS! I've put the above command to my .bushrc to do it automatically.
 
   
  +
You'll likely need to exit all Bash shells for this change to take effect.
----
 
  +
  +
NOTE: There is currently a patch proposed on Jan 23 2012 (after bash-4.2_p20 release) for creating a time-out value for readline for double key mappings. This patch can be found on the bug-bash mailing list under the subject "Bash readline remap ESC insert/command mode key". An additional note, the shorter timeout value for double key mappings versus Vim's timeout is much quicker (using approx. half of Vim's wait time) making typing much quicker. Vim's timeout value seems to allow users to type the first char with a finger, and the second using a toe. Without this patch, users will have have problems typing commands containing an 'i' and a work around is to type 'i' and then the 'right cursor' key. In short, get the patch or await >bash-4.2_p20?

Revision as of 00:03, 21 July 2014

Tip 285 Printable Monobook Previous Next

created 2002 · complexity basic · version 6.0


This tip discusses how to exit from insert mode without needing to press Esc. The Vi editor was originally written on an ADM-3A terminal, which had the Escape key positioned where the Tab key occurs on most modern keyboards. Many touch typists appreciate the fact that they can leave their hands on the keyboard home row while using Vim, so there are several ideas for avoiding the Esc key at its current location (pressing Esc generally requires stretching to the top of the keyboard).

No utility programs or operating system tweaks are required for this tip. For other suggestions involving mapping keys with the operating system or utilities, see Map caps lock to escape in XWindows (for Unix-based systems), or Map caps lock to escape in Windows (for Windows). Some of the suggestions involve more than avoiding escape; topics also discussed include using the CapsLock key for Ctrl, and avoiding irritations from accidental use of CapsLock.

Avoiding the Esc key

If you have an American English keyboard, pressing Ctrl-[ (control plus left square bracket) is equivalent to pressing Esc. This provides an easy way to exit from insert mode.

If you have a keyboard where the bracket is already mapped to Alt Gr-something (like the spanish keyboard), press Ctrl-c to quit insert mode (however, Ctrl-c does not expand abbreviations). :help i_CTRL-C

Use Alt/Meta In a Terminal

Alt keys appear on most PC keyboards. Meta keys were used on some old systems.

If you use Vim in a terminal, simply press alt/meta+normal_mode_key. Most terminals send an escape character followed by the normal_mode_key that you pressed, removing the need to press escape yourself.

The terminals konsole and gnome terminal send the escape by default when you press alt/meta+normal_mode_key. For Xterm you can ctrl+click and select the option "Meta sends escape" or "Alt sends escape". [1]

Thus in insert mode pressing alt+h alt+j alt+k alt+l all take you to normal mode and move in the expected direction. You can hold down alt when moving even while in normal mode since the additional ESC that is sent does no harm.

The advantage of using this scheme is that you can use the alt/meta+key combination with any normal mode key, e.g.

  • Alt+o opens a new line below the one you are currently editing,
  • Alt+A appends to the end of the current line,
  • Alt+p pastes at the current insert location.
  • Alt+k moves up

Thus using vim via a terminal gives you these short cut powers on any stock standard system without the need to edit each systems vim mappings.

Mappings

It can be convenient to use a mapping so that pressing a key, or sequence of keys, generates Escape. The :imap command is used to create the mapping so that it only applies while in insert mode.

For example, the following allows you to press jj to exit from insert mode:

:imap jj <Esc>

To generate Escape, jj has to be typed quickly. :help 'timeout'

A problem with mapping a sequence like jj is that Vim will pause whenever you type j in insert mode (it is waiting for the next key to determine whether to apply the mapping). The pause is merely a visual distraction which you may not notice, and it does not slow down typing.

For simplicity, we will show :imap but careful Vimmers are in the habit of using :inoremap which does not attempt to interpret the result of the mapping (with the :imap command, the result is scanned to see whether it contains another mapping).

If you are considering putting this map in your .vimrc be careful to not put any comments after it, imap will try to interpret the blank spaces after <Esc> producing random jumps after entering normal mode.

Alternative mappings

Here are some alternative suggestions:

" Can be typed even faster than jj.
:imap jk <Esc>
" Press i to enter insert mode, and ii to exit.
:imap ii <Esc>
" Use backtick.
:imap ` <Esc>
" Two semicolons are easy to type.
:imap ;; <Esc>
" Press Shift-Space (may not work on your system).
:imap <S-Space> <Esc>
" Try the following so Shift-Space also enters insert mode.
:nmap <S-Space> i
" Or just Space to enter insert mode.
:nmap <Space> i
" In Mac OS X, mapping <S-space> does not work, but the following
" is better (press the "apple" key and the space key).
" Note that this will conflict with the spotlight shortcut
:imap <D-space> <Esc>
" On gvim and Linux console Vim, you can use Alt-Space.
:imap <M-Space> <Esc>

Using the Tab key

If using MacVim under Mac OS X, see below for a working procedure.

It is possible to map the Tab key but that is not desirable because Ctrl-o and Ctrl-i (Tab) are very useful for jumping to previously visited locations.

With the following in your vimrc, you can press Tab to return to normal mode:

nnoremap <Tab> <Esc>
vnoremap <Tab> <Esc>gV
onoremap <Tab> <Esc>
inoremap <Tab> <Esc>`^
inoremap <Leader><Tab> <Tab>

In normal mode, you can press prefix keys before a command (for example, 12 for a count). The nnoremap causes Tab to cancel any prefix keys.

The vnoremap causes Tab to cancel any selection (gV is required to prevent automatic reselection).

The onoremap causes Tab to cancel any operator-pending command (for example, y).

The first inoremap causes Tab to exit insert mode, and the `^ restores the cursor position so exiting insert does not move the cursor left.

The second inoremap, assuming the default leader key, allows you to press \ then Tab to insert a tab character. You may prefer an alternative mapping to make it easier to insert a tab. For example, on some systems, you may be able to use Alt-Tab to insert a tab character with:

inoremap <M-i> <Tab>

Some plugins may remap the Tab key. To remap them back from .vimrc, use autocmd:

au VimEnter * map <Tab> <Esc>
au VimEnter * imap <Tab> <Esc>
au VimEnter * vmap <Tab> <Esc>

Due to the way that Vim read keys, Ctrl-i is the same as Tab. Therefore, you cannot map Tab to generate Escape, and map Ctrl-i to do something different.

When adjusting indents, you can avoid tabs altogether:

  • In normal mode: Type << to shift the line left one 'shiftwidth', or >> to shift right (and press . to repeat).
  • In insert mode: Press Ctrl-d to shift left, or Ctrl-t to shift right.

Tab key under Mac OS X

If you are using MacVim under Mac OS X, there is a good method to use the Tab key for Escape. The tool KeyRemap4MacBook can configure the Tab key to act as an Esc key in MacVim only (leaving the rest of the system untouched). Then you can press Ctrl-i to insert a tab character, and can press the Tab key to send Escape to MacVim. To do this, add the following to your private.xml file:

  <!-- TAB key changed to act as ESC, for MacVim only -->
  <appdef>
    <appname>MACVIM</appname>
    <equal>org.vim.MacVim</equal>
  </appdef>
  <item>
    <name>Change Tab to Esc in MacVim</name>
    <identifier>private.macvimdef</identifier>
    <only>MACVIM</only>
    <autogen>--KeyToKey-- KeyCode::TAB, KeyCode::ESCAPE</autogen>
  </item>

Using the Enter key

It's very easy to exit insert mode using the Enter key:

:inoremap <CR> <Esc>

An example of using the above would be to type ce to change to the end of a word, then type new text, then press Enter to return to normal mode.

When you want to enter a newline, you may find that Shift-Enter or Ctrl-Enter works (it should always work in gvim, but might not in a terminal, depending upon your system). If your Shift-Enter or Ctrl-Enter works, and you can get used to it, the above might be all you need.

An alternative would be to map Shift-Enter to generate Escape:

:inoremap <S-CR> <Esc>

Then Enter will always work as expected, and Shift-Enter will always exit insert mode. If Shift-Enter does not work on your system, you might find that Ctrl-Enter (<C-CR>) does.

Another, more elaborate, alternative is:

function! ToggleEnterMapping()
  if empty(mapcheck('<CR>', 'i'))
    inoremap <CR> <Esc>`^
    return "\<Esc>"
  else
    iunmap <CR>
    return "\<CR>"
  endif
endfunction
call ToggleEnterMapping()
inoremap <expr> <S-CR> ToggleEnterMapping()
" Optional (so <CR> cancels prefix, selection, operator).
nnoremap <CR> <Esc>
vnoremap <CR> <Esc>gV
onoremap <CR> <Esc>
Features
  • Initially, pressing Enter returns to normal mode.
  • In insert mode, pressing Shift-Enter enters "multiline" mode, meaning that pressing Enter will insert a newline.
  • In insert mode, after pressing Shift-Enter to enter "multiline" mode, pressing Shift-Enter again exits (returns to normal mode).
Explanation

The mapcheck() function returns the current insert-mode mapping for <CR> (Enter). The empty() function returns nonzero (true) if there is no such mapping.

The inoremap <expr> command maps Shift-Enter to generate the expression returned by calling ToggleEnterMapping() (the code for either Escape or Enter). Calling the function toggles the insert-mode mapping for Enter: if it is mapped, it is unmapped; otherwise it is mapped to <Esc>`^ (generate Escape then go to the ^ mark).

Toggling insert mode

Press Ctrl-Space to start and to stop insert mode (the same suggestion using Shift-Space is above):

nnoremap <C-space> i
imap <C-space> <Esc>

Or you may prefer to map Ctrl-Space to a rather than i so that repeatedly pressing Ctrl-Space does not move the cursor back (remember that pressing I allows you to insert a character at the beginning of the line):

nnoremap <C-space> a
imap <C-space> <Esc>

In the terminal <C-space> doesn't work, but <C-@> worked out (at least for me).

An alternative follows. It uses /i to toggle insertion at the cursor, and /a to toggle insertion at the end of the line. If you use /i (or /a) to insert, you must /i (or /a) to exit (not Esc).

nnoremap <silent> /i :let &insertmode=1-&insertmode<CR>
inoremap <silent> /i <Esc>:let &insertmode=1-&insertmode<CR>
nnoremap <silent> /a :let &insertmode=1-&insertmode<Bar>if &insertmode<Bar>:startinsert!<Bar>endif<CR>
inoremap <silent> /a <Esc>:let &insertmode=1-&insertmode<Bar>if &insertmode<Bar>:startinsert!<Bar>endif<CR>
References
Comment

Probably can use :set insertmode! to toggle.

The / is easy to type, but did you mean to use <Leader>? Also, why toggle 'insertmode'? Why not the following (and similar for append):

nnoremap <Leader>i i
inoremap <Leader>i <Esc>

Improving the Esc key

You may not find attempts to replace the Esc key satisfactory. However, if you don't like the cursor moving left when you exit from insert mode, you may want to try this variation from the Tab key section above:

inoremap <Esc> <Esc>`^

The above trick means that the cursor will not move if you press i to enter insert mode, then press Esc to exit. However, pressing a (append) then Esc will move the cursor, so this "improvement" may not satisfy you.

Command-line mode

If you want to map another key to Esc in command-line mode, if you attempt a mapping like

cmap <C-space> <Esc>

the resulting mapping will submit the command-line as if pressing Return rather. To create a mapping to act like Esc in command-line mode, you must map to <C-c> instead.

cmap <C-space> <C-c>

Mapping problems

Vim runs on many different hardware and software platforms. Therefore some key sequences may not be available. For example, you may be able to map Shift-Space in a GUI Vim, but not in a terminal Vim (and even if you could, if you were running via PuTTY, for example, Vim might not receive the key code).

For Shift-Space in terminal Vim, I used "URxvt.keysym.S-space: \033" in .Xresources. (for the rxvt-unicode terminal emulator).

To test your system, enter insert mode then press Ctrl-K followed by the key of interest (for example, press Ctrl-K then Shift-Space). :help i_CTRL-K

Related tips

The following advises using <C-o> instead of <Esc> in insert mode mappings.

The following are not related to the Esc key. They try to avoid CapsLock applying in normal mode (so you can insert text in uppercase when needed, but not type in uppercase after exiting insert mode).

Comments

Use META + <next action>

Depending on your terminal and vim settings it is possible that ^[ is sent firstly while you are pressing META(Alt)+<key>. So during Insert mode you can press META+j to finish editing, return to Normal mode and move to the next line.

Remap Bash Shell's Escape Key for Readline VI mode

Although slightly off-topic here, you can also remap the ESC key for Bash's Readline VI emulation mode to another key sequence.

Create or modify your $HOME/.inputrc:

# Remap ESC to use my double 'i' keypress to toggle insert or movement
# mode.
$if mode=vi
    set keymap vi-command
    "ii": vi-insertion-mode
    set keymap vi-insert
    "ii": vi-movement-mode
$endif

You'll likely need to exit all Bash shells for this change to take effect.

NOTE: There is currently a patch proposed on Jan 23 2012 (after bash-4.2_p20 release) for creating a time-out value for readline for double key mappings. This patch can be found on the bug-bash mailing list under the subject "Bash readline remap ESC insert/command mode key". An additional note, the shorter timeout value for double key mappings versus Vim's timeout is much quicker (using approx. half of Vim's wait time) making typing much quicker. Vim's timeout value seems to allow users to type the first char with a finger, and the second using a toe. Without this patch, users will have have problems typing commands containing an 'i' and a work around is to type 'i' and then the 'right cursor' key. In short, get the patch or await >bash-4.2_p20?