Keybindings
Every key in Macros is bound in Steel and every binding is overridable. Keymaps are named ("fundamental" is the global map; major modes add their own), and you set one with (bind-key "<map>" "<chord>" <command>).
Notation
- C-x — hold Control, press x.
- M-x — hold Meta (Alt/Option), press x; or press Esc then x.
- C-x C-f — a chord: C-x followed by C-f.
- cmd-c — the macOS Command key (system clipboard).
In a binding these are spelled ctrl-, alt-, cmd-, shift-, e.g. "ctrl-x ctrl-f".
Motion (fundamental map)
| Key | Command |
|---|---|
| C-f / C-b | forward-char / backward-char |
| C-n / C-p | next-line / previous-line |
| C-a / C-e | move-beginning-of-line / move-end-of-line |
| M-f / M-b | forward-word / backward-word |
| M-< / M-> | beginning-of-buffer / end-of-buffer |
| C-v / M-v | scroll-up / scroll-down |
| C-l | recenter |
| M-g g | goto-line-cmd |
Editing, kill & yank
| Key | Command |
|---|---|
| C-d | delete-char |
| C-k | kill-line |
| M-d / M-Backspace | kill-word / backward-kill-word |
| C-Space | set-mark |
| C-w / M-w | kill-region / kill-ring-save |
| C-y / M-y | yank / yank-pop |
| C-/ | undo |
| C-? | redo |
| C-t | transpose-chars |
| C-o | open-line |
| M-; | comment-dwim |
The system clipboard always works, including inside modal states: cmd-c / cmd-x / cmd-v (clipboard-copy / -cut / -paste).
Files, buffers & windows
| Key | Command |
|---|---|
| C-x C-f | find-file |
| C-x C-s | save-buffer |
| C-x b | switch-buffer |
| C-x C-b | ibuffer (the buffer manager) |
| C-x k | kill-buffer |
| C-x 2 / C-x 3 | split-window-below / split-window-right |
| C-x o | other-window |
| C-x 0 / C-x 1 | delete-window / delete-other-windows |
| C-x ^ / C-x } / C-x { | resize windows |
| C-x C-c | quit |
Search, command, eval
| Key | Command |
|---|---|
| C-s / C-r | isearch-forward / isearch-backward |
| M-% | replace-string |
| C-c o | occur |
| M-x | execute-extended-command (command palette) |
| M-: | eval-expression |
| M-i | completion-at-point |
| C-g | keyboard-quit |
Keyboard macros
| Key | Command |
|---|---|
| C-x ( / C-x ) | start-kbd-macro / end-kbd-macro |
| C-x e | call-last-kbd-macro |
Feature-specific prefixes live in their own pages: C-c C-l … for LSP, C-c p … for projects, and C-h … for help. Vim-style modal editing is available too, but off by default.
Prefix arguments
A numeric prefix repeats the next command, Emacs-style:
| Key | Effect |
|---|---|
| C-u N cmd | run cmd N times — e.g. C-u 10 C-n moves down 10 lines |
| M-N cmd | shorthand for the same — M-10 C-n |
| C-u cmd | C-u alone means 4; C-u C-u means 16, and so on |
| C-u 5 a | self-insert works too — inserts aaaaa |
The argument applies to motions and simple edits (move, kill, yank, delete, newline, undo/redo). Modal or one-shot commands (M-x, save, quit, toggles) ignore it and run once. Negative arguments aren't supported yet.
Rebinding
Add bind-key calls to your init.scm — it's the recommended way to bind a key. The map name for the global map is "fundamental"; mode maps are named after the mode ("org-mode", "magit-status", "dired-mode", …).
;; Rebind in the global map — pass the command name as a 'name symbol
(bind-key "fundamental" "ctrl-x n" 'next-buffer)
;; Rebind only inside a mode
(bind-key "org-mode" "ctrl-c x" 'org-todo)
;; Bind a command of your own, or an inline lambda
(define (hello) (message "hi"))
(bind-key "fundamental" "ctrl-c h" 'hello)
(bind-key "fundamental" "ctrl-c !" (lambda () (insert-string "!")))
Prefer the 'name symbol form. It names the command without evaluating it, so the binding works no matter what order your config files load in. Both your own defined commands and the built-in commands (next-buffer, find-file, magit-status, …) bind this way.
bind-key also accepts the command directly as a bare identifier (next-buffer, no quote). That form evaluates the function at bind time — a typo becomes an error when your config loads, and editor tooling like go-to-definition follows the binding — but the command must already be defined at that point. A plain string name works too, handy when pasting straight from a command list:
(bind-key "fundamental" "ctrl-x ctrl-d" next-buffer) ; bare identity (must be defined)
(bind-key "fundamental" "ctrl-x ctrl-f" "find-file") ; string name
define-key (the primitive)
bind-key is a thin wrapper over define-key, the lower-level primitive the keymap is built on. define-key takes a command name — a 'symbol (preferred) or a string. It resolves the name at keypress time, so it can't take a function or a lambda (use bind-key for those):
(define-key "fundamental" "ctrl-c d" 'lsp-find-definition) ; 'symbol (preferred)
(define-key "fundamental" "ctrl-c d" "lsp-find-definition") ; string still works
You'll see define-key throughout the bundled config and it's fully supported — reach for it when you specifically want the primitive or the exact Emacs spelling. For everyday rebinding, bind-key does everything it does and takes functions too.
To see what a key currently does, press C-h k (describe-key) and then the key. To list everything active, C-h b (describe-bindings). See Getting help.