My Modern Emacs Configuration
Introduction
This article explores my carefully crafted Emacs configuration that emphasizes minimalism, productivity, and seamless AI integration. Built around modern completion systems and enhanced with Claude Code integration, this setup represents a balance between Emacs' power and contemporary development workflows.
Core Philosophy
The configuration follows three key principles:
- Minimalism: Clean interface with essential features only
- Modern Tooling: Leveraging contemporary packages like Vertico, Consult, and Treesitter
- AI-First Development: Deep integration with Claude Code and multiple AI backends
Architecture Overview
Package Management Strategy
The configuration uses use-package
with automatic installation via :ensure t
. This approach ensures packages are installed on first run while maintaining declarative configuration.
Directory Structure
~/.emacs.d/
├── init.el # Main configuration
├── early-init.el # Early UI and backup setup
├── custom.el # Auto-generated customizations
├── CLAUDE.md # AI assistant instructions
├── lisp/ # Custom packages
│ └── claude-code.el/ # Claude Code integration
├── backups/ # Organized backup system
└── elpa/ # Package installation
Key Features
Completion Ecosystem
The configuration implements a modern completion stack:
- Vertico: Vertical minibuffer completion
- Marginalia: Rich annotations for candidates
- Orderless: Flexible matching patterns
- Consult: Enhanced commands with live preview
- Embark: Context actions on candidates
- Corfu: In-buffer completion with 0.2s auto-delay
This combination provides intelligent, fast completion across all Emacs interfaces.
AI Integration
Claude Code Integration
The centerpiece of AI integration is Claude Code, bound to C-c c
:
(use-package claude-code
:load-path "lisp/claude-code.el"
:config
(claude-code-mode)
;; Auto-switch to claude-code buffer when it starts
(defun claude-code-auto-switch-focus (&optional arg)
"Switch to claude-code buffer and focus on it."
(when-let* ((buffer (get-buffer "*claude*")))
(let ((window (get-buffer-window buffer)))
(if window
(select-window window)
(switch-to-buffer-other-window buffer)))))
(advice-add 'claude-code :after 'claude-code-auto-switch-focus)
:bind-keymap ("C-c c" . claude-code-command-map))
Multi-Backend AI Support
GPTel provides access to multiple AI providers with easy switching:
;; Configure DeepSeek backend
(setq gptel-backend-deepseek
(gptel-make-openai "DeepSeek"
:host "api.deepseek.com"
:endpoint "/chat/completions"
:stream t
:key (lambda () (getenv "DEEPSEEK_API_KEY"))
:models '("deepseek-chat")))
;; Configure Gemini backend (default)
(setq gptel-backend-gemini
(gptel-make-gemini "Gemini"
:key (lambda () (getenv "GEMINI_API_KEY"))
:stream t))
Development Environment
Language Server Protocol
Automatic LSP activation for major languages:
(use-package eglot
:ensure t
:hook ((python-mode js-mode typescript-mode go-mode rust-mode) . eglot-ensure))
Treesitter Integration
Enhanced syntax highlighting via treesitter:
(use-package treesit-auto
:ensure t
:config
(treesit-auto-add-to-auto-mode-alist 'all)
(global-treesit-auto-mode))
Theme Management
Intelligent theme switching based on system appearance:
(defun auto-switch-theme ()
"Switch between standard-light and standard-dark themes based on system appearance."
(let ((dark-mode-p
(string-match-p
"Dark"
(shell-command-to-string
"defaults read -g AppleInterfaceStyle 2>/dev/null || echo Light"))))
(if dark-mode-p
(progn
(load-theme 'standard-dark t)
(setq current-theme-dark t))
(progn
(load-theme 'standard-light t)
(setq current-theme-dark nil)))))
;; Check every 60 seconds
(run-with-timer 0 60 'auto-switch-theme)
Note-Taking with Denote
Structured note-taking system integrated with the org/ workspace:
(use-package denote
:ensure t
:custom
(denote-directory (expand-file-name "~/workspaces/org/"))
(denote-known-keywords '("emacs" "programming" "electronics" "article" "project" "journal"))
(denote-infer-keywords t)
(denote-sort-keywords t)
:bind
(("C-c n n" . denote)
("C-c n i" . denote-link)
("C-c n b" . denote-backlinks)))
Key Bindings Philosophy
The key binding scheme prioritizes:
- Consistency: Related functions grouped under common prefixes
- Discoverability:
which-key
provides context-sensitive help - Muscle Memory: Common operations on easily accessible keys
Primary Key Maps
C-c c
- Claude Code (AI assistance)C-c a
- GPTel (AI backends)C-c n
- Denote (note-taking)C-x g
- Magit (git interface)
Enhanced Navigation
C-s
-consult-line
(enhanced search)C-x b
-consult-buffer
(smart buffer switching)C-x C-r
-consult-recent-file
C-.
-embark-act
(context actions)
Backup and Safety Features
Organized Backup System
Configured in early-init.el
to keep backups organized:
(let ((backup-dir (expand-file-name "backups/backups/" user-emacs-directory))
(auto-save-dir (expand-file-name "backups/auto-saves/" user-emacs-directory)))
(setq backup-directory-alist `((".*" . ,backup-dir))
auto-save-file-name-transforms `((".*" ,auto-save-dir t))))
Smart Auto-Formatting
JSON files are automatically formatted on save (limited to files < 50KB):
(add-hook 'json-mode-hook
(lambda ()
(when (< (buffer-size) 50000)
(add-hook 'before-save-hook 'json-pretty-print-buffer nil t))))
Performance Considerations
Lazy Loading
Most packages use :defer t
or mode-specific hooks to avoid startup delays:
(use-package markdown-mode
:ensure t
:defer t
:mode ("\\.md\\'" . markdown-mode))
Completion Tuning
Corfu auto-completion is tuned for responsiveness:
(use-package corfu
:ensure t
:init (global-corfu-mode)
:custom
(corfu-auto t)
(corfu-auto-delay 0.2)) ; Fast but not intrusive
Environment Integration
Shell Environment Import
API keys and paths are imported from shell:
(use-package exec-path-from-shell
:ensure t
:init
(when (memq window-system '(mac ns x))
(exec-path-from-shell-copy-envs
'("OPENAI_API_KEY" "GEMINI_API_KEY" "DEEPSEEK_API_KEY"))
(exec-path-from-shell-initialize)))
Server Mode
Emacs server starts automatically for external connections:
(require 'server)
(unless (server-running-p)
(server-start))
Workflow Integration
Project-Centric Development
The configuration integrates seamlessly with the ~/workspaces/
structure:
- Notes in
~/workspaces/org/
- Projects as subdirectories
- Claude Code awareness of project context
Git Workflow
Magit provides full git interface with C-x g
, supporting:
- Status overview
- Staging and committing
- Branch management
- Remote operations
Custom Packages
Claude Code Enhancement
The configuration includes custom advice for better Claude Code integration:
(defun claude-code-auto-switch-focus (&optional arg)
"Switch to claude-code buffer and focus on it."
(when-let* ((buffer (get-buffer "*claude*")))
(let ((window (get-buffer-window buffer)))
(if window
(select-window window)
(switch-to-buffer-other-window buffer)))))
(advice-add 'claude-code :after 'claude-code-auto-switch-focus)
Conclusion
This Emacs configuration represents a modern approach to text editing that embraces AI assistance while maintaining Emacs' core strengths. By focusing on completion, project awareness, and seamless AI integration, it creates a development environment that enhances productivity without sacrificing flexibility.
The configuration demonstrates how traditional Emacs can be enhanced with contemporary tools while preserving the editor's fundamental philosophy of extensibility and user control. The result is a setup that feels both familiar to Emacs veterans and approachable to newcomers seeking modern development tools.
Installation and Setup
- Clone configuration to
~/.emacs.d/
- Set environment variables for AI services
- Start Emacs - packages auto-install
- Create
~/workspaces/org/
for note-taking - Install language servers as needed
The configuration is designed to work out of the box while remaining easily customizable for individual preferences and workflows.