Emacs Lisp:产生编译器警告

3

字节编译 Emacs Lisp 很有用,因为它会生成编译器警告,虽然有时候比较难懂,但总是指向错误或未完成的任务,例如缺少导入或未实现的函数。

然而,我找不到一种方法来生成与*Compile-Log*缓冲区良好集成的自定义编译器警告,即显示错误位置的方式。

mymodule.el:247:1:Warning: Unused lexical variable `file-name'

例如,我正在使用以下代码来添加待办事项,并生成编译时消息:
(eval-when-compile 
  (defmacro TODO (string)
    `(eval-when-compile 
       (message "TODO: %s" ,string))))

然而,我找不到一种方法来在编译时添加信息:

  • 文件名
  • 行号

在加载时,变量load-file-name可用,但在编译时为nil。变量default-directory在编译时定义,但在这种情况下没有帮助。

至于行号,我完全不知道有什么方法。

当使用(warn ...)时,会得到类似以下内容:

Warning (emacs): TODO: Complete or remove

即没有任何位置信息。如果我使用(error ...),会自动显示行号等信息,但编译停止而不是显示所有的错误和警告,因此这也不是可行的解决方案。

更新

部分解决方案似乎是

(funcall (if byte-compile-current-file 'byte-compile-warn 'warn) FORMAT [ARGS ...])

尽管在编译时load-file-name没有被设置,至于cl-declare,它似乎并不提供创建新警告的功能。只能控制现有警告。 - kdb
2个回答

4

您需要使用内部变量byte-compile-current-file(正在编译的文件名)和byte-compile-read-position(上次read开始时的字符位置)。

或者,您可以尝试使用函数byte-compile-warning-prefix,该函数在*Warnings*缓冲区中插入file:line前缀。

无论哪种方式,您都需要自己处理Emacs内部的问题;SO是您唯一的朋友。 :-)


2

确实,这是一个问题。即使byte-compile-read-position也相当糟糕,因为当宏被展开时它还没有更新。在Emacs的主干版本中有macroexp--warn-and-return,虽然如--所示,它目前仍被视为内部使用。例如:

(defmacro TODO (string)
  (macroexp--warn-and-return
    (format "TODO: %s" string)
    nil))

为了理解如何使用它,您需要了解它通过返回一段特殊的代码来工作,这使得字节编译器在稍后(当行信息可用时)发出消息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接