Skip to content

Core Plugins

HUME ships a some plugins under the core: namespace — a plugin and grammar manager, language server support, live git diff, and a few keymap alternatives. None of them load automatically. Nothing runs until you ask for it in your init.scm, so a default HUME is exactly what you see.

There are two ways to bring a plugin in:

scheme
(declare-plugin "core:plum")    ; lazy — loads the first time you use it
(load-plugin "core:plum")       ; eager — loads at startup

A plugin's key bindings only exist once its body has run, so a lazily declared plugin needs some other trigger — a command, an event, a language — to fire before you'd press one of its keys. The plugins marked below have no such trigger, so they're loaded eagerly instead. See Plugins for the difference in detail.

core:stdlib

A toolkit of small helpers that other plugins build on, rather than something you use directly. core:git-diff, core:pickers, core:vim-keybind, and core:lsp all depend on it, so declare or load it before them:

scheme
(declare-plugin "core:stdlib")

Always declare it bare

Don't pass #:commands/#:events/#:languages to core:stdlib's own declare-plugin call — leave it exactly as above. Every plugin that depends on core:stdlib relies on its default activation list; a custom one can leave out a helper a dependent plugin needs, and that dependent plugin will then misbehave instead of failing with a clear error.

If you're writing a plugin yourself, see Plugin API → Standard Library for every command it offers.

core:plum

PLUM — the HUME PLUgin Manager — installs and updates third-party plugins and themes from GitHub, and installs the tree-sitter grammars that power syntax highlighting. Its install and cleanup commands depend on core:stdlib.

scheme
(declare-plugin "core:stdlib")
(declare-plugin "core:plum")

PLUM never installs anything on its own: the commands below do the work when you run them.

CommandEffect
:plum-install-pluginsInstall all declared plugins not yet on disk
:plum-cleanup-pluginsRemove on-disk plugins no longer declared
:plum-update-pluginsPull the latest version of every installed third-party plugin
:plum-list-pluginsShow declared / installed / orphan / missing plugins
:plum-install-grammar <lang>Install and compile one grammar
:plum-list-grammarsShow the grammar catalog and what's installed
:plum-cleanup-grammarsRemove compiled grammars you no longer need
:plum-install-theme <user/repo>Install (or reinstall) a theme repo's themes
:plum-update-themesPull the latest version of every installed theme repo
:plum-list-themesShow installed theme repos and the themes each provides
:plum-remove-theme <user/repo>Remove an installed theme repo

plum-ensure-grammars — install a list of grammars not yet compiled — is for init.scm, not the command mode prompt; it takes a list argument.

