Add settings for the Alex linter
The executable for the Alex linter is currently hard-coded as 'alex', which is an issue given the fact that it conflicts with the Haskell lexer generator, whose executable is also called 'alex', has been around a dozen years before the linter, and is packaged in the official repositories of the major Linux distributions. This commit adds options to use a local executable for the alex linter (which is a node package), and an option to set a custom executable. As side changes: * The pattern in the alex handler is made more readable by turnig it into a very-magic regex. * Alex handles plain text, markdown, and HTML. Specific flags for HTML and markdown are provided when instantiating the linters for the respective filetypes, while before those formats were treated as plain text.
This commit is contained in:
parent
4d426bf287
commit
771581a945
18 changed files with 105 additions and 108 deletions
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for asciidoc files
|
" Description: alex for asciidoc files
|
||||||
|
|
||||||
call ale#linter#Define('help', {
|
call ale#handlers#alex#DefineLinter('asciidoc', '--text')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for help files
|
" Description: alex for help files
|
||||||
|
|
||||||
call ale#linter#Define('help', {
|
call ale#handlers#alex#DefineLinter('help', '--text')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for HTML files
|
" Description: alex for HTML files
|
||||||
|
|
||||||
call ale#linter#Define('html', {
|
call ale#handlers#alex#DefineLinter('html', '--html')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for HTML files
|
" Description: alex for mail files
|
||||||
|
|
||||||
call ale#linter#Define('mail', {
|
call ale#handlers#alex#DefineLinter('mail', '--text')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for markdown files
|
" Description: alex for markdown files
|
||||||
|
|
||||||
call ale#linter#Define('markdown', {
|
call ale#handlers#alex#DefineLinter('markdown', '')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for nroff files
|
" Description: alex for nroff files
|
||||||
|
|
||||||
call ale#linter#Define('nroff', {
|
call ale#handlers#alex#DefineLinter('nroff', '--text')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Cian Butler https://github.com/butlerx
|
" Author: Cian Butler https://github.com/butlerx
|
||||||
" Description: alex for PO files
|
" Description: alex for PO files
|
||||||
|
|
||||||
call ale#linter#Define('po', {
|
call ale#handlers#alex#DefineLinter('po', '--text')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for pod files
|
" Description: alex for pod files
|
||||||
|
|
||||||
call ale#linter#Define('pod', {
|
call ale#handlers#alex#DefineLinter('pod', '--text')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for rst files
|
" Description: alex for rst files
|
||||||
|
|
||||||
call ale#linter#Define('rst', {
|
call ale#handlers#alex#DefineLinter('rst', '--text')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for TeX files
|
" Description: alex for TeX files
|
||||||
|
|
||||||
call ale#linter#Define('tex', {
|
call ale#handlers#alex#DefineLinter('tex', '--text')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for texinfo files
|
" Description: alex for texinfo files
|
||||||
|
|
||||||
call ale#linter#Define('texinfo', {
|
call ale#handlers#alex#DefineLinter('texinfo', '--text')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for text files
|
" Description: alex for text files
|
||||||
|
|
||||||
call ale#linter#Define('text', {
|
call ale#handlers#alex#DefineLinter('text', '--text')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: alex for XHTML files
|
" Description: alex for XHTML files
|
||||||
|
|
||||||
call ale#linter#Define('xhtml', {
|
call ale#handlers#alex#DefineLinter('xhtml', '--text')
|
||||||
\ 'name': 'alex',
|
|
||||||
\ 'executable': 'alex',
|
|
||||||
\ 'command': 'alex %s -t',
|
|
||||||
\ 'output_stream': 'stderr',
|
|
||||||
\ 'callback': 'ale#handlers#alex#Handle',
|
|
||||||
\ 'lint_file': 1,
|
|
||||||
\})
|
|
||||||
|
|
|
@ -1,10 +1,23 @@
|
||||||
" Author: Johannes Wienke <languitar@semipol.de>
|
" Author: Johannes Wienke <languitar@semipol.de>
|
||||||
" Description: Error handling for errors in alex output format
|
" Description: Error handling for errors in alex output format
|
||||||
|
|
||||||
|
function! ale#handlers#alex#GetExecutable(buffer) abort
|
||||||
|
return ale#node#FindExecutable(a:buffer, 'alex', [
|
||||||
|
\ 'node_modules/.bin/alex',
|
||||||
|
\ 'node_modules/alex/cli.js',
|
||||||
|
\])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#handlers#alex#CreateCommandCallback(flags) abort
|
||||||
|
return {b -> ale#node#Executable(b, ale#handlers#alex#GetExecutable(b))
|
||||||
|
\ . ' %s '
|
||||||
|
\ . a:flags}
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale#handlers#alex#Handle(buffer, lines) abort
|
function! ale#handlers#alex#Handle(buffer, lines) abort
|
||||||
" Example output:
|
" Example output:
|
||||||
" 6:256-6:262 warning Be careful with “killed”, it’s profane in some cases killed retext-profanities
|
" 6:256-6:262 warning Be careful with “killed”, it’s profane in some cases killed retext-profanities
|
||||||
let l:pattern = '^ *\(\d\+\):\(\d\+\)-\(\d\+\):\(\d\+\) \+warning \+\(.\{-\}\) \+\(.\{-\}\) \+\(.\{-\}\)$'
|
let l:pattern = '\v^ *(\d+):(\d+)-(\d+):(\d+) +warning +(.{-}) +(.{-}) +(.{-})$'
|
||||||
let l:output = []
|
let l:output = []
|
||||||
|
|
||||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||||
|
@ -20,3 +33,21 @@ function! ale#handlers#alex#Handle(buffer, lines) abort
|
||||||
|
|
||||||
return l:output
|
return l:output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Define a linter for a specific filetype. Accept flags to adapt to the filetype.
|
||||||
|
" no flags treat input as markdown
|
||||||
|
" --html treat input as HTML
|
||||||
|
" --text treat input as plaintext
|
||||||
|
function! ale#handlers#alex#DefineLinter(filetype, flags) abort
|
||||||
|
call ale#Set('alex_executable', 'alex')
|
||||||
|
call ale#Set('alex_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
|
|
||||||
|
call ale#linter#Define(a:filetype, {
|
||||||
|
\ 'name': 'alex',
|
||||||
|
\ 'executable_callback': 'ale#handlers#alex#GetExecutable',
|
||||||
|
\ 'command_callback': ale#handlers#alex#CreateCommandCallback(a:flags),
|
||||||
|
\ 'output_stream': 'stderr',
|
||||||
|
\ 'callback': 'ale#handlers#alex#Handle',
|
||||||
|
\ 'lint_file': 1,
|
||||||
|
\})
|
||||||
|
endfunction
|
||||||
|
|
27
doc/ale.txt
27
doc/ale.txt
|
@ -20,7 +20,8 @@ CONTENTS *ale-contents*
|
||||||
5.6 Symbol Search.....................|ale-symbol-search|
|
5.6 Symbol Search.....................|ale-symbol-search|
|
||||||
6. Global Options.......................|ale-options|
|
6. Global Options.......................|ale-options|
|
||||||
6.1 Highlights........................|ale-highlights|
|
6.1 Highlights........................|ale-highlights|
|
||||||
6.2 Options for write-good Linter.....|ale-write-good-options|
|
6.2 Options for alex Linter...........|ale-alex-options|
|
||||||
|
6.3 Options for write-good Linter.....|ale-write-good-options|
|
||||||
7. Integration Documentation............|ale-integrations|
|
7. Integration Documentation............|ale-integrations|
|
||||||
ada...................................|ale-ada-options|
|
ada...................................|ale-ada-options|
|
||||||
gcc.................................|ale-ada-gcc|
|
gcc.................................|ale-ada-gcc|
|
||||||
|
@ -2219,7 +2220,29 @@ ALEWarningSign *ALEWarningSign*
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
6.2. Options for write-good *ale-write-good-options*
|
6.2. Options for alex *ale-alex-options*
|
||||||
|
|
||||||
|
The options for the alex linter are global because it does not make sense to
|
||||||
|
have them specified on a per-language basis.
|
||||||
|
|
||||||
|
g:ale_alex_executable *g:ale_alex_executable*
|
||||||
|
*b:ale_alex_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'alex'`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_alex_use_global *g:ale_alex_use_global*
|
||||||
|
*b:ale_alex_use_global*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `get(g:, 'ale_use_global_executables', 0)`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
6.3. Options for write-good *ale-write-good-options*
|
||||||
|
|
||||||
The options for the write-good linter are global because it does not make
|
The options for the write-good linter are global because it does not make
|
||||||
sense to have them specified on a per-language basis.
|
sense to have them specified on a per-language basis.
|
||||||
|
|
0
test/command_callback/alex-node-modules-2/node_modules/alex/cli.js
generated
vendored
Normal file
0
test/command_callback/alex-node-modules-2/node_modules/alex/cli.js
generated
vendored
Normal file
0
test/command_callback/alex-node-modules/node_modules/.bin/alex
generated
vendored
Normal file
0
test/command_callback/alex-node-modules/node_modules/.bin/alex
generated
vendored
Normal file
34
test/command_callback/test_alex_command_callback.vader
Normal file
34
test/command_callback/test_alex_command_callback.vader
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
Before:
|
||||||
|
call ale#assert#SetUpLinterTest('tex', 'alex')
|
||||||
|
call ale#test#SetFilename('test_file.tex')
|
||||||
|
|
||||||
|
After:
|
||||||
|
call ale#assert#TearDownLinterTest()
|
||||||
|
|
||||||
|
Execute(The global executable should be used when the local one cannot be found):
|
||||||
|
AssertLinter 'alex',
|
||||||
|
\ ale#Escape('alex') . ' %s --text',
|
||||||
|
|
||||||
|
Execute(Should use the node_modules/.bin executable, if available):
|
||||||
|
call ale#test#SetFilename('alex-node-modules/test_file.tex')
|
||||||
|
|
||||||
|
AssertLinter ale#path#Simplify(g:dir . '/alex-node-modules/node_modules/.bin/alex'),
|
||||||
|
\ ale#Escape(ale#path#Simplify(g:dir . '/alex-node-modules/node_modules/.bin/alex'))
|
||||||
|
\ . ' %s --text',
|
||||||
|
|
||||||
|
Execute(Should use the node_modules/alex executable, if available):
|
||||||
|
call ale#test#SetFilename('alex-node-modules-2/test_file.tex')
|
||||||
|
|
||||||
|
AssertLinter ale#path#Simplify(g:dir . '/alex-node-modules-2/node_modules/alex/cli.js'),
|
||||||
|
\ (has('win32') ? 'node.exe ' : '')
|
||||||
|
\ . ale#Escape(ale#path#Simplify(g:dir . '/alex-node-modules-2/node_modules/alex/cli.js'))
|
||||||
|
\ . ' %s --text',
|
||||||
|
|
||||||
|
Execute(Should let users configure a global executable and override local paths):
|
||||||
|
call ale#test#SetFilename('write-good-node-modules-2/test_file.tex')
|
||||||
|
|
||||||
|
let g:ale_alex_executable = '/path/to/custom/alex'
|
||||||
|
let g:ale_alex_use_global = 1
|
||||||
|
|
||||||
|
AssertLinter '/path/to/custom/alex',
|
||||||
|
\ ale#Escape('/path/to/custom/alex') . ' %s --text'
|
Reference in a new issue