zigford.org/vim-quickfix-and-powershell.html
2020-07-21 06:49:32 +10:00

127 lines
5.9 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="main.css" type="text/css" />
<link rel="stylesheet" href="blog.css" type="text/css" />
<link rel="alternate" type="application/rss+xml" title="Subscribe to this page..." href="feed.rss" />
<title>Vim Quickfix and PowerShell</title>
</head><body>
<div id="divbodyholder">
<div class="headerholder"><div class="header">
<div id="title">
<h1 class="nomargin"><a class="ablack" href="http://zigford.org/index.html">zigford.org</a></h1>
<div id="description"><a href="about.html">About</a><a href="links.html"> | Links</a><a href="scripts.html"> | Scripts</a><br>Sharing linux/windows scripts and tips</br></div>
</div></div></div>
<div id="divbody"><div class="content">
<!-- entry begin -->
<h3><a class="ablack" href="vim-quickfix-and-powershell.html">
Vim Quickfix and PowerShell
</a></h3>
<!-- bashblog_timestamp: #201906022350.41# -->
<div class="subtitle">June 02, 2019 &mdash;
Jesse Harris
</div>
<!-- text begin -->
<p>Enno wrote in with a question on how <a href="https://github.com/w0rp/ale">Ale</a> set's
Vim's <code>makeprg</code> and <code>errorformat</code> options when working with PowerShell. </p>
<hr />
<p>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.</p>
<p>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.</p>
<h3>makeprg</h3>
<p><strong>Disclaimer</strong></p>
<p>My understanding of many Vim features is limited, so take what you learn here
with a grain of salt.</p>
<p><code>makeprg</code> defaults to the command <code>make</code>. That way you can enter <code>:make</code> and
have your current project compiled without leaving Vim. Alongside that, the
output is parsed using a string option <code>errorformat</code>. </p>
<p>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 <code>makeprg</code> option like so:</p>
<pre><code> set makeprg=pwsh\ -command\ \"&amp;{
\trap{$_.tostring();continue}&amp;{
\$c=gc\ '%';$c=[string]::join([environment]::newline,$c);
\[void]$executioncontext.invokecommand.newscriptblock($c)
\}
\}\"
</code></pre>
<p>This works on win32 and you can see the resulting output by opening the quickfix
window with <code>:copen</code></p>
<p>Unfortunately, on Unix, the most likely default shell will eat the PowerShell
<code>$Variables</code> so they must be escaped:</p>
<pre><code> set makeprg=pwsh\ -command\ \"&amp;{
\trap{\\$_.tostring\();continue}&amp;{
\\\$c=gc\ '%';\\$c=[string]::join([environment]::newline,\\$c);
\[void]\\$executioncontext.invokecommand.newscriptblock(\\$c)
\}
\}\"
</code></pre>
<p>Now that <code>makeprg</code> is good to go, time to sort out the errorformat.</p>
<h3>errorformat</h3>
<p>Errorformat uses scanf type parsing (which I had to google) that is a parsing
format used by c and other languages.</p>
<p>I spent a couple of hours today working this out by trial-and-error. While Vim's
<code>:help errorformat</code> documentation is great, particularly by including so many
examples, I didn't take the time to read it thoroughly initially.</p>
<p>Here is the winning formula:</p>
<pre><code> set errorformat=%EAt\ line:%l\ char:%c,%-C+%.%#,%Z%m,%-G\\s%#
</code></pre>
<p>Explanation:</p>
<ul>
<li><code>%E</code> tells Vim to begin capturing a multi-line message</li>
<li><code>At\ line:%l</code> records the line number where %l is</li>
<li><code>\ char:%c</code> records the column number where %c is</li>
<li><code>%-C+%.%#</code> continues a multi-line message, but removes this line from the
message if it contains + followed by .* regex</li>
<li><code>%Z%m</code> tells Vim that this is the last line of a multi-line message and uses
the whole line</li>
<li><code>%-G\\s%#</code> tells vim to discard lines that are full whitespace</li>
</ul>
<h3>VimRC</h3>
<p>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:</p>
<pre><code> 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\ \"&amp;{
\trap{$_.tostring();continue}&amp;{
\$c=gc\ '%';$c=[string]::join([environment]::newline,$c);
\[void]$executioncontext.invokecommand.newscriptblock($c)
\}
\}\"
else
autocmd FileType powershell set makeprg=pwsh\ -command\ \"&amp;{
\trap{\\$_.tostring\();continue}&amp;{
\\\$c=gc\ '%';\\$c=[string]::join([environment]::newline,\\$c);
\[void]\\$executioncontext.invokecommand.newscriptblock(\\$c)
\}
\}\"
endif
augroup END
</code></pre>
<p>Tags: <a href='tag_powershell.html'>powershell</a>, <a href='tag_vim.html'>vim</a></p>
<!-- text end -->
<!-- entry end -->
</div>
<div id="footer">&copy <a href="http://twitter.com/zigford_org">Jesse Harris</a> &mdash; <a href="mailto:jesse&#64;zigford&#46;org">jesse&#64;zigford&#46;org</a><br/>
Generated with <a href="https://github.com/cfenollosa/bashblog">bashblog</a>, a single bash script to easily create blogs like this one</div>
</div></div>
</body></html>