Emacs CC-mode indentation problème avec C++0x enum classe

Emacs cc-mode ne semble pas encore reconnaître le type-safe enum class introduit en C++0x. le résultat que j'obtiens est une double indentation pour les énumérations second, third, etc:

enum class Color {
    Blue,
        Red,
        Orange,
        Green
        };

Ce que je voudrais, c'est:

enum class Color {
    Blue,
    Red,
    Orange,
    Green
};

Pouvez-vous recommander une bonne commande à ajouter à .emacs qui rendra CC-mode treat enum class de la même manière qu'il traite l'ancien enum?

33
demandé sur Alan Turing 2011-06-27 22:40:18

1 réponses

C'est le problème:

Cc-mode repose quelque peu sur l'hypothèse que les mots-clés sont des mots simples. Ajouter le support de enum_class au lieu de {[2] } serait juste une question de changer quelques expressions rationnelles.

Au lieu de cela, Emacs traite cela comme une classe. La bonne façon de résoudre ce problème serait d'enseigner à Emacs qu'il s'agit d'une énumération. Mais c'est au-delà de la portée d'une réponse.

C'est le hack:

Nous allons donc modifier l'indentation existante pour se comporter différemment dans ce cas. (Code disponible pour bricoler dans ce gist .)

(defun inside-class-enum-p (pos)
  "Checks if POS is within the braces of a C++ \"enum class\"."
  (ignore-errors
    (save-excursion
      (goto-char pos)
      (up-list -1)
      (backward-sexp 1)
      (looking-back "enum[ \t]+class[ \t]+[^}]+"))))

(defun align-enum-class (langelem)
  (if (inside-class-enum-p (c-langelem-pos langelem))
      0
    (c-lineup-topmost-intro-cont langelem)))

(defun align-enum-class-closing-brace (langelem)
  (if (inside-class-enum-p (c-langelem-pos langelem))
      '-
    '+))

(defun fix-enum-class ()
  "Setup `c++-mode' to better handle \"class enum\"."
  (add-to-list 'c-offsets-alist '(topmost-intro-cont . align-enum-class))
  (add-to-list 'c-offsets-alist
               '(statement-cont . align-enum-class-closing-brace)))

(add-hook 'c++-mode-hook 'fix-enum-class)

Ce n'est pas fortement testé. ;)

Comment ça marche:

c-offsets-alist détermine l'indentation pour différentes positions dans l'arbre syntaxique. On peut lui attribuer des constantes ou des fonctions.

Ces deux fonctions déterminent si la position actuelle est à l'intérieur du enum class {...}. Si c'est le cas, ils renvoient 0 ou '-, que le mode cc interprète comme une profondeur d'indentation. Si ce n'est pas le cas, ils renvoient la valeur par défaut valeur.

inside-class-enum-p Il suffit de passer à l'Accolade précédente et de vérifier si le texte avant qu'il ne soit "classe enum".

26
répondu nschum 2012-05-07 08:50:09