Personal Emacs configuration. Cross-platform (Linux/macOS/Windows) with optional EXWM window manager support on Linux.
- Emacs 31+ (emacs-next on Guix)
- Git, ripgrep (
rg), fd, GnuPG (gpg)
Run M-x kdb-doctor to check for all optional dependencies.
git clone https://github.com/kborling/emacs.d ~/.emacs.d
cp ~/.emacs.d/personal.el.template ~/.emacs.d/personal.el
# Edit personal.el with your API keys, SQL connections, etc.Packages install automatically on first launch.
init.el Main config — everything loads from here
early-init.el Pre-frame performance and UI chrome
personal.el Private settings (API keys — not tracked)
personal.el.template Template for personal.el
custom.el Customize output
lisp/
init-claude-workflow.el Claude transient over agent-shell: start, send, sessions
init-claude.el Claude session archive, history, search, Desktop import
init-claude-print.el Fallback Claude backend over pipes (M-x kdb-claude-print)
init-org.el Org mode, capture templates, org-modern
init-vc.el VC/Git transient menu (Magit-like, built-in VC)
init-exwm.el EXWM window manager (X11 only)
init-terminal.el Terminal/tmux optimizations
- Minibuffer: fido-mode + orderless + marginalia
- In-buffer: corfu + cape + completion-preview (ghost text)
- LSP: eglot with eglot-booster
- Tree-sitter: built-in Emacs 31
treesit-enabled-modes - Languages: C/C++, Rust, Zig, Go, TypeScript, Python, C#/.NET, Angular, HTML/CSS
- Diagnostics: flymake with eldoc integration
- VC: built-in VC with custom transient menu (
C-c g)
Sessions run in agent-shell over ACP, using the claude CLI login (works with a Max subscription, Linux and native Windows). Requires node and npm install -g @agentclientprotocol/claude-agent-acp.
- Start — new session at the project root, pre-filled with the region, Dired files or org entry at point; or pick any project (recent Claude directories first) and branch, which opens in its own git worktree
- Send — region, note, files or a file to a session you pick;
C-c l vhas Claude review your uncommitted changes (agent-review):RETjumps to an issue,mmarks,Ssends marked findings to a session to fix - Sessions —
C-c 'answers the oldest permission request from any session right in the minibuffer (yallow,!always,nreject,ggo there,qlater), then the next; with none pending it jumps to the next session that finished. agent-shell-attention showsAS:nin the mode line, echoes when a session needs you, and sends a desktop notification only while Emacs isn't focused;C-c ;opens agent-shell-hq's peek: every session grouped by project with live status, previewed as you move (n/p,RETswitch,snew);C-c l rhas Claude name the current session - History — every past session (agent-shell, CLI, Desktop's Code tab, imported Desktop chats) in one list: filter, full-text search, ask Claude about them, resume
New machine (see Claude setup checklist): install node and the Claude Code CLI, log in, then C-c l !.
Conversation data stays out of this repo and out of your projects: transcripts, agent-shell screenshots and prompt history all live in the archive (set kdb-claude-archive-dir in personal.el to move it).
Every session can read the archive (~/.claude-archive, via permissions.additionalDirectories and ~/.claude/CLAUDE.md), so Claude can look up earlier work itself.
- org-modern styling, org-appear
- Capture templates: todo, notes, journal, meetings, 1:1s, projects, decisions, specs, Ask Claude
- Refile targets across org files
- Deft for fast note search (
C-c o d)
- Eshell with custom prompt and toggle (
C-`) - Eat terminal emulator with eshell integration
- Clipboard support: macOS (pbcopy), Linux (xclip/xsel/wl-copy), Windows (clip.exe)
- Evil mode (opt-in per project/buffer,
C-c t v) - EPA symmetric encryption (
C-c s e/C-c s d) - Smooth pixel scrolling with momentum
- Custom minimal mode line
- Theme toggle with system-wide dark/light switching (EXWM)
| Key | Action |
|---|---|
C-; |
Comment line |
C-a |
Smart beginning of line |
C-k |
Smart kill line |
C-j |
Join lines |
C-o |
Open line |
C-z |
Undo |
C-\ |
Hippie expand |
C-g |
Smart quit (deactivate region first) |
C-M-s |
Isearch symbol at point |
M-z |
Zap up to char |
C-= / C-- |
Treesit expand/contract |
C-> / C-< |
Multiple cursors next/prev |
C-' |
Multiple cursors mark all |
C-c b |
Copy whole buffer |
C-c C-d |
Duplicate dwim |
C-c C-r |
Replace regexp |
C-c g |
VC transient menu |
| Key | Action |
|---|---|
C-x f |
Project find file (fd) |
C-x g |
Deadgrep (project search) |
C-x C-r |
Recent files |
C-x b |
Ibuffer |
C-x C-b |
Switch to buffer |
C-x k |
Kill current buffer |
C-x M-k |
Kill buffer other window |
C-c C-p / C-c C-n |
Previous/next buffer |
C-c C-o |
Other window |
C-x w s |
Swap window states |
Backtab |
Format current buffer |
| Key | Action |
|---|---|
C-` |
Toggle eshell |
C-~ |
New eat terminal |
C-c x e |
New eshell |
C-c x t |
New eat terminal |
C-c x s |
Shell |
C-c x d |
Dired jump other window |
C-c l opens the Claude transient. All keys below follow C-c l.
| Start | Send | Sessions | History | ||||
|---|---|---|---|---|---|---|---|
n |
New here (C-u pick project) |
s |
Region/note/files → session | ' |
Answer / next waiting | h |
All sessions |
N |
New on project + branch | f |
File → session | d |
Dashboard | / |
Search text |
v |
Review my changes | l |
Peek / switch (by project) | A |
Ask past sessions | ||
r |
Name this session | S |
Sync & commit | ||||
i |
Import Desktop export |
In the history list (C-c l h): RET open, u resume (imported chats continue in a new session that reads the old one), / filter, s search, A ask, g refresh.
Session shortcuts (no transient needed):
| Key | Action |
|---|---|
C-c ; |
Peek at sessions grouped by project (live status, preview), RET to switch |
C-c ' |
Answer the oldest permission request from any session, else jump to the next waiting session |
| Key | Action |
|---|---|
C-. |
Code actions |
C-c c r |
Rename |
C-c c f |
Format buffer |
C-c c o |
Organize imports |
C-c c a |
All code actions |
C-c c q |
Quickfix |
C-c c e |
Extract |
C-c c j |
Inline |
C-c c k |
Rewrite |
C-c c i |
Find implementation |
C-c c d |
Find declaration |
C-c c t |
Find type definition |
C-c c h |
Eldoc |
| Key | Action |
|---|---|
M-n / M-p |
Next/prev diagnostic |
C-c f n / C-c f p |
Next/prev error (skip warnings) |
C-c f d |
Buffer diagnostics |
C-c f D |
Project diagnostics |
C-c f s |
Start flymake |
C-c f q |
Quickfix |
| Key | Action |
|---|---|
C-c o a |
Org agenda |
C-c o c |
Org capture |
C-c o d |
Deft (note search) |
C-c o M |
Markdown → Org |
C-c o P |
Pandoc convert |
Capture templates: t todo, n note, j journal, w work, l link, c artifact, m meeting, 1 1:1, p project, d decision, s spec, a Ask Claude.
| Key | Action |
|---|---|
C-c n r |
Dotnet run |
C-c n b |
Dotnet build |
C-c n t |
Dotnet test |
C-c n ! |
Dotnet command |
tabspaces: one tab per project, each with its own windows and buffer list. C-x C-b (switch buffer) only offers the current workspace's buffers; C-x b (ibuffer) still shows everything. Nothing is written into projects.
| Key | Action |
|---|---|
C-c TAB o |
Open a project in its own workspace (or switch to it) |
C-c TAB s |
Switch to / create a workspace |
C-c TAB b |
Switch buffer within this workspace |
C-c TAB t |
Switch to any buffer, jumping to its workspace |
C-c TAB w |
Show workspaces |
C-c TAB n |
Rename workspace |
C-c TAB f / C-c TAB p |
Next/prev workspace |
C-c TAB r / C-c TAB R |
Remove current / chosen buffer from workspace |
C-c TAB d |
Close workspace (k also kills its buffers) |
| Key | Action |
|---|---|
C-c e v |
Visit init.el |
C-c e r |
Reload init.el |
C-c e d |
Doctor (check dependencies) |
C-c t t |
Toggle theme |
C-c t f |
Toggle fullscreen |
C-c t v |
Toggle evil mode |
C-c t V |
Toggle evil in buffer |
C-c h n / C-c h p |
Next/prev TODO |
C-c h o |
TODO occur |
C-c s e |
Encrypt file |
C-c s d |
Decrypt file |
C-h C-r |
Restart Emacs |
- uwu-theme — dark, colorful
- fleury-theme — dark, warm bronze/amber
- acme-theme — light
EXWM turns Emacs into a tiling window manager. It activates automatically when DESKTOP_SESSION=exwm.
- Add
emacs-exwmto your system packages inconfig.scm - Select "Custom Session" in your display manager — this runs
~/.xsession - Set
kdb-location-coordinatesinpersonal.elfor redshift night light
| Key | Action |
|---|---|
s-0 to s-9 |
Switch workspace |
s-! to s-) |
Move window to workspace |
s-h/j/k/l |
Focus left/down/up/right |
s-H/J/K/L |
Resize windows |
s-v / s-s |
Split right / below |
s-d / s-D |
Delete window / other windows |
s-q |
Close buffer |
s-f / s-F |
Fullscreen / floating toggle |
s-r |
Reset to line-mode |
s-i |
Toggle char/line mode |
s-SPC |
Application launcher |
s-RET |
Terminal |
s-c |
Browser |
s-e |
File manager |
s-t |
Toggle dark/light theme |
s-p |
Power menu |
s-x |
Lock screen |
s-S |
Screenshot |
s-TAB |
Switch EXWM buffer |
s-[ / s-] |
Prev/next workspace |
Terminal emulators (kitty, alacritty, xterm) auto-enter char-mode so keys go directly to the terminal. Use s-r to return to line-mode.
In line-mode, Emacs keys are translated for X applications:
| Emacs | Application |
|---|---|
C-b/f |
Left/Right |
C-p/n |
Up/Down |
C-a/e |
Home/End |
C-w |
Cut |
M-w |
Copy |
C-y |
Paste |
C-s |
Find |
Do this once per machine (e.g. the Windows work machine).
-
Install node, git, ripgrep (
winget install BurntSushi.ripgrep.MSVCon Windows; history search uses it) and the Claude Code CLI; runclaudeonce and log in with the Max account. -
Pull this config and restart Emacs (
agent-shellandagent-shell-attentioninstall themselves). -
Create an empty private repo for this machine's archive (keep work conversations in a separate repo from personal ones), then run
C-c l !(M-x kdb-claude-setup). Answer yes to the ACP adapter and emacs-skills. It:- creates the archive (
~/.claude-archive, its own git repo, never inside this config), or clones an existing one if you give its URL - asks for the private remote;
C-c l Sthen commits and pushes it in the background - sets
cleanupPeriodDaysto 36500 in Claude'ssettings.jsonso transcripts aren't deleted after 30 days - adds the archive to
permissions.additionalDirectoriesand a note toCLAUDE.md, so sessions can look up past work - runs
npm install -g @agentclientprotocol/claude-agent-acpand installs the emacs-skills plugin
On Windows these live in
%USERPROFILE%\.claude, not Emacs's AppData home. Safe to re-run. - creates the archive (
-
Check it works:
C-c l nin a project should open a Claude shell. If agent-shell misbehaves on Windows,M-x kdb-claude-printis the pipe-based fallback. -
Optional — bring in claude.ai / Desktop chat history:
- claude.ai → Settings → Privacy → Export data; save the emailed
manifest-*.jsonto Downloads. C-c l ion the manifest opens its 5 zip links in the browser (they need your login and expire in 24h); let them save next to the manifest.C-c l ion the same manifest again unpacks and imports them; they appear inC-c l has projectdesktop.
On Windows the zips are unpacked with the built-in
tar(nounzipneeded). - claude.ai → Settings → Privacy → Export data; save the emailed
Copy personal.el.template to personal.el and configure:
kdb-sql-connections— Azure SQL connection listkdb-evil-project-list— projects using vim bindingskdb-location-coordinates— lat:long for redshiftkdb-claude-export-directory— Claude Desktop export path