zigford.org

About | Links | Scripts
Sharing linux/windows scripts and tips

Vim Quickfix and PowerShell revisited

August 21, 2019 — Jesse Harris

Pretty much any language can be made to work well with Vim without having to resort to Plugins. That's the beauty of it. Vim is a tool, PowerShell is a tool. It's worth getting to know your tools intermitly to become an expert.


I won't say I'm an expert, but I have been enjoying using some more advanced features of Vim and PowerShell lately. That's why when Enno wrote in originally, I was eager to find a solution.

Recently Enno wrote in again

Dear Jesse,

I found no issue tracker in your repository https://github.com/zigford/vim-powershell, therefore let me try to reach out to you by mail:

Currently, one cannot jump to the error shown in the quickfix list, because the file name is not contained in the output of &makeprg. Sadly, :help errorfmt says

If the error format does not contain a file name Vim cannot switch to the correct file. You will have to do this by hand.

But perhaps the parameters passed to pwsh can be tweaked so that the file name shows up at some point?

Best wishes

Enno

That was about a month ago. Apologies for the delayed response Enno, I've been busy playing with Gentoo on my new Raspberry Pi 4.

Anyway, tonight I decided to investigate how to solve the problem.

The problem can be summed up in 2 parts.

  1. How to make PowerShell emit the filename
  2. How to read the filename with errorformat

Emit the FileName!

This one didn't take me too long to figure out. When I first borrowed code from keith hill, I looked and understood what was happening conceptually but did not think to use the interactive nature of PowerShell and see what else it could do.

Anyway, tonight, the good ole Get-Member makes a solution bleeding obvious:

        $ExecutionContext.InvokeCommand|Get-Member

        Name                    MemberType
        ----                    ----------
        InvokeScript            Method     
        NewScriptBlock          Method
        ToString                Method
        CommandNotFoundAction   Property   
        HasErrors               Property   
        LocationChangedAction   Property   
        PostCommandLookupAction Property   
        PreCommandLookupAction  Property   

Using Keith Hills, code I quick adapt to using InvokeScript which probably (and doesn't) need to be joining strings arrays together anymore.

Here, I demonstrate:

        trap {$_.tostring();continue}&{
        >> [void]$ExecutionContext.InvokeCommand.InvokeScript('./bad.ps1')
        >> }
        At /Users/jpharris/bad.ps1:1 char:16
        + function silly {
        +                ~
        Missing closing '}' in statement block or type definition.

So finally we have the filename where 'line' used to be before. All that's left to do now is update the errorformat.

Errorformat

I say to myself "this shouldn't be too hard", and this is what I think should work:

        set errorformat=%EAt\ %f:%l\ char:%c,%-C+%.%#,%Z%m,%-G\\s%#

But it doesn't! And I sit there for a few hours trying to debug it. Why won't it work? The silly thing is, it does work and the errorformat is correct, but today is one of those days I get to learn something new about Vim (just like every other day).

I haven't been setting the errorformat in my vim window (I'm not a monster). I've been setting it by editing the compiler PowerShell.vim file in my plugin.

I decide to check if the errorformat is being set correctly with:

        verbose set errorformat?
        errorformat=%EAt line:%l char:%c,%-+%.%#,%Z%m,%-G\s%#
            Last set from ~/.vimother/views/~=+bad.ps1= line 29

Ahuh! I did not know it, but errorformat can be saved into a view, therefore I was never testing any of my changes!

Anyway, I best upload my change to github and head off to sleep.

Tags: vim, powershell