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.