Создание имен файлов/номеров строк, связанных в буфере памяти Emacs
Я запускаю pdb на своих тестовых площадках в Python через буфер gud. Когда я получаю 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
clickable и перейти к строке 499 в testfoo.py.
(edit) Люди в списке режимов python привели меня к pdbtrack, и я смог заставить его работать там. См. Ответ ниже...
Ответы
Ответ 1
Благодаря намеку Джерарда Б, я понял это. Я делаю это из pdbtrack (shell) вместо чистого pdb, но он должен работать и в том, и в другом. Вам нужно включить компиляцию-shell-minor-mode. И у вас есть следующий код в вашем .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
Я думаю, что вы хотите настроить compilation-parse-errors-filename-function
, которая является функцией, которая принимает имя файла, и возвращает измененную версию отображаемого имени файла. Это локальная переменная буфера, поэтому вы должны установить ее в каждом буфере, который будет отображать ошибки python (вероятно, используется соответствующий крючок, у меня нет режима python, поэтому я не могу его найти). Вы должны использовать propertize
для возврата версии входного имени файла, которая действует как гиперссылка для загрузки фактического файла. propertytize хорошо документирован в руководстве elisp.
Если компиляция-parse-errors-filename-function не вызвана, то вы хотите добавить список в compilation-error-regexp-alist-alist
(это говорит о том, что alist-alist, это не опечатка), который является списком имен режимов а затем регулярные выражения для соответствия ошибкам и числовые индексы совпадающего номера строки, имени файла и т.д. в совпадении с регулярным выражением ошибки.
Ответ 3
Добавление к Джастину:
У меня есть следующее в моей конфигурации slime, которая должна перейти к файлу и строке из трассировки стека clojure.
К сожалению, я должен признать, что на данный момент это не работает для меня - функция не может найти правильный файл, но насколько я могу судить, это должно быть исправлено путем изменения способа project-root
определяется или изменением структуры моих проектов в файловой системе (у меня просто не было времени или желания смотреть в нее).
Это приносит хороший момент, хотя, в большинстве функциональных возможностей, это довольно сложно определить корень проекта в общем и переносном стиле. В этом случае мы полагаемся на каталог src
, но это, вероятно, не подходит для ваших проектов python.
Итак, следуя примеру Джастина, вы должны быть в состоянии взять некоторые подсказки из приведенной ниже функции и проанализировать имя файла и номера строк из ошибки теста, создать ссылку на номер строки и использовать 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 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))))
Я должен также упомянуть, что я скопировал эту функцию откуда-то в Интернете, но я не могу вспомнить URL-адрес. Кажется, от Фила Хагельберга (technomancy) отличный стартовый комплект Emacs.