/divine

Modal editing for Emacs that feels like Emacs

Primary LanguageEmacs LispGNU General Public License v3.0GPL-3.0

Divine, a modal interface for Emacs with text objects (or something close enough)

Installation

Divine isn’t on Melpa (yet!). Simply clone the repository somewhere in your load-path, and

(require 'divine)

You can now activate Divine for every buffer with M-x global-divine-mode RET, or for the current buffer only with M-x divine-mode RET. The global approach is the preferred way; Divine provides facilities to customize its initial state per-buffer.

The simplest way to activate Divine is to add this to your init file:

(divine-global-mode)

Or with use-package:

(use-package divine
   :init (divine-global-mode))

Getting started

Basic motion

Basic motion is very close to ordinary Emacs commands: F will go forward one character, B backward. f and b will move forward and backward a word, respectively.

With p and n, you move to the previous and the next visible line, respectively. a and e go to the beginning and end of the current line, A end E move through sentences.

isearch is on s, r for backwards. S and R activate regexp search.

Operators

Like Vim and other modal editors, Divine has operators. Operators are commands that act on a region. Calling an operator with a non-empty region active will execute immediately. In normal mode, mark some text (m toggles the mark) and press d to delete it. If no region active region exists, the operator becomes “pending” until the point moves. When the point has moved, it runs on the text range between the previous and the new point position.

Here’s a very simple example, again with d, the deletion operator. If you move to the end of a line and press d, the cursor starts blinking fast and “Pending” appears in the echo area. Press a to go to the beginning of the line, and the line disappears (cancel with u).

All the basic operators have a “magic” motion that can be triggered by pressing them twice: dd kills the current line, cc does the same, but enters insert mode immediately after, ww copies it to the kill-ring, and so on.

Default bindingAction
c (change)Kill REGION to REGISTER then switch to insert mode
d (delete)Kill REGION to REGISTER
w (delete)Copy REGION to REGISTER
SPC wWrap REGION (prompt for char)

REGISTER defaults to the kill-ring.

Text objects

Text objects are motion commands that set both the point and the mark, and thus define a region. There are two types of text objects: scoped motions, which are motions that accept a scope modifier, and pure text objects, which cannot be used as motions.

Scoped motions

Divine has two standard scopes: around and inside, activated by a and i, respectively. Most basic motion commands respect these scopes, and behave as text objects when one is active. For example, di2w will delete two full words, starting from the one the point’s on. da2w will do the same, also eating the surrounding space.

aActivate the around scope.
iActivate the inside scope.

Pure objects

Pure objects accept scope modifiers, but don’t behave as motions even without one. Divine has only one such object, w, which is the balanced expression object. It takes an extra parameter, which is the delimiter to look for. For example, d2w( will unwrap both parentheses around the second sexp around point. di2w( will delete inside the sexp, and da2w( will also delete the parentheses.

wBalanced expression around point1

w is a special object. Special objects can hot-replace a pending operator with their own implementation. When called without a scope modifier, w will hot-replace divine-change by divine-rewrap, and divine-delete by divine-unwrap.

Regions

Divine has no equivalent to Vim’s visual modes. Instead, activating the region with m modifies the behavior of some commands. Operators run immediately and most actions are disabled.

MToggle region
mToggle full lines only
C-mToggle rectangular mark mode