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.