Friday, February 4, 2011

Highlight #if 0 ... #else ... #endif in Emacs

This seems to be a FAQ, and a rather annoying missing feature in Emacs. Especially once you see it working in Vim. I guess it's the closest I can get to penis envy.

Well, envy no more - just add the code below to your .emacs and you're good to go.

It'll highlight, as comments, bits of C/C++ code that are disabled with #if 0 ... #else ... #endif and #if 1 ... #else ... #endif. This is done by configuring cpp-highlight-buffer to recognize "0" as an undefined C preprocessor label and "1" as defined, and then causing cpp-highlight-buffer to be called every time the buffer is highlighted.

If you feel adventurous, I suggest you remove the first few lines - those that start with (setq ... - and use, instead, the Emacs customization interface to configure cpp-highlight-buffer:
M-x customize-group RET cpp RET
It should be pretty easy to recreate the setup below, and then you may want to experiment:
  1. handle any #ifdef ... #else ... #endif blocks, by adding more pre-defined labels (e.g. HAVE_CONFIG_H)
  2. make disabled code read-only
  3. make disabled code completely invisible!
  4. use (background-color . "gray") instead of font-lock-comment-face, so that disabled code is still syntax highlighted as usual, only grayed-out
  5. ...
(don't forget to save your settings once done)

To be fair with Vim, this is a (potentially CPU intensive) hack, but then again, what isn't?

(setq cpp-known-face 'default)
(setq cpp-unknown-face 'default)
(setq cpp-known-writable 't)
(setq cpp-unknown-writable 't)
(setq cpp-edit-list '(("0" font-lock-comment-face default both)
                      ("1" default font-lock-comment-face both)))

(defun my-c-mode-font-lock-if0 (limit)
  (cpp-highlight-buffer t)
  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))

No comments:

Post a Comment