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

Selections ​

Every editing command acts on the current selection. There is no cursor without a selection: even a single-character "cursor position" is a one-character selection.

How selections work ​

A selection has two ends: the anchor and the head. The head is the moving end; the anchor stays fixed until you reset the selection.

Building a selection ​

Whole lines ​

KeyEffect
xSelect the current line. On a line that is already selected, select the next line instead
XSelect the current line. On a line that is already selected, select the line above instead
Ctrl-xGrow the selection by one line downward
Ctrl-Shift-xGrow the selection by one line upward, or shrink one grown downward (kitty only)

x then d deletes a line, x then y copies it. Each x replaces the selection rather than adding to it, so pressing x three times leaves only the third line selected. To select three lines, press x then Ctrl-x twice, or use Extend mode.

Extend mode ​

Press e to enter Extend mode. Every motion then moves only the head while the anchor stays put: moving away grows the selection, and moving back toward where you started shrinks it. Press e again or Esc to return to Normal. The statusline shows EXT while Extend mode is active.

For a one-shot extend without entering Extend mode:

  • Under the kitty keyboard protocol, hold Ctrl with a motion key (Ctrl-h/Ctrl-j/Ctrl-k/Ctrl-l, Ctrl-w/Ctrl-b, Ctrl-f/Ctrl-t, Ctrl-g h, and so on): that one keypress runs the motion with extend on.
  • Keys with their own Ctrl binding keep it (Ctrl-d, Ctrl-u, Ctrl-o, Ctrl-e), and Ctrl with a key that isn't a motion does nothing.
  • Ctrl-x extends the line selection downward (see Whole lines) on any terminal. Its backward twin Ctrl-Shift-x needs kitty, since other terminals can't tell the two apart.

Search has the same one-shot extend: Ctrl-n (kitty only) moves the head to the next search match while the anchor stays put, so the selection covers everything from where you started through that match. Ctrl-Shift-n does the same backward, extending to the previous match.

Extending to a brand-new search

Extend mode also works with a new / or ? search, not only with Ctrl-n/Ctrl-Shift-n stepping through an existing one. Press e, then search: the anchor stays where you were, and the head jumps to the first match as you type, and again on every n/N afterward.

In Extend mode, w/b and x/X also shrink in whole units: the opposite key shrinks the selection one word or one line at a time. The word or line where you started stays selected whichever way you grow or shrink, and crossing back past it flips the selection's direction instead of cutting it off partway.

Word selected with w, then e to enter Extend mode
Lorem ipsum dolor sit

Press w
Lorem ipsum dolor sit

Press w again
Lorem ipsum dolor sit

Press b
Lorem ipsum dolor sit

The anchor stays on the space after Lorem throughout.

Text objects ​

Text objects select structured regions in one step. They use the m prefix: m i for inner content, m a for around (including delimiters, or one adjacent whitespace run for words):

