2013-02-05 26 views
10

ごとに異なるインデント私はemacsの中に、次のインデントを達成しようとしている:のemacs:クラスと構造体

class A 
{ 
    // I ALWAYS use access labels in classes 

    public: // access-label 
     int member; // inclass 
}; 

struct B 
{ 
    // I NEVER use access labels in structs 

    int member; // inclass 
}; 

ただし、次のコンフィギュレーション・ファイルを使用して...

(defun my-cpp-mode() 
    "My C++ mode" 
    (c++-mode) 
    (c-set-style "K&R") 
    (setq c-basic-offset 4) 
    (c-set-offset 'access-label '-) 
    (c-set-offset 'inclass '++) 
    ;; ... 
    (setq mode-name "My C++") 
) 
(add-to-list 'auto-mode-alist '("\\.[ch]p?p?\\'" . my-cpp-mode)) 

...私はのみ達成:

ためだ。もちろん、
class A 
{ 
    public: // access-label 
     int member; // inclass 
}; 

struct B 
{ 
     // this indentation is too long 
     int member; // inclass 
}; 

インデントのための
  • は明らかに「クラス」と「構造体」との間に違いはありません
  • は「inclass」もののインデントがアクセスラベルやないの存在に依存しない、(それが「inclass」すべてです) 。

クラス/構造体またはアクセスラベルの有無に依存してinclusのインデントをどのようにすることができますか?

+0

私は、public:private:インデントレベルを追加しないことが望ましいと思います。 – djechlin

+0

ありがとうございますが、 "{"と "public:"は同じ列にありますが、それは私が望むものではありません。 – Aurelien

+1

私はあなたの欲望を理解することができ、十分な調整をすれば可能であるはずです。一方、クラスと構造の区別がないため、これは簡単には実現できません。C++では構造体のアクセス指定子を使用することもできます。しかし、その使用はまれですが、私はこの質問を+1し、解決策が出てくるかどうかを調べることに興味があります。 – MvG

答えて

7

新しい回答

私はあなたがあなたの質問に言及していた正確な要件に走りました。 新しいプロジェクトのコーディングスタイルに合わせてインデントを設定する必要がありました。少しの研究の後、Custom Line-up Functionsを使ってこれを達成しました。

はこのようにあなたmy-cpp-modeを変更します。

