Emacs の標準のインデント動作を変更したい -- namespace ではインデントしたくないんだ! --

問題点

namespace の {} 内でインデントしてしまう。

namespace My {
    namespace World {
        void func()
        {
            // ...
        }
    }
}

namespace はネストすることも多いし、インデントしたくないなあ……。 例えばこんな感じで…。

namespace My {
namespace World {

void func()
{
    // ...
}

} // End of namespace World
} // End of namespace My

さらにもともとインデントしているファイルは 勝手にインデントを変更せず、そのままにしたいなあ…

namespace Their {
    namespace World {
        void func()
        {
            // ...
        }
    }
}

処方箋

C-c C-s (c-show-syntactic-information) を実行すると、カーソルがある位置のインデント情報が表示される。 たとえば

namespace My {
| <== ここにカーソル
}

ここにカーソルを置いてC-c C-s を実行すると、

Syntactic analysis: ((innamespace 52) (topmost-intro 52))

などと表示される。innamespace というのを覚えておく。

その後 C-c C-o (c-set-offset) で innamespace のインデント設定を変更する。

C-c C-o
Syntactic symbol to change: innamespace    # innamespace と入力
innamespace offset (default +): 0          # 0 と入力

などとする。これで namespace 内で自動的にインデントしなくなる。(すでにインデントされている行でTABを打つなどするとインデントがずれるので、元のコードをそのままにしたいときは注意が必要)

これを init.el に書いておけばOK。下記のように。

(defunc my-c-mode-common-hook ()
    ;; styleの選択
    (c-set-style "stroustrup")

    ;; インデント規則 (c-set-style の後に設定する必要がある) 
    (c-set-offset 'innamespace 0)
)
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

注意点としては、 c-set-offset の指定は c-set-style の後にやらないといけないこと。先に書くと、c-set-style の設定で上書きされて消えてしまう。

旧処方箋(2020年現在、これだと動かなかった c-set-style との順番のせいかもしれない)

Emacs の設定を変更。c-offset-alist の innamespace などの設定を (c-lineup-dont-change) に変える。

Customize で C Offsets Alistを変える。

  1. M-x customize
    • Programming で Enter
    • Language で Enter
    • C を選択して Enter
    • C Offsets Alist を選択して Enter
    • (M-x customize-apropos で c offsets alist を検索してもいける)
  2. C Offsets Alist の 一覧が開く
  3. 下記の設定値の左のチェックボックスを ON にして…
    • namespace-open
    • namespace-close
    • innamespace
  4. 値を (c-lineup-dont-change) に書き換える
  5. State ボタンをおして…
  6. Save for Future Sessions を実行 ==> .emacs とかに設定が書かれる。

以上。

おまけ

  • extern "C" {} とかもインデントしたくない場合は
    • extern-lang-open
    • extern-lang-close
    • inextern-lang
  • も同じ設定にする。

参考資料