Поддержка Quickfix для отслеживания Python

18

Скажем, у меня есть сценарий Python с ошибкой во время выполнения:

$ cat example.py  
#! /usr/bin/env python3

a = 1/0

который дает:

$ python3 example.py 
Traceback (most recent call last):
  File "example.py", line 3, in <module>
    a = 1/0
ZeroDivisionError: division by zero

Я хочу, чтобы Vim перешел к проблемной строке этого файла (строка 3 в данном случае). Я знаю, что Vim может сделать это, потому что он прекрасно работает для перехвата ошибок во время компиляции в C с gccиспользованием :makeи quickfixокна.

быстрый вывод из gcc

Конечно, я могу заполнить окно быстрого исправления Vim, :set makeprg=python3\ %а затем :make, но оно не переходит к номеру строки, на которую указывает трассировка. Когда я смотрю на :copenнего, он просто выделяет первую строку трассы, и я не могу перейти к соответствующему номеру строки.

вывод быстрых исправлений из python3

(Я использую Vim 7.4 в Debian jessieна тот случай, если это имеет значение.)

Мои вопросы:

  • Могу ли я настроить Vim так, чтобы он знал, как получить соответствующий номер строки из трассировки Python?

  • Могу ли я изменить интерпретатор Python, чтобы он выдавал формат ошибки, который Vim уже знает, как анализировать и получать соответствующий номер строки?

Натаниэль М. Бивер
источник
Вы можете создать подкласс логгера в вашем скрипте для создания точек трассировки по одной на строку (см. Здесь, чтобы начать работу), затем настроить errorformatсоответствующим образом и написать плагин компилятора для Vim (см. :help :compilerИ :help write-compiler-plugin). Вероятно, не стоит затраченных усилий, если вы точно не знаете , что делаете, и у вас недостаточно энтузиазма, чтобы выкопать все из документов.
Сато Кацура
Я задал похожий вопрос о StackOverflow, эти ответы могут оказаться полезными stackoverflow.com/questions/11333112/…
jalanb

Ответы:

7

Vim поставляется с набором «компиляторных» скриптов, один из которых называется «pyunit» . Если вы запустите, :compiler pyunitа затем :make(с вашим предложенным значением для 'makeprg'), быстрое исправление будет заполнено, как вы ожидаете. Тем не менее, это работает хорошо только если есть один уровень трассировки стека.

Улучшение этого скрипта компилятора было бы полезным упражнением.

Разборки стопки плагин может представлять интерес, так как она обеспечивает общий механизм для анализа и просмотра местоположения сообщили в трассировке стека и имеет поддержку Python встроенный в.

jamessan
источник
4

Встроенный плагин компилятора pyunit

Как уже предложено jamessan , одним из вариантов является использование встроенного модуля компилятора pyunit:

:compiler pyunit
:set makeprg=python3\ %
:make

Недостатком является то, что сворачивает трассировку стека в одно сообщение об ошибке. Например, следующий скрипт на python:

def lumberjack():
    bright_side_of_death()

def bright_side_of_death():
    return tuple()[0]

lumberjack()

... выдает это сообщение об ошибке:

|| Traceback (most recent call last):
lumberjack.py|7|  IndexError: tuple index out of range

Написание собственного плагина компилятора

В качестве альтернативы вы можете предоставить свой собственный плагин компилятора в ~/.vim/compiler/python.vim:

if exists("current_compiler")
  finish
endif
let current_compiler = "python"

let s:cpo_save = &cpo
set cpo&vim

CompilerSet errorformat=
      \%*\\sFile\ \"%f\"\\,\ line\ %l\\,\ %m,
      \%*\\sFile\ \"%f\"\\,\ line\ %l,
CompilerSet makeprg=python3\ %

let &cpo = s:cpo_save
unlet s:cpo_save

Выберите плагин вручную :compiler pythonили загрузите его автоматически, добавив его в ~/.vim/after/ftplugin/python.vim:

if !exists("current_compiler")
  compiler python
endif

С помощью приведенного выше скрипта Python Vim заполняет окно быстрого исправления:

|| Traceback (most recent call last):
lumberjack.py|7| in <module>
||     lumberjack()
lumberjack.py|2| in lumberjack
||     bright_side_of_death()
lumberjack.py|5| in bright_side_of_death
||     return tuple()[0]
|| IndexError: tuple index out of range

Смотрите :help write-compiler-pluginдля получения дополнительной информации.

siho
источник
3

quickfix.py анализирует трассировку в удобном для vim формате ошибок. Вот пример запуска его для файла с одной строкой 1 / 0.

❯❯❯ quickfix.py tests/errors/div_by_zero.py
"tests/errors/div_by_zero.py":1: ZeroDivisionError: division by zero

По умолчанию он показывает пользовательские файлы, но он также может отображать системные файлы (при запуске его в файле, содержащем import os; os.environ['123']):

❯❯❯ quickfix.py -a /tmp/test.py                                                                                                        
"/usr/lib/lib/python3.7/os.py":678: KeyError: '123'
"/tmp/test.py":1: in function <module>

Конфигурация:

Когда quickfix.pyдоступно в текущем пути, добавьте следующие строки в vimrc, чтобы использовать его.

if has("autocmd")
  autocmd FileType python setlocal makeprg=quickfix.py\ %
  autocmd FileType python setlocal errorformat=%E\"%f\":%l:%m,
endif
jadelord
источник
-1

Не автоматический метод, а трассировка python указывает номер строки --- 3 в вашем примере --- и вызывает vim:

$ vim +3 example.py

откроет example.pyкурсор с помощью третьей строки.

Крис Ханнинг
источник
2
Я знаю об этом, но речь идет о поддержке Quickfix. После запуска :makeфайла, который у меня уже открыт, быстрее :3перейти на третью строку, чем закрыть и снова открыть. Кроме того, выполнение этого вручную является проблемой для более сложных трассировок стека, поэтому я хочу поддержку Quickfix.
Натаниэль М. Бивер