scheme
(call! "plum-ensure-grammars" '("rust" "toml"))

Leaving PLUM out only removes these commands. Already-installed plugins, grammars, and themes keep working without it — PLUM is only needed to install new ones. See Syntax Highlighting for the grammar workflow and Configuration for the theme workflow.

core:lsp

Language server support: hover, go-to-definition, references, diagnostics, rename, formatting, code actions, signature help, completions, and inlay hints. It also downloads and manages the servers themselves (:lsp-install, :lsp-uninstall, :lsp-servers), and the running processes (:lsp-status, :lsp-stop, :lsp-restart).

scheme
(declare-plugin "core:stdlib")
(declare-plugin "core:lsp")

Requires core:stdlib declared or loaded first. core:lsp itself is still declared lazily here — it wakes up on the first buffer with a detected language, or the first :lsp-* command you type, and its key bindings go live at that same moment, before there's a buffer they'd need to act on.

See Language Servers for setup, the full command and key tables, and settings.

core:steel-server

Registers a language server for Scheme buffers (.ss/.scm/.sld) — which includes your own init.scm and plugin files, so you get hover, diagnostics, and completion while editing your HUME config. Requires core:lsp, which provides the editor-side features that make a registered server useful.

scheme
(declare-plugin "core:stdlib")
(declare-plugin "core:lsp")
(declare-plugin "core:steel-server")

Declared lazily like this, it activates on the first Scheme buffer or the first time you run :steel-server-install. It's registered so HUME's own commands and configuration functions are recognized while you edit init.scm or a plugin file — you won't see unknown-identifier warnings for anything HUME itself provides.

This is a temporary plugin. The underlying server isn't in HUME's regular server catalog yet, so it can't be installed through :lsp-install like other servers. Once it lands upstream, HUME's catalog will pick it up automatically and this plugin will be retired.

CommandEffect
:steel-server-installInstall the Scheme language server and register it for Scheme buffers

Installing requires cargo — install Rust from rustup.rs first. See Language Servers for the general LSP workflow.

core:pickers

Fuzzy file, buffer, and modified-file finders: z f opens a file picker (git-index-backed inside a repo, fd-backed otherwise), z b opens a buffer switcher, z m opens a picker over files with staged or unstaged git changes.

scheme
(declare-plugin "core:stdlib")
(load-plugin "core:pickers")

Must be loaded eagerly (core:stdlib only needs to be declared or loaded before it) — its keys are the only way to reach its commands, so declared lazily it would have no trigger to ever wake it up. By default the modified-files picker includes untracked files; turn them off with #:config:

scheme
(declare-plugin "core:stdlib")
(load-plugin "core:pickers" #:config (hash "untracked" #f))

See Fuzzy Finder for the file-source chain, keys, buffer display, and modified-files details.

core:git-diff

Live, VSCode-style inline git diff. As you type, compares the buffer against a git ref (default HEAD) and renders gutter +/-/~ signs, deleted lines as virtual rows, added/changed lines with a background tint, and word-level highlights inside changed lines.

scheme
(declare-plugin "core:stdlib")
(declare-plugin "core:git-diff")

Requires core:stdlib declared or loaded before it. Declared lazily like this, it wakes on the first buffer opened (signs default on) or the first :toggle-git-signs/:toggle-inline-diff you type.

CommandEffect
:toggle-git-signs [ref]Toggle gutter signs for the current buffer
:toggle-inline-diff [ref]Toggle inline rendering (virtual deleted lines, word highlights, background tint) for the current buffer

Both take an optional git ref, e.g. :toggle-inline-diff HEAD~2. Giving a ref always turns that rendering on and points it at that ref; it's sticky across a later bare toggle off/on. The ref is shared between the two commands. A file git doesn't know about yet (untracked, brand-new, or outside a repo) shows no diff.

Also keeps a "steel:git-branch" statusline element fresh for the focused buffer, e.g. (main) — no config needed, just add it to your own configure-statusline! call (see Statusline → Custom elements). Updates when you switch to a buffer and when you save it; empty for a buffer outside any repo.

No default key bindings — bind them yourself, e.g. (bind-key! 'normal "g Shift-d" "toggle-inline-diff").

Configure with #:config:

scheme
(declare-plugin "core:stdlib")
(declare-plugin "core:git-diff"
  #:config (hash "signs" #t "inline" #f "ref" "HEAD"))
KeyTypeDefaultEffect
"signs"bool#tWhether gutter signs start on for a newly opened buffer
"inline"bool#fWhether inline rendering starts on for a newly opened buffer
"ref"string"HEAD"The default git ref a buffer diffs against, until overridden per-buffer via the toggle commands

Inline rendering's background tint and word highlights depend on your theme defining colors for them; HUME's bundled themes do.

core:vim-keybind

Vim muscle memory: $, ^, 0, C and D (change/delete to end of line), Ctrl+6 (alternate buffer, kitty only), and o in Extend mode to swap the selection's ends. It does not bind G — that key is HUME's own prefix (G L/G U/G C, plus G R with core:lsp), and g e already goes to the last line.

scheme
(declare-plugin "core:stdlib")
(load-plugin "core:vim-keybind")

Must be loaded eagerly (core:stdlib only needs to be declared or loaded before it) — it replaces keys HUME already binds, and most of what it rebinds (goto-line-start, goto-line-end, and the rest) are built-in commands, not plugin commands, so there's no first dispatch to trigger loading. Declared lazily, $/^/0 would keep doing HUME's default thing until something unrelated woke the plugin up.

By default ('smart), C is context-sensitive: on a bare cursor with no count it changes to end of line as in vim, but with a real selection, or any count prefix (e.g. 3C), it runs HUME's own copy-selection-on-next-line, so that command stays fully reachable. Change this with #:config:

scheme
(load-plugin "core:vim-keybind" #:config (hash "change-to-eol" 'on))

'on always changes to end of line; 'off leaves C alone. core:stdlib is required for every mode, not just 'smart — config validation itself goes through it.

core:helix-surround

Helix-style surround keys: m s wraps the selection, m d deletes a surrounding pair, m r replaces one.

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

Must be loaded eagerly: it takes over m s — which by default selects a surrounding pair — and removes m w outright, so wrapping lives on m s alone once it's loaded. Declared lazily, m s would silently keep selecting instead of wrapping until something else triggered the plugin.

core:classic-paste

GUI-style paste, if you'd rather not have p choose a source for you: p / P paste the kill ring, Ctrl+V / Ctrl+Shift+V paste the system clipboard (Ctrl+Shift+V needs the kitty protocol).

scheme
(load-plugin "core:classic-paste")

Must be loaded eagerly — it replaces p/P/Ctrl+V/Ctrl+Shift+V's default behavior, so until it loads p keeps pasting the default way instead of erroring or doing nothing.

Released under the MIT License.