Как отладить `Ошибку при обработке функции` в `vim` и `nvim`?

#debugging #vim #neovim

#отладка #vim #neovim

Вопрос:

TL; DR

Как найти, где именно vim или nvim ошибка началась (какой файл?) когда я заинтересован в устранении фактической проблемы, а не просто в удалении неисправного плагина? Что-нибудь лучше, чем strace догадки, чтобы найти источник ошибки?

Проблема

Я часто добавляю плагин в свою vim nvim конфигурацию или и в итоге получаю ошибки при перехвате (открытие, закрытие буфера, запись):

 "test.py" [New] 0L, 0C written
Error detected while processing function 343[12]..272:
line    8:
E716: Key not present in Dictionary: _exec
E116: Invalid arguments for function get(a:args, 'exec', a:1['_exec'])
E15: Invalid expression: get(a:args, 'exec', a:1['_exec'])
  

Проблема в том, что я понятия не имею, откуда они берутся, получаю только некоторый номер строки неизвестного файла, и я знаю, что это не мой vim файл / nvim config.

Комментарии:

1. Это вся трассировка стека. У вас загружено 343 файла :scriptnames ?

2. Это не stacktrace вывод, это все, что vim печатается, когда я пытаюсь открыть пустой test.py файл. Проверю :scriptnames как можно скорее, но да, я загружаю плагины через менеджер, поэтому возможно, что файлов так много. Это то, что это такое — количество открытых файлов?

3. Для меня это запутано. функция 343 [12] ..272: я не знаю, что это значит, обычно это имя функции, которое легко найти. Но это похоже на число. Я знаю, что иногда vim использует порядок загрузки файла в качестве уникального идентификатора для локальных функций скрипта, но я все еще думаю, что имя пришло вместе с ним.

4. Просто чтобы удовлетворить мое и ваше любопытство: у меня загружено всего 114 vim-скриптов (27 плагинов). Так что это кажется неуместным.

Ответ №1:

Где-то у вас есть плагин, который определил словарь с anonymous-functions помощью (проверьте справку, связанную с этим тегом).

Для любопытных, это делается следующим образом:

 let d = {}
function! d.whatever() abort
   throw "blah"
endfunction
  

При выполнении этой функции вы получите ошибку, которую вы наблюдаете в данный момент. Вот почему я перестал работать таким образом, чтобы предпочесть:

 let d = {}
function s:whatever() abort
   throw "blah"
endfunction
let d.whatever = function('s:whatever') " a workaround is required for older versions of vim
" At least this way I'll get a `<SNR>42_whatever` in the exception throwpoint, and thus a scriptname.
  

Вот почему. Теперь, возвращаясь к вашей проблеме, AFAIK, единственное, что вы сможете узнать, это две функции, которые были вызваны:

  • в строке 12 :function {343} вы вызвали
  • :function {272} который содержит ошибку в строке 8.

Благодаря этим двум командам (может иметь префикс с :verbose , я точно не помню), вы получите исходный код двух функций, которые вы должны иметь возможность использовать, чтобы grep ваши плагины знали, где он появляется.

Комментарии:

1. Хахахахахахаха, о которой я знал, :function но я бы никогда не догадался {343} , что это имя функции: D Большое спасибо!