aboutsummaryrefslogtreecommitdiff
path: root/runtime/autoload/provider
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/autoload/provider')
-rw-r--r--runtime/autoload/provider/clipboard.vim75
-rw-r--r--runtime/autoload/provider/node.vim80
-rw-r--r--runtime/autoload/provider/python.vim2
-rw-r--r--runtime/autoload/provider/python3.vim2
-rw-r--r--runtime/autoload/provider/pythonx.vim21
-rw-r--r--runtime/autoload/provider/ruby.vim14
-rw-r--r--runtime/autoload/provider/script_host.rb8
7 files changed, 156 insertions, 46 deletions
diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim
index 1bcc1dea74..6454a01c2a 100644
--- a/runtime/autoload/provider/clipboard.vim
+++ b/runtime/autoload/provider/clipboard.vim
@@ -3,28 +3,36 @@
" available.
let s:copy = {}
let s:paste = {}
+let s:clipboard = {}
" When caching is enabled, store the jobid of the xclip/xsel process keeping
" ownership of the selection, so we know how long the cache is valid.
-let s:selection = { 'owner': 0, 'data': [] }
+let s:selection = { 'owner': 0, 'data': [], 'on_stderr': function('provider#stderr_collector') }
-function! s:selection.on_exit(jobid, data, event)
+function! s:selection.on_exit(jobid, data, event) abort
" At this point this nvim instance might already have launched
" a new provider instance. Don't drop ownership in this case.
if self.owner == a:jobid
let self.owner = 0
endif
+ if a:data != 0
+ let stderr = provider#get_stderr(a:jobid)
+ echohl WarningMsg
+ echomsg 'clipboard: error invoking '.get(self.argv, 0, '?').': '.join(stderr)
+ echohl None
+ endif
+ call provider#clear_stderr(a:jobid)
endfunction
-let s:selections = { '*': s:selection, '+': copy(s:selection)}
+let s:selections = { '*': s:selection, '+': copy(s:selection) }
-function! s:try_cmd(cmd, ...)
+function! s:try_cmd(cmd, ...) abort
let argv = split(a:cmd, " ")
let out = a:0 ? systemlist(argv, a:1, 1) : systemlist(argv, [''], 1)
if v:shell_error
if !exists('s:did_error_try_cmd')
echohl WarningMsg
- echomsg "clipboard: error: ".(len(out) ? out[0] : '')
+ echomsg "clipboard: error: ".(len(out) ? out[0] : v:shell_error)
echohl None
let s:did_error_try_cmd = 1
endif
@@ -34,7 +42,7 @@ function! s:try_cmd(cmd, ...)
endfunction
" Returns TRUE if `cmd` exits with success, else FALSE.
-function! s:cmd_ok(cmd)
+function! s:cmd_ok(cmd) abort
call system(a:cmd)
return v:shell_error == 0
endfunction
@@ -47,7 +55,18 @@ function! provider#clipboard#Error() abort
endfunction
function! provider#clipboard#Executable() abort
- if has('mac') && executable('pbcopy')
+ if exists('g:clipboard')
+ if type({}) isnot# type(g:clipboard)
+ \ || type({}) isnot# type(get(g:clipboard, 'copy', v:null))
+ \ || type({}) isnot# type(get(g:clipboard, 'paste', v:null))
+ let s:err = 'clipboard: invalid g:clipboard'
+ return ''
+ endif
+ let s:copy = get(g:clipboard, 'copy', { '+': v:null, '*': v:null })
+ let s:paste = get(g:clipboard, 'paste', { '+': v:null, '*': v:null })
+ let s:cache_enabled = get(g:clipboard, 'cache_enabled', 0)
+ return get(g:clipboard, 'name', 'g:clipboard')
+ elseif has('mac') && executable('pbcopy')
let s:copy['+'] = 'pbcopy'
let s:paste['+'] = 'pbpaste'
let s:copy['*'] = s:copy['+']
@@ -84,26 +103,33 @@ function! provider#clipboard#Executable() abort
let s:copy['*'] = s:copy['+']
let s:paste['*'] = s:paste['+']
return 'win32yank'
+ elseif exists('$TMUX') && executable('tmux')
+ let s:copy['+'] = 'tmux load-buffer -'
+ let s:paste['+'] = 'tmux save-buffer -'
+ let s:copy['*'] = s:copy['+']
+ let s:paste['*'] = s:paste['+']
+ return 'tmux'
endif
- let s:err = 'clipboard: No clipboard tool available. See :help clipboard'
+ let s:err = 'clipboard: No clipboard tool. :help clipboard'
return ''
endfunction
if empty(provider#clipboard#Executable())
+ " provider#clipboard#Call() *must not* be defined if the provider is broken.
+ " Otherwise eval_has_provider() thinks the clipboard provider is
+ " functioning, and eval_call_provider() will happily call it.
finish
endif
-let s:clipboard = {}
-
-function! s:clipboard.get(reg)
+function! s:clipboard.get(reg) abort
if s:selections[a:reg].owner > 0
return s:selections[a:reg].data
end
return s:try_cmd(s:paste[a:reg])
endfunction
-function! s:clipboard.set(lines, regtype, reg)
+function! s:clipboard.set(lines, regtype, reg) abort
if a:reg == '"'
call s:clipboard.set(a:lines,a:regtype,'+')
if s:copy['*'] != s:copy['+']
@@ -124,20 +150,31 @@ function! s:clipboard.set(lines, regtype, reg)
end
let selection.data = [a:lines, a:regtype]
let argv = split(s:copy[a:reg], " ")
+ let selection.argv = argv
let selection.detach = s:cache_enabled
let selection.cwd = "/"
let jobid = jobstart(argv, selection)
- if jobid <= 0
+ if jobid > 0
+ call jobsend(jobid, a:lines)
+ call jobclose(jobid, 'stdin')
+ let selection.owner = jobid
+ else
echohl WarningMsg
- echo "clipboard: error when invoking provider"
+ echomsg 'clipboard: failed to execute: '.(s:copy[a:reg])
echohl None
return 0
endif
- call jobsend(jobid, a:lines)
- call jobclose(jobid, 'stdin')
- let selection.owner = jobid
+ return 1
endfunction
-function! provider#clipboard#Call(method, args)
- return call(s:clipboard[a:method],a:args,s:clipboard)
+function! provider#clipboard#Call(method, args) abort
+ if get(s:, 'here', v:false) " Clipboard provider must not recurse. #7184
+ return 0
+ endif
+ let s:here = v:true
+ try
+ return call(s:clipboard[a:method],a:args,s:clipboard)
+ finally
+ let s:here = v:false
+ endtry
endfunction
diff --git a/runtime/autoload/provider/node.vim b/runtime/autoload/provider/node.vim
new file mode 100644
index 0000000000..b08ad4f316
--- /dev/null
+++ b/runtime/autoload/provider/node.vim
@@ -0,0 +1,80 @@
+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 has('win32') ? exepath('neovim-node-host.cmd') : 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
+
+ if has('win32')
+ let args = provider#node#Prog()
+ else
+ let args = ['node']
+
+ if !empty($NVIM_NODE_HOST_DEBUG)
+ call add(args, '--inspect-brk')
+ endif
+
+ call add(args , provider#node#Prog())
+ endif
+
+ 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', [])
diff --git a/runtime/autoload/provider/python.vim b/runtime/autoload/provider/python.vim
index b99a046375..81fe194cb9 100644
--- a/runtime/autoload/provider/python.vim
+++ b/runtime/autoload/provider/python.vim
@@ -1,5 +1,5 @@
" The Python provider uses a Python host to emulate an environment for running
-" python-vim plugins. See ":help provider".
+" python-vim plugins. :help provider
"
" Associating the plugin with the Python host is the first step because plugins
" will be passed as command-line arguments
diff --git a/runtime/autoload/provider/python3.vim b/runtime/autoload/provider/python3.vim
index 4f47a03a9b..0c3b75b73d 100644
--- a/runtime/autoload/provider/python3.vim
+++ b/runtime/autoload/provider/python3.vim
@@ -1,5 +1,5 @@
" The Python3 provider uses a Python3 host to emulate an environment for running
-" python3 plugins. See ":help provider".
+" python3 plugins. :help provider
"
" Associating the plugin with the Python3 host is the first step because
" plugins will be passed as command-line arguments
diff --git a/runtime/autoload/provider/pythonx.vim b/runtime/autoload/provider/pythonx.vim
index 08a0f39b01..7285ed43ea 100644
--- a/runtime/autoload/provider/pythonx.vim
+++ b/runtime/autoload/provider/pythonx.vim
@@ -5,17 +5,7 @@ endif
let s:loaded_pythonx_provider = 1
-let s:stderr = {}
-let s:job_opts = {'rpc': v:true}
-
-" TODO(bfredl): this logic is common and should be builtin
-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#pythonx#Require(host) abort
let ver = (a:host.orig_name ==# 'python') ? 2 : 3
@@ -38,9 +28,11 @@ function! provider#pythonx#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
+ finally
+ call provider#clear_stderr(channel_id)
endtry
throw remote#host#LoadErrorForHost(a:host.orig_name,
\ '$NVIM_PYTHON_LOG_FILE')
@@ -112,15 +104,14 @@ function! s:check_interpreter(prog, major_ver) abort
endif
if v:shell_error == 2
- return [0, prog_path . ' does not have the neovim module installed. '
- \ . 'See ":help provider-python".']
+ return [0, prog_path.' does not have the "neovim" module. :help provider-python']
elseif v:shell_error == 127
" This can happen with pyenv's shims.
return [0, prog_path . ' does not exist: ' . prog_ver]
elseif v:shell_error
return [0, 'Checking ' . prog_path . ' caused an unknown error. '
\ . '(' . v:shell_error . ', output: ' . prog_ver . ')'
- \ . ' Please report this at github.com/neovim/neovim.']
+ \ . ' Report this at https://github.com/neovim/neovim']
endif
return [1, '']
diff --git a/runtime/autoload/provider/ruby.vim b/runtime/autoload/provider/ruby.vim
index c8ede20a75..da73a0dfc0 100644
--- a/runtime/autoload/provider/ruby.vim
+++ b/runtime/autoload/provider/ruby.vim
@@ -16,7 +16,11 @@ function! s:job_opts.on_stderr(chan_id, data, event)
endfunction
function! provider#ruby#Detect() abort
- return exepath('neovim-ruby-host')
+ if exists("g:ruby_host_prog")
+ return g:ruby_host_prog
+ else
+ return has('win32') ? exepath('neovim-ruby-host.bat') : exepath('neovim-ruby-host')
+ end
endfunction
function! provider#ruby#Prog()
@@ -24,15 +28,15 @@ function! provider#ruby#Prog()
endfunction
function! provider#ruby#Require(host) abort
- let args = [provider#ruby#Prog()]
+ let prog = provider#ruby#Prog()
let ruby_plugins = remote#host#PluginsForHost(a:host.name)
for plugin in ruby_plugins
- call add(args, plugin.path)
+ let prog .= " " . shellescape(plugin.path)
endfor
try
- let channel_id = jobstart(args, s:job_opts)
+ let channel_id = jobstart(prog, s:job_opts)
if rpcrequest(channel_id, 'poll') ==# 'ok'
return channel_id
endif
@@ -71,7 +75,7 @@ let s:prog = provider#ruby#Detect()
let s:plugin_path = expand('<sfile>:p:h') . '/script_host.rb'
if empty(s:prog)
- let s:err = 'Cannot find the neovim RubyGem. Try :CheckHealth'
+ let s:err = 'Cannot find the neovim RubyGem. Try :checkhealth'
endif
call remote#host#RegisterClone('legacy-ruby-provider', 'ruby')
diff --git a/runtime/autoload/provider/script_host.rb b/runtime/autoload/provider/script_host.rb
index 1dade766c7..a1c58bde85 100644
--- a/runtime/autoload/provider/script_host.rb
+++ b/runtime/autoload/provider/script_host.rb
@@ -1,8 +1,6 @@
begin
- require "neovim/ruby_provider"
+ require 'neovim/ruby_provider'
rescue LoadError
- warn(
- "Your neovim RubyGem is missing or out of date. " +
- "Install the latest version using `gem install neovim`."
- )
+ warn('Your neovim RubyGem is missing or out of date.',
+ 'Install the latest version using `gem install neovim`.')
end