有时你希望只在满足特定条件时才编译某段代码。在维护 Emacs 扩展包时这种需求尤为常见:为了让扩展包兼容旧版 Emacs,你可能需要使用某些在当前 Emacs 版本中已被标记为废弃的函数或变量。
你可以在运行时使用条件表达式来选择新版或旧版代码,但这样做往往会产生关于废弃函数 / 变量的烦人警告。针对这类场景,宏 static-if 就非常实用。它的用法模仿了特殊形式 if(see 条件判断)。
如果要在旧版 Emacs 中使用该功能,可以将 static-if 的源码从 Emacs 源文件 lisp/subr.el 复制到你的扩展包中。
在宏展开阶段测试 condition。如果其值为非 nil,则将宏展开为 then-form;否则将宏展开为被 progn 包裹的 else-forms。else-forms 可以为空。
下面是来自 CC Mode 的一个使用示例,它用于避免在新版 Emacs 中编译 defadvice 结构:
(static-if (boundp 'comment-line-break-function)
(progn)
(defvar c-inside-line-break-advice nil)
(defadvice indent-new-comment-line (around c-line-break-advice
activate preactivate)
"Call `c-indent-new-comment-line' if in CC Mode."
(if (or c-inside-line-break-advice
(not c-buffer-is-cc-mode))
ad-do-it
(let ((c-inside-line-break-advice t))
(c-indent-new-comment-line (ad-get-arg 0))))))