# How I work in Emacs

Posted on

draft, emacs

This is about the way I use and work in Emacs, which I think departs from the more mainstream usage.

This is not so much about my Emacs setup. This is more about how I use Emacs that happens to include some of my configuration as well.[init.el](https://git.sr.ht/~laumann/dotfiles/tree/master/item/emacs.d/init.el) Generally, I try to keep my Emacs configuration as small as possible and leverage all the built-in functionality and this write-up is about recording all the things I find really useful in Emacs. I have tried configuration frameworks like Spacemacs and Doom Emacs, especially when I was switching back from Vim to Emacs. The issue I had with these configuration frameworks is that it adds another layer of things on top of vanilla Emacs that I need to know how to work with. another reason for dropping Doom was the community living in DiscordI really liked Doom Emacs and have cribbed some of the speed improvements, but I stopped using the framework. Today, my philosophy on Emacs configuration is more aligned with System Crafters, namely starting from vanilla Emacs, maintaining my own configuration and preferring built-in tools over external packages.
## Variable-width fonts I have written about writing code in a variable-with font before[Taking Acme for a spin (update)](/acme-editor-update.html) and this is still the default setup. I used the Go fonts, but have switched to the Liberation Sans fonts. Sometimes, I switch to a monospace font and when I do I roll with Fira Code. In terms of styling I now use the default Emacs theme. In the past I had settled on a slightly modified version of nofrils-acme I also have nyan-mode just because it's cute. Aside from a handful of other minor UI modifications I use the defaults. ## Compilation mode In short: compilation mode rules! During development, I tend to follow this pattern: 1. Set up a command with M-x compile. For example `make` or `dune build` or `dune build && ./run-tests` 2. If there is an error in the output, it's nicely highlighted and M-g n takes me directly to the file and line with an error. (This only works if the compiler produces error output with file names and line numbers.) 3. F9 is set up as a shortcut for M-x recompile, so repeating the command is just one keystroke The ability to jump from directly to file that needs attention without having to work out manually the file name and line number is nothing short of amazing. This is something I could never get in a multi-terminal workflow and I don't want to work without it now. I also prefer to have precise control over when I re-run my command. I have explored automatic re-running of commands in all my work setups: in Acme[Watch](https://github.com/9fans/go/blob/main/acme/Watch/main.go) by Russ Cox, in the terminal[entr(1)](http://eradman.com/entrproject/) and in Emacs[File Notifications](https://www.gnu.org/software/emacs/manual/html_node/elisp/File-Notifications.html) in Emacs, but I find that re-running a command on _every_ save is too much. Often I'm just saving a file as a reflex, but I don't want to run my command. Being in control of when the re-run happens works much better for me. ## Shells I also run shells in Emacs. I started with M-x shell, and have slowly graduated to invoking C-x p s, to get a shell for the current project (which tends to be a git repo). I have experimented with using Emacs' eshell but haven't so far found a compelling reason to use it. Using a shell within Emacs has a couple of side effects: I tend not to repeat commands when I need to inspect its output because I can just scroll back and search in the buffer. I don't need to pipe output through less(1) to inspect it. Copying from the shell is the same as copying from any other buffer. Running shells in Emacs _is_ slower than running a terminal like Alacritty or some other terminal emulator that's built for speed. This is only really an issue if I happen to produce a lot of output in a short amount of time, but I try to avoid that. Being as comfortable using shells as I am let's me use all the commands that I already know. Many of the tools I use are CLI tools, such as... ## Git I use Git in the shell. I don't use Magit. Which might be a shame because it's supposedly great. I tried and found it difficult to navigate and remember all the shortcuts. I also suffer from fat finger syndrome and many times experienced hitting some random key that turned out to be bound to a Magit function, then the UI changed and I was immediately lost. The only part of Magit that I use (and like) is the git-commit package. Mostly I found that the terminology used in Magit is just slightly off from Git's own and that causes me a lot of confusion. Plus the interface is (understandably) quite different from Git's CLI which also requires some effort to get used to. I already knew Git and its CLI quite well before encountering Magit and I am comfortable with most of the subcommands and their usage. All that being said, Magit appears to be great for a lot of developers, I probably just haven't put in the time to get used to it. I use Emacs as the editor for commit messages and have `core.editor = emacsclient` in my ~/.gitconfig and `export EDITOR=emacsclient` in my environment. ## Email I have settled on mu4e. It just works. Fetching and indexing mail is done with isync With mu4e I rely on the menu items for actions that I can never remember the keybindings for. Attaching a file to an email is not something I do often, so I don't have the shortcut memorised. ## Package management Gentoo has a lot of app-emacs/ packages. I decided to use those instead of the built-in package manager. Whether this is a good or bad decision remains to be seen. Any packages that don't exist in the Gentoo repository, I just package in my own overlay. This extra "hump" that is needed to pull in a dependency is a great tool to prevent me from installing any random package I come by. One of my favorite packages is app-emacs/ebuild-mode, which is specific to writing Gentoo ebuilds. ## Man pages Especially writing C code (also Hare), I've found that having man pages directly available in an Emacs buffer to be a big help. If the cursor is placed on a word, that word becomes the default suggestion: for example memcpy, then M-x man will suggest memcpy and all I have to do is hit RET. ## Window management I use tab bars and generally have two tabs active - one for development and another for email. I have tried using multiple frames but found it difficult to manage. I create windows in the current tab with C-x 3 (split-window-right) and C-x 2 (split-window-below). Getting rid of windows in the current tab is either with C-x 0 or C-x 1 I switch between windows with C-x o or just use the mouse to select a window. I have tried other packages that implement different ways of navigating windows and tabs, like ace-window, but none of them have stuck. ## Other tools I like browse-url and use it frequently (M-x br-u). I like ffap as well. I am _almost_ ready to rebind C-x C-f to ffap. I started using C-x p g to grep for words in the current project. I grep around in codebases quite frequently and xref provides a nice interface. Emacs' builtin project awareness provides a few other useful shortcuts that I don't use frequently, but I really should. I try to use dired as much as I can, but often revert to browsing the file system in the shell.
Overall, for me Emacs hits the right spot between Acme and Vim (as odd as that might sound). Everything (almost) being text in a buffer makes searching through buffers, be it code, man pages, email, shell history behave the same, and copying from one location to another is a breeze.