emacs 用hide-ifdef实现像现代IDE一样C/C++的宏(#ifndef)阴影

一直没有发现一个好的插件可以达到现代ide一样对#ifndef的处理效果,就自己折腾了一下,下面是效果图:

设置的是C++17标准,可以看到,对一些编译器宏和17标准可以做到高亮和阴影了。 在开始配置之前,要获取一下编译时的宏,参照hide-ifdef的注释:

g++ -dM -E -std=c++17 test.cc -o test.hh

注意,这个test.cc文件不要包含任何库头文件!然后打开test.hh,开启hide-ifdef-mode执行M-x hide-ifdefs。然后C-h v查看hide-ifdef-env,就发现它从test.hh读取了预处理后各种宏的值的一个映射的列表。这也就是为什么test.cc文件不要包含头文件,因为这样就会把比如#include的#define _GLIBCXX_IOSTREAM 1的值也包括进去,然后就把整个iostream都染成暗色了。

然后从C-h的buffer中复制它现在的值,新建一个el文件,创建一个列表:

hideif启动后,直接加载一下gcc-env.el的代码,里面就是一个列表而已,把它赋值给hide-ifdef-env。(setq hide-ifdef-shadow t)是设置shadow不启用的代码而不是折叠它,hide-ifdef-initially就是打开文件就执行hide-ifdefs。

(add-hook 'c-mode-hook #'hide-ifdef-mode)
(add-hook 'c++-mode-hook #'hide-ifdef-mode)
(with-eval-after-load 'hideif
  (load-file "~/.config/emacs/plugin/hide-ifdef/gcc-env.el")
  (setq hide-ifdef-env gcc-cpp20-env-list)
  (setq hide-ifdef-initially t)
  (setq hide-ifdef-shadow t))

大体是不错了,比较蛋疼的是,如果看带有#ifndef … #define 这种防止重复的宏的文件时,如果又不小心执行了一下hide-ifdefs,因为打开文件时执行过一次,有了define的内容,所以就会把文件全部shadow了。

1 个赞
2 个赞

可以试一下 lsp-bridge 的 lsp-bridge-semantic-tokens-mode 功能, 传说可以根据 LSP Server 动态的识别 C++ macro 的语法高亮。