Skip to content

Moving Around ​

HUME's motions put the common jumps (a word, a character on this line, a matching bracket, the line you were on a minute ago) one or two keystrokes away.

Motions move the cursor and replace the current selection. In Extend mode they grow or shrink it instead; see Extend mode.

Basic movement ​

KeyMovement
hOne character left
lOne character right
jOne line down
kOne line up
w/WSelect next word/WORD
b/BSelect previous word/WORD
x/XSelect the current line, then the next/previous one on each press (see Whole lines)

A word breaks at punctuation, so don't is three words. A WORD breaks only at whitespace, so don't is one WORD. Set word-chars (see Buffer options) to widen what counts as a word: adding - makes foo-bar one word instead of three.

By default, w/W/b/B also cover the whitespace before the destination word. When none precedes it (the first word of a line, where a leading run would be indentation, or a word right after punctuation), they cover its trailing whitespace instead. So deleting a word never leaves a double space behind.

Use :set global word-selects-whitespace=after (or per buffer) to prefer the whitespace after the word, or =off to select only the bare word. See Buffer options.

Cursor on the first character, press w
default   Lorem ipsum dolor sit
off       Lorem ipsum dolor sit

Character find ​

Search within the current line for a specific character:

KeyMovement
f + charJump forward to next occurrence of char (inclusive)
F + charJump backward to previous occurrence of char (inclusive)
t + charJump forward to the character before the next occurrence of char (exclusive)
T + charJump backward to the character after the previous occurrence of char (exclusive)
=Repeat last find forward
-Repeat last find backward

After f, F, t, or T, HUME waits for the target character; Tab counts as one.

These are jumps, not extends: the selection collapses to a single character where you land, not a span from where the cursor started:

Cursor on the first character, press f i
Lorem ipsum dolor sit

Cursor on the first character, press t i
Lorem ipsum dolor sit

Line movement ​

The idiomatic line movements live under the g prefix:

KeyMovement
g gFirst line of file
g eLast line of file
g hStart of line
g lEnd of line (last character)
g sFirst non-whitespace character on the line
HomeStart of line
EndEnd of line

Matching pairs ​

KeyMovement
#Jump to the matching bracket or tag

From an opening bracket or tag, # jumps to the closing one, and back again from the closing side.

Where the cursor needs to be

For a bracket, # searches a selection that stays on one line, so it still finds ( ) [ ] { } when a motion leaves the cursor past one. For a tag, the cursor must be on the tag's own markup: its <, its >, the name, or an attribute. A count has no effect.

Structural navigation ​

When the language's grammar supports it (see Syntax Highlighting), these commands jump to the next or previous instance of a structural kind and select all of it, with the cursor (head) on its first character:

KeyCommandSelects
g f / g Fgoto-next-function / goto-prev-functionThe next/previous function
g t / g Tgoto-next-class / goto-prev-classThe next/previous class or type
g a / g Agoto-next-argument / goto-prev-argumentThe next/previous argument
g c / g Cgoto-next-comment / goto-prev-commentThe next/previous comment
g u / g Ugoto-next-test / goto-prev-testThe next/previous unit test
g v / g Vgoto-next-value / goto-prev-valueThe next/previous array/tuple/struct value
g x / g Xgoto-next-tag / goto-prev-tagThe next/previous tag pair

Lowercase jumps forward, uppercase backward, and each kind uses the same letter as its text object key.

  • They stop at either end of the buffer instead of wrapping.
  • Each one records a jump-list entry, so Ctrl-o returns to where you jumped from.
  • Without a matching grammar, g x/g X find tags with a lexical scan, and the others do nothing, with no message.

Jump to a line by number ​

Type : then a line number and press Enter to jump there:

CommandMovement
:<n>Jump to line <n> (e.g. :42)
:goto <n>Same, full form

Line numbers are 1-based. A number past the end of the file lands on the last line. The jump is recorded, so Ctrl-o brings you back.

