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

前回に引き続き、Emacsにおけるindentの設定方法の解説です。

defun-block-intro

関数定義の1行目です。

defun-close

関数定義の閉じ中括弧です。

defun-open

関数定義の開き中括弧です。


以下にdefun-block-introdefun-closedefun-openの解説をします。

void
  hoge
  (
  )
  { // <- defun-open
    // <- defun-block-intro
    // :
    // :
    // :
  } // <- defun-close

do-while-closure

Do-while文のwhileです。

do
  {
    // :
    // :
    // :
  }
while ( flag ); // <- do-while-closure

else-clause

If-else文のelse節です。

if ( a == 0 )
  {
    // :
    // :
    // :
  }
else // <- else-clause
  {
    // :
    // :
    // :
  }

extern-lang-close

外部言語blockの閉じ中括弧です。

extern-lang-open

外部言語blockの開き括弧です。


以下にextern-lang-closeextern-lang-openの解説をします。

extern "C"
  { // <- extern-lang-open
    // :
    // :
    // :
  } // <- extern-lang-close

friend

friend宣言です。

class hoge
  {
    friend class fuga; // <- friend

    // :
    // :
    // :
  };

func-decl-cont

引数listと関数定義の本体の開き中括弧の間の領域です。throwやconstなどを記述します。

void
  hoge
  (
  )
  throw // <- func-decl-cont
  ( // <- func-decl-cont
  ) // <- func-decl-cont
  {
    // :
    // :
    // :
  } 

void
  fuga::piyo
  (
  )
  const // <- func-decl-cont
  {
    // :
    // :
    // :
  }

inclass

Class定義内の要素です。

class hoge
  {
  public:
    hoge (); // <- inclass
    ~hoge (); // <- inclass
    // :
    // :
    // :
  };

inextern-lang

外部言語block内の要素です。

extern "C"
  {
    // <- inextern-lang
    // :
    // :
    // :
  }

inher-cont

多重継承listの2行目以降です。:に対するoffset値であることに注意してください。member-init-contのように、:に対してでなく、前の行に対してであれば両者の整合性が取れていたと思うのですが……。

inher-intro

多重継承listの1行目です。


以下にinher-continher-introの解説をします。

class hoge: public fuga, // <- inher-intro
            public piyo // <- inher-cont
  {
    // :
    // :
    // :
  };

inline-close

Class内のinline methodの開き中括弧です。

inline-open

Class内のinline methodの閉じ中括弧です。


以下にinline-closeinline-openの解説をします。

class hoge
  {
  public:
    hoge
      (
      )
      { // <- inline-open
        // :
        // :
        // :
      } // <- inline-close
  };

innamespace

名前空間内の要素です。

namespace hoge
  {
    // <- innamespace
    // :
    // :
    // :
  }

label

通常のlabelです。

void
  hoge
  (
  )
  {
  fuga: // <- label
    // :
    // :
    // :
  }

member-init-cont

Classのmember初期化listの2行目以降です。

member-init-intro

Classのmember初期化listの1行目です。


以下にmember-init-contmember-init-introの解説をします。

hoge::hoge
  (
  ):
  fuga ( 1 ), // <- member-init-intro
  piyo ( 2 ), // <- member-init-cont
  nyaa ( 3 ) // <- member-init-cont
  {
    // :
    // :
    // :
  }

namespace-close

名前空間の閉じ中括弧です。

namespace-open

名前空間の開き中括弧です。


以下にnamespace-closenamespace-openの解説をします。

namespace hoge
  { // <- namespace-open
    // :
    // :
    // :
  } // <- namespace-close

statement

通常の文です。

statement-block-intro

新規文blockの1行目です。

void
  hoge
  (
  )
  {
    {
      // <- statement-block-intro
      // :
      // :
      // :
    }

    // :
    // :
    // :
  }

statement-case-intro

Case blockの1行目です。

statement-case-open

中括弧で始まるcase blockの開き中括弧です。


以下にstatement-case-introstatement-case-openの解説をします。

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

  case 'b':
    { // <- statement-case-open
      // :
      // :
      // :
    }
  }

statement-cont

文の継続する行です。

hoge =
  fuga + piyo; // <- statement-cont

stream-op

<<演算子を用いた行が連続するときの2行目以降です。

std::cout
  << hoge
  << fuga // <- stream-op
  << std::endl; // <- stream-op

string

複数行に跨る文字列literalの内側です。これは0にしないと、空白文字が入っていると誤認して、混乱するかもしれません。

void
  hoge
  (
  )
  {
    fuga = R"[I learned to understand Cezanne much better, 
and to see truly how he made landscapes when I was hungry.]"; // <- string

    // :
    // :
    // :
  }

