This .emacs.d
represents my libre attempt to build and document an advanced Emacs configuration utilizing most (but not all) of the latest trends in the Emacs community, tailored of course to my personal taste and needs.
This means spicy choices like:
eglot
overlsp-mode
vert&co
overhelm
andiy
corfu
overcompany
straight.el
overpackage.el
flymake
overflycheck
(what a comeback!)lispy
overparedit
SLY
overSLIME
prism
overrainbow-delimiters
andrainbow-blocks
gptel
over the ChatGPT client you made last weekend
My code harmoniously integrates around 200 different packages. I provide a modular code architecture that is easy to fork, mold into your own, and rebrand. If you want your own well-documented vanilla .emacs.d
(rather than a starter kit) but also don't want to start from scratch, this repo is for you.
When I was starting off with Emacs, other people's customizations were deeply helpful for me as a starting point; some of those customizations still find a home in my Emacs instance today. In the spirit of free software, I hope that I can pass on the good will.
You can draw inspiration from this repo, fork it for yourself, copy specific pieces of code, or even just add it as a submodule to your own Emacs directory.
This config makes extensive use of language servers and tree-sitter grammars. Most of my best supported languages will try to load a language server or tree-sitter grammar. If it fails to, it will warn you and give you a chance to install what is missing.
I usually only support one version of Emacs at a time. Currently I am supporting:
- Emacs 29
- Emacs 30
The following operating systems are supported:
Additionally, this entire .emacs.d
can be setup with native compilation, all necessary development environments below, and as your window manager by visiting my profiles repo, which can be executed on the Guix GNU/Linux distribution.
This Emacs configuration reflects my REPL-centered exploratory programming style.
I provide an IDE and REPL for each major environment that I work in.
One can debate about how many of the above languages Emacs is ideal for, but Emacs is certainly a best-in-class environment for Haskell, Elixir, Common Lisp, Scheme, and Clojure.
The best supported developer environments are the Lisp languages. Since they have feature rich IDEs with powerful REPLs, they do not need Eglot, and arguably Lisp with its ascetic syntax benefits less from tree-sitter:
Language | IDE | REPL | Eglot | Tree-sitter |
---|---|---|---|---|
Clojure | CIDER | CIDER | N/A | Yes |
Common Lisp | SLY | SLY | N/A | No |
Scheme | Geiser | Geiser | N/A | No |
I support both Eglot and tree-sitter for the following languages:
Language | IDE | REPL | Eglot | Tree-sitter |
---|---|---|---|---|
C | c-ts-mode |
Yes | Yes | |
C++ | c++-ts-mode |
Yes | Yes | |
Go | go-ts-mode |
go-playground | Yes | Yes |
Python | Anaconda | run-python |
Yes | Yes |
Ruby | Robe | inf-ruby | Yes | Yes |
Rust | Racer | rust-playground | Yes | Yes |
I do not support Eglot or tree-sitter for these languages. Generally it is because GNU Guix does not have an appropriate language server or tree-sitter grammar packaged for it yet:
Language | IDE | REPL | Eglot | Tree-sitter |
---|---|---|---|---|
Dockerfile | docker.el | TRAMP | No | Yes |
Elixir | Alchemist | inf-elixir | No | Yes |
Fish | fish-mode | fish-completion | No | No |
GDScript | gdscript-mode | Yes | No | |
Groovy | groovy-mode | No | No | |
Haskell | Intero | Dante | No | No |
Java | java-ts-mode |
No | Yes | |
JavaScript | js2-mode | Indium | No | No |
Kotlin | kotlin-mode | No | No | |
Objective-C | objc-mode |
No | No | |
PHP | php-mode | PsySH | No | No |
SQL | sql-mode | emacsql | No | No |
Swift | swift-mode | No | No | |
TypeScript | Tide | Indium | No | Yes |
This configuration ships with a great many helpful tools:
Feature | Tool |
---|---|
Benchmarker | elisp-benchmarks |
Bug tracker | debbugs |
Clipboard | Clipetty |
Completion (regular buffer) | Corfu |
Completion (minibuffer) | Vert&co |
Dashboard | Dashboard |
Documentation searcher | devdocs |
File manager | eFar |
Gemini browser | Elpher |
HTTP browser | EWW |
Hyperlinker | Hyperbole |
IRC client | ERC |
Kubernetes client | kubernetes-el |
LLM client | gptel |
LSP client | Eglot |
Mail client | Gnus |
Mail indexer | Notmuch |
Modal editor | lispy |
Modeline | Smart Mode Line |
MUD client | mu.el |
Music player | Emms |
Music streamer | pianobar.el |
Organization | org-mode |
Project interaction | project.el |
REST client | restclient.el |
Shell | Eshell |
Spreadsheets | Dismal |
Syntax checker | flymake |
Syntax highlighter | prism |
Undo visualizer | undo-tree |
Version control | Magit |
Wikipedia editor | mediawiki.el |
Window configuration | winner-mode |
Window manager | exwm |
There are many beautiful theme families for you to enjoy:
- arjen-grey
- deep-thought
- dracula
- exotica
- gotham
- molokai
- omtose-phellack
- purple-haze
- sanityinc-tomorrow
- timu-caribbean
- timu-macos
- timu-rouge
- timu-spacegrey
- zenburn
Package management is provided by:
If you wanted to reference my .emacs.d
from your own, you could add it as a git submodule to your Emacs directory, add that folder to your load path, and then reference specific files of mine that you like.
Run something like this in your Emacs directory:
git submodule add https://github.com/enzuru/.emacs.d enzuru
Add something like this to your init:
(add-to-list 'load-path "~/.emacs.d/enzuru/enzuru/features")
(require 'enzuru-file-management)
Referencing my configuration requires use-package and straight.el.
These are the most important keystrokes of all. If you know these keys keystrokes, you can get helpful information whenever you are stuck! These keystrokes are far more helpful than Google.
C-h(elp) b(indings)
shows the keybindings available in the current buffer.C-h(elp) d(ocumentation)
lets you search through all available documentation.C-h(elp) f(unction)
displays the current list of available functions.C-h(elp) i(nfo)
shows the info docs installed on your computer (no need to have a browser open just to read documentation).C-h(elp) m(ode)
shows information about all the modes in the buffer.C-h(elp) k(ey)
let’s you type a keystroke and find out what it does.C-h(elp) v(ariable)
displays the list of available variables.
This is the stuff that you're used to doing in other editors.
C-w
is my cut,M-w
(orC-q(opy)
) is my copy,C-y
is my paste.C-k
deletes a line.C-g
cancels the current action.
These keystrokes are for navigating Emacs. They are not intuitive at all, but are unfortunately necessary to memorize.
C-up
andC-down
let me skip up and down paragraphs respectively.C-x up
andC-x down
let me get to the top and bottom of a buffer respectively.C-a
andC-e
get me between the front and end of a line respectively.C-f
andC-v
let me scroll up and down respectively.C-s
let’s me search a buffer.M-g
let’s me quickly jump to any line number.
Some Vim and Emacs users share a distaste for the arrow keys for speed reasons, but I personally don’t. I don’t deny that they are a little slower.
C-x C-b(uffer)
helps me find a buffer.C-tab
(orC-x o(ther)
) let’s me switch to another visible buffer.Shift-up
,shift-left
,shift-right
, andshift-down
let me move to a buffer in that direction.C-x left
andC-x right
let me run backward and forward through the list of buffers.C-x k(ill)
aggressively kills a buffer.
C-x 0
deletes an Emacs window, whereasC-x 1
deletes all other Emacs windows.C-x 2
does a horizontal split, andC-x 3
does a vertical split.C-c(onfiguration) left
andC-c(configuration) right
lets me iterate through window configurations.
I have keystrokes setup to emulate tmux/screen using Emacs tabs.
C-z(one) c(reates)
a new workspace.C-z(one) k(ills)
a current workspace.C-z(one) n(ext)
workspace.C-z(one) p(revious)
workspace.
These keystrokes encompass things one commonly does in a terminal.
C-c(onsole) d(ocker)
brings up tools for managing and shelling into Docker containers.C-c(onsole) e(shell)
let’s me boot up an Emacs shell which is an awesome hybrid between a Lisp interpreter and a traditional POSIX shell.C-c(onsole) x(term)
let’s me boot up a real terminal.C-c(onsole) s(tatus)
let’s me bring up a dashboard with the current git status for the git repo that I am working in.C-c(onsole) C-p(ushes)
my current git branch to origin.
These are the most powerful commands, mostly applications.
C-x c(ompile)
let’s me run a compile command on any buffer I’m working on. This can be used to run a REPL for your language too.C-x f(ile)
starts a file manager.C-x i(ntelligence)
starts an LLM client.C-x l(ocate)
locates a file on your disk.C-x s(tring replace)
let’s me replace all strings in a buffer or selection.C-x u(ndo)
will launch an undo-tree visualizer
These are less powerful commands, mostly functions.
C-x C-c(onsult)
let’s me search for a word at point in a project.C-x C-d(ocumentation)
let’s me search online documentation.C-x C-f(ile)
finds a file.C-x C-m(eta)
let’s me run an Emacs function.C-x C-n(ames of tabs)
let's me select a tab's name from a list.C-x C-s(aves)
a buffer for me.C-x C-w(here)
let’s me find where a function is defined in a language agnostic basis.
I redefine C-x C-c because advanced Emacs users almost never exit Emacs and therefore don’t need a hotkey when save-buffers-exit-emacs
will do.
These bindings cover the most important things you'll do while hacking Lisp code in either Elisp, SLY, Geiser, or CIDER:
C-x(ecute) c(ompile)
evaluates a buffer.C-x(ecute) r(egion)
evaluates a region.C-x(ecute) C-d(ocumentation)
views documentation for the symbol at point.C-x(ecute) C-w(here)
jumps to da efinition for the symbol at point.C-h(elp) s(ymbol)
displays the available symbols in whatever Lisp environment you are in.
When you are on parenthesis, modal editing is activated via Lispy. You can use single keystrokes to navigate, edit, and evaluate code:
e
evaluate s-expressionf
forward point through parensb
undo]
move point down[
move point up>
slurp up next s-expression<
barf up s-expressionw
move s-expression ups
move s-expression downr
raise s-expressionC-1
view documentationC-2
view caller arguments
Lispy has obligatory Vim-style navigation too:
h
move leftj
move downk
move upl
move right
Everything is very organized in the enzuru
folder by feature, mode, preference, setup, operating system, and theme. While this repo should work immediately for you on a git pull
, it's obviously a very personalized setup and many things won't appeal to you. If I were you, I would first take a look at my init.el
and then pick a topical elisp file from there.
Happy hacking!
Licensed under the GPLv3; copyright is assigned to my eponymous charity enzu.ru