代码之家  ›  专栏  ›  技术社区  ›  Matt Harrison

使文件名/行号在Emacs GUD缓冲区中可链接

  •  10
  • Matt Harrison  · 技术社区  · 16 年前

    我在python中通过gud缓冲区对我的测试用例运行pdb。当我的测试用例中出现stacktrace/failure时,看起来是这样的:

    FAIL: test_foo_function (__main__.TestFoo)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "test/testfoo.py", line 499, in test_foo_function
        self.assertEqual('foo', 'foo')
    

    我很想把这句话说成:

    File "test/testfoo.py", line 499, in test_foo_function
    

    单击并转到testfoo.py中的第499行。

    (编辑)Python模式列表上的人把我带到PDBTrand,我可以让它在那里工作。请看下面的答案…

    3 回复  |  直到 11 年前
        1
  •  4
  •   Matt Harrison    16 年前

    多亏杰拉德B的暗示,我才明白。我是从pdbtrack(shell)而不是纯pdb来完成这项工作的,但我相信这两种方法都可以。您需要启用编译shell次要模式。并在.emacs中包含以下代码:

    ;; if compilation-shell-minor-mode is on, then these regexes
    ;; will make errors linkable
    (defun matt-add-global-compilation-errors (list)
      (dolist (x list)
        (add-to-list 'compilation-error-regexp-alist (car x))
        (setq compilation-error-regexp-alist-alist
          (cons x
                (assq-delete-all (car x)
                                 compilation-error-regexp-alist-alist)))))
    
    (matt-add-global-compilation-errors
     `(
       (matt-python ,(concat "^ *File \\(\"?\\)\\([^,\" \n    <>]+\\)\\1"
                        ", lines? \\([0-9]+\\)-?\\([0-9]+\\)?")
               2 (3 . 4) nil 2 2)
       (matt-pdb-stack ,(concat "^>?[[:space:]]*\\(\\([-_./a-zA-Z0-9 ]+\\)"
                           "(\\([0-9]+\\))\\)"
                           "[_a-zA-Z0-9]+()[[:space:]]*->")
                  2 3 nil 0 1)
       (matt-python-unittest-err "^  File \"\\([-_./a-zA-Z0-9 ]+\\)\", line \\([0-9]+\\).*" 1 2)
       )
     )
    
    (defun matt-set-local-compilation-errors (errors)
      "Set the buffer local compilation errors.
    
    Ensures than any symbols given are defined in
    compilation-error-regexp-alist-alist."
      (dolist (e errors)
         (when (symbolp e)
          (unless (assoc e compilation-error-regexp-alist-alist)
            (error (concat "Error %s is not listed in "
                           "compilation-error-regexp-alist-alist")
                   e))))
      (set (make-local-variable 'compilation-error-regexp-alist)
           errors))
    

    然后,可以使用标准编译模式导航来压缩错误堆栈跟踪。

        2
  •  2
  •   Justin Smith    16 年前

    我想你要定制的是 compilation-parse-errors-filename-function ,该函数接受文件名,并返回要显示的文件名的修改版本。这是一个缓冲区局部变量,所以应该在每个显示python错误的缓冲区中设置它(可能有一个合适的钩子可以使用,我没有安装python模式,所以无法查找它)。你会用 propertize 返回作为超链接加载实际文件的输入文件名的版本。属性在elisp手册中有很好的记录。

    如果未调用编译分析错误文件名函数,则需要将列表添加到 compilation-error-regexp-alist-alist (也就是说a list-alist,这不是一个拼写错误)它是一个模式名的列表,后跟正则表达式以匹配错误,以及错误regexp-match中匹配行号、文件名等信息的数字索引。

        3
  •  0
  •   liwp    16 年前

    加上贾斯汀的回答:

    我的slime配置中有以下内容,它应该从clojure堆栈跟踪跳到文件和行。

    不幸的是,我必须承认,这对我来说目前还不起作用——函数不能找到正确的文件——但据我所知,这应该是可以改变的。 project-root 是通过在文件系统上更改我的项目的结构来定义的(我只是没有时间或倾向于查看它)。

    不过,它确实提出了一个很好的观点,在像这样的大多数函数中,以通用和可移植的方式找出项目根有点棘手。在这种情况下,我们依赖于 src 目录,但这可能不适合您的python项目。

    因此,从justin停止的地方开始,您应该能够从下面的函数中获得一些提示,并从测试用例错误中解析文件名和行号,创建到行号的链接,并使用 compilation-parse-errors-filename-function propertize gud 缓冲链接。

    如果你真的成功了,请给你自己的问题加上一个答案。我想很多人会觉得它有用。

      (defun slime-jump-to-trace (&optional on)
        "Jump to the file/line that the current stack trace line references.
        Only works with files in your project root's src/, not in dependencies."
        (interactive)
        (save-excursion
          (beginning-of-line)
          (search-forward-regexp "[0-9]: \\([^$(]+\\).*?\\([0-9]*\\))")
          (let ((line (string-to-number (match-string 2)))
                (ns-path (split-string (match-string 1) "\\."))
                (project-root (locate-dominating-file default-directory "src/")))
    
            (find-file (format "%s/src/%s.clj" project-root
                               (mapconcat 'identity ns-path "/")))
            (goto-line line))))
    

    我还应该提到,我从Web上的某个地方复制了这个函数,但是我记不起网址了。它似乎来自菲尔·哈格伯格(Phil Hagelberg)的(技术)优秀的Emacs首发套件。

    推荐文章