From eff718bee9dd45b19e74733b971c4fcb8add2ff9 Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Fri, 21 Aug 2026 11:22:09 +0900 Subject: [PATCH] Fix markdownlint fixer and add markdownlint-cli2 (#5165) * fix(tests): fix ale_c_build_dir_names being unset in tests (#5109) - Use ale#Set() to set the ale_c_build_dir_names variable. - Ensure SetUpLinterTest() is called before any Save commands in tests. - Add c.vim to runtime before non-linter tests are executed. - Remove workarounds in c.vim. * feat: Load Prettier from cjs also * fix: wrong command for markdownlint * feat: explicit support for markdownlint-cli2 - Add markdownlint-cli2 linter and fixer, separate from markdownilnt-cli - Rename markdownlint to markdownlint-cli - Keep markdownlint as alias for markdownlint-cli --------- Co-authored-by: w0rp Co-authored-by: Horacio Sanson --- ale_linters/markdown/markdownlint.vim | 22 ++--- ale_linters/markdown/markdownlint_cli2.vim | 29 +++++++ autoload/ale/fix/registry.vim | 10 ++- autoload/ale/fixers/markdownlint.vim | 17 ++-- autoload/ale/fixers/markdownlint_cli2.vim | 10 +++ autoload/ale/handlers/markdownlint.vim | 17 ++++ doc/ale-markdown.txt | 87 ++++++++++++++++++- doc/ale-supported-languages-and-tools.txt | 3 +- doc/ale.txt | 3 +- supported-tools.md | 3 +- test/fix/test_ale_fix_aliases.vader | 15 ++++ ...est_markdownlint_cli2_fixer_callback.vader | 28 ++++++ .../test_markdownlint_fixer_callback.vader | 21 +++-- test/linter/test_markdown_markdownlint.vader | 10 ++- .../test_markdown_markdownlint_cli2.vader | 24 +++++ 15 files changed, 269 insertions(+), 30 deletions(-) create mode 100644 ale_linters/markdown/markdownlint_cli2.vim create mode 100644 autoload/ale/fixers/markdownlint_cli2.vim create mode 100644 test/fixers/test_markdownlint_cli2_fixer_callback.vader create mode 100644 test/linter/test_markdown_markdownlint_cli2.vader diff --git a/ale_linters/markdown/markdownlint.vim b/ale_linters/markdown/markdownlint.vim index ca5f31301..5d09eb4d3 100644 --- a/ale_linters/markdown/markdownlint.vim +++ b/ale_linters/markdown/markdownlint.vim @@ -1,27 +1,29 @@ " Author: Ty-Lucas Kelley -" Description: Adds support for markdownlint +" Description: Adds support for markdownlint-cli call ale#Set('markdown_markdownlint_executable', 'markdownlint') call ale#Set('markdown_markdownlint_options', '') function! ale_linters#markdown#markdownlint#GetExecutable(buffer) abort - return ale#Var(a:buffer, 'markdown_markdownlint_executable') + return ale#handlers#markdownlint#GetExecutable( + \ a:buffer, + \ 'markdownlint', + \) endfunction function! ale_linters#markdown#markdownlint#GetCommand(buffer) abort - let l:executable = ale_linters#markdown#markdownlint#GetExecutable(a:buffer) - - let l:options = ale#Var(a:buffer, 'markdown_markdownlint_options') - - return ale#Escape(l:executable) - \ . ale#Pad(l:options) . ' %s' + return ale#handlers#markdownlint#GetCommand( + \ a:buffer, + \ 'markdownlint', + \) endfunction call ale#linter#Define('markdown', { -\ 'name': 'markdownlint', +\ 'name': 'markdownlint_cli', +\ 'aliases': ['markdownlint', 'markdownlint-cli'], \ 'executable': function('ale_linters#markdown#markdownlint#GetExecutable'), \ 'lint_file': 1, \ 'output_stream': 'both', \ 'command': function('ale_linters#markdown#markdownlint#GetCommand'), -\ 'callback': 'ale#handlers#markdownlint#Handle' +\ 'callback': 'ale#handlers#markdownlint#Handle', \}) diff --git a/ale_linters/markdown/markdownlint_cli2.vim b/ale_linters/markdown/markdownlint_cli2.vim new file mode 100644 index 000000000..9ebddfc0f --- /dev/null +++ b/ale_linters/markdown/markdownlint_cli2.vim @@ -0,0 +1,29 @@ +" Author: Horacio Sanson +" Description: Adds support for markdownlint-cli2 + +call ale#Set('markdown_markdownlint_cli2_executable', 'markdownlint-cli2') +call ale#Set('markdown_markdownlint_cli2_options', '') + +function! ale_linters#markdown#markdownlint_cli2#GetExecutable(buffer) abort + return ale#handlers#markdownlint#GetExecutable( + \ a:buffer, + \ 'markdownlint_cli2', + \) +endfunction + +function! ale_linters#markdown#markdownlint_cli2#GetCommand(buffer) abort + return ale#handlers#markdownlint#GetCommand( + \ a:buffer, + \ 'markdownlint_cli2', + \) +endfunction + +call ale#linter#Define('markdown', { +\ 'name': 'markdownlint_cli2', +\ 'aliases': ['markdownlint-cli2'], +\ 'executable': function('ale_linters#markdown#markdownlint_cli2#GetExecutable'), +\ 'lint_file': 1, +\ 'output_stream': 'both', +\ 'command': function('ale_linters#markdown#markdownlint_cli2#GetCommand'), +\ 'callback': 'ale#handlers#markdownlint#Handle', +\}) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index aa3954cc1..0770e0f1b 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -787,10 +787,16 @@ let s:default_registry = { \ 'suggested_filetypes': ['verilog'], \ 'description': 'Formats verilog files using verible.', \ }, -\ 'markdownlint': { +\ 'markdownlint-cli': { \ 'function': 'ale#fixers#markdownlint#Fix', \ 'suggested_filetypes': ['markdown'], -\ 'description': 'Fix markdown files with markdownlint.', +\ 'description': 'Fix markdown files with markdownlint-cli.', +\ 'aliases': ['markdownlint'], +\ }, +\ 'markdownlint-cli2': { +\ 'function': 'ale#fixers#markdownlint_cli2#Fix', +\ 'suggested_filetypes': ['markdown'], +\ 'description': 'Fix markdown files with markdownlint-cli2.', \ }, \ 'rumdl': { \ 'function': 'ale#fixers#rumdl#Fix', diff --git a/autoload/ale/fixers/markdownlint.vim b/autoload/ale/fixers/markdownlint.vim index 10e7a0915..4e74e88f6 100644 --- a/autoload/ale/fixers/markdownlint.vim +++ b/autoload/ale/fixers/markdownlint.vim @@ -1,15 +1,22 @@ :scriptencoding utf-8 call ale#Set('markdownlint_executable', 'markdownlint') -call ale#Set('markdownlint_options', '--fix') +call ale#Set('markdownlint_options', '') -function! ale#fixers#markdownlint#Fix(buffer) abort - let l:executable = ale#Var(a:buffer, 'markdownlint_executable') - let l:options = ale#Var(a:buffer, 'markdownlint_options') +function! ale#fixers#markdownlint#FixFor(buffer, name) abort + let l:executable = ale#Var(a:buffer, a:name . '_executable') + let l:options = ale#Var(a:buffer, a:name . '_options') return { \ 'command': ale#Escape(l:executable) - \ . ' ' . l:options, + \ . ' --fix' + \ . ale#Pad(l:options) + \ . ' %t', + \ 'read_temporary_file': 1, \} endfunction +function! ale#fixers#markdownlint#Fix(buffer) abort + return ale#fixers#markdownlint#FixFor(a:buffer, 'markdownlint') +endfunction + diff --git a/autoload/ale/fixers/markdownlint_cli2.vim b/autoload/ale/fixers/markdownlint_cli2.vim new file mode 100644 index 000000000..c15734047 --- /dev/null +++ b/autoload/ale/fixers/markdownlint_cli2.vim @@ -0,0 +1,10 @@ +:scriptencoding utf-8 +" Author: Horacio Sanson +" Description: Fixes Markdown files with markdownlint-cli2 + +call ale#Set('markdownlint_cli2_executable', 'markdownlint-cli2') +call ale#Set('markdownlint_cli2_options', '') + +function! ale#fixers#markdownlint_cli2#Fix(buffer) abort + return ale#fixers#markdownlint#FixFor(a:buffer, 'markdownlint_cli2') +endfunction diff --git a/autoload/ale/handlers/markdownlint.vim b/autoload/ale/handlers/markdownlint.vim index 4ede259b8..7123dc29b 100644 --- a/autoload/ale/handlers/markdownlint.vim +++ b/autoload/ale/handlers/markdownlint.vim @@ -1,6 +1,23 @@ " Author: Ty-Lucas Kelley " Description: Adds support for markdownlint +function! ale#handlers#markdownlint#GetExecutable(buffer, name) abort + return ale#Var(a:buffer, 'markdown_' . a:name . '_executable') +endfunction + +function! ale#handlers#markdownlint#GetCommand(buffer, name) abort + let l:executable = ale#handlers#markdownlint#GetExecutable( + \ a:buffer, + \ a:name, + \) + let l:options = ale#Var( + \ a:buffer, + \ 'markdown_' . a:name . '_options', + \) + + return ale#Escape(l:executable) . ale#Pad(l:options) . ' %s' +endfunction + function! ale#handlers#markdownlint#Handle(buffer, lines) abort let l:pattern=': \?\(\d\+\)\(:\(\d\+\)\?\)\? \(error\|warning\)\? \?\(MD\d\{3}/[A-Za-z0-9-/]\+\) \(.*\)$' let l:output=[] diff --git a/doc/ale-markdown.txt b/doc/ale-markdown.txt index 5076a9433..15a7052af 100644 --- a/doc/ale-markdown.txt +++ b/doc/ale-markdown.txt @@ -44,7 +44,14 @@ g:ale_markdown_harper_config =============================================================================== -markdownlint *ale-markdown-markdownlint* +markdownlint-cli *ale-markdown-markdownlint-cli* + *ale-markdown-markdownlint* + + https://github.com/igorshubovych/markdownlint-cli + + The linter name is `markdownlint_cli`. `markdownlint` and + `markdownlint-cli` are aliases. The fixer name is `markdownlint-cli`; + `markdownlint` is an alias. *ale-options.markdown_markdownlint_executable* *g:ale_markdown_markdownlint_executable* @@ -54,8 +61,7 @@ g:ale_markdown_markdownlint_executable Type: |String| Default: `'markdownlint'` - Override the invoked `markdownlint` binary. You can use other binaries such as - `markdownlint-cli2`. + Override the `markdownlint-cli` executable used by the linter. *ale-options.markdown_markdownlint_options* *g:ale_markdown_markdownlint_options* @@ -65,7 +71,80 @@ g:ale_markdown_markdownlint_options Type: |String| Default: `''` - This variable can be set to pass additional options to markdownlint. + This variable can be set to pass additional linter options to + `markdownlint-cli`. + + *ale-options.markdownlint_executable* + *g:ale_markdownlint_executable* + *b:ale_markdownlint_executable* +markdownlint_executable +g:ale_markdownlint_executable + Type: |String| + Default: `'markdownlint'` + + Override the `markdownlint-cli` executable used by the fixer. + + *ale-options.markdownlint_options* + *g:ale_markdownlint_options* + *b:ale_markdownlint_options* +markdownlint_options +g:ale_markdownlint_options + Type: |String| + Default: `''` + + This variable can be set to pass additional fixer options to + `markdownlint-cli`. ALE always adds the required `--fix` option. + + +=============================================================================== +markdownlint-cli2 *ale-markdown-markdownlint-cli2* + + https://github.com/DavidAnson/markdownlint-cli2 + + The linter name is `markdownlint_cli2`, with `markdownlint-cli2` as an + alias. The fixer name is `markdownlint-cli2`. + + *ale-options.markdown_markdownlint_cli2_executable* + *g:ale_markdown_markdownlint_cli2_executable* + *b:ale_markdown_markdownlint_cli2_executable* +markdown_markdownlint_cli2_executable +g:ale_markdown_markdownlint_cli2_executable + Type: |String| + Default: `'markdownlint-cli2'` + + Override the `markdownlint-cli2` executable used by the linter. + + *ale-options.markdown_markdownlint_cli2_options* + *g:ale_markdown_markdownlint_cli2_options* + *b:ale_markdown_markdownlint_cli2_options* +markdown_markdownlint_cli2_options +g:ale_markdown_markdownlint_cli2_options + Type: |String| + Default: `''` + + This variable can be set to pass additional linter options to + `markdownlint-cli2`. + + *ale-options.markdownlint_cli2_executable* + *g:ale_markdownlint_cli2_executable* + *b:ale_markdownlint_cli2_executable* +markdownlint_cli2_executable +g:ale_markdownlint_cli2_executable + Type: |String| + Default: `'markdownlint-cli2'` + + Override the `markdownlint-cli2` executable used by the fixer. + + *ale-options.markdownlint_cli2_options* + *g:ale_markdownlint_cli2_options* + *b:ale_markdownlint_cli2_options* +markdownlint_cli2_options +g:ale_markdownlint_cli2_options + Type: |String| + Default: `''` + + This variable can be set to pass additional fixer options to + `markdownlint-cli2`. ALE always adds the required `--fix` option. =============================================================================== diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index d677c537e..f8711d89b 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -437,7 +437,8 @@ Notes: * dprint * `harper` * `languagetool`!! - * `markdownlint`!! + * `markdownlint-cli`!! + * `markdownlint-cli2`!! * `marksman` * `mdformat` * `mdl` diff --git a/doc/ale.txt b/doc/ale.txt index a3362c421..638d9b5b5 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -3780,7 +3780,8 @@ documented in additional help files. cspell................................|ale-markdown-cspell| dprint................................|ale-markdown-dprint| harper................................|ale-markdown-harper| - markdownlint..........................|ale-markdown-markdownlint| + markdownlint-cli......................|ale-markdown-markdownlint-cli| + markdownlint-cli2.....................|ale-markdown-markdownlint-cli2| marksman..............................|ale-markdown-marksman| mdformat..............................|ale-markdown-mdformat| mdl...................................|ale-markdown-mdl| diff --git a/supported-tools.md b/supported-tools.md index 9ac849173..ec3a1ea15 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -447,7 +447,8 @@ formatting. * [dprint](https://dprint.dev) * [harper](https://github.com/elijah-potter/harper) :speech_balloon: * [languagetool](https://languagetool.org/) :floppy_disk: :speech_balloon: - * [markdownlint](https://github.com/DavidAnson/markdownlint) :floppy_disk: + * [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli) :floppy_disk: + * [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) :floppy_disk: * [marksman](https://github.com/artempyanykh/marksman) :speech_balloon: * [mdformat](https://github.com/hukkin/mdformat) * [mdl](https://github.com/mivok/markdownlint) diff --git a/test/fix/test_ale_fix_aliases.vader b/test/fix/test_ale_fix_aliases.vader index d3c47b347..00cc8035d 100644 --- a/test/fix/test_ale_fix_aliases.vader +++ b/test/fix/test_ale_fix_aliases.vader @@ -3,3 +3,18 @@ Execute(prettier-eslint should be aliased): Execute(prettier-standard should be aliased): AssertEqual 'ale#fixers#prettier_standard#Fix', ale#fix#registry#GetFunc('prettier-standard') + +Execute(markdownlint should be aliased to markdownlint-cli): + AssertEqual + \ 'ale#fixers#markdownlint#Fix', + \ ale#fix#registry#GetFunc('markdownlint') + +Execute(markdownlint-cli should be available directly): + AssertEqual + \ 'ale#fixers#markdownlint#Fix', + \ ale#fix#registry#GetFunc('markdownlint-cli') + +Execute(markdownlint-cli2 should be available directly): + AssertEqual + \ 'ale#fixers#markdownlint_cli2#Fix', + \ ale#fix#registry#GetFunc('markdownlint-cli2') diff --git a/test/fixers/test_markdownlint_cli2_fixer_callback.vader b/test/fixers/test_markdownlint_cli2_fixer_callback.vader new file mode 100644 index 000000000..647aced41 --- /dev/null +++ b/test/fixers/test_markdownlint_cli2_fixer_callback.vader @@ -0,0 +1,28 @@ +Before: + call ale#assert#SetUpFixerTest('markdown', 'markdownlint-cli2') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The default command should use a temporary file): + AssertFixer { + \ 'command': ale#Escape('markdownlint-cli2') . ' --fix %t', + \ 'read_temporary_file': 1, + \} + +Execute(The executable should be configurable): + let g:ale_markdownlint_cli2_executable = 'custom_markdownlint_cli2' + + AssertFixer { + \ 'command': ale#Escape('custom_markdownlint_cli2') . ' --fix %t', + \ 'read_temporary_file': 1, + \} + +Execute(Custom options should not remove the required --fix option): + let g:ale_markdownlint_cli2_executable = 'markdownlint-cli2' + let g:ale_markdownlint_cli2_options = '--no-globs' + + AssertFixer { + \ 'command': ale#Escape('markdownlint-cli2') . ' --fix --no-globs %t', + \ 'read_temporary_file': 1, + \} diff --git a/test/fixers/test_markdownlint_fixer_callback.vader b/test/fixers/test_markdownlint_fixer_callback.vader index 2a03e734e..b1a807aaf 100644 --- a/test/fixers/test_markdownlint_fixer_callback.vader +++ b/test/fixers/test_markdownlint_fixer_callback.vader @@ -4,14 +4,25 @@ Before: After: call ale#assert#TearDownFixerTest() -Execute: +Execute(The default command should use a temporary file): AssertFixer { - \ 'command': ale#Escape('markdownlint') . ' --fix', + \ 'command': ale#Escape('markdownlint') . ' --fix %t', + \ 'read_temporary_file': 1, \} -Execute: +Execute(The executable should be configurable): let g:ale_markdownlint_executable = 'custom_markdownlint' - + AssertFixer { - \ 'command': ale#Escape('custom_markdownlint') . ' --fix', + \ 'command': ale#Escape('custom_markdownlint') . ' --fix %t', + \ 'read_temporary_file': 1, + \} + +Execute(Custom options should not remove the required --fix option): + let g:ale_markdownlint_executable = 'markdownlint' + let g:ale_markdownlint_options = '--quiet' + + AssertFixer { + \ 'command': ale#Escape('markdownlint') . ' --fix --quiet %t', + \ 'read_temporary_file': 1, \} diff --git a/test/linter/test_markdown_markdownlint.vader b/test/linter/test_markdown_markdownlint.vader index 7ec626ee2..eba0beb6a 100644 --- a/test/linter/test_markdown_markdownlint.vader +++ b/test/linter/test_markdown_markdownlint.vader @@ -1,10 +1,11 @@ Before: + Save g:ale_linters call ale#assert#SetUpLinterTest('markdown', 'markdownlint') After: call ale#assert#TearDownLinterTest() -Execute(The default markdownlint command should be correct): +Execute(The default markdownlint-cli command should be correct): AssertLinter 'markdownlint', ale#Escape('markdownlint') . ' %s' Execute(The executable should be configurable): @@ -12,3 +13,10 @@ Execute(The executable should be configurable): let g:ale_markdown_markdownlint_options = '--option' AssertLinter 'foo bar', ale#Escape('foo bar') . ' --option %s' + +Execute(markdownlint should select the markdownlint-cli linter): + let g:ale_linters = {'markdown': ['markdownlint']} + + AssertEqual + \ ['markdownlint_cli'], + \ map(ale#linter#Get('markdown'), 'v:val.name') diff --git a/test/linter/test_markdown_markdownlint_cli2.vader b/test/linter/test_markdown_markdownlint_cli2.vader new file mode 100644 index 000000000..d50a30379 --- /dev/null +++ b/test/linter/test_markdown_markdownlint_cli2.vader @@ -0,0 +1,24 @@ +Before: + Save g:ale_linters + call ale#assert#SetUpLinterTest('markdown', 'markdownlint_cli2') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default markdownlint-cli2 command should be correct): + AssertLinter + \ 'markdownlint-cli2', + \ ale#Escape('markdownlint-cli2') . ' %s' + +Execute(The executable and options should be configurable): + let g:ale_markdown_markdownlint_cli2_executable = 'foo bar' + let g:ale_markdown_markdownlint_cli2_options = '--no-globs' + + AssertLinter 'foo bar', ale#Escape('foo bar') . ' --no-globs %s' + +Execute(markdownlint-cli2 should select the markdownlint-cli2 linter): + let g:ale_linters = {'markdown': ['markdownlint-cli2']} + + AssertEqual + \ ['markdownlint_cli2'], + \ map(ale#linter#Get('markdown'), 'v:val.name')