Radical Builtins

This is my entry for the June 2026 Emacs Carnival Underappreciated Emacs Builtins. There is a lot of functionality in default vanilla Emacs that is certainly less talked about. I'm going to constrain myself to talking about specific functions that exist, instead of overarching themes like portability.

Regional Commands

Some commands in Emacs work in the current region/selection. This is useful with undo in particular, because you can undo a change that happened in a specific area instead of having to go back through the whole undo history (or using a package like vundo).

Buffer Narrowing

Focusing a single buffer down to just the contents you want to look at makes parsing large code files so much easier. It seems like a basic thing but it helps me out more often than one would think, even when writing to focus on a specific paragraph or sentence to edit in isolation.

Indirect Buffers

Being able to "clone" a buffer also seems like such a trivial functionality, but it has so many uses. I particularly like this for editing large pieces of inline C code in Chicken. First M-x clone-indirect-buffer, then narrow to the C code string, then change to C mode. The narrow-indirect package speeds up this process a bit, but all of this functionality is built in by default.

Register

These might not seem too distinct from bookmarks, which everyone and their grandmother knows about, but I don't see people talking about registers enough. I work with big repos, monorepos that usually contain code for all the internal packages, and multiple apps. Being able to quickly say "I wanna jump back here" is unbelievably valuable, especially in combination with jumping to definitions and the like.

Directory Local Variables

Directory local variables are a silent workhorse for me, and don't get enough love. Knowing that these exist will save you endless config time when working across projects with different standards. Or, in the case of working with Scheme, different Scheme interpreters in Geiser. I like working with both Chicken and Gambit, and being able to set the default in a project easily is so helpful, even though it is ultimately trivial.

This goes beyond basic variable customisation too, you get a whole eval hook to play with. Some example uses of this are to automatically log in to AWS when the project is opened, or automatically starting the project for debugging, etc.

Tramp

As I write this there haven't been many submissions for this carnival, but I feel like Eshell and Tramp will get a lot of mentions. While obviously I do use Tramp for accessing my other machines, something that I hear about less often is that Tramp can read and write into more places than just another remote machine via SSH. There's obviously using it for sudo, but it works great for accessing files inside of Docker containers too (useful when working with devcontainers), and that functionality extends to:

  • Podman.
  • Kubernetes.
  • Distrobox.
  • Even flatpak sandboxes.

Macros

Probably should go without saying that macros are a very useful part of Editor Macros, but I feel that the standard macro functions get overshadowed in discussions, usually by proper Lisp scripting.

Repetitive, one-off tasks are everywhere. Personally, one of the first few keybinds I memorised in Emacs (even before navigation) was F3, F4, and C-x e to record, stop recording, and execute a macro. This single feature has saved me countless hours in doing menial crap such as:

  • Inverting cond statements in Scheme.
  • Stripping whitespace, quotation marks.
  • Editing CSV columns.

And the list goes on. There's so many times that I have run into a task that is repetitive but automatable, but not likely to come up again so not worth scripting. Being able to go "well okay, let me just press F3 and do it once, then just C-x e until I'm done" has saved so much pain.

Scripting Things

This final section I want to dedicate to the variously useful elements of Emacs Lisp.

Timers

Automatically running shell commands or other things at a given time is great, and these are also easy to manage with M-x list-timers. Who needs cron jobs?

Advise

I see advise generally frowned upon on in scripting discussion (for good reason, it can make code messy), but knowing the feature exists is occasionally really helpful.

Take neotree, for example. I want the directory of neotree to be tab-local, so that I can switch between tabs and have it persist. Emacs' tab bar mode doesn't have any hooks for tab selection, but that doesn't matter, because we can make our own.

(defvar tab-bar-select-tab-hook nil "Hook for `tab-bar-select-tab'")
(advice-add 'tab-bar-select-tab :after (lambda (x) (run-hooks 'tab-bar-select-tab-hook)))

Likewise, neotree doesn't have any hooks for when the root changes, which I want to keep track of to automatically update the tab directory. Again, that won't stop me.

(advice-add 'neotree-change-root :after #'theurgy-change-tab-dir)

Advise is one-of-a-kind, and while you definitely don't want to rely on it, sometimes there would be no other option and this system deserve praise for thinking about those cases.

Processes and Filters

For the last point here, I want to show off something that I've automated recently: AWS sign in. You can find the whole source code in my config here, but the relevant function is below.

(defun aws--login (role)
  "Internal login function --- handles the command as a process, and prompts for MFA."
  (let* ((process-name (format "%s-%s" aws-cli-auth-provider (replace-regexp-in-string "[/:]" "-" role)))
       (buffer (get-buffer-create (format "*%s*" process-name)))
       (prompt-regexp (rx (or "Enter verification code")))
       (prompt-sent nil))
    (with-current-buffer buffer
      (erase-buffer))

    (make-process
     :name process-name
     :buffer buffer
     :command (list aws-cli-auth-provider "login" "--force" "--skip-prompt" "--role" role)
     :filter
     (lambda (proc output)
       (with-current-buffer (process-buffer proc)
       (goto-char (point-max))
       (insert output)

       (unless prompt-sent
         (let ((buffer-contents (buffer-string)))
           (when (string-match-p prompt-regexp buffer-contents)
             (setq prompt-sent t)
             (let ((token (read-passwd "MFA token: ")))
               (process-send-string proc (concat token "\n"))))))))
     :sentinel
     (lambda (proc event)
       (when (string= "finished\n" event)
       (run-hooks 'aws-post-signin-hook))))))

Basically, I want to sign in to the AWS CLI for a specific role. This usually works great, however sometimes it might as for an MFA token, so if I run the login command with just shell-command it won't do anything if it hits that snag.

However, if I run the command as a process, well, you can easily wrap that prompt and have Emacs ask for the input in the minibuffer. That's what the filter is doing, it just checks if the process has sent text asking for a prompt and if it has, read that with read-passwd and send it to the process. When I was first thinking how to write this, I expected it to be much more annoying. But this is actually stupidly simple.