My Emacs settings - updated for 2026
- Completion → completion-at-point (Cider/Sly) via Corfu - Cape
- Vertico → Vertical completion interface
- Consult → Smart buffer/file/line commands
- Orderless → Space-separated fuzzy matching
- Marginalia → Minibuffer annotations
- Perspective → Per-project buffer isolation
- Paredit → Structural editing
- Sly → REPL, evaluation, navigation (Common Lisp)
- Quicklisp → Common Lisp library manager
- Corfu/Cape → In-buffer completion (completion-at-point UI)
- Cider → REPL, evaluation, debugging (Clojure)
- Basedpyright → Python types, navigation, rename (LSP)
- Ruff → Python lint + format-on-save (LSP add-on + apheleia)
- uv/envrc → Python projects with per-project venvs, auto-activated
Proper list API for Emacs Lisp, Magnar Sveen)
Installed with script in usr/local/bin, https://emacs-lsp.github.io/lsp-mode/tutorials/clojure-guide (Eric Dallo)
Official guide, but with tweaks:
What I kept:
- Performance tuning (gc-cons-threshold, read-process-output-max)
- Hooks for clojure-mode, clojurescript-mode, clojurec-mode
- LSP as the intelligence layer
What I have changed or removed:
- company-mode (for now)
- LSP provides completion via completion-at-point
- Works with our existing Vertico/Orderless stack
- Simpler, fewer moving parts
- Removed flycheck - LSP has built-in diagnostics.
Characteristics (observed so far):
- lsp-mode shows errors/warnings automatically
- No need for separate checker
- Removed lsp-treemacs
Usage (so far):
- Jump to definition - M-. (lsp-ui-peek)
- Find references - M-?
- Completion - Works with TAB/completion-at-point
- Rename - C-c l r
- Code actions - C-c l a
- Hover documentation - Automatic in minibuffer
- Diagnostics - Errors/warnings inline
- Compliant with Cider
- Paredit and structural editing untouched
Directive and instructions are set in ‘settings/setup-gptel.el’
| command | Description |
|---|---|
M-x gptel-switch-profile | Directive + backend + model together |
M-x gptel-set-directives | Directive only |
M-x gptel-switch-backend | Backend/model only |
In-buffer completion UI, the companion to Vertico for
completion-at-point. Corfu take care of rendering the popup, while
Cape supplies extra backends (file paths, dabbrev, etc.).
Configured in ‘settings/setup-corfu.el’.
- CAPF-native (completion-at-point-functions) same minimalist philosophy as Vertico and Orderless.
- Works automatically with Cider and Sly - no config per backend
- Less complexity from fewer moving parts, and lighter than company-mode
- Popups will appear automatically while typing (corfu-auto)
- corfu-popupinfo shows docs for the selected candidate
| Key | Description |
|---|---|
TAB | Complete / cycle candidates |
C-n | Next candidate |
C-p | Previous candidate |
RET | Accept selected candidate |
C-g | Abort completion |
M-d | Toggle documentation popup (corfu-popupinfo) |
C-M-i | Manually trigger completion-at-point |
Disabled for now in favor of Cider 2.x. Configuration code retained for future reference.
Installed with script in usr/local/bin, https://emacs-lsp.github.io/lsp-mode/tutorials/clojure-guide (Eric Dallo)
What I kept:
- Performance tuning (gc-cons-threshold, read-process-output-max)
- Hooks for clojure-mode, clojurescript-mode, clojurec-mode
- LSP as the intelligence layer
What I have changed or removed:
- Removed company-mode, because…
- LSP provides completion via completion-at-point
- Works with the existing Vertico/Orderless stack
- Less complexity while LSP is driving, it simpler, fewer moving parts involved.
- Removed flycheck - LSP has built-in diagnostics.
Characteristics (observed so far):
- lsp-mode shows errors/warnings automatically
- No need for separate checker
- (Removed lsp-treemacs)
Usage (what I learned so far):
- Jump to definition - M-. (lsp-ui-peek)
- Find references - M-?
- Completion - Works with TAB/completion-at-point
- Rename - C-c l r
- Code actions - C-c l a
- Hover documentation - Automatic in minibuffer
- Diagnostics - Errors/warnings inline
- Compliant with Cider
- Paredit and structural editing untouched
Directive and instructions are set in ‘settings/setup-gptel.el’
| command | Description |
|---|---|
M-x gptel-switch-profile | Directive + backend + model together |
M-x gptel-set-directives | Directive only |
M-x gptel-switch-backend | Backend/model only |
Common Lisp IDE. Configured in ‘settings/setup-sly.el’.
- SBCL installed system-wide via
apt install sbcl(/usr/bin/sbcl) inferior-lisp-programset to “sbcl”- Completion via completion-at-point - works with Corfu, no extra wiring
- Contribs: sly-quicklisp, sly-asdf (loaded if present)
- Installed per-user in
~/quicklisp/(NOT system-wide / not under sudo) - Loaded at SBCL startup via
~/.sbclrc(written byql:add-to-init-file) - Because Sly launches sbcl as your user, it reads your ~/.sbclrc and Quicklisp is available automatically in the REPL
- Files in $HOME must be owned by your dev user, not root. A missing or root-owned ~/.sbclrc is the usual cause of the slynk-quicklisp MISSING-DEPENDENCY error at connect time.
TBA
TBA
We got two complementary strategies for text completion:
Default completion UI that pops up while you type. Works with Cider, Sly, and file paths via Cape. This is the best choice for typical completion scenarios.
| Key | Description |
|---|---|
TAB | Complete / cycle candidates |
C-n | Next candidate |
C-p | Previous candidate |
RET | Accept selected candidate |
C-g | Abort completion |
M-d | Toggle documentation popup (corfu-popupinfo) |
C-M-i | Manually trigger completion-at-point |
Triggered manually with M-/. Cycles through various expansion
strategies (dabbrev, file names, lines, symbols). Gives me an option
for different expansion styles or if I need more control.
M-/ | Smart expansion with all strategies |
C-M-/ | Expand full lines only (great for repeating similar code) |
C-c / | Case-sensitive expansion |
C-c M-/ | Words/symbols only (no file paths or lines) |
C-c C-/ | Current buffer only (faster, less noise) |
C-c f / | File name completion only |
| Key | Description |
|---|---|
C-k | Kill to end of form (structurally safe) |
M-k | Kill whole form |
C-M-k | Kill forward expression |
C-x C-f | Open a file. Starts in the current directory |
C-_ | Undo |
C-M-_ | Redo |
C-x u | Undo tree - vundo tree-view |
Paredit operations are semantic:
| Key | Description |
|---|---|
C-→ | slurp (expand form) |
C-← | barf (contract form) |
M-s | splice (unwrap) |
M-( | wrap |
C-M-f/b | navigate by form |
| Key | Description |
|---|---|
C-M-f | Forward by expression |
C-M-b | Backward by expression |
C-M-u | Up in tree |
C-M-d | Down in tree |
C-→ | Slurp right (pull into form) |
C-<right> | Slurp right (pull into form) |
C-← | Barf right (push out of form) |
C-<left> | Barf right (push out of form) |
C-M-← | Slurp left |
C-M-→ | Barf left |
| Key | Description |
|---|---|
M-( | Wrap with () |
M-s | Splice (remove wrapping) |
M-S (shift-s) | Split expression |
M-J | Join expressions |
| Key | Description |
|---|---|
C-x b | consult-buffer - Buffer switching with groups (files, buffers, bookmarks) |
M-s l | consult-line - Jump to any line in current buffer |
M-g g | consult-goto-line - Better goto-line with preview |
M-g i | consult-imenu - Navigate code structure (great for Clojure!) |
Start with M-x sly (launches sbcl and connects to a sly-mrepl).
| Key | Description |
|---|---|
M-x sly | Start / connect REPL |
C-c C-c | Compile current top-level form |
C-c C-k | Compile & load whole file |
C-x C-e | Eval form before point |
C-c C-z | Switch to REPL |
M-. | Jump to definition |
M-, | Jump back |
C-c C-d d | Describe symbol |
C-c C-d h | HyperSpec lookup |
SLY history is bound to M-p/M-n by default; CIDER-style arrow bindings are added in setup-sly.el.
Note: history is persistent across sessions.
| Key | Description |
|---|---|
M-p | Previous input |
M-n | Next input |
M-r | Search history backwards (incremental) |
M-s | Search history forwards |
C-<up> | Previous input (CIDER-style, custom) |
| =C-<down>= | Next input (CIDER-style, custom) |
| Command / Form | Description |
|---|---|
M-x sly-quickload | Load a system interactively |
(ql:quickload :alexandria) | Load a library |
(ql:system-apropos "json") | Search available systems |
(ql:update-all-dists) | Update library distributions |
| Key | Description |
|---|---|
C-c C-c | Compile current buffer/region to image |
C-c C-o | |
C-c C-d | Open mermaid.live docs |
Python on the uv toolchain. Configured in ‘settings/setup-python.el’.
- uv → ONE binary replaces pyenv/pip/virtualenv/poetry
- basedpyright → types, navigation, rename - the PyCharm-parity piece
- ruff → lint - format - import sort (add-on LSP server)
- envrc/direnv → per-project .venv, invisible after one-time setup
- apheleia → ruff format - import sort on every save
- dape → debugging via debugpy (modern dap-mode replacement)
- python-pytest → magit-style transient test runner
- org-babel → literate exploration; optional Jupyter kernels
Workflow:
- basedpyright provides semantics (completion via Corfu, M-., rename),
- ruff provides style and lint,
- apheleia makes formatting.
- basedpyright and ruff installed per-user via
uv tool installinto~/.local/bin(added to exec-path in setup-python.el) - ruff runs as an add-on LSP server next to basedpyright; lint
rules and formatting live per-project in
pyproject.toml - envrc: each project needs
.envrcwith. .venv/bin/activateand a one-timedirenv allow - setup-python.el is self-contained: it does not depend on setup-lsp.el (Clojure, currently disabled); overlapping settings are identical, so enabling both is harmless
| Key | Description |
|---|---|
M-. | Jump to definition |
M-, | Jump back |
M-? | Find references |
C-c l r | Rename (project-wide, type-aware) |
C-c l a | Code action (auto-import, ignore rule, ..) |
C-c l d | Describe symbol at point |
C-c l t | Find type definition |
TAB | Complete (Corfu, LSP-fed) |
| (save) | ruff format + import sort, automatic |
| Key | Description |
C-c C-p | Start inferior Python REPL |
C-c C-c | Send buffer to REPL |
C-c C-r | Send region |
C-c C-e | Send statement at point |
C-c C-z | Switch to the REPL buffer |
| Key / Command | Description |
M-x dape | Start a debug session (pick debugpy) |
C-x C-a b | Toggle breakpoint |
C-x C-a n | Next (step over) |
C-x C-a s | Step in |
C-x C-a o | Step out |
C-x C-a c | Continue |
C-x C-a q | Quit session |
M-x dape-info | Variables/breakpoints/threads windows |