(defun my-c-lineup-inclass (langelem) 
    (let ((inclass (assoc 'inclass c-syntactic-context))) 
    (save-excursion 
     (goto-char (c-langelem-pos inclass)) 
     (if (or (looking-at "struct") 
       (looking-at "typedef struct")) 
      '+ 
     '++)))) 

(defun my-cpp-mode() 
    "My C++ mode" 
    (c++-mode) 
    (c-set-style "K&R") 
    (setq c-basic-offset 4) 
    (c-set-offset 'access-label '-) 
    (c-set-offset 'inclass 'my-c-lineup-inclass) 
    ;; ... 
    (setq mode-name "My C++") 
) 

この答えが許容できる場合、私は先に行くと、古い答えを削除します。あなたが達成しようとしているものに基づいて

旧回答

、私は別のアプローチを提案することができますか?クラスとクラスのメンバーとは異なるインデントレベルでアクセスラベルが必要なようです。それを達成するために以下を使用してください。 Emacsのドキュメントから

(access-label . /) 

OFFSET場合はシンボル+',の一つである - '++', - '、*', or /」 その後、 `C-基本オフセットの正または負の倍数'は、ベースインデントの に追加されます。 1、-1,2、-2、0.5、および-0.5である。

ここでは、私が定義したカスタムスタイルのスニペットを示します。 c-basic-offsetセットで

(c-add-style 
"xyz-style" 
'((indent-tabs-mode . nil) 
    (fill-column . 75) 
    (c-basic-offset . 4) 
    (c-offsets-alist . (
         (access-label . /) 
         (inextern-lang . 0) 
         (innamespace . 0) 
         (member-init-intro . ++) 
         )))) 

4に、(access-label . /)アクセス・ラベルに2つのスペースの負のインデントを追加します。ここでは、サンプルコードのインデントモードの実際の結果を示します。

class A 
{ 
    // I ALWAYS use access labels in classes 

    public: // access-label 
    int member; // inclass 
}; 

struct B 
{ 
    // I NEVER use access labels in structs 

    int member; // inclass 
}; 

メンバ変数/構造体メンバのインデントレベルが一貫しているため、このモードをお勧めします。 FWIW、Google C Styleも同じアプローチに従います。

私が知る限り、クラスメンバーまたは構造メンバー(inclass sytax要素)を区別することはできません。 M-x c-syntactic-information-on-regionを使用して、リージョンの構文分析を行うことができます。そのような分析の1つでは、次のような結果が得られます。出力から、クラスまたは構造体にあるかどうかを区別するものはありません。

class A         // ((topmost-intro 1)) 
{          // ((class-open 1)) 
             // ((inclass 64) (topmost-intro 64) (comment-intro))I ALWAYS use access labels in classes 
             // ((inclass 64) (topmost-intro 64)) 
    public:        // ((inclass 64) (access-label 64))access-label 
    int member;       // ((inclass 64) (topmost-intro 64))inclass 
};          // ((class-close 1)) 
             // ((topmost-intro 503)) 
struct B        // ((topmost-intro 503)) 
{          // ((class-open 629)) 
             // ((inclass 694) (topmost-intro 694) (comment-intro))I NEVER use access labels in structs 
             // ((inclass 694) (topmost-intro 694)) 
    int member;       // ((inclass 694) (topmost-intro 694))inclass 
};          // ((class-close 629)) 
+0

はい、ありがとう、これは確かに私が使用することを決めた妥協であるので、多くのemacsユーザーに興味があるかもしれないのであなたの答えを+1します。しかし、あなたが言ったように、実際の質問には答えません。 – Aurelien

+1

あなたの最後の編集でOKですが、これは不可能であることを示しています。これは今質問に確実に答えています。ありがとう。 – Aurelien

+0

これは、 'struct'は常にアクセスラベルを持たないことを前提としています。私はアクセスラベルが存在することを認識する解決策があることを願っています... – Arkadiy

0

私のプロジェクトのコーディング標準では、この種の字下げが必要になります。 Arkadiyと同様に、私はアクセスラベルを尊重するソリューションを好む。前述したように

(defun indent-after-access-label (langelem) 
    "Return the appropriate indent for a class or a struct." 
    (save-excursion 
    (save-match-data 
     ;; Optimization to avoid at least a few calls to re-search-backward. 
     (if (assoc 'access-label c-syntactic-context) 
      '++ 
     (if (re-search-backward "\\(?:p\\(?:ublic\\|r\\(?:otected\\|ivate\\)\\)\\)" c-langelem-pos langelem) t) 
      '++ 
      '+))))) 

indent-after-acess-labelシンボル(などc-set-offsetまたはc-offset-alist、経由)inclassのためにインデントとして設定する必要があります。これは私が思いついたものです。

re-search-backwardのためにこれは理想的ではありませんが、動作します。

2

は、上記プラビーン・クマールさんの回答に基づいて、私は、カスタムのラインアップ機能、わずかに異なるバージョンの実装:

(defun my-c-lineup-inclass (langelem) 
    (let ((inclass (assoc 'inclass c-syntactic-context))) 
    (save-excursion 
     (c-beginning-of-defun) ; This sees the correct string. 
     (if (or (looking-at "struct") 
       (looking-at "typedef struct")) 
      '+ 
     '++)))) 

; In particular, the following offsets need to be specified: 
(c-set-offset 'access-label '-) 
(c-set-offset 'inclass 'my-c-lineup-inclass) 
; ... 

元のコードは、ブレースは、次の行、すなわち上にあった場合には動作しませんでした

struct foo 
{ 
     int bar; 
}; 

は、「」にインデントされます。

免責事項:私はLispを知らない。私はちょうど遊んで、これは私のために働く。たとえば、これに関連するパフォーマンスの問題があるかどうかはわかりません。

+0

'(c-beginning-of-defun)'の使用は、構造体/クラスで定義されたインライン関数では機能しないので、完全には正しくありません。 –

関連する問題