diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | ale_linters/asciidoc/textlint.vim | 9 | ||||
-rw-r--r-- | autoload/ale/c.vim | 45 | ||||
-rw-r--r-- | autoload/ale/fix/registry.vim | 5 | ||||
-rw-r--r-- | autoload/ale/fixers/textlint.vim | 15 | ||||
-rw-r--r-- | doc/ale-asciidoc.txt | 6 | ||||
-rw-r--r-- | doc/ale.txt | 3 | ||||
-rw-r--r-- | test/command_callback/test_asciidoc_textlint_command_callbacks.vader | 65 | ||||
-rw-r--r-- | test/fixers/test_textlint_fixer_callback.vader | 42 | ||||
-rw-r--r-- | test/markdown_files/testfile.md | 0 | ||||
-rw-r--r-- | test/test_c_flag_parsing.vader | 11 |
11 files changed, 190 insertions, 13 deletions
@@ -101,7 +101,7 @@ formatting. | ASM | [gcc](https://gcc.gnu.org) | | Ansible | [ansible-lint](https://github.com/willthames/ansible-lint) | | API Blueprint | [drafter](https://github.com/apiaryio/drafter) | -| AsciiDoc | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [write-good](https://github.com/btford/write-good), [vale](https://github.com/ValeLint/vale) | +| AsciiDoc | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [write-good](https://github.com/btford/write-good), [vale](https://github.com/ValeLint/vale), [textlint](https://textlint.github.io/) | | Awk | [gawk](https://www.gnu.org/software/gawk/)| | Bash | [language-server](https://github.com/mads-hartmann/bash-language-server), shell [-n flag](https://www.gnu.org/software/bash/manual/bash.html#index-set), [shellcheck](https://www.shellcheck.net/), [shfmt](https://github.com/mvdan/sh) | | BibTeX | [bibclean](http://ftp.math.utah.edu/pub/bibclean/) | diff --git a/ale_linters/asciidoc/textlint.vim b/ale_linters/asciidoc/textlint.vim new file mode 100644 index 00000000..757718b9 --- /dev/null +++ b/ale_linters/asciidoc/textlint.vim @@ -0,0 +1,9 @@ +" Author: TANIGUCHI Masaya <ta2gch@gmail.com> +" Description: textlint for AsciiDoc files + +call ale#linter#Define('asciidoc', { +\ 'name': 'textlint', +\ 'executable_callback': 'ale#handlers#textlint#GetExecutable', +\ 'command_callback': 'ale#handlers#textlint#GetCommand', +\ 'callback': 'ale#handlers#textlint#HandleTextlintOutput', +\}) diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index 6175082e..6ad5d328 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -46,6 +46,38 @@ function! ale#c#FindProjectRoot(buffer) abort return '' endfunction +function! ale#c#AreSpecialCharsBalanced(option) abort + " Escape \" + let l:option_escaped = substitute(a:option, '\\"', '', 'g') + + " Retain special chars only + let l:special_chars = substitute(l:option_escaped, '[^"''()`]', '', 'g') + let l:special_chars = split(l:special_chars, '\zs') + + " Check if they are balanced + let l:stack = [] + + for l:char in l:special_chars + if l:char is# ')' + if len(l:stack) == 0 || get(l:stack, -1) isnot# '(' + return 0 + endif + + call remove(l:stack, -1) + elseif l:char is# '(' + call add(l:stack, l:char) + else + if len(l:stack) > 0 && get(l:stack, -1) is# l:char + call remove(l:stack, -1) + else + call add(l:stack, l:char) + endif + endif + endfor + + return len(l:stack) == 0 +endfunction + function! ale#c#ParseCFlags(path_prefix, cflag_line) abort let l:cflags_list = [] let l:previous_options = '' @@ -57,17 +89,8 @@ function! ale#c#ParseCFlags(path_prefix, cflag_line) abort let l:option = l:previous_options . l:split_lines[l:option_index] let l:option_index = l:option_index + 1 - " Check if cflag contained an unmatched characters and should not have been splitted - let l:option_special = substitute(l:option, '\\"', '', 'g') - let l:option_special = substitute(l:option_special, '[^"''()`]', '', 'g') - let l:option_special = substitute(l:option_special, '""', '', 'g') - let l:option_special = substitute(l:option_special, '''''', '', 'g') - let l:option_special = substitute(l:option_special, '``', '', 'g') - let l:option_special = substitute(l:option_special, '((', '(', 'g') - let l:option_special = substitute(l:option_special, '))', ')', 'g') - let l:option_special = substitute(l:option_special, '()', '', 'g') - - if len(l:option_special) > 0 && l:option_index < len(l:split_lines) + " Check if cflag contained an unmatched special character and should not have been splitted + if ale#c#AreSpecialCharsBalanced(l:option) == 0 && l:option_index < len(l:split_lines) let l:previous_options = l:option . ' ' continue endif diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 6a8fd382..a7422f22 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -170,6 +170,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['rust'], \ 'description': 'Fix Rust files with Rustfmt.', \ }, +\ 'textlint': { +\ 'function': 'ale#fixers#textlint#Fix', +\ 'suggested_filetypes': ['text','markdown','asciidoc'], +\ 'description': 'Fix text files with textlint --fix', +\ }, \ 'hackfmt': { \ 'function': 'ale#fixers#hackfmt#Fix', \ 'suggested_filetypes': ['hack'], diff --git a/autoload/ale/fixers/textlint.vim b/autoload/ale/fixers/textlint.vim new file mode 100644 index 00000000..38ab2bfd --- /dev/null +++ b/autoload/ale/fixers/textlint.vim @@ -0,0 +1,15 @@ +" Author: TANIGUCHI Masaya <ta2gch@gmail.com> +" Description: Integration of textlint with ALE. + +function! ale#fixers#textlint#Fix(buffer) abort + let l:executable = ale#handlers#textlint#GetExecutable(a:buffer) + let l:options = ale#Var(a:buffer, 'textlint_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' --fix' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/doc/ale-asciidoc.txt b/doc/ale-asciidoc.txt index b6b64fd3..86629fd4 100644 --- a/doc/ale-asciidoc.txt +++ b/doc/ale-asciidoc.txt @@ -9,4 +9,10 @@ See |ale-write-good-options| =============================================================================== +textlint *ale-asciidoc-textlint* + +See |ale-text-textlint| + + +=============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index 6bedf755..27d91605 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -27,6 +27,7 @@ CONTENTS *ale-contents* ansible-lint........................|ale-ansible-ansible-lint| asciidoc..............................|ale-asciidoc-options| write-good..........................|ale-asciidoc-write-good| + textlint............................|ale-asciidoc-textlint| asm...................................|ale-asm-options| gcc.................................|ale-asm-gcc| awk...................................|ale-awk-options| @@ -407,7 +408,7 @@ Notes: * ASM: `gcc` * Ansible: `ansible-lint` * API Blueprint: `drafter` -* AsciiDoc: `alex`!!, `proselint`, `redpen`, `write-good`, `vale` +* AsciiDoc: `alex`!!, `proselint`, `redpen`, `write-good`, `vale`, `textlint` * Awk: `gawk` * Bash: `language-server`, `shell` (-n flag), `shellcheck`, `shfmt` * BibTeX: `bibclean` diff --git a/test/command_callback/test_asciidoc_textlint_command_callbacks.vader b/test/command_callback/test_asciidoc_textlint_command_callbacks.vader new file mode 100644 index 00000000..623833b2 --- /dev/null +++ b/test/command_callback/test_asciidoc_textlint_command_callbacks.vader @@ -0,0 +1,65 @@ +" Author: januswel, w0rp + +Before: + " This is just one language for the linter. + call ale#assert#SetUpLinterTest('asciidoc', 'textlint') + + " The configuration is shared between many languages. + Save g:ale_textlint_executable + Save g:ale_textlint_use_global + Save g:ale_textlint_options + + let g:ale_textlint_executable = 'textlint' + let g:ale_textlint_use_global = 0 + let g:ale_textlint_options = '' + + unlet! b:ale_textlint_executable + unlet! b:ale_textlint_use_global + unlet! b:ale_textlint_options + +After: + unlet! b:command_tail + unlet! b:ale_textlint_executable + unlet! b:ale_textlint_use_global + unlet! b:ale_textlint_options + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'textlint', + \ ale#Escape('textlint') . ' -f json --stdin --stdin-filename %s' + +Execute(The executable should be configurable): + let b:ale_textlint_executable = 'foobar' + + AssertLinter 'foobar', + \ ale#Escape('foobar') . ' -f json --stdin --stdin-filename %s' + +Execute(The options should be configurable): + let b:ale_textlint_options = '--something' + + AssertLinter 'textlint', + \ ale#Escape('textlint') . ' --something -f json --stdin --stdin-filename %s' + +Execute(The local executable from .bin should be used if available): + call ale#test#SetFilename('textlint_paths/with_bin_path/foo.txt') + + AssertLinter + \ ale#path#Simplify(g:dir . '/textlint_paths/with_bin_path/node_modules/.bin/textlint'), + \ ale#Escape(ale#path#Simplify(g:dir . '/textlint_paths/with_bin_path/node_modules/.bin/textlint')) + \ . ' -f json --stdin --stdin-filename %s' + +Execute(The local executable from textlint/bin should be used if available): + call ale#test#SetFilename('textlint_paths/with_textlint_bin_path/foo.txt') + + if has('win32') + AssertLinter + \ ale#path#Simplify(g:dir . '/textlint_paths/with_textlint_bin_path/node_modules/textlint/bin/textlint.js'), + \ ale#Escape('node.exe') . ' ' . ale#Escape(ale#path#Simplify(g:dir . '/textlint_paths/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s' + else + AssertLinter + \ ale#path#Simplify(g:dir . '/textlint_paths/with_textlint_bin_path/node_modules/textlint/bin/textlint.js'), + \ ale#Escape(ale#path#Simplify(g:dir . '/textlint_paths/with_textlint_bin_path/node_modules/textlint/bin/textlint.js')) + \ . ' -f json --stdin --stdin-filename %s' + endif diff --git a/test/fixers/test_textlint_fixer_callback.vader b/test/fixers/test_textlint_fixer_callback.vader new file mode 100644 index 00000000..2848cfa5 --- /dev/null +++ b/test/fixers/test_textlint_fixer_callback.vader @@ -0,0 +1,42 @@ +Before: + Save g:ale_textlint_executable + Save g:ale_textlint_options + Save g:ale_textlint_use_global + + " Use an invalid global executable, so we don't match it. + let g:ale_textlint_executable = 'xxxinvalid' + let g:ale_textlint_options = '' + let g:ale_textlint_use_global = 0 + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The textlint callback should return the correct default values): + call ale#test#SetFilename('../markdown_files/testfile.md') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' --fix' + \ . ' %t', + \ }, + \ ale#fixers#textlint#Fix(bufnr('')) + +Execute(The textlint callback should include custom textlint options): + let g:ale_textlint_options = "--quiet" + call ale#test#SetFilename('../markdown_files/testfile.md') + + AssertEqual + \ { + \ 'read_temporary_file': 1, + \ 'command': ale#Escape('xxxinvalid') + \ . ' --fix' + \ . ' ' . g:ale_textlint_options + \ . ' %t', + \ }, + \ ale#fixers#textlint#Fix(bufnr('')) diff --git a/test/markdown_files/testfile.md b/test/markdown_files/testfile.md new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/markdown_files/testfile.md diff --git a/test/test_c_flag_parsing.vader b/test/test_c_flag_parsing.vader index b187ffec..dbaf6b73 100644 --- a/test/test_c_flag_parsing.vader +++ b/test/test_c_flag_parsing.vader @@ -209,3 +209,14 @@ Execute(ParseCFlags should not merge flags): \ . ' -I'. ale#path#Simplify('kernel/include') . ' ' \ . 'subdir/somedep5.o ' . 'subdir/somedep6.o ' \ ) + +Execute(ParseCFlags should handle parenthesis and quotes): + AssertEqual + \ '-Dgoal=9 -Dtest1="('' '')" -Dtest2=''(` `)'' -Dtest3=`(" ")`', + \ ale#c#ParseCFlags( + \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), + \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla ' + \ . '-Dtest1="('' '')" file1.o ' + \ . '-Dtest2=''(` `)'' file2.o ' + \ . '-Dtest3=`(" ")` file3.o ' + \ ) |