All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
1 " Author: Jesse Harris - https://github.com/zigford
2 " Description: This file adds support for powershell scripts synatax errors
4 call ale#Set('powershell_powershell_executable', 'pwsh')
6 function! ale_linters#powershell#powershell#GetExecutable(buffer) abort
7 return ale#Var(a:buffer, 'powershell_powershell_executable')
10 " Some powershell magic to show syntax errors without executing the script
11 " thanks to keith hill:
12 " https://rkeithhill.wordpress.com/2007/10/30/powershell-quicktip-preparsing-scripts-to-check-for-syntax-errors/
13 function! ale_linters#powershell#powershell#GetCommand(buffer) abort
14 let l:script = ['Param($Script);
15 \ $ErrorView = "Normal";
16 \ trap {$_;continue} & {
17 \ $Contents = Get-Content -Path $Script;
18 \ $Contents = [string]::Join([Environment]::NewLine, $Contents);
19 \ [void]$ExecutionContext.InvokeCommand.NewScriptBlock($Contents);
22 return ale#powershell#RunPowerShell(
23 \ a:buffer, 'powershell_powershell', l:script)
26 " Parse powershell error output using regex into a list of dicts
27 function! ale_linters#powershell#powershell#Handle(buffer, lines) abort
29 " Our 3 patterns we need to scrape the data for the dicts
31 \ '\v^At line:(\d+) char:(\d+)',
33 \ '\vFullyQualifiedErrorId : (\w+)',
38 for l:match in ale#util#GetMatches(a:lines, l:patterns)
39 " We want to work with 3 matches per syntax error
40 let l:matchcount = l:matchcount + 1
42 if l:matchcount == 1 || str2nr(l:match[1])
43 " First match consists of 2 capture groups, and
44 " can capture the line and col
46 " We may be here because the last syntax
47 " didn't emit a code, and so only had 2
49 call add(l:output, l:item)
53 " If the match is 0, it was a failed match
54 " probably due to an unexpected token which
55 " contained a newline. Reset matchcount. to
56 " continue to the next match
59 \ 'lnum': str2nr(l:match[1]),
60 \ 'col': str2nr(l:match[2]),
66 elseif l:matchcount == 2
67 " Second match[0] grabs the full line in order
69 let l:item['text'] = l:match[0]
71 " Final match handles the code, however
72 " powershell only emits 1 code for all errors
73 " so, we get the final code on the last error
74 " and loop over the previously added items to
75 " append the code we now know
76 call add(l:output, l:item)
79 if len(l:match[1]) > 0
81 let l:i['code'] = l:match[1]
85 " Reset the matchcount so we can begin gathering
86 " matches for the next syntax error
94 call ale#linter#Define('powershell', {
95 \ 'name': 'powershell',
96 \ 'executable': function('ale_linters#powershell#powershell#GetExecutable'),
97 \ 'command': function('ale_linters#powershell#powershell#GetCommand'),
98 \ 'output_stream': 'stdout',
99 \ 'callback': 'ale_linters#powershell#powershell#Handle',