Main page: VimMode
This text gives an overview about vim-mode. It is not an extensive introduction to Vim-like editing itself. If you need information about standard key bindings and features of Vi and Vim, we refer to the documentation of Vim itself. Because vim-mode tries the be as close to Vim as possible and practical, many parts of this documentation also apply to vim-mode.
Vim-mode is an emulation mode for VIM-like key-bindings and supports many of VIM’s editing features. Among them are
Vim-mode is developed to be easily extendable and configurable by the user. For this it provides
If some specific motion or command is missing, it can usually be implemented easily by a few lines of code. On the one hand, if a motion is defined properly, it is automatically available as operator in operator-pending mode for commands like ‘c’ or ‘d’. On the other hand, a command taking a motion as operator can also be used in visual mode were the motion is replaced by the active visual region.
Vim-mode can be used with all major modes in Emacs. Because several major-modes are no real editing-modes (e.g., info-mode), parts of the (or all) vim-mode key-bindings can be disabled for a certain major-mode. For example, in info-mode only movement, scrolling and window commands are available, while all other keys behave normally. This behaviour can also be customized.
A fundamental design decision for vim-mode is that we do not want to achieve 100% compatibility with VIM. This means, some commands or motions do not behave exactly as in VIM, e.g., the cursor placement after some command may be different. Usually this is not a big problem because the differences are mostly very small. The reason is that sometimes it is not worth the effort to reach 100% VIM-behaviour or the Emacs behaviour seems to be preferable or the VIM-behaviour seems to be somehow unintuitive (yes, this happens from time to time, e.g., the extension of the visual-region when using ‘iw’ on a sequence of empty lines).
A second point is if Emacs provides better alternatives for some problems or a specific task, we do not implement the VIM-specific one. For example, `Ctrl+P’ in VIM does something roughly equivalent to Emacs’s ‘dabbrev’-feature, but Emacs also knows many more packages for this job. In this case it’s better to bind `Ctrl+P’ to one of the Emacs functions instead of implementing a new (and less feature rich) one which resembles VIM’s behaviour.
Vim-mode is an emulation package for the editing behaviour of VIM. It will never try to emulate VIM’s programming language, so VIM-extension scripts will not work with vim-mode (if you want to extend vim-mode, use EmacsLisp). This also includes configuration variables accessible by VIM’s `:set var=value’ command (although for some special cases a mapping would be possible; theoretically a :set command for ex-mode can easily be defined, but usually using Emacs features is much better). If you want to configure Emacs and/or vim-mode, use Emacs’s customization features.
Download a release or the latest development version from the Bitbucket download page. Extract the archive somewhere and add the following to your .emacs file.
(add-to-list 'load-path "/path/to/vim-mode")
(require 'vim)
(vim-mode 1)
This will enable vim-mode globally. In order to enable all features, vim-mode depends on the following packages. If those packages are not available, only the corresponding features will be disabled. All features that do not depend on those packages will work normally.The Vim-way of editing is the so called `modal editing’. This means the editor know different states and in each state different commands are available. In one state text can be inserted, in another state the text can be manipulated using actions like delete, copy, paste, … During a session the users switches between those different states or modes.
Vim-mode knows several of the modes Vim has:
Vim-mode also knows a few other special modes. These modes cannot be activated from any other mode. In contrast they are activated as default mode when a buffer uses a certain Emacs major-mode. Each of these modes contains a certain subset of bindings to the commands and motions available in normal-mode. The purpose of those special modes is to make a few commands and motions available in non-editing Emacs modes, e.g., info-mode or gdb-mode.
Note that all bindings of window-mode are available in motion-mode and all bindings of motion-mode are available in normal-mode (i.e., exactly those bindings are available, so normal-mode can be seen as an extension of motion-mode).
There is one further special mode:
All submodes of vim-mode are implemented as ordinary Emacs minor-modes. Vim-mode ensures that exactly one of this minor modes is active at the same time.
An important property is, that each submode enables a specific sets of keymaps. Which keymaps are active in which mode is described in KeymapModeTable.
It is possible to define further vim submodes, each with its own set of key bindings, see [[VimMode_-_Extending?]] for further information.
Vim-mode allows to specify the default mode that should be enabled when a new buffer is created depending on the major-mode that is enabled. The following customizable variables can be used to specify the start mode for certain major modes.
vim:default-initial-modevim:initial-modes. It should by one of the symbol 'normal, 'window, 'motion or a symbol for a user defined mode. The mode to be started corresponds to the symbol of the form vim:MODENAME-mode, where MODENAME is one of the symbols above. The default value is 'normal which starts vim-mode in vim:normal-mode in each buffer.vim:initial-mode(major-mode . vim-mode) and major-mode is a symbol specifing a certain major-mode and vim-mode is one of the symbols valid for vim:default-initial-mode. When a certain major-mode is enabled in some buffer and this major-mode has an enty in vim:initial-modes then vim-mode is started in the given mode. By default vim-mode starts in several major-modes in either motion or window mode enabling only motion and window or only window commands.Note: An element (major-mode . nil) disables vim-mode an a certain major-mode.
As described above each submode enables a certain set of keymaps. Vim-mode keymaps are usual Emacs keymaps and can be used exactly as any other keymap. Much of the magic behind the scenes of vim-mode comes from switching between different submodes and therefore enabling and disabling certain keymaps.
Note that all keybindings in vim-mode can be customized and changed. The default keybindings are all specified in the file vim-maps.el.
Usually each submode of vim-mode comes with two keymaps which are strongly related to this mode, a global keymap and a local keymap. The bindings in the global keymap are available in all buffers whenever this submode is active, the bindings in the local keymap a buffer specific (like buffer-local variables). Many modes do not only enable their own keymaps but also keymaps from other modes. For example, normal-mode enables the following keymaps:
in this order, for each one the local keymap preceding the global keymap.
The following table gives an overview of all standard modes and the keymaps they activate.
| Mode | Enabled Keymaps |
| normal-mode | normal-mode, operator-pending-mode, motion-mode, window-mode |
| window-mode | window-mode |
| motion-mode | motion-mode, window-mode |
| operator-pending-mode | operator-pending-mode, motion-mode |
| visual-mode | visual-mode, operator-pending-mode, motion-mode |
The variable that contains a certain keymap has the name vim:MODE-keymap and vim:MODE-local-keymap for the global and the local keymap. There are several convenience functions to define bindings in each of those keymaps, e.g., a new binding in the global normal-mode keymap can be created by
(vim:nmap keysequence 'function)
which is equivalent to
(define-key vim:normal-mode-keymap keysequence 'function)
and in the local keymap by
(vim:local-nmap keysequence 'function)
The following table gives an overview over all standard keymaps, the corresponding variable names and the function used to define bindings.
| Mode | Keymap | Mapping |
| normal-mode | vim:normal-mode-keymap | vim:nmap |
vim:normal-mode-local-keymap | vim:local-nmap | |
| operator-pending-mode | vim:operator-pending-mode-keymap | vim:omap |
vim:operator-pending-mode-local-keymap | vim:local-omap | |
| window-mode | vim:window-mode-keymap | vim:wmap |
vim:window-mode-local-keymap | vim:local-wmap | |
| motion-mode | vim:motion-mode-keymap | vim:mmap |
vim:motion-mode-local-keymap | vim:local-mmap | |
| insert-mode | vim:insert-mode-keymap | vim:imap |
vim:insert-mode-local-keymap | vim:local-imap | |
| visual-mode | vim:visual-mode-keymap | vim:vmap |
vim:visual-mode-local-keymap | vim:local-vmap | |
| ex-mode | vim:emap | |
vim:local-emap |
An exception are the ex-mode bindings. They are not real keybindings but commands that can be executed in ex-mode, but the functions vim:emap and vim:local-emap behave like the others.
Vim-mode provides two macros to define commands and motions. Both are usual emacs lisp functions with special sets of parameters, therefore they can be used as any other interactive function. When executed interactively when vim-mode is activated all those function calles go through some special layers depending on the active submode. For example, when a motion is executed in normal or visual mode, the point is moved according to this motion. When executed in operator-pending mode the motion is used as parameter for the pending command.
The next two sections describe the interface for writing new commands and motions. Both should then be bound to some keys in appropriate keymaps.
Vim-mode commands are defined using the macro vim:defcmd, which has the following form.
(vim:defcmd command-name ((count [count-name])
(motion [motion-name])
(register [register-name])
(argument[:{char,text,file,buffer,...}] [arg-name])
[nonrepeatable]
[keep-visual])
body ...)The first three arguments are keyword arguments similar to defun*. The fourth and fifth argument are not real arguments, i.e., they do not bind a value. Instead they define special attributes of the command.
Each of the arguments is optional. An argument is either given as two element list (parameter parameter-name) or without explicit name just parameter. When no parameter name is specified the name is the same as the parameter itself, i.e., the parameter count defines the variable count whereas the parameter (count cnt) defines the variable cnt.
The parameters have the following meanings.
countnil.motioncount is nil if the command takes a motion because the repeat count will be used by the motion. If this parameter is not present the command will not take a motion but will be executed without switching to operator-pending mode.argumentargument, i.e., argument:char defines an argument which is a single character, argument:text a general string, argument:file a file-path and argument:buffer a buffer-name. If no explicit type is given the argument type will be char. Note that the only allowed argument type for commands bound in another mode than ex-mode (using vim:emap or vim:local-emap) is char, i.e., when calling the command an additional character is read an passed to the function. An example for a command like this is the r command of Vim. All other argument types make only sense for ex-mode commands.registernonrepeatablekeep-visualAs described above vim:defcmd can be used to define commands for both normal-mode and ex-mode. Each command should place (point) at the correct position after the operation.
In order to call a command from lisp-code, one has to use keyword arguments, e.g.,
(vim:cmd-delete-line :count 5)
deletes five lines. Note that the keyword used to call a commands are always :count, :motion, :register or :argument no matter which parameter names are used to define the command.
Vim-mode motions can be defined with the macro vim:defmotion. Similar to commands motions have several keyword-like optional parameters and a view attributes. The general form is as follows.
(vim:defmotion motion-name ((count [count-name])
(argument [argument-name])
{inclusive,exclusive,linewise,block})
body ...)The count and argument parameters are optional and can have a special variable-name. Exactly one of the attributes inclusive, exclusive, linewise, block must be specified.
countargumentf F t T of Vim.inclusive, exclusive, linewise, blockEach motion command should return an object of type vim:motion (see below). If the function does not return such an object explicitly, it is automatically created implicitly based on the position of (point) before and after execution of the motion and the specified motion-type. This means when a motion is called from lisp code it returns always a vim:motion object.
In Vim there several types of motions. The four basic types are
The motion type has no influence when the motion is just used to move (point) but influences on which region of the buffer a certain command that requires a motion parameter works. If the motions starts at point beg and ends at point end, characterwise inclusive motions work on all characters from beg to end including end while characterwise exclusive motions work on all characters from beg up to end - 1 excluding end. Examples for the first type are e % for the second type w l. Linewise motions always operate on whole lines from the line containing beg up to the line containing end. Blockwise motions operate on the rectangular region defined by row and column of beg and end.
A motion returns an object of type vim:motion either implicitly or explicitly and a command gets an object of type vim:motion passed in its motion parameter when called. The command should the work on the region specified by the begin and end position of the motion w.r.t. the motion type, e.g., linewise motions should work on whole lines.
The vim:motion object is a structure with four fields:
typeinclusive, exclusive, linewise, block.has-begin(point). All usual motions should set this field to nil and specify the new position of (point) as end position whereas text-objects, e.g., iw aw ib ab should set it to t and specify both positions.begin(point).endMost usual motions do not need to create the vim:motion object explicitly. Just move (point) to the desired position and the vim:motion object will be created automatically.
Note that an explicitly returned vim:motion object may have a different type than the default motion type. The default motion type is only important for simple motions that do not return an explicit vim:motion.
When writing commands operating on motions, you can use the helper functions defined in vim-core.el to retrieve information about the region covered by the motion w.r.t. the motion type. Among them there the following functions: vim:motion-line-count, vim:motion-first-line, vim:motion-last-line, vim:motion-first-col, vim:motion-last-col, vim:motion-begin-pos, vim:motion-end-pos.