summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--ale_linters/asciidoc/textlint.vim9
-rw-r--r--autoload/ale/c.vim45
-rw-r--r--autoload/ale/fix/registry.vim5
-rw-r--r--autoload/ale/fixers/textlint.vim15
-rw-r--r--doc/ale-asciidoc.txt6
-rw-r--r--doc/ale.txt3
-rw-r--r--test/command_callback/test_asciidoc_textlint_command_callbacks.vader65
-rw-r--r--test/fixers/test_textlint_fixer_callback.vader42
-rw-r--r--test/markdown_files/testfile.md0
-rw-r--r--test/test_c_flag_parsing.vader11
11 files changed, 190 insertions, 13 deletions
diff --git a/README.md b/README.md
index 73217677..cb7f643d 100644
--- a/README.md
+++ b/README.md
@@ -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 '
+ \ )