Vim Quickfix and PowerShell
Enno wrote in with a question on how Ale set's
Vim's makeprg
and errorformat
options when working with PowerShell.
Under the hood, I'm not sure if Ale uses those Vim features for processing command output. Thus I'm not able to capture what those settings would look like for PowerShell.
However the question did pique my curiosity and I'm interested in what the options would look like if you wanted to parse PowerShell without Ale.
makeprg
Disclaimer
My understanding of many Vim features is limited, so take what you learn here with a grain of salt.
makeprg
defaults to the command make
. That way you can enter :make
and
have your current project compiled without leaving Vim. Alongside that, the
output is parsed using a string option errorformat
.
In order for PowerShell to produce some syntax checking output, you can run a
small script over the code and parse it's output. Therefore I embedded the
script into the makeprg
option like so:
set makeprg=pwsh\ -command\ \"&{
\trap{$_.tostring();continue}&{
\$c=gc\ '%';$c=[string]::join([environment]::newline,$c);
\[void]$executioncontext.invokecommand.newscriptblock($c)
\}
\}\"
This works on win32 and you can see the resulting output by opening the quickfix
window with :copen
Unfortunately, on Unix, the most likely default shell will eat the PowerShell
$Variables
so they must be escaped:
set makeprg=pwsh\ -command\ \"&{
\trap{\\$_.tostring\();continue}&{
\\\$c=gc\ '%';\\$c=[string]::join([environment]::newline,\\$c);
\[void]\\$executioncontext.invokecommand.newscriptblock(\\$c)
\}
\}\"
Now that makeprg
is good to go, time to sort out the errorformat.
errorformat
Errorformat uses scanf type parsing (which I had to google) that is a parsing format used by c and other languages.
I spent a couple of hours today working this out by trial-and-error. While Vim's
:help errorformat
documentation is great, particularly by including so many
examples, I didn't take the time to read it thoroughly initially.
Here is the winning formula:
set errorformat=%EAt\ line:%l\ char:%c,%-C+%.%#,%Z%m,%-G\\s%#
Explanation:
%E
tells Vim to begin capturing a multi-line messageAt\ line:%l
records the line number where %l is\ char:%c
records the column number where %c is%-C+%.%#
continues a multi-line message, but removes this line from the message if it contains + followed by .* regex%Z%m
tells Vim that this is the last line of a multi-line message and uses the whole line%-G\\s%#
tells vim to discard lines that are full whitespace
VimRC
While I'm not sure I'll use this, as I like Ale, I hope it is useful to someone out there, you could put it in your .vimrc like this:
augroup powershell
autocmd!
autocmd BufNewFile,BufRead *.ps1,*.psm1 setlocal FileType=powershell
autocmd FileType powershell setlocal errorformat=%EAt\ line:%l\ char:%c,
\%-C+%.%#,
\%Z%m,
\%-G\\s%#
if has('win32')
autocmd FileType powershell set makeprg=pwsh\ -command\ \"&{
\trap{$_.tostring();continue}&{
\$c=gc\ '%';$c=[string]::join([environment]::newline,$c);
\[void]$executioncontext.invokecommand.newscriptblock($c)
\}
\}\"
else
autocmd FileType powershell set makeprg=pwsh\ -command\ \"&{
\trap{\\$_.tostring\();continue}&{
\\\$c=gc\ '%';\\$c=[string]::join([environment]::newline,\\$c);
\[void]\\$executioncontext.invokecommand.newscriptblock(\\$c)
\}
\}\"
endif
augroup END
Tags: powershell, vim