如何调试Elisp?

68

通常调试的最简单方法是使用printf。我该如何调试emacs-lisp代码?如何从elisp向emacs编辑器打印一些内容?或者是否有任何方法来调试elisp代码?

例如,我该如何检查以下代码是否在.emacs文件中运行?

(load "auctex.el" nil t t)

这个手册可能对你有所帮助。 - Yantao Xie
2
请允许我推荐这篇关于 Edebug 的博客文章 - Malabarba
5个回答

93

调试器(edebug)的使用非常简单。进入函数的定义并键入M-x edebug-defun。下一次调用该函数时,您将能够像使用其他调试器一样逐步执行代码。键入?以获取键绑定列表或查看edebug的文档。


3
值得注意的是,在调试时最重要的按键绑定:SPC用于进行下一步,i用于单步进入,o用于单步跳出,q用于退出。 - kotchwane

36

GNU Emacs中有两个调试器:

  • edebug -- 在另一篇帖子中有解释
  • debug

我使用debug。以下是常见的入口点(使用调试器的方法):

  • 使用M-x debug-on-entry,然后输入您想要进入调试器的函数。

  • 使用M-x toggle-debug-on-error -- 当出现错误时进入调试器。

  • M-x toggle-debug-on-quit -- 当用户按下C-g时进入调试器。
  • 在代码中特定位置(断点)显式调用函数debug,以在这些位置进入调试器:
    (debug)

您可以使用d来单步调试,或者使用c跳过特定评估的细节。


4
如何检查不同变量的值?我可以通过一个函数进行调试,但不知道如何检查不同变量的值。 - Alok
5
您可以将光标放在变量上并按 RET,或按 e 并评估您感兴趣的变量。 - danlei
3
在原始(调用)上下文中,您可以评估任何sexp。您还可以向函数 debug 提供要评估的sexp,以便在调试器打开时显示其值。例如:(debug nil (current-buffer)) - Drew
1
@nate,Elisp文档列出了可用的命令。特别是要查看jue键绑定。如果debug不够用,Edebug似乎提供了更精细的控制流程的可能性。 - Y. E.
1
@nate:这就是 c 的作用。我称之为“跳过细节”。c 代表“继续”,大概是这个意思。它会完全评估给定的步骤,而不需要让你通过每个中间步骤来完成它。 - Drew
显示剩余3条评论

23

这对于打印数值很有用

(message "Hello (%s)" foo)

但对于数据结构并不是很有效。对于这种情况,使用

(prin1 list-foo)

或者使用 (prin1-to-string) 将其嵌入到 (message) 中。


6
你可以使用"%S"来打印带格式的数据结构。 - ocodo

8

最简单的调试方式可能是交互式运行您的代码。您可以在Lisp缓冲区中通过将光标放在表达式后并运行C-x C-e (eval-last-sexp)来实现。

或者:

(message "hello world")

使用C-h f message命令可以了解有关内置消息函数的更多信息。如果您生成了大量消息,则可能需要将变量message-log-max自定义为较大的值。


这相当于 printf 方法,有时候也是一个非常好的方法。 - Drew

3
为了一一回答您的问题:
  • 打印内容:有很多种方法。 (message "Hello") 将字符串放在回显区中; (insert "hello") 将字符串插入到当前光标所在位置的缓冲区中...
  • 如何检查以下代码是否被运行:我会用(比如)“frotzumotzulous”(即任何一个字符串,只要它不是真正的文件名)替换“auctex.el”,然后看看是否会出错信息。如果没有错误,那么显然该代码没有被运行。

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