21

What is the preferable, general method of debugging/tracing vim plugins ? Suppose I have got a fairly sophisticated plugin Foo, which on a key pressed F9 opens new window with file-browser and gives the possibility to choose a file, after that the filename is copied into the main window. I would like to see what is called when I press the F9 key, some kind of call trace.

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Darek
  • 2,861
  • 4
  • 29
  • 52
  • See also: [Is there a "vim runtime log"? - Stack Overflow](https://stackoverflow.com/questions/3025615/is-there-a-vim-runtime-log) – user202729 Oct 08 '21 at 09:49

3 Answers3

21

The best way I have found is to use the -V flag when starting (g)vim. You can specify a level of tracing N and a filename for the written log:

$ vim -V[N]{filename}

Then trace messages will be given for each file that is sourced. (See :help -V for more info.)

Trawling through the resulting logfile can be painful, but it is usually pretty informative. I find it best to view the logfile before and after the trigger event (pressing <F9> in your case) to get a picture of when is happening.

Prince Goulash
  • 15,295
  • 2
  • 46
  • 47
  • 1
    In my case, the syntax was: `vim -V[insert number] [insert filename]` - for example `vim -V20 filename.txt` – Ben Creasy Apr 21 '18 at 16:48
  • 1
    See `:help 'verbose'`. – Hans Ginzel May 09 '18 at 14:28
  • See `:help 'verbose'` for the meaning of the levels. Unfortunately there's no way to prevent the buffering of the log file (see `:help 'verbosefile'`), and it isn't possible to add timestamp either ([Vim verbosefile with timestamps - Stack Overflow](https://stackoverflow.com/questions/7091224/vim-verbosefile-with-timestamps)) – user202729 Oct 08 '21 at 09:41
7

If you already have vim open, try executing the command manually under VIM's built in debugger.

1) Find out what vim does when you press the key

:map <F-9>

2) Run the mapped command manually under debugger

:debug _mapped_command_

3) Right now you should be dropped in to the debugger, so

set verbose=20

4) And finally press n and Enter key to continue running the script

At this point you should see a whole bunch of output on the screen. You can press Space to scroll the screen, j/k to move by line.

Any output that starts with "Line #:" is the line vim is executing at that time.

Frison Alexander
  • 3,228
  • 2
  • 29
  • 32
  • To set a breakpoint while in debug mode, use `:breaka[dd] func [lnum] {name}` or `:breaka[dd] file [lnum] {name}`. To set a conditional breakpoint, modify the script to include an if-statement with your condition, put a no-op inside the if-statement (like `let xyz = 1`), and use `breakadd` to add a breakpoint on the no-op line. (See `:help breakadd`.) Then type `cont` or `c` to continue execution until the breakpoint line is executed. – David Winiecki Apr 19 '22 at 21:45
1

For sophisticated plugins, normally command line debugging or tracing is not enough.

You can use BreakPts to do a visual debug inside vim.

It is based on remote debugging, so you need to debug a server instance of vim.

Basically:

Terminal 1:

$ vim --servername Foo
...
set breakpoint on any Foo function
do whatever operation which trigger Foo logic
...

Terminal 2:

$ vim
:BreakPts
:BPRemoteServ FOO
:BPDWhere locate (actual debug execution point)
:BPDNext or F12 (next execution line)
:BPDStep or F11 (step inside functions, dictionary functions)
:BPDEvaluate or F8 (if pressed on visual selection evaluates that)
:BPDCont or F5 (continue execution)

See some plugins are loaded dinamically so you need to operate with them prior to set breakpoints.

Once loaded you can set breakpoints from connected vim with:

:BPFunctions (Show debuggeable fuctions on RemoteServer)
:BPScripts (Show debuggeable scripts on RemoteServer)
:BPPoints (Show defined breakpoints on RemoteServer)

I have fix/tweak/evolve a lot of vim plugins thanks to this great plugin.

albfan
  • 12,542
  • 4
  • 61
  • 80