notes from /dev/null

by Charles Choi 최민수


12 Jun 2024

An accidental lock-in feature of the Apple ecosystem

It’s WWDC week, when Apple shines their spotlight on its developer ecosystem every June. Given the moment, I’d like take this opportunity to give all the flowers to the unsung developers who have built and maintained a feature in Apple products that I hold quite dear: the Emacs keybindings in Apple UI frameworks.

If you don’t know, when using a macOS native app like Notes, OmniGraffle, or Safari, you can use the following keybindings in any text field:

  • C-a - move cursor to beginning of line
  • C-e - move cursor to end of line
  • C-f - move cursor forward one character
  • C-b - move cursor backward one character
  • C-k - kill text to end of line
  • C-y - yank killed text (mostly, more on this later)

It can not be overstated how extraordinarily convenient this feature is to Emacs users. Even more astonishing is how this set of bindings has continued to be maintained (since 2001!) across the different OS variants Apple ships (macOS, iOS, iPadOS, tvOS).

Backstory

My anecdotal understanding of this feature’s history is that it started with the NextStep OS back in 1988. The developers of NextStep used Emacs and so whenever they typed in the text widgets of the NextStep UI, they naturally wanted to use Emacs bindings. It was unlikely that this was ever an exec-level requirement. But the developers wanted it, so they made it happen.

Fast forward in time, NeXT effectively acquires Apple and in doing so repackages the NextStep frameworks to ship Mac OS X (now called macOS). This decision fatefully keeps NextStep’s text system and its conventions intact in the UI framework called AppKit as part of family of frameworks called Cocoa. Fast-forward to 2007, the iPhone becomes a thing. Apple makes another fateful decision to build iPhone OS (now called iOS) off of Cocoa but create a new touch-based UI framework called UIKit. UIKit’s text system is heavily influenced by Cocoa where it too carries over the Emacs keybindings. Variants of iOS in the form of iPadOS and tvOS come to be, further propagating these keybindings. In 2019, a declarative UI framework called SwiftUI is created where its text system too adopts the Emacs keybindings.

Configuring Keybindings in macOS

Wonderfully enough, you can still configure the keybindings in AppKit-based apps on macOS using the NextStep style configuration as shown in the Text System Defaults and Key Bindings document. There it provides guidance on adding more Emacs-style keybindings.

Of note is that macOS has always supported an alternate clipboard to emulate the Emacs kill-ring. This works independent of the system clipboard, and requires a bit of configuration to get working. There are two steps to this:

  • Redefine the keybinding C-y to yankAndSelect:

In the file $HOME/Library/KeyBindings/DefaultKeyBinding.dict (for details see the link above), add the following line in the body between the braces.

"^y" = "yankAndSelect:";
  • Use the command line utility defaults to set the variable NSTextKillRingSize.

This variable controls the size of the kill ring. Here we will set it to 5.

$ defaults write NSGlobalDomain NSTextKillRingSize 5

You can confirm the value in NSTextKillRingSize as follows.

$ defaults read -g NSTextKillRingSize

Refer to man defaults for more information on it.

At this point, you will need to log out and back in for the new keybindings to take effect.

Caveats

You can’t have everything though as not all apps are built with AppKit. Focusing on only the default Emacs bindings, here’s a survey of the different levels of support for them from the different UI frameworks.

Binding AppKit/SwiftUI (macOS) UIKit/SwiftUI (iOS, iPadOS) Mac Catalyst
C-a Y Y Y
C-e Y Y Y
C-f Y Y Y
C-b Y Y Y
C-k Y Y Y
C-y Y N N

Unsurprisingly, UIKit chose to not support a kill ring, so effectively C-k is a delete function and yanking is not supported. The column for Mac Catalyst is a category of apps built to work for both iPadOS and macOS based largely on UIKit. Such apps include Messages and Stocks.

Closing Thoughts

I’ll never take for granted the repeated decision over the years by the Apple text system developers to keep supporting the Emacs keybindings. While perhaps not intended, this feature quite seriously is an ecosystem lock-in factor for me. It is a gift and to some extent, a secret handshake, that I’ll always be grateful for. To whoever was, is, or will be involved with keeping this feature alive, thank you.

emacs   ios   computer

Past Articles

8
JUN
2024

Announcing a plan to change some Casual package names

The Casual project has grown beyond just working with Calc. Better to introduce some breaking name changes now than later.

read more
3
JUN
2024

Announcing Casual Info

Annoucing Casual Info, a Transient menu for the Emacs Info reader.

read more
28
MAY
2024

Announcing Casual Avy

Announcing Casual Avy, an opinionated Transient-based menu for Avy, GNU Emacs package for jumping to visible text using a character-based decision tree.

read more
9
MAY
2024

Sunrise and Sunset in Emacs

If you don’t know sunrise-sunset in Emacs, now you know.

read more
6
MAY
2024

Announcing Casual Dired - an opinionated porcelain for the Emacs file manager

Announcing Casual Dired, an opinionated Transient-based porcelain for the Emacs file manager Dired.

read more
1
MAY
2024

Mathing in Emacs with Casual

Casual provides much better computer algebra system (CAS )to work with in Emacs. This post shows you how.

read more
18
APR
2024

Writing Better Elisp Docstrings

Emacs has a lot of tools to help you write better docstrings. And if a tool you want doesn’t exist, Emacs can let you make your own.

read more
10
APR
2024

Exporting UTF-8 Smart Quotes from Org Mode

This post shows a way to use UTF-8 characters for smart quotes when exporting to Markdown or HTML from Org.

read more
24
MAR
2024

Announcing Casual - An opinionated porcelain for Emacs Calc

Announcing the first public release of Casual - an opinionated Transient-based porcelain to support the casual usage of Emacs Calc.

read more

Page 1 / 11   >

 

AboutMastodonInstagramGitHub

Feeds & TagsGet Captee for macOS

Powered by Pelican