EmacsのKill-Ringと
macOSのクリップボードは、
どういう同期しているの?

関連記事

1. macOSのクリップボードとEmacsのKill-Ring

macOSでEmacsを使っていると、コピー&ペーストの挙動に混乱します。
⌘Cと⌘V に M-wC-yを混ぜると、何が記憶されているのかわからなくなるのです1

2つの異なる仕組み macOSクリップボード アプリ間で共有 最後の1つを保持 ⌘C / ⌘V Kill-Ring Emacs内部のみ 複数履歴を保持 C-w / C-y

macOSのクリップボードは、アプリ間でテキストや画像を受け渡すための仕組みです2
Safariでコピーした文字列をメモ帳に貼り付ける、といった操作がを経由します。

基本的にアプリをまたいで共通に使え、「最後にコピーした1つ」を保持します。

一方、Kill-RingはEmacs内部だけで使われる履歴構造です。
名前に「Ring」とあるとおり、複数の削除・コピー履歴を輪のように保持します。

  • C-wC-k などで削除(kill)した内容
  • M-w でコピーした内容

これらが順番に溜まり、C-yで貼り付け、M-yで過去にさかのぼれます3
こちらは「履歴が積み重なる箱」だと考えています。

2. ⌘キー操作とEmacs操作は似ているが同じではない

2.1. ⌘C と M-w の関係

通常のテキストバッファでは、⌘CとM-wはとても似た結果になります。
どちらも選択範囲をコピーし、macOSのクリップボードとKill-Ringの両方に反映されます4

ただし、

  • ⌘Cは「OSの操作がたまたまEmacsでも使えるもの」
  • M-wは「Emacsが意図して用意したコピー操作」

この違いは、あとで履歴をたどりたいかどうか、という点で効いてきます。

2.2. ⌘V と C-y の決定的な違い

ここが一番混乱しやすいところです。
⌘VとC-yは見た目は同じ「貼り付け」ですが、内部ではまったく別の経路を通ります。

C-y の実際の挙動 C-y 実行 他アプリが最近 クリップボード更新? YES クリップボード から貼付 NO Kill-Ring から貼付 ※ M-yで履歴を遡れるのはKill-Ringから貼付した場合のみ
  • ⌘Vは「macOSのクリップボード」を直接貼り付ける
  • C-yは「Kill-Ringの先頭」を貼り付ける5

そのため、C-yの直後にM-yで履歴を切り替えられますが、⌘Vではそれができません6

3. Kill-Ringは編集の流れを支えるもの

Kill-Ringは「コピー履歴」ではなく、「編集の副産物」だと思っています。
消した行や移動したブロックが、あとから必要になるかもしれない。
その可能性を自然に残してくれるのがKill-Ringです7

C-yは「最後に消したものを貼る」操作です。
最初から狙い通りの内容が出るとは、あまり期待していません。

一度貼ってみて、違ったらすぐM-y
この使い方を前提に、Kill-Ringは探索可能な履歴として機能しています。

3.1. macOSのクリップボードは外部アプリとの橋渡し

一方、macOSのクリップボードは、Emacsの外と中をつなぐためのものだと割り切っています。

  • ブラウザやPDFから持ってくるときは⌘C8
  • Emacsから他アプリへ渡すときも⌘C

Emacs内部の編集では、できるだけ関与させません。

ちなみに、Emacsで削除操作をすると、macOSのクリップボードが上書きされることがあります。

  1. この記事で説明する挙動は、Emacs 24以降のデフォルト設定に基づいています。Emacs 24より前のバージョンでは、kill/yankコマンドはクリップボードではなくプライマリ選択を使用していました。現在の挙動は変数select-enable-clipboardがデフォルトでtに設定されているためです。 – Clipboard (GNU Emacs Manual)
  2. macOSでは、Emacsはpbcopy/pbpasteコマンドを通じてシステムクリップボードと統合されています。GUI版EmacsではネイティブのクリップボードAPIを使用しますが、ターミナル版では追加の設定が必要になる場合があります。また、macOS Sierra以降ではユニバーサルクリップボード機能により、iPhoneやiPadとクリップボードを共有できます。 – Emacs とmacOS / GNUstep
  3. 連続して実行されるkillコマンド(C-w、C-k、M-dなど)は、それらのテキストを1つのKill-Ringエントリにまとめます。例えば、C-kを3回連続で実行すると、3行分のテキストが1つの履歴として保存され、C-y一回で全て貼り付けられます。この動作により、複数の削除操作を1つの単位として扱えます。 – Killing And Yanking (EmacsWiki)
  4. クリップボード統合を完全に無効化したい場合は、(setq select-enable-clipboard nil)を設定します。これにより、EmacsのkillとyankはKill-Ringのみを使用し、システムクリップボードとは完全に独立して動作します。Emacs 24以前の挙動に戻したい場合に有用です。 – Copy And Paste (EmacsWiki)
  5. より正確には、C-yは他のアプリケーションがクリップボードを「所有」している場合(つまりEmacs外で最近コピーした場合)、クリップボードから貼り付けます。Emacs内で最後にkill/copy操作を行った後であれば、Kill-Ringの先頭から貼り付けます。ただし、クリップボードから貼り付けた場合でもKill-Ring履歴には追加されないため、M-yで過去の履歴を遡ることはできません。 – Clipboard (GNU Emacs Manual)
  6. M-y(yank-pop)は、直前のコマンドがyankコマンド(C-yまたはM-y自身)である場合にのみ機能します。⌘Vは通常のテキスト挿入として扱われるため、その後M-yを実行してもKill-Ring履歴を遡ることはできません。また、yank-pop-change-selectionをtに設定すると、M-yで選択した内容がクリップボードにも保存されます。 – Clipboard (GNU Emacs Manual)
  7. Kill-Ringに保存される履歴の数は、変数kill-ring-maxで制御されます。デフォルト値は60で、60個までのkill履歴を保持します。この値を変更することで、より多くの履歴を保持したり、メモリ使用量を削減したりできます。 – Killing And Yanking (EmacsWiki)
  8. macOSではクリップボードマネージャー機能がサポートされています。Emacsを終了する際、Emacsがクリップボードの「所有者」である場合、クリップボードマネージャーにデータを転送します。これにより、Emacs終了後もクリップボード内容が失われません。この動作が遅延を引き起こす場合は、x-select-enable-clipboard-managerをnilに設定できます。 – Clipboard (GNU Emacs Manual)