substatement

ifwhilefordoelseの直後の1行目です。

substatement-open

部分文の開き中括弧です。trycatchの直後の開き中括弧もこれです。


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

if ( a == 0 )
  hoge (); // <- substatement

if ( b < 0 )
  b = -( b + 1 ); // <- substatement
else
  b += 1; // <- substatement

while ( c > 0 )
  --c; // <- substatement

for ( std::size_t i = 0; i < N; ++i )
  std::cout << "i: " << i << std::endl; // <- substatement

do
  fuga () // <- substatement
while ( piyo () );

if ( d == 0 )
  { // <- substatement-open
    // :
    // :
    // :
  }

try
  { // <- substatement-open
    // :
    // :
    // :
  }
catch
  (
    // :
  )
  { // <- substatement-open
    // :
    // :
    // :
  }

template-args-cont

Template引数の2行目以降です。個人的にはtemplateの<>も括弧扱いして解析してほしいのですが……。

template
  <
    class hoge, // <- template-args-cont
    class fuga // <- template-args-cont
    > // <- template-args-cont
  void
  hoge
  (
  )
  {
    // :
    // :
    // :
  }

topmost-intro

最上位の言語構成要素の1行目です。

topmost-intro-cont

最上位の言語構成要素の2行目以降です。名前はtopmost-contのほうがよかったかもしれません……。


以下にtopmost-introtopmost-intro-contの解説をします。

void // <- topmost-intro
  hoge // <- topmost-intro-cont
  ( // <- topmost-intro-cont
  )
  {
    // :
    // :
    // :
  }


最後にI.S.のindentの設定を載せておきます。基本的にはgnu styleに近いですが、より例外の少ないruleにしています。tab-widthを32にしているのは、tab文字を使用せず、万が一tab文字が紛れこんだときにtab文字が目立つようにするためです。

(add-hook 'c++-mode-hook
          '(lambda ()
             (setq tab-width 32)
             (setq c-basic-offset 2)
             (setq c++-auto-newline nil)
             (setq c++-tab-always-indent t)
             (c-set-offset 'access-label '-)
             (c-set-offset 'arglist-close 0)
             (c-set-offset 'arglist-cont 0)
             (c-set-offset 'arglist-cont-nonempty 0)
             (c-set-offset 'arglist-intro '+)
             (c-set-offset 'block-close 0)
             (c-set-offset 'block-open 0)
             (c-set-offset 'brace-entry-open 0)
             (c-set-offset 'brace-list-close 0)
             (c-set-offset 'brace-list-entry 0)
             (c-set-offset 'brace-list-intro '+)
             (c-set-offset 'brace-list-open '+)
             (c-set-offset 'c 1)
             (c-set-offset 'case-label 0)
             (c-set-offset 'catch-clause 0)
             (c-set-offset 'class-close '+)
             (c-set-offset 'class-open '+)
             (c-set-offset 'comment-intro 0)
             (c-set-offset 'cpp-macro 0)
             (c-set-offset 'cpp-macro-cont '+)
             (c-set-offset 'defun-block-intro '+)
             (c-set-offset 'defun-close 0)
             (c-set-offset 'defun-open '+)
             (c-set-offset 'do-while-closure 0)
             (c-set-offset 'else-clause 0)
             (c-set-offset 'extern-lang-close '+)
             (c-set-offset 'extern-lang-open '+)
             (c-set-offset 'friend 0)
             (c-set-offset 'func-decl-cont '+)
             (c-set-offset 'inclass '+)
             (c-set-offset 'inextern-lang '+)
             (c-set-offset 'inher-cont '+)
             (c-set-offset 'inher-intro '+)
             (c-set-offset 'inline-close 0)
             (c-set-offset 'inline-open '+)
             (c-set-offset 'innamespace '+)
             (c-set-offset 'label 0)
             (c-set-offset 'member-init-cont 0)
             (c-set-offset 'member-init-intro 0)
             (c-set-offset 'namespace-close '+)
             (c-set-offset 'namespace-open '+)
             (c-set-offset 'statement 0)
             (c-set-offset 'statement-block-intro '+)
             (c-set-offset 'statement-case-intro '+)
             (c-set-offset 'statement-case-open '+)
             (c-set-offset 'statement-cont '+)
             (c-set-offset 'stream-op 0)
             (c-set-offset 'string 0)
             (c-set-offset 'substatement '+)
             (c-set-offset 'substatement-open '+)
             (c-set-offset 'template-args-cont '++)
             (c-set-offset 'topmost-intro 0)
             (c-set-offset 'topmost-intro-cont '+)
             ))