EmacsにおけるC++ source codeの細かいindent設定方法 (1)

Source codeにおけるindentの流儀についての議論は果てがないように見受けられます。I.S.にとってもindentについては拘りがあり、defaultの設定では満足できないことが多いです。

Emacsではfileの編集中に自動的にindentを行ってくれますが、そのindent方法が自分の好みでなければ、その便利な機能も一転迷惑極まりない機能に成り果てます。

Emacsでは、設定file*1において、以下のようにstyleを選択することができますが、その用意されているstyleの全てが自分の好みでなければ、自分でindent設定を細かく記述するか、手動でひたすらindentしつづけるか、自動indentの苦痛に黙って耐えつづけるしかありません。

(add-hook 'c++-mode-hook
          '(lambda ()
             (c-set-style "gnu") ; k&r、bsd、stroustrup、whitesmith、ellemtel、linuxなどがある。
             ))


細かく設定するには以下のようにします。

(add-hook 'c++-mode-hook
          '(lambda ()
             (c-set-offset 'access-label '-)
             (c-set-offset 'arglist-close 0)
             (c-set-offset 'arglist-cont 0)
             ; :
             ; :
             ; :
             ))

このc-set-offset関数の第1引数は構文symbolと呼びます。構文symbolはsource code中の認識された構造を記述しています。例えば、defun-openは関数定義の開き中括弧のことです。

c-set-offset関数の第2引数には、offset値を指定することができます。offset値とは、次のindentの深さが現在のindentの深さからどれだけ離れているかを示す値です。整数、特殊symbol(+-++--*/)等を指定することができます。

整数を指定した場合、それがそのままoffset値になります。

特殊symbolを指定した場合、offset値は下記のとおりとなります。変数c-basic-offsetの倍数となっています。

+

c-basic-offsetの1倍

-

c-basic-offsetの-1倍

++

c-basic-offsetの2倍

--

c-basic-offsetの-2倍

*

c-basic-offsetの0.5倍

/

c-basic-offsetの-0.5倍



以下、C++に関係のある各構文symbolをalphabet順に説明します。C-c C-sでその箇所における構文symbolを表示させることができます。また、C-c C-oでその場であたかもc-set-offsetを実行したかのように構文symbolに対するoffset値を変更することもできます。

access-label

C++access control labelです。publicとかprotectedとかprivateとかのアレです。

class hoge
  {
  public: // <- access-label
    // :
    // :
    // :

  protected: // <- access-label
    // :
    // :
    // :

  private: // <- access-label
    // :
    // :
    // :
  };

arglist-close

引数listの閉じ括弧です。

arglist-cont

引数listの開き括弧の行に引数がない場合の引数の2行目以降です。

arglist-cont-nonempty

引数listの開き括弧の行に引数がある場合の引数の2行目以降です。

arglist-intro

引数listの引数の1行目です。


以下にarglist-closearglist-contarglist-cont-nonemptyarglist-introの解説をします。

int
  hoge
  (
    int x, // <- arglist-intro
    int y, // <- arglist-cont
    int z // <- arglist-cont
  ) // <- arglist-close
  {
    // :
    // :
    // :
  }

int
  fuga ( int x,
  int y, // <- arglist-cont-nonempty
  int z ) // <- arglist-cont-nonempty
  {
    // :
    // :
    // :
  }

block-close

文blockの閉じ中括弧です。

block-open

文blockの開き中括弧です。

brace-entry-open

行が開き中括弧で始まるときのenumのlistや静的配列の初期化listの2行目以降のentryです。

hoge hoge_array [] =
  {
    {
      // :
      // :
      // :
    },
    { // <- brace-entry-open
      // :
      // :
      // :
    },
    // :
    // :
    // :
  };

brace-list-close

Enumのlistや静的配列の初期化listの閉じ中括弧です。

brace-list-entry

Enumのlistや静的配列の初期化listの2行目以降のentryです。

brace-list-intro

Enumのlistや静的配列の初期化listの1行目のentryです。

brace-list-open

Enumのlistや静的配列の初期化listの開き中括弧です。


以下にbrace-list-closebrace-list-entrybrace-list-introの解説をします。

hoge hoge_array [] =
  { // <- brace-list-open
    0, // <- brace-list-intro
    1, // <- brace-list-entry
    2, // <- brace-list-entry
  }; // <- brace-list-close

c

複数行に跨るC-styleのcommentの内側です。

/*
 * <- c
 */ // <- c

case-label

Switch文内のcase labelやdefault labelのことです。

switch ( c )
  {
  case 'a': // <- case-label
    // :
    // :
    // :

  case 'b': // <- case-label
    // :
    // :
    // :

  default: // <- case-label
    // :
    // :
    // :
  };

catch-clause

Try-catch文のcatch節です。

try
  {
    // :
    // :
    // :
  }
catch // <- catch-clause
  (
    // :
  )
  {
    // :
    // :
    // :
  }

class-close

Class定義の閉じ中括弧です。

class-open

Class定義の開き中括弧です。


以下にclass-closeclass-openの解説をします。

class hoge
  { // <- class-open
    // :
    // :
    // :
  }; // <- class-close

comment-intro

C++-styleならcomment、C-styleならcommentの1行目です。

// Comment <- comment-intro

/* Comment */ // <- comment-intro

/* <- comment-intro
 * Comment
 */

cpp-macro

Macro定義の1行目です。

cpp-macro-cont

Macro定義の2行目以降です。


以下にcpp-macrocpp-macro-contの解説をします。

#include <cstdlib> // <- cpp-macro

#define \ // <- cpp-macro
  hoge \ // <- cpp-macro-cont
  ( fuga + piyo ) // <- cpp-macro-cont


長くなったので、次回に続きます。