From 73afd2e26220d25cd2b7a0a0f54e13c78922d2b5 Mon Sep 17 00:00:00 2001 From: Kohei YOSHIDA Date: Wed, 31 Jul 2024 21:00:39 +0900 Subject: [PATCH 1/3] Add option to use `rebar3 fmt` instead of standalone `erlfmt` for erlfmt fixer --- autoload/ale/erlang.vim | 9 ++++ autoload/ale/fixers/erlfmt.vim | 30 +++++++++++-- doc/ale-erlang.txt | 26 +++++++++++ test/fixers/test_erlfmt_fixer_callback.vader | 46 +++++++++++++++++--- 4 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 autoload/ale/erlang.vim diff --git a/autoload/ale/erlang.vim b/autoload/ale/erlang.vim new file mode 100644 index 0000000000..d83ae78d2e --- /dev/null +++ b/autoload/ale/erlang.vim @@ -0,0 +1,9 @@ +" Author: Kohei YOSHIDA - https://github.com/yosida95 +" Description: Helper functions for Erlang tools + +call ale#Set('erlang_rebar_executable', 'rebar3') +call ale#Set('erlang_rebar_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#erlang#GetRebarExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'erlang_rebar', ['rebar3']) +endfunction diff --git a/autoload/ale/fixers/erlfmt.vim b/autoload/ale/fixers/erlfmt.vim index f9951e9dd3..258b6456b5 100644 --- a/autoload/ale/fixers/erlfmt.vim +++ b/autoload/ale/fixers/erlfmt.vim @@ -4,6 +4,7 @@ call ale#Set('erlang_erlfmt_executable', 'erlfmt') call ale#Set('erlang_erlfmt_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('erlang_erlfmt_options', '') +call ale#Set('erlang_erlfmt_use_rebar', 0) function! ale#fixers#erlfmt#GetExecutable(buffer) abort return ale#path#FindExecutable(a:buffer, 'erlang_erlfmt', ['erlfmt']) @@ -11,11 +12,34 @@ endfunction function! ale#fixers#erlfmt#Fix(buffer) abort let l:options = ale#Var(a:buffer, 'erlang_erlfmt_options') - let l:executable = ale#fixers#erlfmt#GetExecutable(a:buffer) + let l:use_rebar = ale#Var(a:buffer, 'erlang_erlfmt_use_rebar') - let l:command = ale#Escape(l:executable) . (empty(l:options) ? '' : ' ' . l:options) . ' %s' + if l:use_rebar + let l:executable = ale#erlang#GetRebarExecutable(a:buffer) + let l:command = [ale#Escape(l:executable), 'fmt'] + else + let l:executable = ale#fixers#erlfmt#GetExecutable(a:buffer) + let l:command = [ale#Escape(l:executable)] + endif + + if !empty(l:options) + call add(l:command, l:options) + endif + + let l:read_temporary_file = 0 + + if l:use_rebar + " As rebar3 emits error messages to STDOUT rather than STDERR, read the + " temporary file to prevent the buffer from being overridden by error + " messages. + call extend(l:command, ['--write', '%t']) + let l:read_temporary_file = 1 + else + call add(l:command, '-') + endif return { - \ 'command': l:command + \ 'command': join(l:command, ' '), + \ 'read_temporary_file': l:read_temporary_file, \} endfunction diff --git a/doc/ale-erlang.txt b/doc/ale-erlang.txt index 2c6ff22a2f..e00e78146b 100644 --- a/doc/ale-erlang.txt +++ b/doc/ale-erlang.txt @@ -2,6 +2,22 @@ ALE Erlang Integration *ale-erlang-options* +g:ale_erlang_rebar_executable *g:ale_erlang_rebar_executable* + *b:ale_erlang_rebar_executable* + Type: |String| + Default: `rebar3` + + See |ale-integrations-local-executables| + + +g:ale_erlang_rebar_use_global *g:ale_erlang_rebar_use_global* + *b:ale_erlang_rebar_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== dialyzer *ale-erlang-dialyzer* @@ -116,6 +132,16 @@ g:ale_erlang_erlfmt_options *g:ale_erlang_erlfmt_options* `--insert-pragma` or `--print-width`. +g:ale_erlang_erlfmt_use_rebar + *g:ale_erlang_erlfmt_use_rebar* + *b:ale_erlang_erlfmt_use_rebar* + Type: |Number| + Default: 0 + + Whether to use `erlfmt` as a rebar plugin by invoking `rebar3 fmt` or + as a standalone `erlfmt` command. + + ------------------------------------------------------------------------------- syntaxerl *ale-erlang-syntaxerl* diff --git a/test/fixers/test_erlfmt_fixer_callback.vader b/test/fixers/test_erlfmt_fixer_callback.vader index 132cd6eefe..71df93e269 100644 --- a/test/fixers/test_erlfmt_fixer_callback.vader +++ b/test/fixers/test_erlfmt_fixer_callback.vader @@ -1,9 +1,7 @@ Before: - Save b:ale_elm_format_executable - Save b:ale_elm_format_options - - let b:ale_elm_format_executable = 'erlfmt' - let b:ale_elm_format_options = '' + Save b:ale_erlang_erlfmt_options + Save b:ale_erlang_erlfmt_use_rebar + Save b:ale_erlang_rebar_executable After: Restore @@ -11,7 +9,8 @@ After: Execute(The erlfmt command should handle empty options): AssertEqual \ { - \ 'command': ale#Escape('erlfmt') . ' %s' + \ 'command': ale#Escape('erlfmt') . ' -', + \ 'read_temporary_file': 0, \ }, \ ale#fixers#erlfmt#Fix(bufnr('')) @@ -20,6 +19,39 @@ Execute(The erlfmt command should handle custom options): AssertEqual \ { - \ 'command': ale#Escape('erlfmt') . ' --insert-pragma %s' + \ 'command': ale#Escape('erlfmt') . ' --insert-pragma -', + \ 'read_temporary_file': 0, + \ }, + \ ale#fixers#erlfmt#Fix(bufnr('')) + +Execute(The erlfmt command should be able to be invoked by rebar3): + let b:ale_erlang_erlfmt_use_rebar = 1 + + AssertEqual + \ { + \ 'command': ale#Escape('rebar3') . ' fmt --write %t', + \ 'read_temporary_file': 1, + \ }, + \ ale#fixers#erlfmt#Fix(bufnr('')) + +Execute(The erlfmt command should be able to be invoked by rebar3 with custom options): + let b:ale_erlang_erlfmt_options = '--insert-pragma' + let b:ale_erlang_erlfmt_use_rebar = 1 + + AssertEqual + \ { + \ 'command': ale#Escape('rebar3') . ' fmt --insert-pragma --write %t', + \ 'read_temporary_file': 1, + \ }, + \ ale#fixers#erlfmt#Fix(bufnr('')) + +Execute(The rebar executable path should be configurable): + let b:ale_erlang_rebar_executable = '/path/to/rebar3' + let b:ale_erlang_erlfmt_use_rebar = 1 + + AssertEqual + \ { + \ 'command': ale#Escape('/path/to/rebar3') . ' fmt --write %t', + \ 'read_temporary_file': 1, \ }, \ ale#fixers#erlfmt#Fix(bufnr('')) From ce1e84334cd8aebbad4147432c2ed2840db243ee Mon Sep 17 00:00:00 2001 From: Kohei YOSHIDA Date: Wed, 31 Jul 2024 22:38:47 +0900 Subject: [PATCH 2/3] Add erlfmt to fixers registry --- autoload/ale/fix/registry.vim | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 38a87153f5..7e8de37f3f 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -666,6 +666,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['ruby'], \ 'description': 'A formatter for Ruby source code', \ }, +\ 'erlfmt': { +\ 'function': 'ale#fixers#erlfmt#Fix', +\ 'suggested_filetypes': ['erlang'], +\ 'description': 'Code formatter for Erlang', +\ }, \} " Reset the function registry to the default entries. From 75a194583c0f54896c3016cfce0299f35a0dc963 Mon Sep 17 00:00:00 2001 From: Kohei YOSHIDA Date: Fri, 2 Aug 2024 16:28:07 +0900 Subject: [PATCH 3/3] Move Erlang helpers to the file with erlfmt fixer to reduce runtime cost --- autoload/ale/erlang.vim | 9 --------- autoload/ale/fixers/erlfmt.vim | 9 ++++++++- 2 files changed, 8 insertions(+), 10 deletions(-) delete mode 100644 autoload/ale/erlang.vim diff --git a/autoload/ale/erlang.vim b/autoload/ale/erlang.vim deleted file mode 100644 index d83ae78d2e..0000000000 --- a/autoload/ale/erlang.vim +++ /dev/null @@ -1,9 +0,0 @@ -" Author: Kohei YOSHIDA - https://github.com/yosida95 -" Description: Helper functions for Erlang tools - -call ale#Set('erlang_rebar_executable', 'rebar3') -call ale#Set('erlang_rebar_use_global', get(g:, 'ale_use_global_executables', 0)) - -function! ale#erlang#GetRebarExecutable(buffer) abort - return ale#path#FindExecutable(a:buffer, 'erlang_rebar', ['rebar3']) -endfunction diff --git a/autoload/ale/fixers/erlfmt.vim b/autoload/ale/fixers/erlfmt.vim index 258b6456b5..d76316d1bb 100644 --- a/autoload/ale/fixers/erlfmt.vim +++ b/autoload/ale/fixers/erlfmt.vim @@ -6,16 +6,23 @@ call ale#Set('erlang_erlfmt_use_global', get(g:, 'ale_use_global_executables', 0 call ale#Set('erlang_erlfmt_options', '') call ale#Set('erlang_erlfmt_use_rebar', 0) +call ale#Set('erlang_rebar_executable', 'rebar3') +call ale#Set('erlang_rebar_use_global', get(g:, 'ale_use_global_executables', 0)) + function! ale#fixers#erlfmt#GetExecutable(buffer) abort return ale#path#FindExecutable(a:buffer, 'erlang_erlfmt', ['erlfmt']) endfunction +function! ale#fixers#erlfmt#GetRebarExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'erlang_rebar', ['rebar3']) +endfunction + function! ale#fixers#erlfmt#Fix(buffer) abort let l:options = ale#Var(a:buffer, 'erlang_erlfmt_options') let l:use_rebar = ale#Var(a:buffer, 'erlang_erlfmt_use_rebar') if l:use_rebar - let l:executable = ale#erlang#GetRebarExecutable(a:buffer) + let l:executable = ale#fixers#erlfmt#GetRebarExecutable(a:buffer) let l:command = [ale#Escape(l:executable), 'fmt'] else let l:executable = ale#fixers#erlfmt#GetExecutable(a:buffer)