You're reading docs for unreleased changes —  switch to v0.12.0.
Skip to content

Editing

Say what you mean, then say what to do with it. Because the selection always comes first, you can see exactly what an edit will touch before it happens — and the same handful of action keys work on a character, a word, a block, or forty places at once.

Inserting text

KeyWhere insertion begins
iBefore the selection
aAfter the selection
IFirst non-blank character on line
AEnd of line
oNew line below
ONew line above

Press Esc or Ctrl+c to return to Normal mode. Ctrl+w deletes the word before the cursor while you type.

Leaving Insert mode selects the text you just typed, instead of leaving a plain cursor — so you can immediately act on it again: delete it, surround it, search for it. Pressing Esc without typing anything leaves the cursor where you started. Disable this with the select-inserted-text option (see Configuration).

Because of this, i re-enters Insert mode before the current selection — so typing something, pressing Esc, then pressing i again continues before what you just typed, not after it. Use a to continue typing after it instead.

Whichever way you entered Insert mode, m i i recovers what you last typed after Esc — see Text objects.

Deleting and changing text

KeyEffect
dDelete selection (pushed onto the kill ring)
cDelete selection content and enter Insert mode (one undo group). A trailing newline is kept — c on a line rewrites its content without removing the line itself.

Use x to select the current line first if you want a line-wise delete (x then d).

See Copy & Paste for what the kill ring is and how to paste from it.

Replacing text

KeyEffect
r + charReplace every selected character with the typed character

Line endings inside the selection are left alone, so replacing across several lines won't collapse them into one. On a single character, r is delimiter-aware: replacing one half of a bracket or quote pair updates its partner too.

Enter and Tab count as the typed character, replacing with a newline or tab.

Changing case

KeyEffect
G LLowercase the selection
G UUppercase the selection
G CCapitalize the selection

Lines and alignment

KeyEffect
JJoin the selected lines into one
&Align selections into a column
>Indent lines touched by a selection
<Unindent lines touched by a selection

J replaces each line break with a single space and drops the next line's indentation, so joining wrapped code or prose doesn't leave a gap in the middle. When the next line is empty or only whitespace, the lines are joined with no space at all. Joining several lines at once leaves one cursor on each inserted space, ready to act on.

& lines up your selections using the primary selection's line as the starting point. Spaces are inserted at the left edge of each selection to reach that column, and if some other line needs more room, the column widens for everybody — which means the primary selection can shift right too. Multi-line selections are left alone. Where a selection sits too far right already, the run of spaces or tabs immediately to its left is squeezed down (never below one).

You can align to the left or the right depending on which end of the selection is the anchor; Ctrl+e swaps anchor and head. See Selections.

>/< shift every line touched by a selection by one indent level, using the buffer's tab-width and tab-style (see Configuration) — a prefix count shifts by that many levels at once (3>). A blank or whitespace-only line inside the selection is left alone, so it never picks up trailing whitespace. Each touched line's whole indent is re-rendered to the new width in the current tab-style, not just prepended to or trimmed from — so < immediately after > restores the previous indent width exactly (the characters themselves are re-rendered in tab-style, so a mixed tabs-and-spaces indent normalizes rather than coming back byte-identical). < on an indent narrower than one level flattens it to the left margin instead of going negative, so > afterward lands on a full level rather than back where the first < started.

Undo and redo

KeyEffect
uUndo (accepts a count — 5u undoes five steps)
U / Ctrl+rRedo

Undo history is a tree rather than a straight line, so redoing after new edits follows the most recent branch. The history lives in memory only and starts fresh each time you open a file.

Repeat

KeyEffect
.Repeat the last editing command

Dot-repeat replays the most recent insert session or editing command — delete, change, paste and so on, but not y.

Macros

Macros record and replay sequences of keys and are stored in registers. Register q is the default.

KeyEffect
Q Q or Q qStart recording into the default register q
Q <0-9>Start recording into a numbered register
Q (while recording)Stop recording
q qReplay register q
q <0-9>Replay a numbered register
<count> q qReplay register q <count> times

Recording is ignored in read-only buffers, and while a macro is already recording or replaying — so a macro can't record itself or nest.

Numeric count

Prefix a command with digits to repeat it. The first digit must be 19; 0 counts only once a count is already under way. So 12w moves forward 12 words and 10j moves down 10 lines. Counts above 10,000 are capped at 10,000.

ExampleEffect
3wMove forward 3 words
5jMove down 5 lines
12wMove forward 12 words
10jMove down 10 lines

0 on its own does nothing by default — g h goes to the start of the line. If you want vim's 0, the core:vim-keybind plugin binds it (see Core Plugins).

Surround

HUME's surround commands select or wrap delimiter pairs using the m prefix — see Selections for the full list of m i/m a text objects.

KeyEffect
m s + charSelect the surrounding delimiter pair (both ends)
m w + charWrap each selection with a delimiter pair

To delete or replace a pair, select it with m s and then act: m s ( then d deletes the parentheses, r replaces them.

Cursor inside, press m s (
call(one, two)

Press d
callone, two

...or press r [ instead
call[one, two]

Helix-style surround (bundled plugin)

If you prefer Helix's dedicated surround keys, a bundled plugin provides them:

KeyEffect
m s + charWrap (add surround)
m d + charDelete the surrounding pair
m r + char + newReplace the surrounding pair with a new delimiter

Note that this moves wrapping onto m s: it takes over the default m s (select the pair) and removes m w.

scheme
(load-plugin "core:helix-surround")

Released under the MIT License.