SiteMap Search ElispArea HowTo Glossary RecentChanges News Problems Suggestions

VimMode - User's Guide

Main page: VimMode

Introduction

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.

What vim-mode can do.

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.

What vim-mode cannot do.

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.

Installation

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.

Vim-mode modes

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:

normal-mode
In this mode the cursor can be moved and the text can be manipulated.
operator-pending-mode
This is a very special mode. When a command is executed normal-mode, sometimes an additional parameter is required. Then vim-mode goes to operator-pending-mode waiting for the parameter to be specified by the user. This additional parameter is a motion, i.e., some operation that moves the cursor. When this motion is executed, the operation is applied to the region given by the old and the new position of the cursor.
insert-mode
Text is inserted into the buffer.
replace-mode
Like insert mode but the inserted text overwrites the text in the buffer.
visual-mode
A visual region is activated like Emacs’s region. Vim-mode knows three types of visual-regions: character wise, whole lines and rectangular blocks. When a command is executed in visual-mode that would require a motion parameter in operator-pending-mode, the visual region is used to specify this motion.

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.

motion-mode
Only motions, scroll commands and window-commands are available.
window-mode
Only window commands are available.

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:

emacs-mode
In this mode all key-bindings of vim-mode are disabled and Emacs behaves like … well … Emacs. This mode can be used to temporarily switch to usual Emacs editing in a certain buffer. By default switching to and from emacs-mode is bound to Ctrl+Z.

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.

Selecting an appropriate start mode

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-mode
The start mode for all major modes, for which no special start mode is specified in vim: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
An associated list where each element is a pair (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.

Key Bindings

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:

  1. normal-mode
  2. operator-pending-mode
  3. motion-mode
  4. window-mode

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.

ModeEnabled 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.

ModeKeymapMapping
normal-mode vim:normal-mode-keymapvim:nmap
vim:normal-mode-local-keymapvim:local-nmap
operator-pending-mode vim:operator-pending-mode-keymapvim:omap
vim:operator-pending-mode-local-keymapvim:local-omap
window-mode vim:window-mode-keymapvim:wmap
vim:window-mode-local-keymapvim:local-wmap
motion-mode vim:motion-mode-keymapvim:mmap
vim:motion-mode-local-keymapvim:local-mmap
insert-mode vim:insert-mode-keymapvim:imap
vim:insert-mode-local-keymapvim:local-imap
visual-mode vim:visual-mode-keymapvim:vmap
vim:visual-mode-local-keymapvim: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.

Defining new commands and motions

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.

Write new commands

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.

count
A numeric argument usually defining how many times a certain command should be repeated. If no explicit count has been given, the parameter has the value nil.
motion
If the command operates on a certain region, the region is usually defined by a motion and this argument should be specified. When the command is executed in normal-mode vim-mode will switch to operator-pending to wait for the motion to be specified. Afterwards the command is executed with this motion. Note that usually count 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.
argument
Some commands take another argument besides the motion and the count. There are several types of arguments, the type is specified by appending a colon and the type-name after argument, 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.
register
If specified the command can operator on a register. The name of the register, which is a character, is passed in this argument.
nonrepeatable
If specified the command cannot be repeated by the repeat command bound to ‘.’ by default. This is usually the case for scrolling or window commands.
keep-visual
If specified the command does not end visual-mode when executed in visual-mode. This is usually the case for scrolling or window commands. Note that most editing commands do disable visual-mode.

As 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.

Writing new motions

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.

count
The number of times the motion should be repeated.
argument
An extra character argument to be given after the motion command has been initiated. Examples are the motions f F t T of Vim.
inclusive, exclusive, linewise, block
This is the default motion type of this motion command (see below).

Each 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.

Motion types and vim:motion objects

In Vim there several types of motions. The four basic types are

  1. characterwise, inclusive
  2. characterwise, exclusive
  3. linewise
  4. blockwise

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:

type
The motion type, inclusive, exclusive, linewise, block.
has-begin
If non nil the motion defines both an explicit end position and an explicit start position of the region. If it is nil the motion only defines an explicit end position and the start position is implicitly set to (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
The beginning of the motion, if not given it is set to (point).
end
The end position of the motion.

Most 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.