WEBVTT captioned by sachac, checked by bhavin
NOTE introduction
00:00:00.000 --> 00:00:05.079
Hello, my name is Charles Choi and welcome to my talk:
00:00:05.080 --> 00:00:11.359
"Reimagining the Emacs user experience with Casual Suite."
00:00:11.360 --> 00:00:14.919
Casual Suite is a set of opinionated user interfaces to
00:00:14.920 --> 00:00:18.399
different modes offered in Emacs. Before I get into
00:00:18.400 --> 00:00:22.199
describing Casual in detail, let's first talk about the
00:00:22.200 --> 00:00:27.039
existing Emacs user experience. To make Emacs go, people
00:00:27.040 --> 00:00:31.079
can either invoke commands by name with
00:00:31.080 --> 00:00:34.081
execute-extended-command,
00:00:34.082 --> 00:00:36.403
run a command directly with a pre-assigned
00:00:36.404 --> 00:00:43.799
key binding, finally, use a mouse menu if it's available.
NOTE Recall vs recognition
00:00:43.800 --> 00:00:46.719
From human-computer interface research, there is a
00:00:46.720 --> 00:00:50.799
concept of recall versus recognition in user interface
00:00:50.800 --> 00:00:56.599
design. Let's show their distinction by example. A common
00:00:56.600 --> 00:01:00.839
recall interface is password entry. Absent any historical
00:01:00.840 --> 00:01:04.639
affordances, a user must directly remember information to
00:01:04.640 --> 00:01:09.839
succeed with this interface. In contrast, menus offer
00:01:09.840 --> 00:01:13.439
immediate visual cues on what commands are available. This
00:01:13.440 --> 00:01:16.839
allows a user to recognize familiar behavior to support
00:01:16.840 --> 00:01:21.879
successful selection of it. From user interface research,
00:01:21.880 --> 00:01:26.119
the key finding is this. Interfaces emphasizing
00:01:26.120 --> 00:01:29.999
recognition are much easier to use than those relying on
00:01:30.000 --> 00:01:35.799
recall. In this light, we see that the Emacs user experience
00:01:35.800 --> 00:01:41.279
leans too much towards recall. Completion in history can
00:01:41.280 --> 00:01:44.479
help tip the scales towards recognition, but only by a
00:01:44.480 --> 00:01:47.959
little bit.
00:01:47.960 --> 00:01:52.399
This reliance on recall is discouraging to users both new
00:01:52.400 --> 00:01:56.839
and old, and that's a shame because Emacs has so many useful
00:01:56.840 --> 00:02:00.759
commands. But the kicker is that most of them are
00:02:00.760 --> 00:02:05.239
infrequently used. You can't recall them all. At least I
00:02:05.240 --> 00:02:11.239
can't. So, a conundrum. While I've been using Emacs since
00:02:11.240 --> 00:02:15.159
the early 90s, truthfully, it's been only in this past
00:02:15.160 --> 00:02:19.679
decade that I've leveled up in using it. Org Mode, Magit,
00:02:19.680 --> 00:02:23.199
Eglot, Avy, and many other packages have transformed how I
00:02:23.200 --> 00:02:28.639
use it. I can only deal with so much cognitive load and
00:02:28.640 --> 00:02:34.799
physically straining key bindings. So, what to do about it?
NOTE Emacs with keyboard-driven menus
00:02:34.800 --> 00:02:36.159
Let's bring back an old ideal.
00:02:36.160 --> 00:02:42.359
Keyboard-driven menus have been around since TTY video
00:02:42.360 --> 00:02:47.359
terminals with mainframes. If you're old enough to recall
00:02:47.360 --> 00:02:50.079
working with such interfaces, these terms will seem
00:02:50.080 --> 00:02:53.239
familiar. They all worked with the limitations of
00:02:53.240 --> 00:02:57.639
text-based video displays.
00:02:57.640 --> 00:03:01.599
With keyboard-driven menus, if a command exists but nobody
00:03:01.600 --> 00:03:05.519
can find it, it's not really useful. A well-designed menu
00:03:05.520 --> 00:03:09.719
can make a command discoverable. If the command is
00:03:09.720 --> 00:03:15.199
infrequently used, making it recognizable helps a lot. And
00:03:15.200 --> 00:03:18.679
for working primarily with text, having keyboard-only
00:03:18.680 --> 00:03:24.119
interactions encourages flow. Given the above, the next
00:03:24.120 --> 00:03:28.479
steps seem natural:
00:03:28.480 --> 00:03:32.759
augment Emacs with keyboard-driven menus. This is not
00:03:32.760 --> 00:03:36.639
saying that I want to obsolete name commands, keybindings,
00:03:36.640 --> 00:03:41.079
and mouse menus. They all can happily coexist. Emacs is
00:03:41.080 --> 00:03:43.399
large. It can contain multitudes.
NOTE Transient
00:03:43.400 --> 00:03:49.879
Conveniently, Emacs has a built-in library for building
00:03:49.880 --> 00:03:53.839
such menus. It's called Transient, and it's been around
00:03:53.840 --> 00:03:59.319
since Emacs 28. Developed primarily by Jonas Bernoulli as a
00:03:59.320 --> 00:04:03.199
UI toolkit for Magit, Transient has an essential feature
00:04:03.200 --> 00:04:08.199
for building great keyboard-driven interfaces.
NOTE A Transient menu can be pinned
00:04:08.200 --> 00:04:11.919
A transient menu can be pinned and their state updated as
00:04:11.920 --> 00:04:15.239
commands are issued from them. This lets us build
00:04:15.240 --> 00:04:18.399
interfaces that reflect internal state changes made by
00:04:18.400 --> 00:04:21.919
commands issued from the user. This is great because many
00:04:21.920 --> 00:04:26.599
modes have stateful behavior, and guess what? Emacs has a lot
00:04:26.600 --> 00:04:29.302
of modes.
NOTE Modes are apps, really
00:04:29.303 --> 00:04:31.999
If you think about it, Emacs modes are akin to the
00:04:32.000 --> 00:04:35.079
ecosystem of apps that we see today, but with far less
00:04:35.080 --> 00:04:39.319
structure and packaging. A mode, like an app, focuses on
00:04:39.320 --> 00:04:42.959
delivering specific behavior to the user. There are many
00:04:42.960 --> 00:04:45.999
built-in modes in Emacs, and these modes are complex with
00:04:46.000 --> 00:04:50.679
dozens, if not hundreds, of commands. Calc itself has over
00:04:50.680 --> 00:04:54.879
1,000 of them. It's frustrating to know that these commands
00:04:54.880 --> 00:04:59.526
are there, but I really can't access them via recall.
NOTE Transient all the modes!
00:04:59.527 --> 00:05:05.079
So I decided to do something about it, and that was to transient
00:05:05.080 --> 00:05:09.999
all the modes, or at least the most major ones. This past
00:05:10.000 --> 00:05:12.679
summer, I had the time and resources to start building
00:05:12.680 --> 00:05:15.799
Transient interfaces for modes that I wanted to more
00:05:15.800 --> 00:05:22.319
elegantly use. I decided to call this work Casual. Given its
00:05:22.320 --> 00:05:25.519
definition, it seemed like a good fit for the vibe that I
00:05:25.520 --> 00:05:28.039
wanted these interfaces to embody.
NOTE Casual design principles
00:05:28.040 --> 00:05:34.999
Design principles that I embraced up front were
00:05:35.000 --> 00:05:38.239
handcrafted information architecture and layout. This is
00:05:38.240 --> 00:05:41.799
largely an exercise in mapping a mode's command set to a
00:05:41.800 --> 00:05:47.119
hierarchical menu structure. I wanted these menus to make
00:05:47.120 --> 00:05:50.719
sense to most people. Ideally, users would not have to read
00:05:50.720 --> 00:05:55.839
documentation to get at the command that they wanted. Early
00:05:55.840 --> 00:05:59.359
on, I quickly learned that it was impossible to maintain the
00:05:59.360 --> 00:06:02.479
existing default key bindings when mapping them over to a
00:06:02.480 --> 00:06:06.759
hierarchical menu. Also, some bindings I just flat out
00:06:06.760 --> 00:06:10.199
disagreed with. I resolved to be friendly, but not
00:06:10.200 --> 00:06:14.919
beholden to them. In all of the above, I've gone out of my way
00:06:14.920 --> 00:06:17.959
to make clear that my design decisions are opinionated.
NOTE Casual design conventions
00:06:17.960 --> 00:06:21.719
Using casual.
00:06:21.720 --> 00:06:30.039
To reinforce habit, a common key binding is used per mode to
00:06:30.040 --> 00:06:33.799
raise a main menu. This key binding is left to user
00:06:33.800 --> 00:06:36.719
preference. For me, that binding is C-o.
00:06:36.720 --> 00:06:44.639
Command bindings are mnemonic when possible.
00:06:44.640 --> 00:06:49.559
Mode-specific settings are given their own menu. Since
00:06:49.560 --> 00:06:53.319
transient menus can be pinned, we can support repeat or
00:06:53.320 --> 00:06:58.479
stateful behavior in a mode.
00:06:58.480 --> 00:07:02.319
As of this writing, there are 11 modes supported by Casual,
00:07:02.320 --> 00:07:04.365
with several more on the way.
NOTE Casual Dired
00:07:04.366 --> 00:07:05.719
Let's look at the Casual menu
00:07:05.720 --> 00:07:12.479
for Dired to highlight the design conventions previously
00:07:12.480 --> 00:07:13.559
mentioned.
00:07:13.560 --> 00:07:17.719
In a Dired Emacs window, the user can invoke their preferred
00:07:17.720 --> 00:07:22.279
key binding to call a top-level Casual main menu. This main
00:07:22.280 --> 00:07:27.919
menu is displayed at the bottom of the Emacs frame. Zooming
00:07:27.920 --> 00:07:30.839
into this menu, we see the commands offered in it
00:07:30.840 --> 00:07:34.559
categorized into different sections. Each command has a
00:07:34.560 --> 00:07:38.039
key binding, usually a single character shown before its
00:07:38.040 --> 00:07:42.599
label. The File section holds commands that act upon the
00:07:42.600 --> 00:07:47.559
currently selected item or marked items. The Directory
00:07:47.560 --> 00:07:50.319
section holds commands that affect the current directory
00:07:50.320 --> 00:07:55.599
or its subdirs within it. The Mark section has marking
00:07:55.600 --> 00:08:00.279
commands that allow for aggregate operations. The
00:08:00.280 --> 00:08:03.399
Navigation section shows commands that move the point in a
00:08:03.400 --> 00:08:09.559
direct buffer. The quick section provides access to
00:08:09.560 --> 00:08:14.519
bookmark and buffer list commands. Search and replace
00:08:14.520 --> 00:08:19.119
commands are grouped in the search section. New directory
00:08:19.120 --> 00:08:24.079
and file creation are given their own section. Finally, at
00:08:24.080 --> 00:08:27.599
the bottom of the menu are commands dedicated to Casual menu
00:08:27.600 --> 00:08:28.439
navigation.
00:08:28.440 --> 00:08:34.079
Casual is conformant to Transient conventions where the
00:08:34.080 --> 00:08:39.479
key binding C-g for dismiss one and C-q to dismiss all
00:08:39.480 --> 00:08:43.639
menus are honored. Another transient convention is to
00:08:43.640 --> 00:08:49.519
reserve the key binding q to quit the current mode. For most
00:08:49.520 --> 00:08:53.959
main menus, casual uses the , key binding to invoke a
00:08:53.960 --> 00:08:58.999
mode-specific settings menu. Casual also adopts the
00:08:59.000 --> 00:09:02.039
common UI convention of using ... >
00:09:02.040 --> 00:09:05.879
symbols to denote required input and submenus
00:09:05.880 --> 00:09:06.639
respectively.
NOTE Casual EditKit
00:09:06.640 --> 00:09:13.919
Some commands are more global or non-mode specific in
00:09:13.920 --> 00:09:18.039
nature. A great deal of these commands relate to editing,
00:09:18.040 --> 00:09:23.239
which I find to be a prime motivation for using Emacs. Let's
00:09:23.240 --> 00:09:25.559
examine one such menu that supports this.
00:09:25.560 --> 00:09:31.599
The main menu for Casual EditKit is designed to provide easy
00:09:31.600 --> 00:09:36.279
access to editing and editing-related commands. Like the
00:09:36.280 --> 00:09:39.959
previous Dired menu, it organizes commands into different
00:09:39.960 --> 00:09:40.679
sections.
00:09:40.680 --> 00:09:45.999
Commands related to file and buffer operations are in the
00:09:46.000 --> 00:09:50.519
File section. Commands for editing text are in the Edit
00:09:50.520 --> 00:09:55.599
section. S- or balanced expression commands are given a
00:09:55.600 --> 00:09:59.439
dedicated section for their own. More often than not, in
00:09:59.440 --> 00:10:02.159
many modes, I find them to do what I want.
00:10:02.160 --> 00:10:08.879
The tools section provides access to common tools.
00:10:08.880 --> 00:10:13.719
Bookmarks I consider to be an essential feature. If you
00:10:13.720 --> 00:10:18.439
haven't used them, it's never too late to start. Emacs
00:10:18.440 --> 00:10:20.799
window management commands are given this section.
00:10:20.800 --> 00:10:25.799
Commands for search and replace, macros, and projects can
00:10:25.800 --> 00:10:32.199
be accessed from here. Finally, the menu navigation
00:10:32.200 --> 00:10:35.719
section. Note that register commands can be accessed from
00:10:35.720 --> 00:10:36.199
here.
NOTE EditKit demo
00:10:36.200 --> 00:10:42.439
Okay, enough screenshots. Let's look at Casual in action
00:10:42.440 --> 00:10:48.439
with a demo of the EditKit menus. Let's start our demo of
00:10:48.440 --> 00:10:54.439
casual-editkit with raising the menu, which is bound to
00:10:54.440 --> 00:10:58.919
C-o. You'll see the menu pop up here. In
00:10:58.920 --> 00:11:02.519
particular, we want to look at the edit operation. We'll
00:11:02.520 --> 00:11:08.679
press e and we'll see a number of menu items that allow you to
00:11:08.680 --> 00:11:16.239
make editing transformations to the text, be it marking,
00:11:16.240 --> 00:11:20.239
copying, killing, transposing, transforming, moving, or
00:11:20.240 --> 00:11:24.279
deleting the text. You'll see also that there is a submenu
00:11:24.280 --> 00:11:31.996
for rectangle operations. Let's first...
NOTE Marking and moving
00:11:31.997 --> 00:11:37.406
Let's actually dig through and look at what's in the Mark submenu.
00:11:37.407 --> 00:11:42.039
You'll see that there are increments of text in which you can
00:11:42.040 --> 00:11:45.239
mark. You can mark a word, a sentence, a paragraph, and
00:11:45.240 --> 00:11:49.559
balanced expression. If we go back, you'll see a similar
00:11:49.560 --> 00:11:57.339
pattern for copying as well as killing. Transposing.
00:11:57.340 --> 00:12:02.879
Let's go and try to move a sentence. We have the point there at
00:12:02.880 --> 00:12:07.119
hello there. We'll move that sentence around. If we
00:12:07.120 --> 00:12:12.119
press s, we can move it backward or forward. In this case,
00:12:12.120 --> 00:12:16.279
let's move it forward. We'll press f. You'll see hello
00:12:16.280 --> 00:12:21.639
there move up a sentence. Then we can also press b to move
00:12:21.640 --> 00:12:29.879
it back. Then press RET to dismiss. Also, if we wanted
00:12:29.880 --> 00:12:35.199
to, we can... In this menu particularly, you'll see that we
00:12:35.200 --> 00:12:38.839
also have cursor navigation, so we can move the point there.
00:12:38.840 --> 00:12:43.039
That's not in all the menus, but in a good part number of the
00:12:43.040 --> 00:12:47.919
menus in Casual Edit Kit, you'll see that here. Let's press
00:12:47.920 --> 00:12:53.139
RET to dismiss that.
NOTE Rectangles
00:12:53.140 --> 00:12:58.643
Let's actually look at some rectangle operations here.
00:12:58.644 --> 00:13:01.759
In this case, we have a list with
00:13:01.760 --> 00:13:08.519
items x, y, and z. Let's say we wanted to prefix each item
00:13:08.520 --> 00:13:14.239
here with a string. We'll say we want to put in there
00:13:14.240 --> 00:13:21.159
hello. One way of doing that is to make a rectangle. So
00:13:21.160 --> 00:13:25.719
if we go into our rectangle menu, first off, what we need to do
00:13:25.720 --> 00:13:31.199
is define that rectangle region. We'll press m to mark
00:13:31.200 --> 00:13:35.439
where the point is right there. Then we can use our cursor
00:13:35.440 --> 00:13:39.559
operation to move the point to define the rectangle. In this
00:13:39.560 --> 00:13:43.839
case, it's right at the start there. We can use the string
00:13:43.840 --> 00:13:49.679
insert command, i, to insert hello, colon, and then we'll
00:13:49.680 --> 00:13:54.799
put a space there to make it look a little nicer. Sure
00:13:54.800 --> 00:13:58.119
enough, that's in there.
00:13:58.120 --> 00:14:04.975
We can have access to a number of rectangle commands here.
NOTE Numbering
00:14:04.976 --> 00:14:11.599
If we wanted to, let's say, number, we can go through that same
00:14:11.600 --> 00:14:16.719
operation here, define a region, a rectangle region that
00:14:16.720 --> 00:14:22.679
is, and press n. You'll see that it has incremented a
00:14:22.680 --> 00:14:28.639
number for each item in that rectangle region. We can also
00:14:28.640 --> 00:14:32.468
tap u to undo these operations
00:14:32.469 --> 00:14:36.599
and leave that at that.
NOTE Sorting
00:14:36.600 --> 00:14:47.239
Sorting. If we select a region here, And we go back. You'll
00:14:47.240 --> 00:14:52.399
see that the sort submenu is now enabled. Sorting won't work
00:14:52.400 --> 00:14:56.239
unless you have a region started. That's one of the nice
00:14:56.240 --> 00:15:01.679
things about transient is that it allows you to visually
00:15:01.680 --> 00:15:09.079
enable or disable command items with regards to whatever
00:15:09.080 --> 00:15:12.559
the current state or context is here. In this case is
00:15:12.560 --> 00:15:17.359
whether or not you have a region highlighted. Let's say we
00:15:17.360 --> 00:15:22.879
want to sort these two columns of numbers and so there's a
00:15:22.880 --> 00:15:29.759
command called n here which is numeric fields. Let's choose that
00:15:29.760 --> 00:15:35.919
here. Sure enough we get that. But there's a nice twist
00:15:35.920 --> 00:15:39.679
there. Let's say we wanted to sort on the second column.
00:15:39.680 --> 00:15:48.919
Let's move our point back up to here and we'll mark that.
00:15:48.920 --> 00:15:52.799
Since everything is in a continuous line, we can sort of
00:15:52.800 --> 00:15:55.948
pretend that this region is actually a paragraph
00:15:55.949 --> 00:15:59.359
and mark that.
00:15:59.360 --> 00:16:06.999
We'll go and select our sorting routine. But now we need to
00:16:07.000 --> 00:16:11.319
figure out how to make numeric fields sort on the second
00:16:11.320 --> 00:16:16.359
column. In transient, if we press a ?, that
00:16:16.360 --> 00:16:21.439
gives us basically a intermediate help section where, if we
00:16:21.440 --> 00:16:27.279
press a key binding, it will tell us or load the docstring for
00:16:27.280 --> 00:16:33.039
the command that's there. That command in this case is
00:16:33.040 --> 00:16:40.039
sort-numeric-fields. It requires an argument. That
00:16:40.040 --> 00:16:44.079
argument can be passed using the prefix argument,
00:16:44.080 --> 00:16:52.119
C-u. Press q. Let's do that. In this case, we
00:16:52.120 --> 00:16:58.679
want to check or use the value 2 and press n. Sure enough,
00:16:58.680 --> 00:17:04.339
that region is sorted with respect to the second column.
NOTE Casual has transformed my user experience with Emacs
00:17:04.340 --> 00:17:12.159
Before Casual, so many powerful Emacs commands were not
00:17:12.160 --> 00:17:15.559
available to me because they were too hard to recall or I
00:17:15.560 --> 00:17:19.879
could not discover them. Making Casual has changed that,
00:17:19.880 --> 00:17:24.359
letting me reimagine more positively my user experience
00:17:24.360 --> 00:17:29.199
with Emacs. If you're interested in any of what I've shown
00:17:29.200 --> 00:17:34.450
today, I invite you to try out Casual.
NOTE Thanks and acknowledgements
00:17:34.451 --> 00:17:37.032
Before I leave, my thanks and acknowledgments
00:17:37.033 --> 00:17:38.679
go out to the following people.
00:17:38.680 --> 00:17:43.399
First, to Jonas Bernoulli for making Transient and Magit.
00:17:43.400 --> 00:17:49.319
Casual would not be possible without your work. Next, to
00:17:49.320 --> 00:17:54.399
Psionic-k for writing Transient Showcase. It showed me how I
00:17:54.400 --> 00:17:59.439
could build casual. To all the casual users and their
00:17:59.440 --> 00:18:05.319
support, I am genuinely appreciative. Finally, to Jon
00:18:05.320 --> 00:18:08.759
Snader for writing the kind posts on Casual on the Irreal
00:18:08.760 --> 00:18:10.519
website. Thank you.
00:18:10.520 --> 00:18:15.797
Casual can be found on MELPA,
00:18:15.798 --> 00:18:23.720
and its repository is hosted on GitHub.