Keybindings for multiple clipboards

[Tweet : ADN : nvALT]

It’s been a while since I brought up keybindings. If you haven’t followed my obsession with them in the past, you can catch up on all the fun in older posts and by browsing through the massive KeyBindings project I’ve assembled. To summarize, KeyBindings on OS X can provide all kinds of text editing assistance that’s available and consistent across every app you use.

One thing I’ve been playing with more lately is having multiple clipboards in each app. This trick uses the “kill buffer,” which is completely separate from the system clipboard (⌘C). It’s what’s used when you use ^k to delete text. It’s more expansive in the shell or in Emacs, but it’s still handy in any Cocoa text field.

Using the default Emacs shortcuts that are available already, you can move the cursor to the beginning of a line with ^a (Control-a), and the end of the line with ^e. You can use ^k to delete (or “kill”) the text from the cursor to the end of the line. Deleting an entire line or field is as simple as ^a,^k. This has the same effect has typing “End, Command-Delete” but instead of just removing the text it places it into the kill buffer. You can then paste it with ^y (“yank” from the buffer).

Keep in mind that the kill buffer exists on a per-app basis, so text you kill in one app won’t yank in another app. That being said, here’s a handy trick that makes using it worthwhile: multiple clipboards using the “kill ring.”

The first step is to enable the kill ring. Go to Terminal and run the command:

defaults write -g NSTextKillRingSize -int 3

Note: Most instructions you’ll find for this use -string instead of -int, but I never got it to work in text fields outside of the shell until I changed it to -int.

This will set the kill ring to hold 3 items. You can change the number as needed. Next you override the default ^y keybinding. Create (or open if you’ve done this before) a text file at ~/Library/KeyBindings/DefaultKeyBinding.dict. If you’re working with a new file, paste the entire contents below. If you have existing keybindings, just add the ^y to the plist.

{
	"^y" = (yankAndSelect:);
}

To test:

  1. Open TextEdit (restart it if it was already open)
  2. Type a line of text, then hit ^a, ^k
  3. Write another line with different text, and repeat step 2
  4. Do it one more time for a total of three “kills”
  5. On a blank line, type ^y. This should paste the last line you killed
  6. Type ^y again, and the pasted text should be replaced by the second line you killed
  7. One more time, and you should see the first line. Subsequent repetitions will cycle through the buffer

Bash Bonus

If you’re a Bash user, you can use a wider variety of Emacs shortcuts to delete/copy text. Most importantly, you can use ^w to delete backwards to the previous whitespace, or Option-Delete to delete backwards stopping at the first non-alphanumeric character. The latter allows easy removal of path items, one level at a time. Each time one of these shortcuts is used, the deleted text is prepended to the current kill buffer, so ^y will restore the entire deleted text, not just single words.

Here’s the real tip, though, and I just learned this. If you have the kill ring enabled and you type ^y, you can follow it immediately with M-y (Option-y) to cycle the kill ring. I had previously thought that the kill ring just didn’t work in Bash…

Bash Bonus Bonus

Did you know you can repeat any keyboard command or escape sequence command a given number of times by typing Option-# before it, where # is the number of times to repeat it? Type Option-minus and then a number will repeat the command backwards, too. So typing Option-3 and hitting ^w will delete three arguments back on the command line in one step.

You can find all kinds of cool stuff in the Readline docs.