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. diff --git a/autoload/ale/fixers/erlfmt.vim b/autoload/ale/fixers/erlfmt.vim index f9951e9dd3..d76316d1bb 100644 --- a/autoload/ale/fixers/erlfmt.vim +++ b/autoload/ale/fixers/erlfmt.vim @@ -4,18 +4,49 @@ 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) + +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:executable = ale#fixers#erlfmt#GetExecutable(a:buffer) + let l:use_rebar = ale#Var(a:buffer, 'erlang_erlfmt_use_rebar') + + if l:use_rebar + 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) + 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 - let l:command = ale#Escape(l:executable) . (empty(l:options) ? '' : ' ' . l:options) . ' %s' + 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(''))