Tip 12Linting the Current File

The ALE plugin runs linting tools asynchronously on your buffer. Errors and warnings are marked with signs to make them easily visible, and you can quickly jump between them using the navigation commands provided. In this tip, you’ll install the ALE plugin and eslint tool and use them to find and repair errors in a sample JavaScript file. You’ll also learn how to configure ALE so that it runs your preferred linting tools for each specified filetype. And you’ll learn of various ways to configure ALE so that it runs linters when manually invoked, or automatically in response to various events.

Preparation

To follow the examples in this tip, you’ll need to install Andrew Wray’s ALE plugin.[27] ALE stands for asynchronous linting engine. You can install it into your bundle package like this:

=> $ cd $VIMCONFIG/pack/bundle/start
=> $ git clone https://github.com/w0rp/ale.git

Run :helptags ALL, then you can find extensive documentation for the plugin by looking up :help ale. Next, add the following lines to your vimrc file:

 " For JavaScript files, use `eslint` (and only eslint)
 let​ g:ale_linters = {
 ​ ​'javascript'​: [​'eslint'​],
 ​ }
 
 " Mappings in the style of unimpaired-next
 nmap <​silent​> [W <Plug>(ale_first)
 nmap <​silent​> [​w​ <Plug>(ale_previous)
 nmap <​silent​> ]​w​ <Plug>(ale_next)
 nmap <​silent​> ]W <Plug>(ale_last)

Setting the g:ale_linters variable this way means that when you open JavaScript files, ALE will perform linting with the eslint tool.

You’ll need the ale_first, ale_previous, ale_next, and ale_last mappings to traverse the list of warnings produced by linting tools. I’ve suggested mappings in the style of Tim Pope’s Unimpaired plugin[28] (mnemonic: “w” is for warning), but feel free to customize these to your own taste.

Setting Up the Demo Project

The source code that accompanies this book includes a linting directory. Switch to that directory and use npm to install eslint and its dependencies:

=> $ cd code/linting
=> $ npm install
<= [email protected] /Users/drew/modvim/code/linting
 └── [email protected]
 ...

You’ll be using the eslint tool to find some deliberate mistakes in the sample code.

Running eslint from the Command Line

The date-in.js file looks like this:

1: exports.dateIn = (count=0, unit=​'days'​) => {
const​ now = ​new​ Date();
const​ dayInMs = 1000 * 60 * 60 * 24;
const​ offset = 0;
5: 
if​ (​/^days​​?​​$/​.test(unit)) {
offset = count * dayInMs;
} ​else​ ​if​ (​/^weeks​​?​​$/​.test(unit)) {
offset = count * dayInMs * 7;
10:  }
const​ targetDate = ​new​ Date(now.getTime() + offset);
return​ targetDate.toISOString().slice(0, 10)
};

It contains a couple of deliberate mistakes. To identify them, run eslint on the date-in.js file like this:

=> $ ./node_modules/.bin/eslint date-in.js
<= 
 /Users/drew/modvim/code/linting/date-in.js
  1:33 error Strings must use doublequote quotes
  7:5 error 'offset' is constant no-const-assign
  9:5 error 'offset' is constant no-const-assign
 13:47 error Missing semicolon semi
 
 ✖ 4 problems (4 errors, 0 warnings)

(Take a look at .eslintrc.json if you want to see how the eslint rules have been configured.)

eslint raised four problems. Each is listed with a line number, a column number, a message, and an identifier for the rule that was violated. For example, on line 1 at column 33, the quotes rule raised the error “Strings must use doublequote.”

To fix these, you could navigate to them one by one using Vim’s regular navigation commands. For example, 1G followed by 33| would move your cursor to the address of the first error. But it would be more convenient if Vim would parse the list and use it to generate a list of locations for you to jump between. In the next part of this tip, we’ll see how to do this.

Meet the Asynchronous Linting Engine

Open the date-in.js file in Vim:

=> $ cd code/linting
=> $ vim date-in.js

If you’ve correctly installed ALE and eslint, you should see something like the following screenshot:

images/ale-errors.png

At the left of the screen you can see Vim’s sign column (also known as the “gutter”), where a symbol draws attention to each line containing a warning. The characters where a warning occurs are underlined, although this styling may appear different for you depending on your chosen color scheme.

