EmacsのC-mとC-jは、
結局は同じように改行される
(electric-indent-mode)

  • EmacsのC-mとC-jはASCII規格の制御文字に由来し、それぞれCRとLFを送る異なるキーです。
  • 標準設定ではC-mが単純な改行、C-jがインデント付き改行に対応しています。
  • Emacs 24.4からelectric-indent-modeがデフォルトで有効になり、C-mでも改行後に自動インデントが走るようになりました。
  • 結果としてどちらを押しても同じ挙動に見えますが、electric-indent-modeを無効にすると違いが現れます。

関連記事

1. まず制御文字の話

Emacsを使っていて、改行で使う C-mC-jの挙動がほとんど似ているので、どっちを常用したらいいのかを知りたいと思いました。

通常、Enterキー(あるいはReturnキー)に対応するキーは、C-mです。
これは、Emacsとは無関係で、ASCII規格の制御文字に由来しています。

C-m と C-j の違い C-m / RET CR(0x0D) Carriage Return 行頭へ戻る newline C-j LF(0x0A) Line Feed 次の行へ進む newline-and-indent VS 機械式タイプライター時代の独立した2つの動作に由来 Windows: CRLF / Unix: LF単独
  • C-mは、CR(Carriage Return, ASCII 0x0D)、
  • C-jは、LF(Line Feed, ASCII 0x0A)

を送ります1

機械式タイプライターの時代、CRはもともと「行頭へ戻る」、LFは「次の行へ進む」という独立した動作でした2
しかし、その後テキストファイルのフォーマットはいろいろあって、WindowsではCRLFの組み合わせ、UnixはLF単独という慣習に落ち着きました3

2. EmacsでのキーバインドとRETの扱い

Emacsの標準設定では、

  • C-mnewlineに、
  • C-jnewline-and-indent

バインドされています4

EmacsではRETC-mは同じコマンドに紐づいています。
RETキーは端末からCRとして送られてくることが多いからです。
一方、C-jはLFなので別扱いです。

つまり、素のEmacsでは、C-mRETは単純な改行、C-jはインデント付き改行です。

3. electric-indent-modeが変えた

ところが、「素のEmacs」というのが話のミソです。
というのも、Emacs 24.4(2014年10月20日リリース)から、electric-indent-modeがデフォルトで有効になりました5

electric-indent-mode が変えたこと Emacs 24.4〜 デフォルト有効 キー 標準コマンド モード有効時 C-m / RET newline インデントされる ← フックが走る C-j newline-and-indent インデントされる ↓ 結果は同じ 確認方法 M-x electric-indent-mode で一時無効化 → C-m は改行のみ / C-j はインデント付き改行

このモードが有効だと、newlineコマンドでは、electric-indent-modeのフックが改行後に走り、現在のメジャーモードのインデントルールを適用します。

つまり、RETC-m でも、押すたびにインデントが自動調整されます。
newline-and-indentに置き換わっているわけではありませんが、結果としてC-mRETを押しても自動インデントが効くようになっているのです。

3.1. C-mとC-jの違いを体感するには?

ちなみに、次のコマンドで一時的に無効にすると違いがはっきりします6

M-x electric-indent-mode

このモードを切った状態でC-mを押すと、カーソルは行頭に移動するだけでインデントされません。
C-jを押せばインデントされます。

つまり、どちらを押しても同じ結果になるのは、electric-indent-modeがデフォルト有効になったからです。

キー送る文字標準コマンドelectric-indent-mode有効時
C-mRETCR (0x0D)newlineインデントされる
C-jLF (0x0A)newline-and-indentインデントされる

ということで、現代のEmacs使いがC-jを明示的に使うケースは減りました。
しかし、もしインデントを変えずに純粋な改行だけを挿入したい場面では、electric-indent-modeを意図的に切ってC-mと使い分けることもできます。

  1. CRは10進数で13、LFは10進数で10に対応します。ASCII規格(ANSI X3.4-1968)で定義された制御文字で、現在はISO/IEC 646として国際標準化されています。 – ASCII – Wikipedia
  2. 機械式タイプライターでは、キャリッジ(紙を保持する部分)を左端に戻す操作がCR、紙を一行分送る操作がLFに対応していました。テレタイプ端末もこの動作を引き継ぎました。 – Carriage return – Wikipedia
  3. WindowsのCRLF慣習はMS-DOSから引き継いだもので、CP/Mの慣習に由来します。UnixがLF単独を採用したのに対し、クラシックMac OSはCR単独を使用していました。現在のmacOSはUnixベースのためLF単独です。 – Newline – Wikipedia
  4. newline-and-indentはインデントにindent-line-functionの値を使います。プログラミングモードではTABキーと同じインデント処理が走ります。 – Indent Convenience (GNU Emacs Manual)
  5. 機能自体はEmacs 24.1(2012年)で追加されていましたが、デフォルト無効でした。24.4でのデフォルト有効化がリリースハイライトの一つとして明記されています。 – GNU Emacs Release History
  6. グローバルに無効化したい場合は init.el(electric-indent-mode -1) を追記します。特定のバッファだけ無効にするには M-x electric-indent-local-mode を使います。electric-indent-local-mode もEmacs 24.4で追加されました。 – electric-indent-mode – Emacs Online Documentation