Command mode
Command mode is where HUME reaches commands that aren't bound to a key. Press : in Normal mode to open the command mode prompt, type a name, and press Enter. Esc dismisses without running.
Every command in this manual is one of two kinds, and each is reachable only its own way:
- Typed commands: everything on this page. Reached only from the command mode prompt, take a text argument and an optional
!. - Editor commands: everything in the Builtin Commands reference. Reached only from a key or a plugin (including your
init.scm), never from the command mode prompt.
INFO
Navigate buffers with :bprev/:bnext from the command mode prompt. Doing this often enough to want a keybind? Use the editor commands goto-prev-buffer/goto-next-buffer in init.scm instead:
(bind-key! 'normal "ctrl-h" "goto-prev-buffer")
(bind-key! 'normal "ctrl-l" "goto-next-buffer")Most typed commands have a short alias. Both forms are listed below, and both work. Press Tab at any point for completion of names and, where it makes sense, arguments. When several candidates match, the first Tab completes the text they share and opens the candidate list; press Tab again to pick the first candidate and Shift-Tab to pick the last. :set global command-completion=first-candidate fills in the first candidate at once instead.
For running HUME from a shell instead, see Command-line Flags.
Quitting and saving
| Command | Effect |
|---|---|
:q, :quit | Close the focused pane; with one pane, close the buffer, and quit HUME when it's the last one |
:q! | Same, discarding unsaved changes |
:qa, :quit-all | Quit everything. Refuses if any buffer has unsaved changes, and jumps to the first one |
:qa! | Quit everything, discarding unsaved changes |
:w, :write | Save |
:w <path> | Save as |
:w! | Save, retrying with a permission change if the first attempt is refused; also overwrites a file changed on disk since it was last read or saved |
:wa, :write-all | Save every modified buffer |
:wq, :write-quit | Save, then close the focused pane; with one pane, close the buffer, and quit HUME when it's the last one |
Relative paths given to :w resolve against HUME's working directory (:pwd), not the shell's.
Files
| Command | Effect |
|---|---|
:e <path>, :edit <path> | Open a file. <path> may end in :line or :line:col to jump there, e.g. :e file.txt:42:5 |
:e | Reload the current file. Refuses if there are unsaved changes |
:e! | Reload, discarding unsaved changes |
:checktime | Check every open buffer against its file on disk right now, instead of waiting for the next automatic check (switching back to HUME, switching to the buffer) |
In arguments, % expands to the current file's path and # to the alternate file's. Both only work as a whole argument: :w %.bak won't expand. :b is the exception: it resolves # itself, which is why :b # works for buffers with no file on disk.
See Files & Buffers for what happens when a file changes on disk.
Buffers
| Command | Effect |
|---|---|
:ls, :list-buffers | List open buffers in the bottom drawer |
:b <name>, :buffer <name> | Switch buffer. Accepts a name, a unique filename prefix, a full path, a number from :ls, or # for the previous buffer (:b# and :b # both work) |
:bn, :bnext | Next buffer |
:bp, :bprev | Previous buffer |
:bd, :buffer-delete | Close the buffer. Refuses if there are unsaved changes; closing the last one leaves a scratch buffer |
:bd! | Close the buffer, discarding unsaved changes |
:b# is the quickest way back to the previous buffer. The same jump is also an editor command, goto-alternate-buffer, for binding to a key, and core:vim-keybind binds it to Ctrl-6 for you.
Panes
| Command | Effect |
|---|---|
:sp, :split | Split the focused pane, stacking the new pane below |
:vsp, :vsplit | Split the focused pane side by side |
Splitting is refused with a message when the pane is already too small. Focus and closing use the Ctrl-p prefix (Ctrl-p then h/j/k/l/p/s/v/c/t/T). See the Default Keys.
Tabs
A tab is a saved window layout (its own set of panes and splits), not a per-buffer strip.
| Command | Effect |
|---|---|
:tabnew [path], :tabe [path] | Open a new tab. With no path, the new tab's pane views the same buffer as the current one; with path, it opens that file instead |
:tabclose, :tabc | Close the current tab and every pane it owns. Refused with a message if it's the only tab |
:tabnext, :tabn | Switch to the next tab in display order |
:tabprev, :tabp | Switch to the previous tab in display order |
Cycling is also bound to Ctrl-p t/Ctrl-p T. See the Default Keys. By default the tab bar only appears once more than one tab is open (:set global tabline=always/never/dynamic changes this; see Configuration).
Editing
| Command | Effect |
|---|---|
:sort | Sort adjacent rows by their selected text |
:sort -r | Sort in reverse |
:sort -i | Sort case-insensitively |
:earlier [n|5m] | Step back n revisions (:earlier, :earlier 3), or back to how the buffer looked an age ago (:earlier 5m) |
:later [n|5m] | Step forward again after :earlier, same argument forms |
:sort groups your selections into runs of adjacent rows and sorts each run independently, keyed by whatever text you selected on that row, not necessarily the whole line. Select whole lines (% selects the whole buffer) to sort a file; select a single column across a block of lines to sort by that column instead. A run sorts numerically only if every row's key looks like a number: one row with non-numeric text drops the whole run back to plain text order. Two selections on the same row combine into one key rather than being treated as separate rows, so sorting several items within one line isn't what :sort does.
A single selection that spans several rows keeps its place in the buffer: the rows underneath it reorder, but the selection itself still covers the same stretch of text afterward.
:earlier and :later step through the undo history: back, then forward again along the path redo follows. A bare number counts revisions; a number with an s/m/h/d suffix names an age (:earlier 90s, :later 2h). Traveling past either end stops at the oldest/newest revision with a message.
:sortmia 34
zoe 19
kai 52
Result
zoe 19
mia 34
kai 52
Settings
| Command | Effect |
|---|---|
:set global <option>=<value> | Set an option everywhere |
:set buffer <option>=<value> | Set an option for this buffer only |
:set pane <option>=<value> | Set an option for this pane only (wrap-mode only) |
See Configuration for every option.
Display
| Command | Effect |
|---|---|
:theme <name> | Load a theme; with no argument, show the current one |
:theme-debug | Show the resolved styles for the main UI scopes |
:wrap, :toggle-soft-wrap | Toggle line wrapping in this pane. See wrap styles |
:mes, :messages | Show the message log in a read-only buffer |
Navigation
| Command | Effect |
|---|---|
:cd <path>, :change-directory <path> | Change the working directory |
:pwd, :print-working-directory | Print the working directory |
:goto <n> | Jump to line <n>. :42 is shorthand. Records a jump, so Ctrl-o comes back |
Config and plugins
| Command | Effect |
|---|---|
:plugins, :plugin-status | Show each plugin entry's state (declared, loaded or failed), what is still waiting to trigger it, and any plugin that is not installed (absent) |
:reload-config | Re-run init.scm from scratch |
:ver, :version | Show the editor version |
:tutor | Open the interactive tutorial |
Plugins add commands of their own once you load them. The :plum-* commands (installing plugins and grammars) come from core:plum, and :lsp-status, :lsp-stop, :lsp-restart, :diagnostics, and :format-source from core:lsp, and :lsp-install, :lsp-uninstall, and :lsp-catalog from core:lsp-install. None of these plugins is loaded until you ask for it in init.scm. See Core Plugins.
Finding a command
There is no listing command. Open the command mode prompt with : and press Tab: completion shows every registered typed name and alias, including stubs for plugins that haven't loaded yet. It never shows editor commands, since those aren't reachable from the command mode prompt at all; see Builtin Commands for the full list.