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的偏移设置:
- 定义判断上一行标记的自定义函数:
(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)))
- 在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
相关产品推荐
相关产品推荐

