From 7c2a5052a850a6e7df10c2b4f84fd5b343175d8d Mon Sep 17 00:00:00 2001 From: w0rp Date: Thu, 31 Aug 2017 13:12:24 +0100 Subject: [PATCH] Fix #895 - Run Node.js scripts with node.exe instead of node on Windows --- ale_linters/javascript/standard.vim | 10 +--------- autoload/ale/fixers/eslint.vim | 10 +--------- autoload/ale/fixers/standard.vim | 10 +--------- autoload/ale/fixers/stylelint.vim | 10 +--------- autoload/ale/handlers/eslint.vim | 10 +--------- autoload/ale/node.vim | 20 +++++++++++++++++++ doc/ale.txt | 16 +++++++++++++++ .../test_standard_command_callback.vader | 2 +- test/fixers/test_eslint_fixer_callback.vader | 2 +- .../fixers/test_standard_fixer_callback.vader | 2 +- .../test_stylelint_fixer_callback.vader | 2 +- test/test_eslint_executable_detection.vader | 6 +++--- 12 files changed, 48 insertions(+), 52 deletions(-) diff --git a/ale_linters/javascript/standard.vim b/ale_linters/javascript/standard.vim index fc534eb..aa6a3a7 100644 --- a/ale_linters/javascript/standard.vim +++ b/ale_linters/javascript/standard.vim @@ -14,17 +14,9 @@ endfunction function! ale_linters#javascript#standard#GetCommand(buffer) abort let l:executable = ale_linters#javascript#standard#GetExecutable(a:buffer) - - if ale#Has('win32') && l:executable =~? '\.js$' - " .js files have to be executed with Node on Windows. - let l:head = 'node ' . ale#Escape(l:executable) - else - let l:head = ale#Escape(l:executable) - endif - let l:options = ale#Var(a:buffer, 'javascript_standard_options') - return l:head + return ale#node#Executable(a:buffer, l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' --stdin %s' endfunction diff --git a/autoload/ale/fixers/eslint.vim b/autoload/ale/fixers/eslint.vim index ce65c48..892b30d 100644 --- a/autoload/ale/fixers/eslint.vim +++ b/autoload/ale/fixers/eslint.vim @@ -28,16 +28,8 @@ function! ale#fixers#eslint#Fix(buffer) abort return 0 endif - if ale#Has('win32') && l:executable =~? 'eslint\.js$' - " For Windows, if we detect an eslint.js script, we need to execute - " it with node, or the file can be opened with a text editor. - let l:head = 'node ' . ale#Escape(l:executable) - else - let l:head = ale#Escape(l:executable) - endif - return { - \ 'command': l:head + \ 'command': ale#node#Executable(a:buffer, l:executable) \ . ' --config ' . ale#Escape(l:config) \ . ' --fix %t', \ 'read_temporary_file': 1, diff --git a/autoload/ale/fixers/standard.vim b/autoload/ale/fixers/standard.vim index 6a0c6b6..443560e 100644 --- a/autoload/ale/fixers/standard.vim +++ b/autoload/ale/fixers/standard.vim @@ -11,16 +11,8 @@ endfunction function! ale#fixers#standard#Fix(buffer) abort let l:executable = ale#fixers#standard#GetExecutable(a:buffer) - if ale#Has('win32') && l:executable =~? 'cmd\.js$' - " For Windows, if we detect an standard.js script, we need to execute - " it with node, or the file can be opened with a text editor. - let l:head = 'node ' . ale#Escape(l:executable) - else - let l:head = ale#Escape(l:executable) - endif - return { - \ 'command': l:head + \ 'command': ale#node#Executable(a:buffer, l:executable) \ . ' --fix %t', \ 'read_temporary_file': 1, \} diff --git a/autoload/ale/fixers/stylelint.vim b/autoload/ale/fixers/stylelint.vim index 7d5abb7..899fcf4 100644 --- a/autoload/ale/fixers/stylelint.vim +++ b/autoload/ale/fixers/stylelint.vim @@ -15,16 +15,8 @@ endfunction function! ale#fixers#stylelint#Fix(buffer) abort let l:executable = ale#fixers#stylelint#GetExecutable(a:buffer) - if ale#Has('win32') && l:executable =~? 'stylelint\.js$' - " For Windows, if we detect an stylelint.js script, we need to execute - " it with node, or the file can be opened with a text editor. - let l:head = 'node ' . ale#Escape(l:executable) - else - let l:head = ale#Escape(l:executable) - endif - return { - \ 'command': l:head + \ 'command': ale#node#Executable(a:buffer, l:executable) \ . ' --fix %t', \ 'read_temporary_file': 1, \} diff --git a/autoload/ale/handlers/eslint.vim b/autoload/ale/handlers/eslint.vim index 6c5d75c..4ef7489 100644 --- a/autoload/ale/handlers/eslint.vim +++ b/autoload/ale/handlers/eslint.vim @@ -17,17 +17,9 @@ endfunction function! ale#handlers#eslint#GetCommand(buffer) abort let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) - if ale#Has('win32') && l:executable =~? 'eslint\.js$' - " For Windows, if we detect an eslint.js script, we need to execute - " it with node, or the file can be opened with a text editor. - let l:head = 'node ' . ale#Escape(l:executable) - else - let l:head = ale#Escape(l:executable) - endif - let l:options = ale#Var(a:buffer, 'javascript_eslint_options') - return l:head + return ale#node#Executable(a:buffer, l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' -f unix --stdin --stdin-filename %s' endfunction diff --git a/autoload/ale/node.vim b/autoload/ale/node.vim index 54b53fb..f75280b 100644 --- a/autoload/ale/node.vim +++ b/autoload/ale/node.vim @@ -1,6 +1,8 @@ " Author: w0rp " Description: Functions for working with Node executables. +call ale#Set('windows_node_executable_path', 'node.exe') + " Given a buffer number, a base variable name, and a list of paths to search " for in ancestor directories, detect the executable path for a Node program. " @@ -20,3 +22,21 @@ function! ale#node#FindExecutable(buffer, base_var_name, path_list) abort return ale#Var(a:buffer, a:base_var_name . '_executable') endfunction + +" Create a executable string which executes a Node.js script command with a +" Node.js executable if needed. +" +" The executable string should not be escaped before passing it to this +" function, the executable string will be escaped when returned by this +" function. +" +" The executable is only prefixed for Windows machines +function! ale#node#Executable(buffer, executable) abort + if ale#Has('win32') && a:executable =~? '\.js$' + let l:node = ale#Var(a:buffer, 'windows_node_executable_path') + + return ale#Escape(l:node) . ' ' . ale#Escape(a:executable) + endif + + return ale#Escape(a:executable) +endfunction diff --git a/doc/ale.txt b/doc/ale.txt index 9055d86..362171c 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1089,6 +1089,22 @@ b:ale_warn_about_trailing_whitespace *b:ale_warn_about_trailing_whitespace* This option may be configured on a per buffer basis. +g:ale_windows_node_executable_path *g:ale_windows_node_executable_path* + *b:ale_windows_node_executable_path* + + Type: |String| + Default: `'node.exe'` + + This variable is used as the path to the executable to use for executing + scripts with Node.js on Windows. + + For Windows, any file with a `.js` file extension needs to be executed with + the node executable explicitly. Otherwise, Windows could try and open the + scripts with other applications, like a text editor. Therefore, these + scripts are executed with whatever executable is configured with this + setting. + + ------------------------------------------------------------------------------- 6.1. Highlights *ale-highlights* diff --git a/test/command_callback/test_standard_command_callback.vader b/test/command_callback/test_standard_command_callback.vader index fa90175..193ead8 100644 --- a/test/command_callback/test_standard_command_callback.vader +++ b/test/command_callback/test_standard_command_callback.vader @@ -67,7 +67,7 @@ Execute(.js files should be executed with node on Windows): \ ale_linters#javascript#standard#GetExecutable(bufnr('')) AssertEqual - \ 'node ' . ale#Escape(b:executable) . ' --stdin %s', + \ ale#Escape('node.exe') . ' ' . ale#Escape(b:executable) . ' --stdin %s', \ ale_linters#javascript#standard#GetCommand(bufnr('')) Execute(The global executable should be used otherwise): diff --git a/test/fixers/test_eslint_fixer_callback.vader b/test/fixers/test_eslint_fixer_callback.vader index 58f7561..218461d 100644 --- a/test/fixers/test_eslint_fixer_callback.vader +++ b/test/fixers/test_eslint_fixer_callback.vader @@ -26,7 +26,7 @@ Execute(The eslint fixer with eslint.js should be run with node on Windows): AssertEqual \ { \ 'read_temporary_file': 1, - \ 'command': 'node ' + \ 'command': ale#Escape('node.exe') . ' ' \ . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --config ' . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js')) \ . ' --fix %t', diff --git a/test/fixers/test_standard_fixer_callback.vader b/test/fixers/test_standard_fixer_callback.vader index 934b07b..88169bb 100644 --- a/test/fixers/test_standard_fixer_callback.vader +++ b/test/fixers/test_standard_fixer_callback.vader @@ -25,7 +25,7 @@ Execute(The standard fixer with standard.js should be run with node on Windows): AssertEqual \ { \ 'read_temporary_file': 1, - \ 'command': 'node ' + \ 'command': ale#Escape('node.exe') . ' ' \ . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/standard/bin/cmd.js')) \ . ' --fix %t', \ }, diff --git a/test/fixers/test_stylelint_fixer_callback.vader b/test/fixers/test_stylelint_fixer_callback.vader index 6c99196..482704d 100644 --- a/test/fixers/test_stylelint_fixer_callback.vader +++ b/test/fixers/test_stylelint_fixer_callback.vader @@ -25,7 +25,7 @@ Execute(The stylelint fixer with stylelint.js should be run with node on Windows AssertEqual \ { \ 'read_temporary_file': 1, - \ 'command': 'node ' + \ 'command': ale#Escape('node.exe') . ' ' \ . ale#Escape(simplify(g:dir . '/../eslint-test-files/react-app/node_modules/stylelint/bin/stylelint.js')) \ . ' --fix %t', \ }, diff --git a/test/test_eslint_executable_detection.vader b/test/test_eslint_executable_detection.vader index 30ae38d..411fa13 100644 --- a/test/test_eslint_executable_detection.vader +++ b/test/test_eslint_executable_detection.vader @@ -58,7 +58,7 @@ Execute(eslint.js executables should be run with node on Windows): " We have to execute the file with node. AssertEqual - \ 'node ''' - \ . g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js' - \ . ''' -f unix --stdin --stdin-filename %s', + \ ale#Escape('node.exe') . ' ' + \ . ale#Escape(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js') + \ . ' -f unix --stdin --stdin-filename %s', \ ale#handlers#eslint#GetCommand(bufnr(''))