在 Emacs 的 C/C++ 模式下,将#if 0...#endif 块中的代码面更改为注释面 [英] In C/C++ mode in Emacs, change face of code in #if 0...#endif block to comment face

查看:18
本文介绍了在 Emacs 的 C/C++ 模式下,将#if 0...#endif 块中的代码面更改为注释面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将在其他一些代码编辑器中找到的功能添加到我的 Emacs 配置中,其中 #if 0...#endif 块中的 C/C++ 代码会自动设置为注释字体/字体.根据我的测试,cpp-highlight-mode 做了我想要的事情,但需要用户操作.似乎绑定字体锁定功能是使行为自动化的正确选项.

I'm trying to add functionality found in some other code editors to my Emacs configuration, whereby C/C++ code within #if 0...#endif blocks is automatically set to the comment face/font. Based on my testing, cpp-highlight-mode does something like what I want, but requires user action. It seems like tying into the font-lock functionality is the correct option to make the behavior automatic.

我已经成功地按照 GNU 文档中的示例改变了单行正则表达式的外观.例如:

I have successfully followed examples in the GNU documentation to change the face of single-line regular expressions. For example:

(add-hook 'c-mode-common-hook
  (lambda ()
    (font-lock-add-keywords nil
      '(("\<\(FIXME\|TODO\|HACK\|fixme\|todo\|hack\)" 1 
        font-lock-warning-face t)))))

可以很好地突出显示文件中任何位置的调试相关关键字.但是,我在将 #if 0...#endif 匹配为多行正则表达式时遇到问题.我在这篇文章中找到了一些有用的信息(How to compose region like "<?php foo; bar; ?>>"),这表明必须特别告知 Emacs 允许多行匹配.但是这段代码:

works fine to highlight debug related keywords anywhere in a file. However, I am having problems matching #if 0...#endif as a multiline regular expression. I found some useful information in this post (How to compose region like "<?php foo; bar; ?>"), that suggested that Emacs must be told specifically to allow for multiline matches. But this code:

(add-hook 'c-mode-common-hook
  (lambda ()
    '(progn
      (setq font-lock-multiline t)
      (font-lock-add-keywords nil
        '(("#if 0\(.\|
\)*?#endif" 1
          font-lock-comment-face t))))))

仍然对我不起作用.也许我的正则表达式是错误的(尽管它似乎可以使用 M-x re-builder),我弄乱了我的语法,或者我完全遵循了错误的方法.我在 OS X 10.6.5 上使用 Aquamacs 2.1(基于 GNU Emacs 23.2.50.1),如果这有区别的话.

still does not work for me. Perhaps my regular expression is wrong (though it appears to work using M-x re-builder), I've messed up my syntax, or I'm following the wrong approach entirely. I'm using Aquamacs 2.1 (which is based on GNU Emacs 23.2.50.1) on OS X 10.6.5, if that makes a difference.

如有任何帮助,我们将不胜感激!

Any assistance would be appreciated!

推荐答案

即使您使用了多行正则表达式,您仍然会遇到嵌套 #ifdef/#endif 以来的问题它会在第一个 #endif 处停止字体锁定.此代码有效,但我不确定大文件是否会明显变慢:

Even if you got the multiline regexp to work, you'd still have problems with nested #ifdef/#endif's since it would stop font-locking at the first #endif. This code works, although I'm not sure if there will be a noticeable slow down for large files:

(defun my-c-mode-font-lock-if0 (limit)
  (save-restriction
    (widen)
    (save-excursion
      (goto-char (point-min))
      (let ((depth 0) str start start-depth)
        (while (re-search-forward "^\s-*#\s-*\(if\|else\|endif\)" limit 'move)
          (setq str (match-string 1))
          (if (string= str "if")
              (progn
                (setq depth (1+ depth))
                (when (and (null start) (looking-at "\s-+0"))
                  (setq start (match-end 0)
                        start-depth depth)))
            (when (and start (= depth start-depth))
              (c-put-font-lock-face start (match-beginning 0) 'font-lock-comment-face)
              (setq start nil))
            (when (string= str "endif")
              (setq depth (1- depth)))))
        (when (and start (> depth 0))
          (c-put-font-lock-face start (point) 'font-lock-comment-face)))))
  nil)

(defun my-c-mode-common-hook ()
  (font-lock-add-keywords
   nil
   '((my-c-mode-font-lock-if0 (0 font-lock-comment-face prepend))) 'add-to-end))

(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

考虑#else

编辑 #2:处理 if/else/endif 的任意嵌套的 Niftier 代码

EDIT #2: Niftier code to handle arbitrary nesting of if/else/endif's

这篇关于在 Emacs 的 C/C++ 模式下,将#if 0...#endif 块中的代码面更改为注释面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