Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] remote: add node host #7458

Merged
merged 3 commits into from Nov 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 62 additions & 0 deletions runtime/autoload/health/provider.vim
Expand Up @@ -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')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is yarn a requirement, @billyvg ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, it shouldn't be, it seems I didn't pull in neovim/node-host@40c370a

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'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should not need a separate command for Windows, I believe the ruby check does it that way because of the different quoting. (Though it may possibly be unnecessary there as well, since system([...]) is called with a list.)

Copy link
Contributor

@janlazo janlazo Oct 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Safe to use same command in Windows. Nevermind. npm.cmd calls npm node in the same directory. npm in Windows is a shell script.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, ok.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the same case for ruby, I think I recall.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This used ruby's provider script as a template)

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
76 changes: 76 additions & 0 deletions runtime/autoload/provider/node.vim
@@ -0,0 +1,76 @@
if exists('g:loaded_node_provider')
finish
endif
let g:loaded_node_provider = 1

let s:job_opts = {'rpc': v:true, 'on_stderr': function('provider#stderr_collector')}

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 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

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', [])
4 changes: 4 additions & 0 deletions runtime/autoload/remote/host.vim
Expand Up @@ -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'))