- 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-mとC-jの挙動がほとんど似ているので、どっちを常用したらいいのかを知りたいと思いました。
通常、Enterキー(あるいはReturnキー)に対応するキーは、C-mです。
これは、Emacsとは無関係で、ASCII規格の制御文字に由来しています。
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-mはnewlineに、C-jはnewline-and-indentに
バインドされています4。
EmacsではRETとC-mは同じコマンドに紐づいています。RETキーは端末からCRとして送られてくることが多いからです。
一方、C-jはLFなので別扱いです。
つまり、素のEmacsでは、C-mとRETは単純な改行、C-jはインデント付き改行です。
3. electric-indent-modeが変えた
ところが、「素のEmacs」というのが話のミソです。
というのも、Emacs 24.4(2014年10月20日リリース)から、electric-indent-modeがデフォルトで有効になりました5。
このモードが有効だと、newlineコマンドでは、electric-indent-modeのフックが改行後に走り、現在のメジャーモードのインデントルールを適用します。
つまり、RETやC-m でも、押すたびにインデントが自動調整されます。newline-and-indentに置き換わっているわけではありませんが、結果としてC-mとRETを押しても自動インデントが効くようになっているのです。
3.1. C-mとC-jの違いを体感するには?
ちなみに、次のコマンドで一時的に無効にすると違いがはっきりします6。
M-x electric-indent-mode
このモードを切った状態でC-mを押すと、カーソルは行頭に移動するだけでインデントされません。C-jを押せばインデントされます。
つまり、どちらを押しても同じ結果になるのは、electric-indent-modeがデフォルト有効になったからです。
| キー | 送る文字 | 標準コマンド | electric-indent-mode有効時 |
|---|---|---|---|
C-m、RET | CR (0x0D) | newline | インデントされる |
C-j | LF (0x0A) | newline-and-indent | インデントされる |
ということで、現代のEmacs使いがC-jを明示的に使うケースは減りました。
しかし、もしインデントを変えずに純粋な改行だけを挿入したい場面では、electric-indent-modeを意図的に切ってC-mと使い分けることもできます。
- CRは10進数で13、LFは10進数で10に対応します。ASCII規格(ANSI X3.4-1968)で定義された制御文字で、現在はISO/IEC 646として国際標準化されています。 – ASCII – Wikipedia
- 機械式タイプライターでは、キャリッジ(紙を保持する部分)を左端に戻す操作がCR、紙を一行分送る操作がLFに対応していました。テレタイプ端末もこの動作を引き継ぎました。 – Carriage return – Wikipedia
- WindowsのCRLF慣習はMS-DOSから引き継いだもので、CP/Mの慣習に由来します。UnixがLF単独を採用したのに対し、クラシックMac OSはCR単独を使用していました。現在のmacOSはUnixベースのためLF単独です。 – Newline – Wikipedia
newline-and-indentはインデントにindent-line-functionの値を使います。プログラミングモードではTABキーと同じインデント処理が走ります。 – Indent Convenience (GNU Emacs Manual)- 機能自体はEmacs 24.1(2012年)で追加されていましたが、デフォルト無効でした。24.4でのデフォルト有効化がリリースハイライトの一つとして明記されています。 – GNU Emacs Release History
- グローバルに無効化したい場合は
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