求教,关于Emacs的C++语法高亮问题

for(int i = 0;i < n;i++) R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1));

这一行中的(i & 1)好像被当做关键字高亮为红色了,虽然这个问题不是很明显,但由于本人有强迫症,并且在有些代码中这样的现象很多,所以有办法解决一下吗?

你这是选择性的强迫症么?

  • 正文

    • 中文、英文逗号混用
    • 行内代码没有使用 ``,并且与左右中文之间没有空格
  • 代码

    • for( 括号前面没有空格
    • 0;in;i 分号后面没有空格
    • for(...) ...; 写成了一行
1 个赞

你这个看起来像是 Raw Emacs 的 c++-mode 效果: c++-mode 默认就是这个效果:

c++-mode--raw-emacs

代码风格的问题,毕竟我还不是程序员,所以我承认我的代码风格有点问题.但您能帮我解决我提的问题吗?并且我好像也没有中英逗号混用吧. 我记得我用了Markdown的```cpp啊

所以请问怎么解决呢?关于Emacs我是直接用apt装的.

face--c++-mode--emacs

不知道这是 c++-mode 的 feature 还是 bug。

看了一下 cc-*.el 文件当中有用到 font-lock-type-face 的地方,暂时没有发现什么问题(主要是源代码太多/复杂了)。

也许可以试试单独为 (x & y) 定义一条规则,来覆盖 c++-mode 的默认效果。

很大可能是个bug, 反馈一下吧

谢谢了.

那么追问一句:

您的Emacs的c++-mode是怎么弄的呢?

我给的截图中只是部分例子,其实不光是位运算,有的其他情况也会有这样的问题,只是我不方便给出代码.

而且我对elisp了解不多,也照顾不到所有这样的情况.

upd: 不光是(i & 1)这样的情况,像(a * 2)这样一个括号内变量乘上一个常数也会有这样的情况,但只对于部分运算符如此.

这是个历史遗留“问题”吧,我试了在 Emacs 24.5 上也是一样,可以通过以下代码修复:

(defun fix-c++-mode-face ()
  (font-lock-add-keywords
   nil
   '(("(\\([a-zA-Z_][a-zA-Z_0-9]*\s+\\)[&\*]\s+[+-]?[a-zA-Z_0-9]+" (1 nil t)))
   'append))
(add-hook 'c++-mode-hook 'fix-c++-mode-face)

这个方案的覆盖面有限,再复杂一点语句,例如 (a * (~b)); 就不适用了。只能帮到这里了,你自己慢慢摸索吧。

谢谢!

既然是"历史遗留"的问题,那我也不多问了.

Emacs 22.1 不存在这个问题,应该是最近几个大版本才有的,可是这也好几年了,看来用 Emacs 写 C++ 的人比较少,或者都不在乎,毕竟这高亮都是靠正则匹配的,规则复杂了,顾此失彼是难免的,又都不想花太多力气去调试、把问题搞复杂,所以将就了。

這個時候我就要推薦 cquery rainbow semantic highlighting 了,不過不能代替全部功能。擴展後吃掉 cc-mode 一些高亮還是能做到的

https://github.com/jacobdufault/cquery/wiki/Visual-Studio-Code 插件默認帶彩虹配色

Emacs 插件也支持semantic highlighting,但不是彩虹的,也缺colortheme (如spacemacs colortheme),大家有動力的話來貢獻啊

另外,cquery-sem-highlight-method 默認爲 overlay ,有嚴重性能問題。使用 https://github.com/emacs-mirror/emacs/commits/feature/noverlay 分支似乎能緩解。font-lock 也挺慢的。

有興趣的話可以看這個issue,支持更多種類的 semantic highlighting: https://github.com/jacobdufault/cquery/issues/239

cquery 中輸出 semantic highlighting 信息的代碼在這裏 cquery/message_handler.cc at master · jacobdufault/cquery · GitHub

2 个赞

哈哈, 强迫症不一定要强迫大多数人认为规范的东西。。。。有些强迫症就喜欢用刀子吃米饭 :grimacing:

正是因为情况太多, 作者会考虑不到, 所以应该多反馈, cc-mode的作者好像是德国人, 很严谨

貌似正则匹配时候,将 & 和 * 之前的字符当做类型 (引用和指针)来对待了,应该是个 bug。

歪个楼,ACMer?还是 OIer?

这代码风格就像学生做作业...

正式程序这个变量命名习惯会被修理的...

应该是算法竞赛的程序吧

代码的可维护意识要从娃娃抓起...

好吧我没注意到😂