最近の Emacs のコメント機能についてのまとめ。

追記 この記事を元に書籍が出来ました!

時間と命を削って、より詳細に解説しましたので、Emacs に興味がある人はぜひ一度手に取ってみて下さい。

Emacs実践入門 ?思考を直感的にコード化し、開発を加速する (WEB+DB PRESS plus)

Emacs実践入門 ?思考を直感的にコード化し、開発を加速する (WEB+DB PRESS plus)

大相撲の本場所終了の傷心も癒えてきたので、久しぶりに Emacs について書きます。
エディタの重要な機能のひとつにコメントとコメントアウトがあります。
Emacs のコメント機能はとても優秀で、標準で様々な言語をサポートしています。ですので、拡張やプラグイン的なものをインストールすることなく、簡単にコメントをつけたり、コメントアウトしたり、それを解除したりできます。
例えば、

a:link, a:visited {
  background-color: transparent;
  color: #c88f22;
  text-decoration: none;
}

という CSS をリージョン選択して、M-x comment-region というコマンドを実行するだけで

/* a:link, a:visited { */
/*   background-color: transparent; */
/*   color: #c88f22; */
/*   text-decoration: none; */
/* } */

このように一気にコメントアウトすることができます。
ですので、ソースに複数行に渡るコメント文を入れる場合は、ずらずらと文章を書いてから、一気にコメントアウトするのが基本となります。
いちいち、コメント文字をタイプしていてはいけません。

最強コメントキーバインド M-; (comment-dwim)。

C-u M-x comment-region というコマンドで、コメントアウトを解除できるという説明が多くありますが、現在の Emacs には comment-dwim というコマンドがあります。
このコマンドは標準で M-; にバインドされており、その説明に Call the comment command you want (Do What I Mean). とあるように、空気を読んで様々なコメントを自動的に使い分けてくれます。
ヘルプに書いてある内容を紹介すると、

  1. transient-mark-mode がオンでリージョンが有効のときに M-; すると、コメントアウト、もしくは解除のコマンドになる
  2. transient-mark-mode がオンでリージョンが有効のときに C-u 数値 M-; すると、コメント文字列を数値分にする(下に補足説明あり)
  3. 何もない行で M-; した場合、コメント文字列を挿入する
  4. 何か書かれている行で M-; した場合、行末にコメント文字列を挿入する
  5. コメント行で M-; した場合、コメント文までジャンプする
  6. コメント行で、引数を与えて M-; した場合(C-u M-; という感じ)、コメント行であれば削除する。

という感じです。
transient-mark-mode を使っていない人の場合は、M-; が空気を読んでくれないので、そいういう人は、

(global-set-key (kbd "C-c ;") 'comment-or-uncomment-region)

という感じで、comment-or-uncomment-region コマンドを使うと良いと思います。
よくある .emacs

(define-key global-map "\C-c;" 'comment-region)      ; コメントアウト
(define-key global-map "\C-c:" 'uncomment-region)    ; コメント解除

という、2つのキーバインドにコメントと解除を割り当ててる設定は古いので、これから Emacs を使う人はあまり参考にしないほうがいいと思います。comment-or-uncomment-region を使いましょう。
2. について補足しておくと、リージョン選択して、C-u 3 M-; とすると、Lisp の場合は、

;;; (set-language-environment "Japanese")
;;; (set-default-coding-systems 'utf-8-unix)
;;; (set-terminal-coding-system 'utf-8)
;;; (set-keyboard-coding-system 'utf-8)

という風に、コメント文字を3つにするという意味です。

コメントのスタイル

最初に例に出した CSSコメントアウトは、各行にコメントアウトをおこなっていてちょっとカッコ悪いです。
Emacs さんも、そういうことは感じているようで、コメントのスタイルを変更できるようになっています。

(defconst comment-styles
  '((plain	. (nil nil nil nil))
    (indent	. (nil nil nil t))
    (indent-or-triple
                . (nil nil nil multi-char))
    (aligned	. (nil t nil t))
    (multi-line	. (t nil nil t))
    (extra-line	. (t nil t t))
    (box	. (nil t t t))
    (box-multi	. (t t t t)))
  "Comment region styles of the form (STYLE . (MULTI ALIGN EXTRA INDENT)).
STYLE should be a mnemonic symbol.
MULTI specifies that comments are allowed to span multiple lines.
ALIGN specifies that the `comment-end' markers should be aligned.
EXTRA specifies that an extra line should be used before and after the
  region to comment (to put the `comment-end' and `comment-start').
INDENT specifies that the `comment-start' markers should not be put at the
  left margin but at the current indentation of the region to comment.
If INDENT is `multi-char', that means indent multi-character
  comment starters, but not one-character comment starters.")

コメントのスタイルは、標準で上記のように用意されています。デフォルトは indent ですので、変更したい場合は、

(setq comment-style 'multi-line)

というように .emacs に書いて、C-x C-e で評価しましょう。

/* a:link, a:visited {
 *   background-color: transparent;
 *   color: #c88f22;
 *   text-decoration: none;
 * } */

multi-line だと、こんな感じになります。
ちなみに box は、

/* ******************************** */
/* a:link, a:visited {              */
/*   background-color: transparent; */
/*   color: #c88f22;                */
/*   text-decoration: none;         */
/* }                                */
/* ******************************** */

こんな感じのゴージャスなコメントアウトになります。たまにソースで見ますが、みんな手入力してなかったんですね。
というわけで、みなさん Emacs でより良いコメントライフをお送り下さい :-)