How do I debug vim indentexpr script?

Viewed 224

I have downloaded a verilog/systemverilog indent file which looks really comprehensive. However, there is a problem: it doesn't work. I'm looking at the vimscript code and want to both fix it (I'm on vim 8.2, maybe there's a version mismatch) as well as enhance it. However, I'm running into issues debugging. Specifically, indentexpr scripts have a variable v:lnum which is set when indentkey is pressed and the indentexpr is evaluated.

BUT, I don't know of a way to enter debug mode on just the indentexpr call. I tried manually calling the function inside the vimscript but that leaves v:lnum as some garbage number (well, the last line to invoke indentexpr). Is there a way to enter debug mode when I actually hit a key that invokes indentexpr?

1 Answers

The best way for v:lnum to be used is as an argument to the function. Here's an example: vim-ruby's indentexpr setting used to look like this:

setlocal indentexpr=GetRubyIndent()

Inside the function, the variable v:lnum was used to get the line number that it was called on. This, as you've discovered, is pretty inconvenient. So, the better way is:

setlocal indentexpr=GetRubyIndent(v:lnum)

So, find the place in the script where the indentexpr is set and change it to take the magic v:lnum variable as an argument. You could then rewrite the function itself to take a single argument:

function! GetRubyIndent(lnum)

Now, in that function, the a:lnum variable will be the line number, and you can call the function with that argument. Search-and-replace v:lnum with a:lnum everywhere in the function. The indent script should now work as it did before, and you'll be able to call the function manually with a line number.

Here's the specific commit that does this in the vim-ruby repository, as an example

Additionally, echomsg "foo" will print a message that you can read afterwards by running the :messages command. And I can recommend the Decho plugin for easy-to-read debug messages.

Related