Search code examples
functionneovimrubocoplinter

ALE Fixer Configuration in Neovim


I want to configure my Ruby fixer to perform the following sequence:

  1. Turn syntax off
  2. Run the rubocop fixer
  3. Turn syntax on

According to :help ale-fix-configuration:

Synchronous functions and asynchronous jobs will be run in a sequence for fixing files, and can be combined. For example:

  let g:ale_fixers = {
  \   'javascript': [
  \       'DoSomething',
  \       'eslint',
  \       {buffer, lines -> filter(lines, 'v:val !=~ ''^\s*//''')},
  \   ],
  \}

I tried to follow the example:

function! SyntaxTurnOff()
  exec "syntax off"
endfunction

function! SyntaxTurnOn()
  exec "syntax on"
endfunction

" FIXERS
let g:ale_fixers = {
      \   '*': ['remove_trailing_lines', 'trim_whitespace'],
      \ 'ruby': [
      \ 'SyntaxTurnOff',
      \ 'rubocop',
      \ 'SyntaxTurnOn',
      \],
      \ 'python': ['flake8'],
      \ 'json': ['jq'],
      \}

However, when I try to execute it by calling :ALEFix in the editor, I get the following error:

Error detected while processing function ale#fix#Fix[37]..<SNR>305_RunFixer:                                                                                                          
line   17:
E118: Too many arguments for function: SyntaxTurnOff

What am I doing wrong?


Solution

  • I found another way to make this work.

    Rather than trying to sequence function calls within the fixers Object, I used autogroups instead.

    First I defined the following functions:

    function! SyntaxTurnOff()
      "Turns syntax off only in current buffer
      exec "syntax clear"
    endfunction
    
    function! SyntaxTurnOn()
      exec "syntax on"
    endfunction
    

    Then, I used the built-in ALEFixPre and ALEFixPost autocommands:

    augroup YourGroup
        autocmd!
        autocmd User ALEFixPre     call SyntaxTurnOff()
        autocmd User ALEFixPost    call SyntaxTurnOn()
    augroup END
    

    My fixers are back to their previous, simple configuration.

    " FIXERS
    let g:ale_fixers = {
          \   '*': ['remove_trailing_lines', 'trim_whitespace'],
          \ 'ruby': ['rubocop'],
          \ 'python': ['flake8'],
          \ 'json': ['jq'],
          \}
    

    I'd be happy to hear of a better way, but this works for me, and I hope it helps someone else.

    This came about because I had a 400-line file that was incredibly slow to fix, not because of rubocop, but because of syntax highlighting in Neovim. Before, running ALEFix would hold up that buffer for ages; now it's not instantaneous but it's pretty fast. To be fair, it's not due to ALEFix as such but rather to whatever Neovim has to do to redraw the buffer with syntax highlighting.