You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Emacs中C++类与结构体的正确缩进配置问题

Emacs C++类成员缩进配置方案

我试过相关缩进配置方案但均未生效,目标是让类中public/private标签后的函数声明按tab-width缩进,但不能直接将brace-list-entry设为tab-width——这会导致所有带该标记的行递归额外缩进。我需要实现逻辑:当前行标记为brace-list-entry时,若上一行也是该标记则缩进0,否则缩进tab-width。

我的C++头文件示例:

// my_header
namespace foo
{
    template<typename T>
    class ResizablePoolAllocator
    {
        static_assert(sizeof(T) >= sizeof(void*));  // 'brace-list-intro
    public:
    inline T* Alloc() { return (T*)_alloc(); }      // 'brace-list-entry
    inline void Free(T* ptr) { _free(ptr); }        // 'brace-list-entry

    private:
    void* _alloc();                                 // 'brace-list-entry
    void _free(void* ptr);                          // 'brace-list-entry
    };
}

当前Emacs配置相关部分:

(defun my-cpp-common-mode-hook ()
  (c-set-offset 'substatement-open 0)
  (c-set-offset 'inline-open 0)
  (c-set-offset 'comment-intro 0)
  (c-set-offset 'defun-block-intro 'tab-width)
  (c-set-offset 'statement-block-intro 'tab-width)
  (c-set-offset 'substatement 'tab-width)
  (c-set-offset 'topmost-intro 0)
  (c-set-offset 'statement-cont 'tab-width)
  (c-set-offset 'func-decl-cont 0)
  (c-set-offset 'brace-list-open 0)
  (c-set-offset 'brace-list-intro 'tab-width)
  (c-set-offset 'brace-list-entry 0)
  ;; EXPERIMENTAL:
  ;;(c-set-offset 'arglist-intro 'c-lineup-arglist-intro-after-paren)
  (c-set-offset 'arglist-intro 'tab-width)
  )

(add-hook 'c++-mode-hook
      (lambda ()
        (setq indent-tabs-mode t)
        (setq tab-width 4)
        (setq c-basic-offset 4)
        (highlight-doxygen-mode t)
        )
      )
(add-hook 'c++-mode-hook 'my-cpp-common-mode-hook)

解决方案

通过自定义缩进函数实现条件逻辑,替换原有brace-list-entry的偏移设置:

  1. 定义判断上一行标记的自定义函数:
(defun my-brace-list-entry-offset (offset)
  "根据上一行的语法标记决定brace-list-entry的缩进量。"
  (save-excursion
    (forward-line -1)
    (if (eq (c-guess-basic-syntax) 'brace-list-entry)
        0
      tab-width)))
  1. 在hook函数中替换原有brace-list-entry的配置:
(defun my-cpp-common-mode-hook ()
  ;; 保留原有其他配置项
  (c-set-offset 'substatement-open 0)
  (c-set-offset 'inline-open 0)
  (c-set-offset 'comment-intro 0)
  (c-set-offset 'defun-block-intro 'tab-width)
  (c-set-offset 'statement-block-intro 'tab-width)
  (c-set-offset 'substatement 'tab-width)
  (c-set-offset 'topmost-intro 0)
  (c-set-offset 'statement-cont 'tab-width)
  (c-set-offset 'func-decl-cont 0)
  (c-set-offset 'brace-list-open 0)
  (c-set-offset 'brace-list-intro 'tab-width)
  ;; 替换为自定义缩进逻辑
  (c-set-offset 'brace-list-entry 'my-brace-list-entry-offset)
  ;; EXPERIMENTAL:
  ;;(c-set-offset 'arglist-intro 'c-lineup-arglist-intro-after-paren)
  (c-set-offset 'arglist-intro 'tab-width)
  )

该函数会检查当前行的上一行语法标记:

  • 若上一行也是brace-list-entry(同属一个访问控制块的前一个函数),则缩进0;
  • 若上一行是public/private等非brace-list-entry行,则缩进tab-width。

配置完成后,重新打开头文件并使用C-M-\重新缩进整个缓冲区,即可看到符合预期的缩进效果。


内容的提问来源于stack exchange,提问作者alexpanter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:27:28