diff --git a/README.md b/README.md index d255469..9ddf89a 100644 --- a/README.md +++ b/README.md @@ -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. 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__. 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. diff --git a/plugin/defaults.vim b/plugin/defaults.vim index 01897f5..4fb992c 100644 --- a/plugin/defaults.vim +++ b/plugin/defaults.vim @@ -160,6 +160,82 @@ if !exists('g:formatdef_xo_javascript') let g:formatdef_xo_javascript = '"xo --fix --stdin"' 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('')) +endif + if !exists('g:formatters_javascript') let g:formatters_javascript = [ \ 'jsbeautify_javascript',