Posts tagged "emacs":
Speed Dialing Your Favorite Files
I may be dating myself, but I vividly remember setting up speed dials for my most frequently called numbers on my AT&T landline phone. In the early '90s, you could store a phone number in a numbered memory slot (referred to as "programming") and later dial your grandma, for example, by pressing SPD+2
. Retro is in—so if you're too young to remember that and want to know more, just ask your favorite LLM chatbot to fill you in.
Speed-dialing as a user experience concept is widespread, although we don't normally call it that anymore. It is implemented as a feature that I use many times a day in my web browser. I use Safari on a Mac and typically keep many tabs open. I pin the first few to frequently visited URLs, like https://planet.emacslife.com. I can quickly switch to one of them using the keyboard shortcut CMD+1..9
, always knowing which website I'll get. Other browsers offer similar functionality, though they may use different shortcuts, like CTRL+1..9
.
The two apps I use most often on my Mac are Safari and Emacs, and I wondered, “Why don't I have a similar speed-dialing feature in Emacs?” It would be incredibly useful to switch instantly to my important files for reading or jotting down notes. I also like to optimize my keybindings, and consistency plays a big role in that—whether it’s adopting Emacs keybindings elsewhere or bringing external shortcuts into Emacs. It would be great to use the same CMD+1..9
shortcut to recreate this functionality in Emacs.
But doesn’t Emacs already have Tab Bar and Tab Line features? Maybe one of them (I can never remember which is which) could be adapted or enhanced to do what I want. Note, however, that I’m talking about speed dialing files, not tabs. I don’t want to select a tab or cycle through them—I want to jump directly to a specific buffer that’s visiting a specific file. Tabs feel a bit unnatural in Emacs; they make sense in browsers, but in Emacs, we typically work with buffers by name.
Direct addressing—using a name or a short index—is both powerful and highly efficient. Cycling is the least efficient method (looking at you, CMD+TAB
). Completion is a middle ground—it requires extra keystrokes compared to direct addressing and is less predictable when the candidate list changes (in how many characters must be typed to get a single match). However, it’s essential when the list of candidates is long.
Direct Addressing > Completion > Cycling
In general, I prefer direct addressing whenever possible, completion when necessary, and cycling only as a last resort. Emacs' built-in bookmark-jump
falls into the completion category. It would be my next choice if the number of my frequently used files was above ten.
Another reason I avoid using tabs for this in Emacs is that I don’t want to waste screen real estate on a tab bar if I don’t have to. My speed dials are mostly static—I may change them occasionally, but if I assign 1
to school.org
and 2
to house.org
, I want to stick with that. Thanks to muscle memory, I don’t need to see the list in front of me at all times. Plus, accidentally switching to the wrong frequently used file isn’t a big deal—I can quickly flip through a few of them to find what I need.
The beauty of Emacs is that I can create a Safari-like speed-dial experience with just a couple of elisp expressions in my init.el
file.
;; ;; Speed Dialing Favorite Files ;; (defvar /speed-dial-list '(("⓵-todo" . "~/todo.org") ("⓶-emacs" . "~/para/areas/emacs.org") ("⓷-family" . "~/para/areas/family.org") ("⓸-house" . "~/para/areas/house.org") ("⓹-garden" . "~/para/areas/garden.org") ("⓺-42" . "~/para/areas/42.org") ("⓻-init" . "~/.emacs.d/init.el") ("⓼-O1" . "~/para/projects/proj1.org") ("⓽-O2" . "~/para/projects/proj2.org") ("⓾-O3" . "~/para/projects/proj3.org")) "List of speed-dial entries as (LABEL . FILENAME).") ;; Global keybindings for speed dialing using '<Super>' + digit (let ((i 1)) (dolist (entry /speed-dial-list) (keymap-global-set (format "s-%d" (mod i 10)) `(lambda() (interactive) (find-file-existing ,(cdr entry)))) (setq i (1+ i))))
As you can see, I use the <Super>
key modifier to define bindings that match my Safari shortcuts, CMD+1..9
. Note a little trick: using the mod function inside keymap-global-set
to get s-0
to invoke the tenth speed-dial entry.
Currently, the speed-dial bindings simply call the find-file-existing
function to switch to the corresponding buffer, opening the file if needed. But you can customize this further by using your own function for tailored behavior.
For example, you might use repeated presses of the same CMD+0..9
to change folding in an Org buffer, jump to a predefined heading, switch to a related buffer, or perform other context-specific actions.

Rather than visualizing the speed-dial entries as tabs, I found a way to display them without taking up valuable screen real estate. I simply splice the speed-dial labels into the Emacs frame title bar, which I don't really use for anything else. By default, it shows the current buffer name, but that information is also displayed in the mode line, which is where my eyes naturally go.
;; Inject my speed-dial list into the frame title (setq frame-title-format (concat (mapconcat #'car /speed-dial-list " ") " - %b"))
For my needs, displaying speed-dial entries in the Emacs frame title, followed by the current buffer name, works perfectly. My main Emacs frame is always wide enough to accommodate it. If I couldn’t use the frame title, I’d probably just open my init.el
whenever I needed to check which speed-dial number maps to which file. But you might find an even better approach that works for you.
Enjoy the malleability of Emacs and the freedom it gives you!
Discuss this post on Reddit.