Extension

The main functionality of Evil is implemented in terms of reusable macros. Package writers can use these to define new commands.

Motions

A motion is a command which moves the cursor, such as w or e. Motions are defined with the macro evil-define-motion. Motions not defined in this way should be declared with evil-declare-motion.

(evil-declare-motion COMMAND)

Declare COMMAND to be a movement function. This ensures that it behaves correctly in visual state.

(evil-define-motion MOTION (COUNT ARGS...) DOC [[KEY VALUE]...] BODY...)

Define a motion command MOTION. ARGS is a list of arguments. Motions can have any number of arguments, but the first (if any) has the predefined meaning of count. BODY must execute the motion by moving point.

Optional keyword arguments are:

  • :type - determines how the motion works after an operator (one of inclusive, line, block and exclusive, or a self-defined motion type)
  • :jump - if non-nil, the previous position is stored in the jump list, so that it can be restored with C-o

For example, this is a motion that moves the cursor forward by a number of characters:

(evil-define-motion foo-forward (count)
  "Move to the right by COUNT characters."
  :type inclusive
  (forward-char (or count 1)))

The type of a motion determines how it works when used together with an operator. Inclusive motions include the endpoint in the range being operated on, while exclusive motions do not. Line motions extend the whole range to linewise positions, effectively behaving as if the endpoint were really at the end of the line. Blockwise ranges behave as a “rectangle” on screen rather than a contiguous range of characters.

Operators

An operator is a command that acts on the text moved over by a motion, such as c (change), d (delete) or y (yank or copy, not to be confused with “yank” in Emacs terminology which means paste).

(evil-define-operator OPERATOR (BEG END ARGS...) DOC [[KEY VALUE]...] BODY...)

Define an operator command OPERATOR. The operator acts on the range of characters BEG through END. BODY must execute the operator by potentially manipulating the buffer contents, or otherwise causing side effects to happen.

Optional keyword arguments are:

  • :type - force the input range to be of a given type (inclusive, line, block, and exclusive, or a self-defined motion type).
  • :motion - use a predetermined motion instead of waiting for one from the keyboard. This does not affect the behavior in visual state, where selection boundaries are always used.
  • :repeat - if non-nil (default), then . will repeat the operator.
  • :move-point - if non-nil (default), the cursor will be moved to the beginning of the range before the body executes
  • :keep-visual - if non-nil, the selection is not disabled when the operator is executed in visual state. By default, visual state is exited automatically.
  • :restore-point - if non-nil, point is restored when the operator is executed from ex.

For example, this is an operator that performs ROT13 encryption on the text under consideration:

(evil-define-operator evil-rot13 (beg end)
  "ROT13 encrypt text."
  (rot13-region beg end))

Binding this to g? (where it is by default) will cause a key sequence such as g?w to encrypt from the current cursor to the end of the word.

Text objects

Text objects are like motions in that they define a range over which an operator may act. Unlike motions, text objects can set both a beginning and an endpoint. In visual state, text objects alter both ends of the selection.

Text objects are not directly usable in normal state. Instead, they are bound in the two keymaps evil-inner-text-ojects-map and evil-outer-text-objects-map, which are available in visual and operator-pending state under the keys i and a respectively.

(evil-define-text-object OBJECT (COUNT) DOC [[KEY VALUE]...] BODY...)

Define a text object command OBJECT. BODY should return a range (BEG END) to the right of point if COUNT is positive, and to the left of it if negative.

Optional keyword arguments:

  • :type - determines how the range applies after an operator (inclusive, line, block, and exclusive, or a self-defined motion type).
  • :extend-selection - if non-nil (default), the text object always enlarges the current selection. Otherwise, it replaces the current selection.

For eample, this is a text object which selects the next three characters after the current location:

(evil-define-text-object foo (count)
  "Select three characters."
  (list (point) (+ 3 (point))))

For convenience, Evil provides several functions returning a list of positions which can be used for defining text objects. All of them follow the convention that a positive count selects text after the current location, while negative count selects text before it.

Note

