Surprise and Emacs Defaults
05 Jul 2023 Charles Choi
Throughout the history of building computers (both hardware and software), there have been different schools of thought on how to build them. There’s really no one “right” way, however different schools have formed with different levels of success. The thinking of such schools gets further compounded by the many levels of abstraction in computer design. More often than not, a school with a successful pattern at one level of abstraction tries to apply that to other (or worse yet, all) levels. An observation in building computers is that invariably you must ship something that embodies both policy and mechanism. Systems that coherently separate the two end up being more flexible to change.
When I think of the default settings in Emacs (base and external packages alike) and its design overall, I can’t help but think of its culture’s emphasis on providing mechanism and deferring policy to user choice. Perhaps this thinking was influenced by the design of X11 protocols (“Provide mechanism rather than policy. In particular, place user interface policy in the clients’ hands.”). Regardless, this school of thinking values building systems with generalized behavior that can be sculpted into many specific use cases. With such thinking there is a strong tendency to not fixate on the default policy, as it can always be defined by the end user.
Another school of thought, particularly coming from 80’s microcomputer user interface research has been to emphasize consistency to improve usability. Such thinking, evangelized by folks such as Bruce Tognazzini and Don Norman, has had a profound influence in thinking about computer user experience (UX). Key to gaining such consistency was to be very opinionated about policy. Informed by human computer interface (HCI) research and scaled by microcomputer adoption, the UX of such opinionated software became the expected convention by contemporary users.
Suffice to say, the conflict between such schools of thought play out repeatedly in many different places; the most recent one that comes to mind is the Fediverse (Mastodon, ActivityPub, etc.) versus Scott Jenson.
It also plays out in thinking about the default settings (aka the policy choices) in Emacs in 2023.
New users are often surprised by the policy choices in Emacs because these choices often diverge from conventional app UX. When surprised, the reaction can be quite adverse. Such was the reaction from @summeremacs which prompted me to write this post. I’ve had similar reaction multiple times as well over my several decades of using Emacs.
I don’t have any power to make Emacs maintainers change their defaults, but I will call out that the default settings they ship are a policy choice. If one considers usability with minimal training (and consequently minimal surprise) to be valuable, as I do, then positive first impressions are important! I think it would be a better thing for Emacs defaults to be less surprising to contemporary users.
That said, here are some opinionated Emacs settings that I think makes Emacs less surprising.
Variables
bookmark-save-flag
By default, bookmarks are saved only when you exit Emacs cleanly. This is problematic if you keep Emacs running for a long time, particularly if you use Emacs server and are not aware of this default behavior. I got burned badly by this several years back when first adding a number of bookmarks during a long-running Emacs server session. The session ended up being in a bad state, crashing Emacs, and I had lost all those bookmarks. Persisting bookmark changes to disk as it happens it is the saner default. I leave it as an open question as to why bookmark-save
behavior is so complicated.
Default | My Setting |
---|---|
t | 1 |
Interestingly enough, in the recent post Emacs: mark and register basics, Stavrou remarks that he discovered bookmark-save-flag
after implementing his own logic to persist bookmarks, which reinforces my opinion that the default behavior of persisting bookmarks is surprising.
sentence-end-double-space
The one that triggered @summeremacs. Yes, sentences are single-spaced in 2023.
Default | My Setting |
---|---|
t | nil |
delete-selection-mode
If you select text and then type over it, it should delete that text. Surprisingly, you do not get this behavior out of the box with default Emacs. You have to explicitly enable it.
Default | My Setting |
---|---|
nil | t |
dired-auto-revert-buffer
By default, Dired buffers will not update themselves unless you explicitly tell them to. Setting this variable to t
will auto-update the Dired buffer when you revisit it.
Default | My Setting |
---|---|
nil | t |
global-auto-revert-mode, global-auto-revert-non-file-buffers
Whenever the disk state changes, Emacs should update as well. While supported, this is not turned on by default. Changing these two variables to t
fixes this.
Default | My Setting |
---|---|
nil | t |
dired-dwim-target
If you like Dired to emulate Midnite Commander with having two Dired buffers side-by-side and moving files between then both, then use this setting.
Default | My Setting |
---|---|
nil | dired-dwim-target-next |
eshell-scroll-to-bottom-on-input
Pretty much every terminal program will scroll to the bottom on input. Eshell won’t though until you configure it to.
Default | My Setting |
---|---|
nil | this |
magit-save-repository-buffers
IMHO Magit is too cautious by defaulting to prompting the user to save every modified file in a repo before taking action. This gets annoying quite fast. Setting it to dontask
will save you from a lot of prompts.
Default | My Setting |
---|---|
t | dontask |
Ediff
Having the visual diff tool, Ediff, packaged into Emacs is really convenient. I’ll be blunt though: Ediff default behavior out of the box is awkward. First, the Ediff control panel is put into a separate frame (GUI window) when running in GUI mode, making GUI window management an issue. Second is the default behavior to show the diffs on top of each other rather than side-by-side. Third, when you quit Ediff, your previous window1 layout is messed up.
Here is what I do to address the above three points:
Variable | Default | My Setting | Notes |
---|---|---|---|
ediff-split-window-function | split-window-vertically | split-window-horizontally | Show diffs side-by-side |
ediff-window-setup-function | ediff-setup-windows-default | ediff-setup-windows-plain | Puts the control panel in the same frame as the diff windows1 |
Updated 2023-07-10 - Please disregard this Ediff checkpoint and restore logic. A much better configuration is offered in the post Using Ediff in 2023.
Checkpoint and restore window1 configuration for
Ediff session (code from helm - Restoring windows and layout after an Ediff session - Emacs Stack Exchange):
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Man-notify-method
When raising a man
page in Emacs, the default behavior is to open it in a new buffer but keep the focus on your current buffer. Typically I want to read the man page and quickly exit it. Changing this variable to aggressive
will change the focus to the new man
buffer so you can immediately (q)uit it.
Default | My Setting |
---|---|
friendly | aggressive |
Summary
Reviewing the above defaults, I’m struck by seeing that many of them deal with synchronizing state (typically persisting to disk) and choose to make the user responsible for managing it. This stands in stark contrast to conventional UX in both desktop and mobile apps to automatically synchronize state on behalf of the user. My preferences definitely are in-line with the latter camp.
If you’ve gotten to here I hope this post has been helpful, especially if you’re new to Emacs. Let me qualify that I very much like using Emacs and that I am deeply grateful to its many contributors who help make it an essential tool for me. That said, I do think first impressions are important in software, and the less surprises it gives the user, the better. Ciao folks!
Footnotes
1 Emacs window definition, which is a whole another story on the different semantics Emacs uses to describe UI elements.