░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░██╗░░██╗░██╗░░░██╗░░░░░░███████╗░███╗░░░███╗░░█████╗░░░█████╗░░░██████╗░░░
░░░██║░░██║░╚██╗░██╔╝░░░░░░██╔════╝░████╗░████║░██╔══██╗░██╔══██╗░██╔════╝░░░
░░░███████║░░╚████╔╝░░██╗░░█████╗░░░██╔████╔██║░███████║░██║░░╚═╝░╚█████╗░░░░
░░░██╔══██║░░░╚██╔╝░░░╚═╝░░██╔══╝░░░██║╚██╔╝██║░██╔══██║░██║░░██╗░░╚═══██╗░░░
░░░██║░░██║░░░░██║░░░░░░░░░███████╗░██║░╚═╝░██║░██║░░██║░╚█████╔╝░██████╔╝░░░
░░░╚═╝░░╚═╝░░░░╚═╝░░░░░░░░░╚══════╝░╚═╝░░░░░╚═╝░╚═╝░░╚═╝░░╚════╝░░╚═════╝░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
This is my personal Doom Emacs config. It’s not the tidiest thing in the world, as it’s constantly in flux with some active development going on in various places (i.e. check out the lisp
directory). As with other personal configs you might find on GitHub, it’s not really intended to be reused by anyone but me, however feel free to take from it whatever is useful to you.
The TypeScript/TSX development environment is powered by elisp-tree-sitter and a custom-written tsx-mode
that replaces web-mode
. This means greatly improved stability, syntax highlighting, performance while editing, and also AST-based editing for JSX tags, similar to the web-mode
element/tag/attribute editing capabilities. Although I haven’t published it anywhere, I use it for work every day.
Since Emacs 28+ now supports color emojis, I’ve moved away from the emoji
module in Doom (which uses the emojify
package under the hood) in favor of native emoji support. This means the Noto Color Emoji
font, or some other emoji font, is needed instead of manually downloading twemoji images. While Emacs has a shiny new built-in emoji-insert
command, I missed being able to search emojis by keyword, so I’ve included a emoji-insert-dwim
command that fills this gap.
I’ve heavily customized my org-mode display to use olivetti for comfortable reading and writing (in favor of Doom’s default zen-mode) and switched to “properly” sized bullet icons that don’t ruin the monospace column layout of the nested content.
There are some hydras for smartparens, window management, and a personalized hydra for enhanced evil-mc multiple cursor editing.
All of the following needs to be set up for the config to run smoothly. This only has to be done once per environment. Note that the setup documentation here might be incomplete, as I don’t regularly test the setup process, because I don’t buy new laptops every day…
These fonts and graphics are required by my config, but have no convenient packages associated with them that can be installed. They must be set up manually for now, until I script them somehow.
In order of importance:
- JetBrains Mono is the all-purpose font for this config
- Fira Code is a supplemental font for certain symbols that JetBrains Mono doesn’t support
- Noto Color Emoji is for displaying emojis natively in Emacs 28+
- Noto Sans CJK is only for Chinese, Japanese and Korean character support
- Noto Sans Thai is only for Thai support
wget https://download.jetbrains.com/fonts/JetBrainsMono-2.225.zip
unzip JetBrainsMono-2.225.zip
# manually look for the TTF files in the extracted file structure
mv *.ttf ~/.local/share/fonts/
Run ./scripts/firacode.sh
to automatically install Fira Code fonts to ~/.local/share/fonts
Download the TTF file from https://github.com/googlefonts/noto-emoji/raw/main/fonts/NotoColorEmoji.ttf and put it in ~/.local/share/fonts
Download the Super OTC NotoSansCJK.ttc
file from https://www.google.com/get/noto/help/cjk/, unzip, then move the file to ~/.local/share/fonts
Download the zip file from https://www.google.com/get/noto/#sans-thai, unzip, the move all the *.ttf
files to ~/.local/share/fonts
My config currently is optimized for running on Ubuntu 20.04, where all of these packages should be available.
Ensure that Node is installed:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
nvm install node
For language servers other than those specified below, you can use the lsp-install-server
command provided by lsp-mode.
sudo npm install -g typescript-language-server typescript
sudo npm install -g vscode-css-languageserver-bin
sudo npm install -g vscode-html-languageserver-bin
In order to compile vterm within Emacs on demand, these dependencies are required:
# Assuming Ubuntu 20.04, which includes these packages by default
sudo apt install libtool-bin cmake
sudo apt install ripgrep fd-find
Cheat’s way to get PDF tools server (it’s hard to compile pdf-tools from scratch locally in WSL)
sudo apt install elpa-pdf-tools-server
There’s a custom org-babel-execute:tsx
function that helps transpile TSX for org-mode HTML exports. This uses esbuild to bundle the code into browser-runnable JavaScript.
npm install -g esbuild
Ensure that WSL is set up to run as WSL 2. This makes a big difference in performance.
Use these instructions as a guide,, paying special attention to the apt install
dependencies that Emacs requires.
Then to run using X410 (a Windows X server), follow these instructions, paying special attention to the firewall settings. “Public network” access is required. This can be manually configured in advanced firewall settings in Windows.
To set up xdg-open
across the WSL border, which allows opening files and links from WSL into the Windows host, wslview
from the wslu toolkit can be symlinked into ~/.local/bin/xdg-open
. Follow the commands in ./scripts/setup_xdg_open_wsl.sh
to set it up.
pinentry-wsl-ps1.sh
makes it possible (but still clunky) to use proper cretential storage for HTTPS authenticated git repos that need a password store.
ln -rs ./scripts/pinentry-wsl-ps1.sh ~/.local/bin/
First link the convenience script from this repo to an accessible location on the PATH
:
ln -rs ./scripts/runemacs.sh ~/.local/bin/
Then create a Windows desktop shortcut with the target:
"C:\Program Files\PowerShell\7\pwsh.exe" -windowstyle hidden -command wsl.exe $command
Where $command
is the command you want to run in WSL. A command prompt window will still flash up on screen briefly when the command is started.
This shortcut can be placed in C:\Users\username\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
to appear in the start menu.
Note that the command may need to have an absolute path in order to work, e.g. /home/username/.local/bin/runemacs.sh
It’s helpful to set this in .bashrc
to force lsp-mode
to use some optimizations.
export LSP_USE_PLISTS=true # an emacs lsp-mode optimization