From c59c0d1a573a7b2fe491f78af4f2033bde454753 Mon Sep 17 00:00:00 2001 From: Evan Chen Date: Wed, 15 Apr 2026 09:04:59 -0400 Subject: [PATCH] feat(markdown): add rumdl server and fixer (#5115) * feat: put in the main linter files * feat: add to registry * docs: add rumdl to docs * tests: vader tests * edit: actually split the options into two * style: make rumdl fixer test mimic markdownlint * fix: stupidity overwhelming * fix: actually let's look for pyproject too copied from tombi * i'm a buffoon fix wrong indentation * alignment ci is made for people like me * missed toc entry --- ale_linters/markdown/rumdl.vim | 48 +++++++++++++++++++++ autoload/ale/fix/registry.vim | 5 +++ autoload/ale/fixers/rumdl.vim | 18 ++++++++ doc/ale-markdown.txt | 34 +++++++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + test/fixers/test_rumdl_fixer_callback.vader | 24 +++++++++++ test/linter/test_markdown_rumdl.vader | 18 ++++++++ 9 files changed, 150 insertions(+) create mode 100644 ale_linters/markdown/rumdl.vim create mode 100644 autoload/ale/fixers/rumdl.vim create mode 100644 test/fixers/test_rumdl_fixer_callback.vader create mode 100644 test/linter/test_markdown_rumdl.vader diff --git a/ale_linters/markdown/rumdl.vim b/ale_linters/markdown/rumdl.vim new file mode 100644 index 00000000..ec4cf693 --- /dev/null +++ b/ale_linters/markdown/rumdl.vim @@ -0,0 +1,48 @@ +" Author: Evan Chen +" Description: Fast Markdown linter and formatter written in Rust + + +call ale#Set('markdown_rumdl_executable', 'rumdl') +call ale#Set('markdown_rumdl_options', '') + +function! ale_linters#markdown#rumdl#GetProjectRoot(buffer) abort + let l:dotconfig = ale#path#FindNearestFile(a:buffer, '.rumdl.toml') + let l:config = ale#path#FindNearestFile(a:buffer, 'rumdl.toml') + + if !empty(l:dotconfig) && !empty(l:config) + let l:nearest = len(l:dotconfig) >= len(l:config) ? l:dotconfig : l:config + + return fnamemodify(l:nearest, ':h') + elseif !empty(l:dotconfig) + return fnamemodify(l:dotconfig, ':h') + elseif !empty(l:config) + return fnamemodify(l:config, ':h') + endif + + " Try to find nearest pyproject.toml + let l:pyproject_file = ale#path#FindNearestFile(a:buffer, 'pyproject.toml') + + if !empty(l:pyproject_file) + return fnamemodify(l:pyproject_file . '/', ':p:h:h') + endif + + " Try to find nearest `git` directory + let l:gitdir = ale#path#FindNearestFile(a:buffer, '.git') + + if !empty(l:gitdir) + return fnamemodify(l:gitdir . '/', ':p:h:h') + endif + + return fnamemodify(bufname(a:buffer), ':p:h') +endfunction + +call ale#linter#Define('markdown', { +\ 'name': 'rumdl', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'markdown_rumdl_executable')}, +\ 'command': {b -> ale#Escape(ale#Var(b, 'markdown_rumdl_executable')) +\ . ' server --stdio' +\ . ale#Pad(ale#Var(b, 'markdown_rumdl_options'))}, +\ 'project_root': function('ale_linters#markdown#rumdl#GetProjectRoot'), +\ 'language': 'markdown', +\}) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index a39d15f1..7347a2a4 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -767,6 +767,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['markdown'], \ 'description': 'Fix markdown files with markdownlint.', \ }, +\ 'rumdl': { +\ 'function': 'ale#fixers#rumdl#Fix', +\ 'suggested_filetypes': ['markdown'], +\ 'description': 'Fix markdown files with rumdl.', +\ }, \} " Reset the function registry to the default entries. diff --git a/autoload/ale/fixers/rumdl.vim b/autoload/ale/fixers/rumdl.vim new file mode 100644 index 00000000..8f77f7ec --- /dev/null +++ b/autoload/ale/fixers/rumdl.vim @@ -0,0 +1,18 @@ +scriptencoding utf-8 + +" Author: Evan Chen +" Description: Fast Markdown linter and formatter written in Rust + + +call ale#Set('markdown_rumdl_executable', 'rumdl') +call ale#Set('markdown_rumdl_fmt_options', '--silent') + +function! ale#fixers#rumdl#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'markdown_rumdl_executable') + let l:options = ale#Var(a:buffer, 'markdown_rumdl_fmt_options') + + return { + \ 'command': ale#Escape(l:executable) . ' fmt -' + \ . ale#Pad(l:options), + \} +endfunction diff --git a/doc/ale-markdown.txt b/doc/ale-markdown.txt index 7ee577e1..3f45cbc0 100644 --- a/doc/ale-markdown.txt +++ b/doc/ale-markdown.txt @@ -244,6 +244,40 @@ g:ale_markdown_remark_lint_use_global See |ale-integrations-local-executables| +=============================================================================== +rumdl *ale-markdown-rumdl* + + *ale-options.markdown_rumdl_executable* + *g:ale_markdown_rumdl_executable* + *b:ale_markdown_rumdl_executable* +markdown_rumdl_executable +g:ale_markdown_rumdl_executable + Type: |String| + Default: `'rumdl'` + + Override the invoked `rumdl` binary. + + *ale-options.markdown_rumdl_options* + *g:ale_markdown_rumdl_options* + *b:ale_markdown_rumdl_options* +markdown_rumdl_options +g:ale_markdown_rumdl_options + Type: |String| + Default: `''` + + This variable can be set to pass additional options to `rumdl server`. + + *ale-options.markdown_rumdl_fmt_options* + *g:ale_markdown_rumdl_fmt_options* + *b:ale_markdown_rumdl_fmt_options* +markdown_rumdl_fmt_options +g:ale_markdown_rumdl_fmt_options + Type: |String| + Default: `'--silent'` + + This variable can be set to pass additional options to `rumdl fmt`. + + =============================================================================== textlint *ale-markdown-textlint* diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 41332998..97cec814 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -417,6 +417,7 @@ Notes: * `pymarkdown` * `redpen` * `remark-lint` + * `rumdl` * `textlint` * `vale` * `write-good` diff --git a/doc/ale.txt b/doc/ale.txt index b152f097..279953d0 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -3748,6 +3748,7 @@ documented in additional help files. prettier..............................|ale-markdown-prettier| pymarkdown............................|ale-markdown-pymarkdown| remark-lint...........................|ale-markdown-remark-lint| + rumdl.................................|ale-markdown-rumdl| textlint..............................|ale-markdown-textlint| write-good............................|ale-markdown-write-good| redpen................................|ale-markdown-redpen| diff --git a/supported-tools.md b/supported-tools.md index 7f7be5ee..7a077ff8 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -427,6 +427,7 @@ formatting. * [pymarkdown](https://github.com/jackdewinter/pymarkdown) :floppy_disk: * [redpen](http://redpen.cc/) * [remark-lint](https://github.com/wooorm/remark-lint) + * [rumdl](https://github.com/rvben/rumdl/issues) :speech_balloon: * [textlint](https://textlint.github.io/) * [vale](https://github.com/ValeLint/vale) * [write-good](https://github.com/btford/write-good) diff --git a/test/fixers/test_rumdl_fixer_callback.vader b/test/fixers/test_rumdl_fixer_callback.vader new file mode 100644 index 00000000..fe57ea26 --- /dev/null +++ b/test/fixers/test_rumdl_fixer_callback.vader @@ -0,0 +1,24 @@ +Before: + call ale#assert#SetUpFixerTest('markdown', 'rumdl') + +After: + call ale#assert#TearDownFixerTest() + +Execute: + AssertFixer { + \ 'command': ale#Escape('rumdl') . ' fmt - --silent', + \} + +Execute: + let g:ale_markdown_rumdl_executable = 'rumdl_custom' + + AssertFixer { + \ 'command': ale#Escape('rumdl_custom') . ' fmt - --silent', + \} + +Execute: + let g:ale_markdown_rumdl_fmt_options = '' + + AssertFixer { + \ 'command': ale#Escape('rumdl') . ' fmt -', + \} diff --git a/test/linter/test_markdown_rumdl.vader b/test/linter/test_markdown_rumdl.vader new file mode 100644 index 00000000..b9ecc6e0 --- /dev/null +++ b/test/linter/test_markdown_rumdl.vader @@ -0,0 +1,18 @@ +Before: + call ale#assert#SetUpLinterTest('markdown', 'rumdl') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinter 'rumdl', ale#Escape('rumdl') . ' server --stdio' + +Execute(The executable should be configurable): + let b:ale_markdown_rumdl_executable = 'rumdl_custom' + + AssertLinter 'rumdl_custom', ale#Escape('rumdl_custom') . ' server --stdio' + +Execute(The server options should be configurable): + let b:ale_markdown_rumdl_options = '--some-flag' + + AssertLinter 'rumdl', ale#Escape('rumdl') . ' server --stdio --some-flag'