From 8b199cb2fe5f9c2380937bfd5ea0654bdaef2918 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Sun, 29 Oct 2017 11:06:47 -0700 Subject: [PATCH 1/3] health: add node health check --- runtime/autoload/health/provider.vim | 62 ++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/runtime/autoload/health/provider.vim b/runtime/autoload/health/provider.vim index 0eaa678459..806a9d043b 100644 --- a/runtime/autoload/health/provider.vim +++ b/runtime/autoload/health/provider.vim @@ -487,9 +487,71 @@ function! s:check_ruby() abort endif endfunction +function! s:check_node() abort + call health#report_start('Node provider (optional)') + + let loaded_var = 'g:loaded_node_provider' + if exists(loaded_var) && !exists('*provider#node#Call') + call health#report_info('Disabled. '.loaded_var.'='.eval(loaded_var)) + return + endif + + if !executable('node') || !executable('npm') || !executable('yarn') + call health#report_warn( + \ '`node` and `npm` must be in $PATH.', + \ ['Install Node.js and verify that `node` and `npm` commands work.']) + return + endif + call health#report_info('Node: '. s:system('node -v')) + + let host = provider#node#Detect() + if empty(host) + call health#report_warn('Missing "neovim" npm package.', + \ ['Run in shell: npm install -g neovim', + \ 'Is the npm bin directory in $PATH?']) + return + endif + call health#report_info('Host: '. host) + + let latest_npm_cmd = has('win32') ? 'cmd /c npm info neovim --json' : 'npm info neovim --json' + let latest_npm = s:system(split(latest_npm_cmd)) + if s:shell_error || empty(latest_npm) + call health#report_error('Failed to run: '. latest_npm_cmd, + \ ["Make sure you're connected to the internet.", + \ 'Are you behind a firewall or proxy?']) + return + endif + if !empty(latest_npm) + try + let pkg_data = json_decode(latest_npm) + catch /E474/ + return 'error: '.latest_npm + endtry + let latest_npm = get(get(pkg_data, 'dist-tags', {}), 'latest', 'unable to parse') + endif + + let current_npm_cmd = host .' --version' + let current_npm = s:system(current_npm_cmd) + if s:shell_error + call health#report_error('Failed to run: '. current_npm_cmd, + \ ['Report this issue with the output of: ', current_npm_cmd]) + return + endif + + if s:version_cmp(current_npm, latest_npm) == -1 + call health#report_warn( + \ printf('Package "neovim" is out-of-date. Installed: %s, latest: %s', + \ current_npm, latest_npm), + \ ['Run in shell: npm update neovim']) + else + call health#report_ok('Latest "neovim" npm is installed: '. current_npm) + endif +endfunction + function! health#provider#check() abort call s:check_clipboard() call s:check_python(2) call s:check_python(3) call s:check_ruby() + call s:check_node() endfunction From 7890157931a3fdfddb647a06e27346071c55564c Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Sun, 29 Oct 2017 11:10:33 -0700 Subject: [PATCH 2/3] remote: add node.js as a remote plugin provider --- runtime/autoload/provider/node.vim | 82 ++++++++++++++++++++++++++++++ runtime/autoload/remote/host.vim | 4 ++ 2 files changed, 86 insertions(+) create mode 100644 runtime/autoload/provider/node.vim diff --git a/runtime/autoload/provider/node.vim b/runtime/autoload/provider/node.vim new file mode 100644 index 0000000000..8a2a105bb4 --- /dev/null +++ b/runtime/autoload/provider/node.vim @@ -0,0 +1,82 @@ +if exists('g:loaded_node_provider') + finish +endif +let g:loaded_node_provider = 1 + +let s:stderr = {} +let s:job_opts = {'rpc': v:true} + +function! s:job_opts.on_stderr(chan_id, data, event) + let stderr = get(s:stderr, a:chan_id, ['']) + let last = remove(stderr, -1) + let a:data[0] = last.a:data[0] + call extend(stderr, a:data) + let s:stderr[a:chan_id] = stderr +endfunction + +function! provider#node#Detect() abort + return exepath('neovim-node-host') +endfunction + +function! provider#node#Prog() + return s:prog +endfunction + +function! provider#node#Require(host) abort + if s:err != '' + echoerr s:err + return + endif + + let args = ['node'] + + if !empty($NVIM_NODE_HOST_DEBUG) + call add(args, '--inspect-brk') + endif + + call add(args , provider#node#Prog()) + + try + let channel_id = jobstart(args, s:job_opts) + if rpcrequest(channel_id, 'poll') ==# 'ok' + return channel_id + endif + catch + echomsg v:throwpoint + echomsg v:exception + for row in get(s:stderr, channel_id, []) + echomsg row + endfor + endtry + throw remote#host#LoadErrorForHost(a:host.orig_name, '$NVIM_NODE_LOG_FILE') +endfunction + +function! provider#node#Call(method, args) + if s:err != '' + echoerr s:err + return + endif + + if !exists('s:host') + try + let s:host = remote#host#Require('node') + catch + let s:err = v:exception + echohl WarningMsg + echomsg v:exception + echohl None + return + endtry + endif + return call('rpcrequest', insert(insert(a:args, 'node_'.a:method), s:host)) +endfunction + + +let s:err = '' +let s:prog = provider#node#Detect() + +if empty(s:prog) + let s:err = 'Cannot find the "neovim" node package. Try :CheckHealth' +endif + +call remote#host#RegisterPlugin('node-provider', 'node', []) diff --git a/runtime/autoload/remote/host.vim b/runtime/autoload/remote/host.vim index e695fb7df7..dfaab7d246 100644 --- a/runtime/autoload/remote/host.vim +++ b/runtime/autoload/remote/host.vim @@ -199,3 +199,7 @@ call remote#host#Register('python3', '*', " Ruby call remote#host#Register('ruby', '*.rb', \ function('provider#ruby#Require')) + +" nodejs +call remote#host#Register('node', '*', + \ function('provider#node#Require')) From eed10f7e23a7ec27e5ba147379fb6acbfcb10c20 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Tue, 31 Oct 2017 08:35:29 -0700 Subject: [PATCH 3/3] use `provider#stderr_collector` --- runtime/autoload/provider/node.vim | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/runtime/autoload/provider/node.vim b/runtime/autoload/provider/node.vim index 8a2a105bb4..ce2740e813 100644 --- a/runtime/autoload/provider/node.vim +++ b/runtime/autoload/provider/node.vim @@ -3,16 +3,7 @@ if exists('g:loaded_node_provider') endif let g:loaded_node_provider = 1 -let s:stderr = {} -let s:job_opts = {'rpc': v:true} - -function! s:job_opts.on_stderr(chan_id, data, event) - let stderr = get(s:stderr, a:chan_id, ['']) - let last = remove(stderr, -1) - let a:data[0] = last.a:data[0] - call extend(stderr, a:data) - let s:stderr[a:chan_id] = stderr -endfunction +let s:job_opts = {'rpc': v:true, 'on_stderr': function('provider#stderr_collector')} function! provider#node#Detect() abort return exepath('neovim-node-host') @@ -44,10 +35,13 @@ function! provider#node#Require(host) abort catch echomsg v:throwpoint echomsg v:exception - for row in get(s:stderr, channel_id, []) + for row in provider#get_stderr(channel_id) echomsg row endfor endtry + finally + call provider#clear_stderr(channel_id) + endtry throw remote#host#LoadErrorForHost(a:host.orig_name, '$NVIM_NODE_LOG_FILE') endfunction