Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to use rebar3 fmt instead of standalone erlfmt #4811

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions autoload/ale/fix/registry.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
37 changes: 34 additions & 3 deletions autoload/ale/fixers/erlfmt.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be clearer if the two cases were handled in separate functions, like this:

function! ale#fixers#erlfmt#Fix(buffer) abort
    return ale#Var(a:buffer, 'erlang_erlfmt_use_rebar3')
    \   ? s:FixWithRebar3(a:buffer)
    \   : s:FixWithEscript(a:buffer)
endfunction

However, it seems to me that from user's perspective it would be better to add separate rebar3_fmt fixer.

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
26 changes: 26 additions & 0 deletions doc/ale-erlang.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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*

Expand Down Expand Up @@ -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*

Expand Down
46 changes: 39 additions & 7 deletions test/fixers/test_erlfmt_fixer_callback.vader
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
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

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(''))

Expand All @@ -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(''))