15

I started using syntastic plugin with vim to report lint errors in my javascript code.

I also integrated eslint with syntastic, and it shows me nice errors, warnings in case they are present as per rules written in my .eslintrc file.

Is there any way in which I can fix some common errors e.g missing semi-colon, missing space etc with a key-stroke?

Edit:

I have found that eslint has an option

  --fix Automatically fix problems

which can be used for such cases. I need to run this command to let eslint fix those issues

eslint --fix -c myconfig file.js

I want to know how that can be integrated with vim?

6
  • 5
    1. You don't need that plugin for syntax checking. 2. Auto fixing errors is a very bad idea.
    – romainl
    Jun 22, 2016 at 20:19
  • 1
    Not all errors I am talking about errors such as space around =, space around if block, indentation etc. These are errors related to code styles, not actual errors.
    – WitVault
    Jun 22, 2016 at 20:33
  • 1
    The short answer is yes, of course you can. You'd need to define a custom function to parse the lines in the quickfix looking for the specific errors that you wanted to fix, and execute a command based on those errors. You could easily use the quickfix to take you to the location of each error as well. You'd then map the function to a keystroke. map <C-j> call Function()<CR> But this would be a very custom tailored function that you would need to write to suit your needs. And romainl's point is that if you do something wrong you can easily end up doing more harm than good. Caution is advised
    – Tumbler41
    Jun 22, 2016 at 21:02
  • 1
    Use a pretty printer to enforce consistent formatting.
    – lcd047
    Jun 23, 2016 at 5:23
  • 1
    I need to run this command to let eslint fix those issues - I'm handing you the gun since you're asking, but it's still pointing at your foot: fixmyjs (first hit on Google), and also see a related answer on SO. You really should consider changing these to run vimdiff against the original and the patched versions, rather than replace the original.
    – lcd047
    Jun 23, 2016 at 16:12

2 Answers 2

13

As mentioned in the comments be aware of the consequences this modification has to you work environment (know exactly which eslint rules you use to "fix" things).

To answer your question: adding the option to the eslint execution with syntactic is straight forward. Simply add this to your .vimrc:

" execute eslint with --fix flag
let g:syntastic_javascript_eslint_args = ['--fix']

But as eslint is executed on the file after vim writes its buffer to the file, vim doesn't know about the fixes eslint does. So somehow vim has to load the file again (the manual way would be to simply type :e in normal/command mode). To do that, we can use the autoread option together with checktime:

" enable autoread to reload any files from files when checktime is called and
" the file is changed
set autoread

To call checktime we can use an autocmd which gets executed every time a buffer is written to a file. But as syntactic is using its own autocmd on same event BufWritePost we have to add our autocmd after syntactic adds its own. I found that this is the case when we add our autocmd on VimEnter:

" add an autocmd after vim started to execute checktime for *.js files on write
au VimEnter *.js au BufWritePost *.js checktime

So after adding all three parts to your .vimrc vim should behave as expected (lint and autocorrect on file save :w).

0
7

The solution given in Jepz's answer didn't completely work for me. eslint was correctly called with the --fix option. However, maybe it's because of internals that have changed, but it seems like checktime was called before the end of eslint --fix, so the file reloading didn't work properly, triggering a file has changed, are you sure you want to write to it? on the next save.

However, by digging into issues, I've discovered a hidden hook that seems to trigger after the Syntastic checks have completed, called SyntasticCheckHook (source).

With this, you can simply call checktime after the Syntastic checks have run.

Here is my final code:

set autoread

let g:syntastic_javascript_checkers = ['eslint']

" autofix with eslint
let g:syntastic_javascript_eslint_args = ['--fix']
function! SyntasticCheckHook(errors)
  checktime
endfunction

Edit: I've personally switched to ALE for linting, which supports autofixing natively.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.