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