You can quickly jump forward and back between warnings using the ]w and [w mappings that you set up earlier. Note that as your cursor visits each warning, the error message is printed at the bottom of the screen. For example: jump to the first warning by pressing [W, then you’ll see the message “Strings must use doublequote.”

Now, go ahead and fix each of those warnings. Use whatever method feels most comfortable for you, but if you get stuck, try running these commands:

=> :1s/'/"/g
=> :4s/const/let
=> :13normal A;

Every time you change the buffer, ALE automatically re-runs eslint. You should see the warning markers disappearing moments after you fix each issue. Note that you don’t even have to save the buffer for ALE to perform linting.

Specifying Which Linters to Run

Out of the box, ALE supports linting tools for many different programming languages. For some languages, ALE supports multiple linters out of the box. To find out which tools are supported for the current filetype, run the following:

=> :ALEInfo
<= Current Filetype: javascript
 Available Linters: ['eslint', 'flow', 'jscs', 'jshint', 'standard', 'xo']
 Enabled Linters: ['eslint']
 Linter Variables:
 let g:ale_javascript_eslint_executable = 'eslint'
 let g:ale_javascript_eslint_options = ''
 let g:ale_javascript_eslint_use_global = 0
 ...

For JavaScript files, ALE can use any of these linting tools: eslint,[29] jscs,[30] jshint,[31] flow,[32] standard,[33] and xo.[34] If you have none of these tools installed, ALE won’t perform any linting on your JavaScript files. If you have all of these tools installed, ALE will run each linter on your JavaScript file, collecting all the results together. This behavior works nicely if you have two linting tools that complement each other. But the more linters you run, the greater the chance you’ll end up with the same error being reported more than once.

To specify which linters you want to run for each filetype, use the g:ale_linters variable (:help g:ale_linters). Earlier on, we set g:ale_linters.javascript to [’eslint’]. This ensured that only eslint would run, even if some of the other JavaScript linters had been available on your system.

Specifying When to Run Linters

By default, ALE automatically runs linters whenever the text in a buffer changes. You might like this behavior, or you might find it distracting. It’s a matter of personal preference. ALE provides configuration options, which let you specify how often linters are run with some granularity. In this section, we’ll look at a few different ways of setting up ALE.

The sign column is only visible when a buffer contains errors. If you find it distracting that the sign column appears and disappears while you’re typing, you’ll want to set the g:ale_sign_column_always variable to 1. Put this in your vimrc file (the lines marked default are included for illustration purposes):

 let​ g:ale_lint_on_text_changed = ​'always'​ " default
 let​ g:ale_lint_on_save = 1 " default
 let​ g:ale_lint_on_enter = 1 " default
 let​ g:ale_lint_on_filetype_changed = 1 " default
 let​ g:ale_sign_column_always = 1

If you’d prefer to have ALE run linters only when a buffer is saved, you could put this in your vimrc:

 let​ g:ale_lint_on_text_changed = ​'never'
 let​ g:ale_lint_on_save = 1 " default
 let​ g:ale_lint_on_enter = 0
 let​ g:ale_lint_on_filetype_changed = 0

Alternatively, you might prefer to have ALE run linters only when you invoke it by hand. If so, you can disable all autocommands. For convenience, you might also want to create a mapping to trigger the :ALELint command:

 nnoremap <Leader>​l​ :ALELint<CR>
 let​ g:ale_lint_on_text_changed = ​'never'
 let​ g:ale_lint_on_save = 0
 let​ g:ale_lint_on_enter = 0
 let​ g:ale_lint_on_filetype_changed = 0

One thing is common with all of these configurations: ALE always runs linters asynchronously. Whichever method you choose, you’ll always be able to continue operating Vim while ALE is running linters.

Alternatives to ALE

Besides ALE, other linting plugins are available for Vim. Syntastic[35] is the most mature linting plugin, and it supports more linting tools and programming languages than any of the others. At present, Syntastic doesn’t make use of the job control functionality, so Vim is blocked while linting.

Neomake[36] is another linting plugin that runs asynchronously. As well as running linters on an individual file, Neomake supports running commands that operate on an entire project.

I encourage you to evaluate these plugins and weigh up the pros and cons for yourself. By their nature, these plugins don’t play well together, so you’ll have to pick one of them and uninstall the others.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.183.150