linter/markdown: adds support for languatool (#2155)
This commit is contained in:
parent
fd31987f23
commit
7eae06d3f3
6 changed files with 165 additions and 0 deletions
5
ale_linters/mail/languagetool.vim
Normal file
5
ale_linters/mail/languagetool.vim
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
" Author: Vincent (wahrwolf [ät] wolfpit.net)
|
||||||
|
" Description: languagetool for mails
|
||||||
|
|
||||||
|
|
||||||
|
call ale#handlers#languagetool#DefineLinter('mail')
|
5
ale_linters/markdown/languagetool.vim
Normal file
5
ale_linters/markdown/languagetool.vim
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
" Author: Vincent (wahrwolf [ät] wolfpit.net)
|
||||||
|
" Description: languagetool for markdown files
|
||||||
|
|
||||||
|
|
||||||
|
call ale#handlers#languagetool#DefineLinter('markdown')
|
4
ale_linters/text/languagetool.vim
Normal file
4
ale_linters/text/languagetool.vim
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
" Author: Vincent (wahrwolf [ät] wolfpit.net)
|
||||||
|
" Description: languagetool for text files
|
||||||
|
|
||||||
|
call ale#handlers#languagetool#DefineLinter('text')
|
74
autoload/ale/handlers/languagetool.vim
Normal file
74
autoload/ale/handlers/languagetool.vim
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
" Author: Vincent (wahrwolf [ät] wolfpit.net)
|
||||||
|
" Description: languagetool for markdown files
|
||||||
|
"
|
||||||
|
call ale#Set('languagetool_executable', 'languagetool')
|
||||||
|
|
||||||
|
function! ale#handlers#languagetool#GetExecutable(buffer) abort
|
||||||
|
return ale#Var(a:buffer, 'languagetool_executable')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#handlers#languagetool#GetCommand(buffer) abort
|
||||||
|
let l:executable = ale#handlers#languagetool#GetExecutable(a:buffer)
|
||||||
|
|
||||||
|
return ale#Escape(l:executable) . ' --autoDetect '
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#handlers#languagetool#HandleOutput(buffer, lines) abort
|
||||||
|
" Match lines like:
|
||||||
|
" 1.) Line 5, column 1, Rule ID:
|
||||||
|
let l:head_pattern = '^\v.+.\) Line (\d+), column (\d+), Rule ID. (.+)$'
|
||||||
|
let l:head_matches = ale#util#GetMatches(a:lines, l:head_pattern)
|
||||||
|
|
||||||
|
" Match lines like:
|
||||||
|
" Message: Did you forget a comma after a conjunctive/linking adverb?
|
||||||
|
let l:message_pattern = '^\vMessage. (.+)$'
|
||||||
|
let l:message_matches = ale#util#GetMatches(a:lines, l:message_pattern)
|
||||||
|
|
||||||
|
" Match lines like:
|
||||||
|
" ^^^^^ "
|
||||||
|
let l:markers_pattern = '^\v *(\^+) *$'
|
||||||
|
let l:markers_matches = ale#util#GetMatches(a:lines, l:markers_pattern)
|
||||||
|
|
||||||
|
let l:output = []
|
||||||
|
|
||||||
|
|
||||||
|
" Okay tbh I was to lazy to figure out a smarter solution here
|
||||||
|
" We just check that the arrays are same sized and merge everything
|
||||||
|
" together
|
||||||
|
let l:i = 0
|
||||||
|
|
||||||
|
while l:i < len(l:head_matches)
|
||||||
|
\ && (
|
||||||
|
\ (len(l:head_matches) == len(l:markers_matches))
|
||||||
|
\ && (len(l:head_matches) == len(l:message_matches))
|
||||||
|
\ )
|
||||||
|
let l:item = {
|
||||||
|
\ 'lnum' : str2nr(l:head_matches[l:i][1]),
|
||||||
|
\ 'col' : str2nr(l:head_matches[l:i][2]),
|
||||||
|
\ 'end_col' : str2nr(l:head_matches[l:i][2]) + len(l:markers_matches[l:i][1])-1,
|
||||||
|
\ 'type' : 'W',
|
||||||
|
\ 'code' : l:head_matches[l:i][3],
|
||||||
|
\ 'text' : l:message_matches[l:i][1]
|
||||||
|
\}
|
||||||
|
call add(l:output, l:item)
|
||||||
|
let l:i+=1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Define the languagetool linter for a given filetype.
|
||||||
|
" TODO:
|
||||||
|
" - Add language detection settings based on user env (for mothertongue)
|
||||||
|
" - Add fixer
|
||||||
|
" - Add config options for rules
|
||||||
|
function! ale#handlers#languagetool#DefineLinter(filetype) abort
|
||||||
|
call ale#linter#Define(a:filetype, {
|
||||||
|
\ 'name': 'languagetool',
|
||||||
|
\ 'executable_callback': 'ale#handlers#languagetool#GetExecutable',
|
||||||
|
\ 'command_callback': 'ale#handlers#languagetool#GetCommand',
|
||||||
|
\ 'output_stream': 'stdout',
|
||||||
|
\ 'callback': 'ale#handlers#languagetool#HandleOutput',
|
||||||
|
\ 'lint_file': 1,
|
||||||
|
\})
|
||||||
|
endfunction
|
|
@ -0,0 +1,15 @@
|
||||||
|
Before:
|
||||||
|
call ale#assert#SetUpLinterTest('text', 'languagetool')
|
||||||
|
|
||||||
|
After:
|
||||||
|
call ale#assert#TearDownLinterTest()
|
||||||
|
|
||||||
|
Execute(The default command should be correct):
|
||||||
|
AssertLinter 'languagetool', ale#Escape('languagetool')
|
||||||
|
\ . ' --autoDetect '
|
||||||
|
|
||||||
|
Execute(Should be able to set a custom executable):
|
||||||
|
let g:ale_languagetool_executable = 'foobar'
|
||||||
|
|
||||||
|
AssertLinter 'foobar' , ale#Escape('foobar')
|
||||||
|
\ . ' --autoDetect '
|
62
test/handler/test_languagetool_handler.vader
Normal file
62
test/handler/test_languagetool_handler.vader
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
Before:
|
||||||
|
runtime! ale_linters/text/languagetool.vim
|
||||||
|
|
||||||
|
After:
|
||||||
|
call ale#linter#Reset()
|
||||||
|
|
||||||
|
Execute(languagetool handler should report 3 errors):
|
||||||
|
AssertEqual
|
||||||
|
\ [
|
||||||
|
\ {
|
||||||
|
\ 'lnum': 3,
|
||||||
|
\ 'col': 19,
|
||||||
|
\ 'end_col': 20,
|
||||||
|
\ 'text': 'This sentence does not start with an uppercase letter',
|
||||||
|
\ 'type': 'W',
|
||||||
|
\ 'code': 'UPPERCASE_SENTENCE_START',
|
||||||
|
\ },
|
||||||
|
\ {
|
||||||
|
\ 'lnum': 3,
|
||||||
|
\ 'col': 36,
|
||||||
|
\ 'end_col': 42,
|
||||||
|
\ 'text': "Did you mean 'to see'?",
|
||||||
|
\ 'type': 'W',
|
||||||
|
\ 'code': 'TOO_TO[1]',
|
||||||
|
\ },
|
||||||
|
\ {
|
||||||
|
\ 'lnum': 3,
|
||||||
|
\ 'col': 44,
|
||||||
|
\ 'end_col': 45,
|
||||||
|
\ 'text': "Use 'a' instead of 'an' if the following word doesn't start with a vowel sound, e.g. 'a sentence', 'a university'",
|
||||||
|
\ 'type': 'W',
|
||||||
|
\ 'code': 'EN_A_VS_AN',
|
||||||
|
\ }
|
||||||
|
\ ],
|
||||||
|
\ ale#handlers#languagetool#HandleOutput(bufnr(''), [
|
||||||
|
\ '1.) Line 3, column 19, Rule ID: UPPERCASE_SENTENCE_START',
|
||||||
|
\ 'Message: This sentence does not start with an uppercase letter',
|
||||||
|
\ 'Suggestion: Or',
|
||||||
|
\ '...red phrases for details on potential errors. or use this text too see an few of of the probl...',
|
||||||
|
\ ' ^^ ',
|
||||||
|
\ '',
|
||||||
|
\ '2.) Line 3, column 36, Rule ID: TOO_TO[1]',
|
||||||
|
\ "Message: Did you mean 'to see'?",
|
||||||
|
\ 'Suggestion: to see',
|
||||||
|
\ '...etails on potential errors. or use this text too see an few of of the problems that LanguageTool ...',
|
||||||
|
\ ' ^^^^^^^ ',
|
||||||
|
\ '',
|
||||||
|
\ '3.) Line 3, column 44, Rule ID: EN_A_VS_AN',
|
||||||
|
\ "Message: Use 'a' instead of 'an' if the following word doesn't start with a vowel sound, e.g. 'a sentence', 'a university'",
|
||||||
|
\ 'Suggestion: a',
|
||||||
|
\ '...n potential errors. or use this text too see an few of of the problems that LanguageTool can...',
|
||||||
|
\ ' ^^ ',
|
||||||
|
\ 'Time: 2629ms for 8 sentences (3.0 sentences/sec)'
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
Execute(languagetool handler should report no errors on empty input):
|
||||||
|
AssertEqual
|
||||||
|
\ [],
|
||||||
|
\ ale#handlers#languagetool#HandleOutput(bufnr(''), [
|
||||||
|
\ '',
|
||||||
|
\ 'Time: 2629ms for 8 sentences (3.0 sentences/sec)'
|
||||||
|
\ ])
|
Reference in a new issue