【问题标题】:Troubleshooting techniques for Emacs and Emacs LispEmacs 和 Emacs Lisp 的故障排除技术
【发布时间】:2011-01-06 10:47:01
【问题描述】:

大约 4 年以来,我一直是一个相当普通的 emacs 用户,但在自定义 emacs 和排除 elisp 故障时,我仍然是新手。最近,我开始自定义 emacs 作为我的 ruby​​ 开发环境,并且我从 StackOverflow 的人们那里学到了一些技术。 例如,这里有人告诉我关于 C-u C-M-x 使用 edebug 检测函数,然后逐步执行代码。我还发现,emacs 中的大多数命令和模式都提供了大量的钩子(函数或正则表达式或可自定义的变量),它们将提供任何新手想要的大部分内容。
现在我很贪心 - 我正在寻找更多你过去使用过并发现有用的技术和技巧。

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:
     (setq debug-on-error t)
     (setq debug-on-quit t)
    

    当您想调试任意深度的问题时,这些帮助。您已经发现了edebug(这是我找出其他人代码的首选工具)。 describe-function 通常会为您提供指向加载它的.el 文件(以及行号)的链接。这对于跳转到问题的根源很有用。我经常这样做,复制函数,放入一些 message 调用并重新评估 C-x C-e 以运行该函数而不是原始函数。

    更新:这是我从presentation by John Wiegley 那里得到的一些信息。

    (global-set-key (kbd "C-c C-d")
            (lambda () (interactive)
              (setq debug-on-error (if debug-on-error nil t))
              (message (format "debug-on-error : %s" debug-on-error))))
    

    让您只需按一下键即可切换debug-on-error

    【讨论】:

    • 关于编辑,toggle-debug-on-error默认存在:)
    • +1,谢谢。当编写自己的内容比考虑搜索现有内容更容易时,会说一些话。 :)
    【解决方案2】:

    C-x Esc Esc 为您提供已运行的 M-x 命令的可浏览历史记录,但会显示 elisp 代码。

    IELM 是 emacs lisp 的 repl。

    Speedbar 是浏览 .el 文件的绝佳方式,我也发现自己经常使用 C-h i(浏览 elisp 手册)并使用 speedbar 浏览主题节点树。

    信息浏览器中的 C-s / C-r 增量搜索实际上会搜索过去的分页符。

    我经常运行 M-: 来快速测试一些代码,而不必切换到我的 *ielm* 缓冲区。

    对于特别棘手的代码,我在桌面上创建了一个快捷方式来运行 emacs -q -l development-init.el(尤其是处理缓冲区和外部进程的低级操作的代码很方便,这种东西可以很容易地挂起 emacs 或用 segv 杀死它)。

    【讨论】:

      【解决方案3】:

      如果破解您的 .emacs 文件,请始终让 emacs 进程运行,并通过启动第二个 Emacs 进程来测试更改(使用--debug-init)。这样,如果出现问题,您仍然可以使用编辑器。

      【讨论】:

        【解决方案4】:

        就我而言,我更喜欢(推荐)debug 而不是 edebug,但这可能只是品味问题。

        除了 Noufal 提到的 debug-on-* 变量之外,您还可以通过 M-x debug-on-entry 进入给定函数的调试器。

        您可以在代码的断点处对debug 进行显式调用:(debug)(debug nil sexp-to-print)

        【讨论】:

          【解决方案5】:

          我在调试工具上的初始化文件 cmets:

          ;;;; * Debugging, Tracing, and Profiling
          
          ;; M-: (info "(elisp) Debugging") RET
          
          ;; Standard debugger:
          ;; M-x debug-on-entry FUNCTION
          ;; M-x cancel-debug-on-entry &optional FUNCTION
          ;; debug &rest DEBUGGER-ARGS
          ;; M-x toggle-debug-on-error
          ;; M-x toggle-debug-on-quit
          ;; setq debug-on-signal
          ;; setq debug-on-next-call
          ;; setq debug-on-event
          ;; setq debug-on-message REGEXP
          
          ;; Edebug -- a source-level debugger for Emacs Lisp
          ;; M-x edebug-defun (C-u C-M-x) Cancel with eval-defun (C-M-x)
          ;; M-x edebug-all-defs -- Toggle edebugging of all definitions
          ;; M-x edebug-all-forms -- Toggle edebugging of all forms
          ;; M-x edebug-eval-top-level-form
          
          ;; Tracing:
          ;; M-x trace-function FUNCTION &optional BUFFER
          ;; M-x untrace-function FUNCTION
          ;; M-x untrace-all
          
          ;; Timing and benchmarking:
          ;; (benchmark-run &optional REPETITIONS &rest FORMS)
          
          ;; Emacs Lisp Profiler (ELP)
          ;; M-x elp-instrument-package
          ;; M-x elp-instrument-list
          ;; M-x elp-instrument-function
          ;; M-x elp-reset-*
          ;; M-x elp-results
          ;; M-x elp-restore-all
          ;;
          ;; "There's a built-in profiler called ELP. You can try something like
          ;; M-x elp-instrument-package, enter "vc", and then try finding a file
          ;; Afterwards, M-x elp-results will show you a profile report.
          ;; (Note that if the time is instead being spent in non-vc-related
          ;; functions, this technique will not show it, but you can instrument
          ;; further packages if you like.)" http://stackoverflow.com/a/6732810/324105
          
          ;; CPU & Memory Profiler ('Native Profiler')
          ;; M-x profiler-start
          ;; M-x profiler-report
          ;; M-x profiler-reset
          ;; M-x profiler-stop
          ;; M-x profiler-*
          
          ;; Dope ("DOtemacs ProfilEr. A per-sexp-evaltime profiler.")
          ;; https://raw.github.com/emacsmirror/dope/master/dope.el
          ;; M-x dope-quick-start will show a little introduction tutorial.
          
          ;; Spinning:
          ;; Set debug-on-quit to t
          ;; When the problem happens, hit C-g for a backtrace.
          

          【讨论】:

            【解决方案6】:

            欢迎来到启蒙的前几步。 ;)

            首先,一些简单的快速点击:

            (add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)
            

            这将为您提供有关迷你缓冲区的一些提示。它非常方便!这个技巧不是关于故障排除,而是更多关于使其易于编写,但仍然如此。

            从 MELPA 获取 erefactor 包,看看它的作用。我注意到在对函数执行C-x C-e 之后,它会通过 elint 运行结果。省去很多麻烦。

            emacs 入门套件中的这个钩子很棒。它会删除任何无效的 .elc 文件。如果您不小心,旧的 elc 文件可能会成为您的眼中钉。反过来看自动编译。

            (add-hook 'emacs-lisp-mode-hook 'starter-kit-remove-elc-on-save)
            
            (defun starter-kit-remove-elc-on-save ()
              "If you're saving an elisp file, likely the .elc is no longer valid."
              (make-local-variable 'after-save-hook)
              (add-hook 'after-save-hook
                        (lambda ()
                          (if (file-exists-p (concat buffer-file-name "c"))
                              (delete-file (concat buffer-file-name "c"))))))
            

            最后,在编辑 lisp、emacs-lisp 或 scheme 时,请务必尝试使用 paredit。太棒了。

            【讨论】:

            • 我个人认为删除 .elc 文件是一个糟糕的主意。 byte-recompile-directory 之类的工具仅在存在相应(但已过时)的 .elc 文件时才编译文件,因此删除该文件实际上可以防止重新编译!相反,我强烈建议在文件过期时自动重新编译文件。我曾经使用after-save-hook 来运行(when (file-exists-p (byte-compile-dest-file buffer-file-name)) (byte-compile-file buffer-file-name)),但现在我真的很喜欢auto-compile,它几乎可以处理所有可能发生的事情。
            • 老实说,我宁愿使用慢速 elisp 也不要不一致。
            • 当然,但是如果 .elc 文件在必要时自动重新编译,那么您将获得两全其美:一致且快速。说真的,看看自动编译。
            • 是的,自动编译看起来不错。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-27
            • 2016-06-18
            相关资源
            最近更新 更多