Paragraph movement ​

KeySelects
{The previous paragraph
}The next paragraph

A paragraph is a block of non-empty lines between empty lines. Both keys select the whole paragraph they land on, plus the gap of empty lines below it, if any. Pressing {/} past the first/last paragraph does nothing.

The jump is recorded, so Ctrl-o brings you back. To select the paragraph without moving, use m i p (see Text objects).

Scrolling ​

KeyEffect
PageDownScroll one viewport down
PageUpScroll one viewport up
Ctrl-dScroll half a viewport down
Ctrl-uScroll half a viewport up

View prefix (z) ​

Press z then a second key to reposition the view; the cursor itself stays put:

KeyEffect
z kScroll cursor to top of screen
z zCenter view on cursor
z jScroll cursor to bottom of screen

Search navigation ​

KeyEffect
/patternSearch forward
?patternSearch backward
nNext match
NPrevious match
*Select the word under the cursor and search for it as a whole word, ignoring any current selection. Does nothing on whitespace or a blank line
m /Turn every search match in the buffer into a selection
Ctrl-/Search for the primary selection's text, literally (kitty only). Does nothing when the selection is only a line ending

m / precondition ​

m / uses the buffer's live search pattern if one is active, or else the search register s (the last pattern submitted to / or ?, or set by * or Ctrl-/). With neither, it does nothing: no error, and the selections stay unchanged. It runs from Normal or Extend mode. See Register prefix for the full list of registers.

Regex syntax ​

/, ?, s (sift-within), and * all use Rust regex syntax. Notable points:

  • Smart case. A pattern with no uppercase letter matches case-insensitively; one uppercase letter anywhere makes it case-sensitive. This looks at the raw pattern text, so an escape like \W or \S counts as uppercase and makes the search case-sensitive. Override with (?i) or (?-i).
  • Anchors. At / and ?, ^ and $ match at the start and end of the buffer. At s they match at the start and end of each selection; see Sift within.
  • Other inline flags: (?m) multiline ^/$, (?s) dot-matches-newline, (?x) extended (whitespace ignored), (?U) swap greedy/non-greedy.
  • . does not match newlines unless you add (?s).
  • No backreferences, no lookaround, no possessive quantifiers. \c and \C are not case toggles: a pattern containing them is invalid.
  • Invalid patterns do nothing during live preview: the cursor stays put. Pressing Enter on one reports it and leaves your last search as it was. Pressing Enter on a pattern that matches nothing shows "no match"; the pattern still becomes the current search.

Flags ​

Start a pattern typed at /, ?, or s with one or more of these letters followed by / to change how it's matched:

FlagEffect
mMove (or extend) every selection to its own next match, instead of only the primary. No effect at s, which already applies to every selection.
vMatch the pattern literally: none of its characters are treated as regex syntax.

Flags combine in any order: mv/.rs moves every selection to its own next literal .rs. n and N keep repeating with whichever flags were last used, until you search again.

Only m and/or v followed by / is read as flags. A pattern that starts with a / of its own (a path, say) is plain text: /usr/bin searches for /usr/bin. To search literally for text that looks like flags, prefix it with v/: v/m/s searches for m/s.

Search and replace ​

HUME has no substitute command. Replace with multiple selections instead:

  1. Search for the pattern with /foo (or * on a word to match it).
  2. Press m / to turn every match in the buffer into a selection.
  3. Press c and type the replacement once: every selected instance changes together.
  4. Esc returns you to Normal.

To replace within one region instead of the whole buffer, select the region first (e.g. x for a line, or m i { for a block), then use s (sift-within) with a regex instead of m /.

Jump list ​

HUME keeps a jump list of recent cursor positions.

KeyEffect
Ctrl-oJump to previous position
Ctrl-iJump to next position
TabJump to next position (except under the kitty protocol, where Tab moves between panes)

To get back to the buffer you were last in, use :b #. :e # does the same for a buffer that has a file name.

Released under the MIT License.