The thingatpt library is used quite extensively in Evil to define text objects, and this dependency leaks through in the following functions. A thing in this context is any symbol for which there is a function called forward-THING [1] which moves past a number of things.

(evil-select-inner-object THING BEG END TYPE [COUNT LINE])

Return an inner text object range of COUNT objects. If COUNT is positive, return objects following point; if COUNT is negative, return objects preceding point. If one is unspecified, the other is used with a negative argument. THING is a symbol understood by *thing-at-point*. BEG, END and TYPE specify the current selection. If LINE is non-nil, the text object should be linewise, otherwise it is character wise.

(evil-select-an-object THING BEG END TYPE COUNT [LINE])

Return an outer text object range of COUNT objects. If COUNT is positive, return objects following point; if COUNT is negative, return objects preceding point. If one is unspecified, the other is used with a negative argument. THING is a symbol understood by thing-at-point. BEG, END and TYPE specify the current selection. If LINE is non-nil, the text object should be linewise, otherwise it is character wise.

(evil-select-paren OPEN CLOSE BEG END TYPE COUNT [INCLUSIVE])

Return a range (BEG END) of COUNT delimited text objects. OPEN and CLOSE specify the opening and closing delimiter, respectively. BEG END TYPE are the currently selected (visual) range. If INCLUSIVE is non-nil, OPEN and CLOSE are included in the range; otherwise they are excluded.

If you aren’t inside a pair of the opening and closing delimiters, it jumps you inside the next one. If there isn’t one, it errors.

The types of OPEN and CLOSE specify which kind of THING is used for parsing with evil-select-block. If OPEN and CLOSE are characters evil-up-paren is used. Otherwise OPEN and CLOSE must be regular expressions and evil-up-block is used.

If the selection is exclusive, whitespace at the end or at the beginning of the selection until the end-of-line or beginning-of-line is ignored.

Range types

A type is a transformation acting on a pair of buffer positions. Evil defines the types inclusive, line, block and exclusive, which are used for motion ranges and visual selection. New types may be defined with the macro evil-define-type.

(evil-define-type TYPE DOC [[KEY FUNC]...])

Define type TYPE. DOC is a general description and shows up in all docstrings.

Optional keyword arguments:

  • :expand - expansion function. This function should accept two positions in the current buffer, BEG and END,and return a pair of expanded buffer positions.
  • :contract - the opposite of :expand. Optional.
  • :one-to-one - non-nil if expansion is one-to-one. This means that :expand followed by :contract always return the original range.
  • :normalize - normalization function. This function should accept two unexpanded positions and adjust them before expansion. May be used to deal with buffer boundaries.
  • :string - description function. Takes two buffer positions and returns a human-readable string. For example “2 lines”

If further keywords and functions are specified, they are assumed to be transformations on buffer positions, like :expand and :contract.

States

States are defined with the macro evil-define-state, which takes care to define the necessary hooks, keymaps and variables, as well as a toggle function evil-NAME-state and a predicate function evil-NAME-state-p for checking whether the state is active.

(evil-define-state STATE DOC [[KEY VAL]...] BODY...)

Define an Evil state STATE. DOC is a general description and shows up in all docstrings; the first line of the string should be the full name of the state.

BODY is executed each time the state is enabled or disabled.

Optional keyword arguments:

  • :tag - the mode line indicator, e.g. “<T>”.
  • :message - string shown in the echo area when the state is activated.
  • :cursor - default cursor specification.
  • :enable - list of other state keymaps to enable when in this state.
  • :entry-hook - list of functions to run when entering this state.
  • :exit-hook - list of functions to run when exiting this state.
  • :suppress-keymap - if non-nil, effectively disables bindings to self-insert-command by making evil-suppress-map the parent of the global state keymap.

The global keymap of this state will be evil-test-state-map, the local keymap will be evil-test-state-local-map, and so on.

For example:

(evil-define-state test
  "Test state."
  :tag " <T> "
  (message (if (evil-test-state-p)
               "Enabling test state."
             "Disabling test state.")))

Footnotes

[1]There are many more ways that a thing can be defined, but the definition of forward-THING is perhaps the most straightforward way to go about it.