feature: implement local ESLint support

Support to use the project local eslint installation to be used to
reformat javascript source with the eslint --fix command
This commit is contained in:
Christian Hubinger 2017-03-12 01:23:40 +01:00
parent 42adced250
commit 0f90dc3a0f
2 changed files with 86 additions and 0 deletions

View File

@ -158,6 +158,16 @@ Here is a list of formatprograms that are supported by default, and thus will be
It can be installed by running `npm install -g standard` (`nodejs` is required). No more configuration needed. It can be installed by running `npm install -g standard` (`nodejs` is required). No more configuration needed.
More information about the style guide can be found here: http://standardjs.com/. More information about the style guide can be found here: http://standardjs.com/.
* `ESlint (local)` for __Javascript__. http://eslint.org/
It can be installed by running `npm install eslint`. The linter is then installed locally at ```node_modules/.bin/eslint```
When opening a javascript file (```vim autocmd FileType javscript```) vim will walk up from the current file to search for such local installation and a
ESLint configuration file (either .eslintrc or eslintrc.json). When both are found eslint will be configured as first javascript formatter.
This linter can be disabled using global setting
```vim
let g:formatters_javascript_eslint_local = 0
```
Currently only working on *nix like OS (Linux, MacOS etc.) requires OS to provide sh like shell syntax
* `xo` for __Javascript__. * `xo` for __Javascript__.
It can be installed by running `npm install -g xo` (`nodejs` is required). It can be installed by running `npm install -g xo` (`nodejs` is required).
Here is the link to the repository: https://github.com/sindresorhus/xo. Here is the link to the repository: https://github.com/sindresorhus/xo.

View File

@ -160,6 +160,82 @@ if !exists('g:formatdef_xo_javascript')
let g:formatdef_xo_javascript = '"xo --fix --stdin"' let g:formatdef_xo_javascript = '"xo --fix --stdin"'
endif endif
" Setup ESLint local. Setup is done for each file in an autocmd to make sure
" the most local instance of ESLint and corresponding config is used.
" No windows support at the moment.
if !exists('g:formatdef_eslint_local') && !has('win32')
" set disable flag when not defined already
let g:formatters_javascript_eslint_local = exists('g:formatters_javascript_eslint_local') ? g:formatters_javascript_eslint_local : 1
" find file upwards the filesystem
function! s:find_upward(path, filename)
let l:current_folder = fnamemodify(a:path, ':p:h')
if l:current_folder == "/"
return
endif
let l:prog = l:current_folder.a:filename
if filereadable(l:prog)
return l:prog
elseif l:current_folder == "/"
return
else
return s:find_upward(fnamemodify(l:current_folder, ':h'), a:filename)
endif
endfunction
" add 'eslint_local' as first javscript formatter
function s:register_eslint_local()
let l:index = index(g:formatters_javascript, 'eslint_local')
if l:index == -1
call insert(g:formatters_javascript, 'eslint_local', 0)
endif
endfunction
" remmove 'eslint_local' from javscript formatters
function s:unregister_eslint_local()
let l:index = index(g:formatters_javascript, 'eslint_local')
if l:index != -1
call remove(g:formatters_javascript, l:index)
endif
endfunction
function! s:setup_eslint_local_cmd(path)
let verbose = &verbose || g:autoformat_verbosemode == 1
if g:formatters_javascript_eslint_local == 0
echomsg 'Disable ESLint local'
call s:unregister_eslint_local()
return
endif
" find formatter & config file
let l:prog = s:find_upward(a:path, '/node_modules/.bin/eslint')
let l:cfg = s:find_upward(a:path, '/.eslintrc.json')
if empty(l:cfg)
let l:cfg = s:find_upward(a:path, '/.eslintrc')
endif
if (empty(l:cfg) || empty(l:prog))
if verbose
echomsg 'No local ESLint program and/or config found'
endif
call s:unregister_eslint_local();
return
endif
" This formatter uses a temporary file as ESLint has not option to only
" print the formatted source to stdout. It will allways modify the file
" in place.
if !exists('l:eslint_js_tmp_file')
let l:eslint_js_tmp_file = fnameescape(tempname().".js")
endif
let g:formatdef_eslint_local =
\ '"rm -f '.l:eslint_js_tmp_file.';
\ cat '.expand('%').' > '.l:eslint_js_tmp_file.'; '
\ .l:prog.' -c '.l:cfg.' --fix '.l:eslint_js_tmp_file.' 1> /dev/null; exit_code=$?
\ cat '.l:eslint_js_tmp_file.'; rm -f '.l:eslint_js_tmp_file.'; exit $exit_code"'
call s:register_eslint_local()
endfunction
" register hook to setup lint command correctly for the current file
autocmd FileType javascript call s:setup_eslint_local_cmd(expand('<afile>'))
endif
if !exists('g:formatters_javascript') if !exists('g:formatters_javascript')
let g:formatters_javascript = [ let g:formatters_javascript = [
\ 'jsbeautify_javascript', \ 'jsbeautify_javascript',