From 42d106201146dec2f6b1e1d4bf46c899e9c63b6d Mon Sep 17 00:00:00 2001 From: Johan Larsson <13087841+jolars@users.noreply.github.com> Date: Wed, 19 Aug 2026 03:46:57 +0200 Subject: [PATCH] Add support for fatou (#5159) Add a linter that runs the fatou language server (`fatou lsp`) for Julia diagnostics, and a fixer that formats Julia with `fatou format`. --- ale_linters/julia/fatou.vim | 18 +++++++++++ autoload/ale/fix/registry.vim | 5 ++++ autoload/ale/fixers/fatou.vim | 15 ++++++++++ doc/ale-julia.txt | 33 +++++++++++++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + test/fixers/test_fatou_fixer_callback.vader | 20 +++++++++++++ test/linter/test_julia_fatou.vader | 23 ++++++++++++++ test/test-files/fatou/fatou.toml | 0 test/test-files/fatou/subdir/file.jl | 0 11 files changed, 117 insertions(+) create mode 100644 ale_linters/julia/fatou.vim create mode 100644 autoload/ale/fixers/fatou.vim create mode 100644 test/fixers/test_fatou_fixer_callback.vader create mode 100644 test/linter/test_julia_fatou.vader create mode 100644 test/test-files/fatou/fatou.toml create mode 100644 test/test-files/fatou/subdir/file.jl diff --git a/ale_linters/julia/fatou.vim b/ale_linters/julia/fatou.vim new file mode 100644 index 000000000..9592d7293 --- /dev/null +++ b/ale_linters/julia/fatou.vim @@ -0,0 +1,18 @@ +" Author: Johan Larsson +" Description: A language server, formatter, and linter for Julia + +call ale#Set('julia_fatou_executable', 'fatou') + +function! ale_linters#julia#fatou#GetProjectRoot(buffer) abort + let l:config = ale#path#FindNearestFile(a:buffer, 'fatou.toml') + + return !empty(l:config) ? fnamemodify(l:config, ':h') : '' +endfunction + +call ale#linter#Define('julia', { +\ 'name': 'fatou', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'julia_fatou_executable')}, +\ 'command': '%e lsp', +\ 'project_root': function('ale_linters#julia#fatou#GetProjectRoot'), +\}) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 50cc5ba1f..aa3954cc1 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -124,6 +124,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['erlang'], \ 'description': 'Format Erlang code with erlfmt', \ }, +\ 'fatou': { +\ 'function': 'ale#fixers#fatou#Fix', +\ 'suggested_filetypes': ['julia'], +\ 'description': 'Format Julia files with fatou.', +\ }, \ 'fecs': { \ 'function': 'ale#fixers#fecs#Fix', \ 'suggested_filetypes': ['javascript', 'css', 'html'], diff --git a/autoload/ale/fixers/fatou.vim b/autoload/ale/fixers/fatou.vim new file mode 100644 index 000000000..18085c1b1 --- /dev/null +++ b/autoload/ale/fixers/fatou.vim @@ -0,0 +1,15 @@ +" Author: Johan Larsson +" Description: Format Julia files with fatou. + +call ale#Set('julia_fatou_executable', 'fatou') +call ale#Set('julia_fatou_options', '') + +function! ale#fixers#fatou#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'julia_fatou_executable') + let l:options = ale#Var(a:buffer, 'julia_fatou_options') + + return { + \ 'command': ale#Escape(l:executable) . ' format' + \ . ale#Pad(l:options), + \} +endfunction diff --git a/doc/ale-julia.txt b/doc/ale-julia.txt index 175037b1b..31ad51c36 100644 --- a/doc/ale-julia.txt +++ b/doc/ale-julia.txt @@ -2,6 +2,39 @@ ALE Julia Integration *ale-julia-options* +=============================================================================== +fatou *ale-julia-fatou* + +fatou is a language server, formatter, and linter for Julia. The `fatou` linter +runs the language server (`fatou lsp`) to report diagnostics, and the `fatou` +fixer formats Julia with `fatou format`. + +Project-level configuration is read from a `fatou.toml` file discovered by +walking up from the file being edited. See https://github.com/jolars/fatou for +more information. + + *ale-options.julia_fatou_executable* + *g:ale_julia_fatou_executable* + *b:ale_julia_fatou_executable* +julia_fatou_executable +g:ale_julia_fatou_executable + Type: |String| + Default: `'fatou'` + + This variable can be changed to change the path to fatou. + + *ale-options.julia_fatou_options* + *g:ale_julia_fatou_options* + *b:ale_julia_fatou_options* +julia_fatou_options +g:ale_julia_fatou_options + Type: |String| + Default: `''` + + This variable can be changed to pass additional arguments to the `fatou + format` command used by the fixer. + + =============================================================================== languageserver *ale-julia-languageserver* diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index b29e7508f..960d79275 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -386,6 +386,7 @@ Notes: * `jsonnet-lint` * `jsonnetfmt` * Julia + * `fatou` * `languageserver` * Kotlin * `kotlinc`!! diff --git a/doc/ale.txt b/doc/ale.txt index 0aebe7590..34e3d4b0c 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -3744,6 +3744,7 @@ documented in additional help files. jsonnetfmt............................|ale-jsonnet-jsonnetfmt| jsonnet-lint..........................|ale-jsonnet-jsonnet-lint| julia...................................|ale-julia-options| + fatou.................................|ale-julia-fatou| languageserver........................|ale-julia-languageserver| kotlin..................................|ale-kotlin-options| kotlinc...............................|ale-kotlin-kotlinc| diff --git a/supported-tools.md b/supported-tools.md index b6cdf959d..376404dfb 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -396,6 +396,7 @@ formatting. * [jsonnet-lint](https://jsonnet.org/learning/tools.html) :speech_balloon: * [jsonnetfmt](https://jsonnet.org/learning/tools.html) :speech_balloon: * Julia + * [fatou](https://github.com/jolars/fatou) :speech_balloon: * [languageserver](https://github.com/JuliaEditorSupport/LanguageServer.jl) * Kotlin * [kotlinc](https://kotlinlang.org) :floppy_disk: diff --git a/test/fixers/test_fatou_fixer_callback.vader b/test/fixers/test_fatou_fixer_callback.vader new file mode 100644 index 000000000..c03aa3421 --- /dev/null +++ b/test/fixers/test_fatou_fixer_callback.vader @@ -0,0 +1,20 @@ +Before: + call ale#assert#SetUpFixerTest('julia', 'fatou') + +After: + call ale#assert#TearDownFixerTest() + +Execute(The default command should be correct): + AssertFixer + \ { + \ 'command': ale#Escape('fatou') . ' format', + \ } + +Execute(The executable and options should be configurable): + let g:ale_julia_fatou_executable = 'foobar' + let g:ale_julia_fatou_options = '--line-width 80' + + AssertFixer + \ { + \ 'command': ale#Escape('foobar') . ' format --line-width 80', + \ } diff --git a/test/linter/test_julia_fatou.vader b/test/linter/test_julia_fatou.vader new file mode 100644 index 000000000..df6657e16 --- /dev/null +++ b/test/linter/test_julia_fatou.vader @@ -0,0 +1,23 @@ +Before: + call ale#assert#SetUpLinterTest('julia', 'fatou') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The default executable path should be correct): + AssertLinter 'fatou', ale#Escape('fatou') . ' lsp' + +Execute(The executable should be configurable): + let g:ale_julia_fatou_executable = '/path/to/fatou' + + AssertLinter '/path/to/fatou', ale#Escape('/path/to/fatou') . ' lsp' + +Execute(The project root should be detected correctly with a configuration file): + call ale#test#SetFilename('../test-files/fatou/subdir/file.jl') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/fatou') + +Execute(The project root should be empty when no project files can be detected): + call ale#test#SetFilename('../test-files/dummy') + + AssertLSPProject '' diff --git a/test/test-files/fatou/fatou.toml b/test/test-files/fatou/fatou.toml new file mode 100644 index 000000000..e69de29bb diff --git a/test/test-files/fatou/subdir/file.jl b/test/test-files/fatou/subdir/file.jl new file mode 100644 index 000000000..e69de29bb