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

Python 使文件名/行号在Emacs gud缓冲区中可链接,python,emacs,pdb,gud,Python,Emacs,Pdb,Gud,我正在通过gud缓冲区在Python中的测试用例上运行pdb。当我在testcase中得到stacktrace/失败时,它看起来如下: FAIL: test_foo_function (__main__.TestFoo) ---------------------------------------------------------------------- Traceback (most recent call last): File "test/testfoo.py", line 49

我正在通过gud缓冲区在Python中的测试用例上运行pdb。当我在testcase中得到stacktrace/失败时,它看起来如下:

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')
我希望能够使这条线像:

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


(编辑)python模式列表上的人把我带到pdbtrack,我能够让它在那里工作。请参见下面的答案…

我认为您要自定义的是编译解析错误文件名函数,该函数接受文件名,并返回要显示的文件名的修改版本。这是一个缓冲区局部变量,因此您应该在显示python错误的每个缓冲区中设置它(可能有一个合适的钩子可供使用,我没有安装python模式,因此无法查找)。您可以使用
propertize
返回输入文件名的版本,该文件名充当加载实际文件的超链接。elisp手册中详细记录了propertize


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

添加到Justin的答案中:

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

不幸的是,我必须承认,它目前实际上并不适用于我-函数无法找到正确的文件-但据我所知,这应该可以通过更改
项目根的定义方式或更改文件系统上项目的结构来解决(我只是没有时间或兴趣去研究它)

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

因此,从Justin结束的地方开始,您应该能够从下面的函数中获得一些技巧,并从测试用例错误中解析文件名和行号,创建一个到行号的链接,并使用
编译解析错误文件名函数
属性
gud
buf中生成行提供链接

如果你真的成功了,请为你自己的问题添加一个答案。我想很多人会发现它很有用

  (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上的某个地方复制了这个函数,但我记不起URL。它似乎来自Phil Hagelberg(technomancy)的优秀Emacs初学者工具包。

感谢Gerard 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))
;;如果编译shell次要模式处于启用状态,则这些正则表达式
;将使错误可链接
(defun matt add全局编译错误(列表)
(dolist(x列表)
(添加到列表“编译错误注册表列表(car x))
(setq编译错误regexp)
(十)
(assq全部删除(车辆x)
编译错误regexp(“”);“”)
(请添加全局编译错误。)
`(
(matt python,(concat“^*文件\(\”?\)\([^,\“\n]+\\)\\1”
“,行?\([0-9]+\)-?\([0-9]+\)?”)
2(3.4)无2(2)
(亚光pdb堆栈,(concat“^>?[:空格:]*\\(\\([-\./a-zA-Z0-9]+\\))
"(\\([0-9]+\\))\\)"
“[_a-zA-Z0-9]+()[:空格:]*->”)
2 3零0 1)
(matt python单元测试错误“^File\”\([-\./a-zA-Z0-9]+\)\”,第\([0-9]+\).*行12)
)
)
(defun matt set本地编译错误(错误)
“设置缓冲区本地编译错误。
确保中定义的符号多于给定的任何符号
编译错误regexp。”
(dolist(e错误)
(何时(symbolp e)
(除非(关联编译错误regexp)
(错误(concat“错误%s未在中列出”
“编译错误(regexp-alist”)
e) ))
(设置(使局部变量的编译错误为regexp列表)
(错误)

然后,您可以使用标准编译模式导航来快速浏览错误堆栈跟踪。

这将非常酷。我很想了解更多关于在gud缓冲区中运行测试的设置。很抱歉,我无法回答您的问题,尽管我在我的博客上有一篇关于旧设置()的帖子。我目前正在使用shell模式/python模式(python.org版本不是emacs版本)和pdbtrack请注意,当文件/缓冲区第一次打开时,这种方法会起作用。随着时间的推移,会出现一些“漂移”(即光标出现在实际行之后的几行)谢谢!但我注意到,虽然长回溯顶部的行是可点击的,但向下的行不是。我还没有时间剖析代码以了解其“漂移”的原因。但是,禁用并重新启用编译shell次要模式似乎可以纠正漂移。
;; 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))