C++0x 枚举类的 Emacs cc 模式缩进问题

2022-01-02 00:00:00 enums indentation c++ emacs c++11

Emacs cc-mode 似乎还不能识别 C++0x 中引入的类型安全的 enum class.我得到的结果是第二个、第三个等枚举的双缩进:

Emacs cc-mode does not appear to yet recognize the type-safe enum class introduced in C++0x. The result I get is a double indentation for second, third, etc enums:

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

我想要的是:

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

你能推荐一个好的命令添加到 .emacs 中,这将使 cc-mode 像对待普通的旧 enum<一样对待 enum class/代码>?

Can you recommend a good command to add to .emacs which will make cc-mode treat enum class the same way it treats the plain old enum?

推荐答案

这是问题所在:

cc-mode 在某种程度上依赖于关键字是单个单词的假设.添加对 enum_class 而不是 enum class 的支持只是改变一些正则表达式的问题.

This is the problem:

cc-mode relies somewhat on the assumption that keywords are single words. Adding support for enum_class instead of enum class would just be a matter of changing a few regexps.

相反,Emacs 将其视为一个类.解决这个问题的正确方法是教 Emacs 这是一个枚举.但这超出了答案的范围.

Instead Emacs treats this as a class. The correct way of solving this would be teaching Emacs that this is an enum. But that's beyond the scope of an answer.

因此,在这种情况下,我们将修改现有缩进以使其表现不同.(此gist中的代码可用于修补.)

So we'll modify the existing indentation to behave differently in this one case. (Code available for tinkering in this 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[ 	]+class[ 	]+[^}]+"))))

(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)

这没有经过大量测试.;)

This is not heavily tested. ;)

c-offsets-alist 确定语法树中不同位置的缩进.可以为它分配常量或函数.

c-offsets-alist determines the indentation for different positions in the syntax tree. It can be assigned constants or functions.

这两个函数找出当前位置是否在inside enum class {...}.如果是这种情况,它们将返回 0 或 '-,cc 模式将其解释为缩进深度.如果不是,则返回默认值.

These two functions find out whether the current position is inside the enum class {...}. If that's the case, they return 0 or '-, which cc-mode interprets as an indentation depth. If it isn't, they return the default value.

inside-class-enum-p 简单地移动到前一个大括号并检查它之前的文本是否是枚举类".

inside-class-enum-p simply moves up to the previous brace and checks if the text before it is "enum class".

相关文章