Emacs缩进C++ 11 lambda函数(cc模式)

Hug*_*ues 17 c++ emacs indentation c++11

默认的Emacs C++模式(cc-mode)仍然无法识别许多C++ 11功能.一个恼人的问题是它对用作函数参数的lambda函数应用了太多的缩进:

std::vector<int> ar(4);
std::generate_n(std::begin(ar), 4, [] {
        static int g_i;
        return g_i++;
    });
std::for_each(std::begin(ar), std::end(ar), [](int i) {
        std::cout << " " << i;
    });
bool b = std::is_sorted(std::begin(ar), std::end(ar), [&](int l, int r) {
        return l<r;
    });
std::cout << "   " << b << "\n";
Run Code Online (Sandbox Code Playgroud)

理想情况下,人们会更喜欢:

std::vector<int> ar(4);
std::generate_n(std::begin(ar), 4, [] {
    static int g_i;
    return g_i++;
});
std::for_each(std::begin(ar), std::end(ar), [](int i) {
    std::cout << " " << i;
});
bool b = std::is_sorted(std::begin(ar), std::end(ar), [&](int l, int r) {
    return l<r;
});
std::cout << "   " << b << "\n";
Run Code Online (Sandbox Code Playgroud)

对此有好的解决方案吗?

Hug*_*ues 15

使用C++ 0x枚举类的Emacs cc模式缩进问题中的讨论修复了enum class 格式问题.

这启发了以下建议功能.它在打开的参数列表中检测到一个打开的C++ lambda函数,并取消一级缩进以在问题中产生"理想"结果:

(defadvice c-lineup-arglist (around my activate)
  "Improve indentation of continued C++11 lambda function opened as argument."
  (setq ad-return-value
        (if (and (equal major-mode 'c++-mode)
                 (ignore-errors
                   (save-excursion
                     (goto-char (c-langelem-pos langelem))
                     ;; Detect "[...](" or "[...]{". preceded by "," or "(",
                     ;;   and with unclosed brace.
                     (looking-at ".*[(,][ \t]*\\[[^]]*\\][ \t]*[({][^}]*$"))))
            0                           ; no additional indent
          ad-do-it)))                   ; default behavior
Run Code Online (Sandbox Code Playgroud)

  • 有关较新的 Emacsen 中的规范解决方案,请参阅 [frinkr 的回答](/sf/answers/3552881811/)。 (2认同)

fri*_*nkr 12

在Emacs26中,接受的答案对我不再有用。我只是将“ inlambda”设置为0。

  (c-offsets-alist . ((case-label . 0)
                      (inline-open . 0)
                      (substatement-open . 0)
                      (inlambda . 0) ; no extra indent for lambda
                      (block-open . 0) ; no space before {
                      (knr-argdecl-intro . -)))
Run Code Online (Sandbox Code Playgroud)