SequenceSelects
m i w / m a wInner word / word + one adjacent whitespace run (see word-selects-whitespace)
m i W / m a WInner WORD / WORD + one adjacent whitespace run (see word-selects-whitespace)
m i ( / m a (Inside () / including ()
m i [ / m a [Inside [] / including []
m i { / m a {Inside {} / including {}
m i < / m a <Inside <> / including <>
m i " / m a "Inside "…" / including "…"
m i ' / m a 'Inside '…' / including '…'
m i ` / m a `Inside `…` / including `…`
m i a / m a aArgument (trimmed) / argument + separator comma
m i l / m a lLine content (no newline) / full line (with newline)
m i p / m a pParagraph text / the paragraph plus its trailing blank gap
m i f / m a fInside a function / the function including its signature (and attributes, decorators, …)
m i t / m a tInside a class or type / the class or type including its header
m i c / m a cInside a comment / the whole comment block
m i u / m a uInside a unit test function's body / the whole unit test, including its attribute or decorator
m i v / m a vInside an array/tuple/struct value / the value plus its separator comma
m i x / m a xBetween a pair of tags / the tags and everything between them

Closing brackets work as well as opening ones: m i ) is the same as m i (, and likewise for ], }, and >.

m i a / m a a and the last six rows above (f, t, c, u, v, x) are structure-aware. When the language's grammar supports it (see Syntax Highlighting), they select the actual function, class, comment, unit test, value, or tag pair.

  • Wherever the grammar doesn't cover the cursor (a syntax error, a buffer with no grammar at all), a and x fall back to a lexical scan.
  • Without a grammar, f/t/c/u/v do nothing, with no message.
  • Where the grammar covers it, a nested list, tuple, or struct literal passed as a call argument is itself the argument; use m i v / m a v for its members.

m i x selects the content without its surrounding whitespace. With the cursor on a tag itself, it selects the content of the enclosing pair.

Under the g prefix, each of f/t/a/c/u/v/x also jumps to the next or previous instance of its kind (lowercase forward, uppercase backward, e.g. g f/g F). See Moving Around.

Two shortcuts select the word under the cursor directly:

KeyEffect
m mWord under the cursor, same as m a w: with one adjacent whitespace run by default, by the same rule as w/b. Set word-selects-whitespace to off to get m i w instead (see Buffer options)
M MWORD under the cursor, same as m a W

How m i and m a differ on a word and on brackets:

Cursor mid-word, press m i w
Lorem ipsum dolor
Press m a w
Lorem ipsum dolor

Cursor inside the parens, press m i (
call(one, two)
Press m a (
call(one, two)

m i i selects the text you most recently typed before leaving Insert mode, however you entered it (i, a, o, O, A, I, c), so you can act on what you wrote. It follows the inserted text through later edits, and stops working once that text is deleted or the buffer's text is replaced. There is no m a i.

Select all ​

KeyEffect
%Select entire buffer
m /Turn every search match in the buffer into a selection. See Moving Around

Flipping and collapsing the selection ​

KeyEffect
;Collapse selection to head and exit Extend mode
Ctrl-;Collapse selection to anchor and exit Extend mode (kitty only)
Ctrl-eSwap anchor and head of each selection (Normal and Extend mode, any terminal)

Undoing a selection change ​

KeyEffect
m uGo back to the selections you last built, then to earlier ones
m UGo forward again through the selections m u stepped back over

m u brings back selections you built and then lost to a later change: a set of lines, several cursors, a text object, a drag. It restores every selection, not just the primary one.

Each selection command, such as x, %, C, ,, s, * or a text object, saves the selections it leaves. Extending, in Extend mode or with a Ctrl key, updates the selections it started from, so a run of extensions is saved once, and so is a mouse drag. Moving around saves nothing: a motion such as j, w or f, a search with /, ? or n, a click, scrolling or the jump list.

An edit keeps two selections in the undo history: the ones you made it with and the ones it left, such as the text a paste or r wrote, or the text you typed in Insert mode. i and a keep the selection you pressed them on. Once you edit, m u goes back through these, newest edit first, so d then u brings back what you deleted even after you collapse it. Selections you built but did not edit with are dropped at your next edit. A single cursor is never a step.

After you move away, the first m u returns to the selections you last saved, and each further one steps back. A count steps back that many (3 m u). Saving new selections after stepping back drops the ones m U would have returned to. Each pane keeps its own selections for each buffer and offers only the edits it made; edits from another pane move them along with the text. In a read-only buffer, m u goes back only as far as your last edit, as u cannot run there.

Multiple selections ​

HUME can hold several selections at once. Editing commands act on all of them, each independently.

ActionKeyEffect
Sift within selectionsEnter a regex pattern; each selection is narrowed to its sub-matches
Split on newlinesSSplit multi-line selections into one selection per line
Copy to next lineCAdd a copy of each selection on the line below, at the same columns. No text is copied
Trim whitespace_Shrink each selection so it starts and ends on non-whitespace; the text is unchanged
Keep primary,Remove all selections except the primary
Remove primaryCtrl-,Remove the primary selection, promote next (kitty only)
Cycle primary forward)Make the next selection the primary
Cycle primary backward(Make the previous selection the primary

Each copy C adds sits one selection-height below the last: a one-line selection copies to the next line, a three-line one three lines further down. A count (3C) adds that many copies at once, stopping where the buffer ends. Pressing C repeatedly stacks cursors line by line for column editing. HUME has no rectangular (block) selection.

Sift within (s) ​

Press s to enter Sift mode, type a regex pattern and press Enter. Each selection is narrowed to the parts matching the pattern, one new selection per match. This splits a line into tokens, for example:

  1. Select a line (x)
  2. Press s and type \w+ to select each word individually
  3. Press d to delete all words at once

The pattern sees each selection's text on its own, without a line break the selection ends on: the same text c would change.

  • ^ and $ match at the start and end of the selection, not of the line or the buffer. On ## Title selected with x, ^#+ selects ## and Title$ selects Title.
  • Add (?m) to make ^ and $ also match at the start and end of each line inside the selection.
  • \b treats the selection's edges as the edges of the text.
  • A line break the selection ends on is never matched, so a selection covering only an empty line has nothing to sift.

s needs at least one selection wider than a single character; on a bare single-character cursor it does nothing. Pressing Enter on an invalid pattern, or one with no match, reports it and leaves the selections as they were. See Regex syntax for the pattern flavor and case-sensitivity rules.

Released under the MIT License.