Обеспечение связывания имен файлов / номеров строк в буфере Emacs gud - PullRequest
10 голосов
/ 18 января 2010

Я запускаю pdb на моих тестовых примерах в Python через буфер gud.Когда я получаю трассировку / сбой стека в моем тестовом примере, это выглядит следующим образом:

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')

Я бы хотел иметь возможность сделать строку (-и) как:кликабельны и введите строку 499 в testfoo.py.

(правка) Ребята из списка режимов Python привели меня к pdbtrack, и я смог заставить его работать там.Смотрите ответ ниже ...

Ответы [ 3 ]

4 голосов
/ 23 января 2010

Благодаря подсказке Джерарда Б я понял это. Я делаю это из pdbtrack (shell) вместо чистого pdb, но я думаю, он должен работать в обоих случаях. Вам нужно включить compilation-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 голосов
/ 19 января 2010

Я думаю, что вы хотите настроить это compilation-parse-errors-filename-function, которая является функцией, которая принимает имя файла и возвращает измененную версию имени файла для отображения. Это локальная переменная буфера, поэтому вы должны установить ее в каждом буфере, который будет отображать ошибки Python (вероятно, есть подходящий хук для использования, у меня не установлен режим Python, поэтому я не могу его найти). Вы должны использовать propertize для возврата версии входного имени файла, которая действует как гиперссылка для загрузки фактического файла. Правильность хорошо документирована в руководстве elisp.

Если compilation-parse-errors-filename-function не вызывается, то вы хотите добавить список к compilation-error-regexp-alist-alist (который говорит alist-alist, который не является опечаткой), который является списком имен режимов за ним следуют регулярные выражения для сопоставления ошибок и числовые индексы совпадающего номера строки, имени файла и т. д. в совпадении с регулярным выражением ошибки.

0 голосов
/ 19 января 2010

Добавление к ответу Джастина:

У меня есть следующее в моей конфигурации слизи, которая должна перейти к файлу и строке из трассировки стека 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'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))))

Я должен также упомянуть, что я скопировал эту функцию из Интернета, но не могу вспомнить URL. Кажется, это из превосходного стартового набора Emacs Фила Хейгельберга (техномантии).

...