diff options
Diffstat (limited to 'runtime/autoload')
| -rw-r--r-- | runtime/autoload/health.vim | 18 | ||||
| -rw-r--r-- | runtime/autoload/health/provider.vim | 100 | ||||
| -rw-r--r-- | runtime/autoload/provider/clipboard.vim | 73 |
3 files changed, 147 insertions, 44 deletions
diff --git a/runtime/autoload/health.vim b/runtime/autoload/health.vim index cbfd7c76a1..a84cb6a3cc 100644 --- a/runtime/autoload/health.vim +++ b/runtime/autoload/health.vim @@ -9,13 +9,20 @@ function! s:enhance_syntax() abort highlight link healthInfo ModeMsg syntax keyword healthSuccess SUCCESS - highlight link healthSuccess Function + highlight link healthSuccess ModeMsg syntax keyword healthSuggestion SUGGESTIONS highlight link healthSuggestion String + syntax match healthHelp "|.\{-}|" contains=healthBar + syntax match healthBar "|" contained conceal + highlight link healthHelp Identifier + " We do not care about markdown syntax errors in :CheckHealth output. highlight! link markdownError Normal + + " We don't need code blocks. + silent! syntax clear markdownCodeBlock endfunction " Runs the specified healthchecks. @@ -28,6 +35,8 @@ function! health#check(plugin_names) abort tabnew setlocal wrap breakindent setlocal filetype=markdown bufhidden=wipe + setlocal conceallevel=2 concealcursor=nc + setlocal keywordprg=:help call s:enhance_syntax() if empty(healthchecks) @@ -78,6 +87,11 @@ function! s:indent_after_line1(s, columns) abort return join(lines, "\n") endfunction +" Changes ':help clipboard' to '|clipoard|'. Also removes surrounding quotes. +function! s:help_to_link(s) abort + return substitute(a:s, '\v[''"]?:h%[elp] ([^''"]+)[''"]?', '|\1|', 'g') +endfunction + " Format a message for a specific report item function! s:format_report_message(status, msg, ...) abort " {{{ let output = ' - ' . a:status . ': ' . s:indent_after_line1(a:msg, 4) @@ -99,7 +113,7 @@ function! s:format_report_message(status, msg, ...) abort " {{{ let output .= "\n - " . s:indent_after_line1(suggestion, 10) endfor - return output + return s:help_to_link(output) endfunction " }}} " Use {msg} to report information in the current section diff --git a/runtime/autoload/health/provider.vim b/runtime/autoload/health/provider.vim index d4b2f07a17..16ce2e3249 100644 --- a/runtime/autoload/health/provider.vim +++ b/runtime/autoload/health/provider.vim @@ -1,3 +1,5 @@ +let s:shell_error = 0 + function! s:is_bad_response(s) abort return a:s =~? '\v(^unable)|(^error)' endfunction @@ -22,11 +24,67 @@ function! s:version_cmp(a, b) abort return 0 endfunction +" Handler for s:system() function. +function! s:system_handler(jobid, data, event) abort + if a:event == 'stdout' + let self.stdout .= join(a:data, '') + elseif a:event == 'stderr' + let self.stderr .= join(a:data, '') + elseif a:event == 'exit' + let s:shell_error = a:data + endif +endfunction + +" Run a system command and timeout after 30 seconds. +function! s:system(cmd, ...) abort + let stdin = a:0 ? a:1 : '' + let opts = { + \ 'stdout': '', + \ 'stderr': '', + \ 'on_stdout': function('s:system_handler'), + \ 'on_stderr': function('s:system_handler'), + \ 'on_exit': function('s:system_handler'), + \ } + let jobid = jobstart(a:cmd, opts) + + if jobid < 1 + call health#report_error(printf('Command error %d: %s', jobid, + \ type(a:cmd) == type([]) ? join(a:cmd) : a:cmd))) + let s:shell_error = 1 + return '' + endif + + if !empty(stdin) + call jobsend(jobid, stdin) + endif + + let res = jobwait([jobid], 30000) + if res[0] == -1 + call health#report_error(printf('Command timed out: %s', + \ type(a:cmd) == type([]) ? join(a:cmd) : a:cmd)) + call jobstop(jobid) + elseif s:shell_error != 0 + call health#report_error(printf("Command error (%d) %s: %s", jobid, + \ type(a:cmd) == type([]) ? join(a:cmd) : a:cmd, + \ opts.stderr)) + endif + + return opts.stdout +endfunction + +function! s:systemlist(cmd, ...) abort + let stdout = split(s:system(a:cmd, a:0 ? a:1 : ''), "\n") + if a:0 > 1 && !empty(a:2) + return filter(stdout, '!empty(v:val)') + endif + return stdout +endfunction + " Fetch the contents of a URL. function! s:download(url) abort if executable('curl') - let rv = system(['curl', '-sL', a:url]) - return v:shell_error ? 'curl error: '.v:shell_error : rv + let rv = s:system(['curl', '-sL', a:url]) + return s:shell_error ? 'curl error: '.s:shell_error : rv elseif executable('python') let script = " \try:\n @@ -37,14 +95,27 @@ function! s:download(url) abort \response = urlopen('".a:url."')\n \print(response.read().decode('utf8'))\n \" - let rv = system(['python', '-c', script]) - return empty(rv) && v:shell_error - \ ? 'python urllib.request error: '.v:shell_error + let rv = s:system(['python', '-c', script]) + return empty(rv) && s:shell_error + \ ? 'python urllib.request error: '.s:shell_error \ : rv endif return 'missing `curl` and `python`, cannot make pypi request' endfunction +" Check for clipboard tools. +function! s:check_clipboard() abort + call health#report_start('Clipboard') + + let clipboard_tool = provider#clipboard#Executable() + if empty(clipboard_tool) + call health#report_warn( + \ "No clipboard tool found. Using the system clipboard won't work.", + \ ['See |clipboard|.']) + else + call health#report_ok('Clipboard tool found: '. clipboard_tool) + endif +endfunction " Get the latest Neovim Python client version from PyPI. function! s:latest_pypi_version() abort @@ -73,7 +144,7 @@ endfunction " ] function! s:version_info(python) abort let pypi_version = s:latest_pypi_version() - let python_version = s:trim(system([ + let python_version = s:trim(s:system([ \ a:python, \ '-c', \ 'import sys; print(".".join(str(x) for x in sys.version_info[:3]))', @@ -83,11 +154,11 @@ function! s:version_info(python) abort let python_version = 'unable to parse python response' endif - let nvim_path = s:trim(system([ + let nvim_path = s:trim(s:system([ \ a:python, \ '-c', \ 'import neovim; print(neovim.__file__)'])) - let nvim_path = v:shell_error ? '' : nvim_path + let nvim_path = s:shell_error ? '' : nvim_path if empty(nvim_path) return [python_version, 'unable to find nvim executable', pypi_version, 'unable to get nvim executable'] @@ -195,7 +266,7 @@ function! s:check_python(version) abort call health#report_ok(printf('pyenv found: "%s"', pyenv)) endif - let python_bin = s:trim(system( + let python_bin = s:trim(s:system( \ printf('"%s" which %s 2>/dev/null', pyenv, python_bin_name))) if empty(python_bin) @@ -272,7 +343,7 @@ function! s:check_python(version) abort if exists('$VIRTUAL_ENV') if !empty(pyenv) - let pyenv_prefix = resolve(s:trim(system([pyenv, 'prefix']))) + let pyenv_prefix = resolve(s:trim(s:system([pyenv, 'prefix']))) if $VIRTUAL_ENV != pyenv_prefix let virtualenv_inactive = 1 endif @@ -338,7 +409,7 @@ endfunction function! s:check_ruby() abort call health#report_start('Ruby provider') - let ruby_version = systemlist('ruby -v')[0] + let ruby_version = s:systemlist('ruby -v')[0] let ruby_prog = provider#ruby#Detect() let suggestions = \ ['Install or upgrade the neovim RubyGem using `gem install neovim`.'] @@ -348,13 +419,13 @@ function! s:check_ruby() abort let prog_vers = 'not found' call health#report_error('Missing Neovim RubyGem', suggestions) else - silent let latest_gem = get(systemlist("gem list -ra '^neovim$' 2>/dev/null | " . + silent let latest_gem = get(s:systemlist("gem list -ra '^neovim$' 2>/dev/null | " . \ "awk -F'[()]' '{print $2}' | " . \ 'cut -d, -f1'), 0, 'not found') let latest_desc = ' (latest: ' . latest_gem . ')' - silent let prog_vers = systemlist(ruby_prog . ' --version')[0] - if v:shell_error + silent let prog_vers = s:systemlist(ruby_prog . ' --version')[0] + if s:shell_error let prog_vers = 'not found' . latest_desc call health#report_warn('Neovim RubyGem is not up-to-date.', suggestions) elseif s:version_cmp(prog_vers, latest_gem) == -1 @@ -371,6 +442,7 @@ function! s:check_ruby() abort endfunction function! health#provider#check() abort + call s:check_clipboard() call s:check_python(2) call s:check_python(3) call s:check_ruby() diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim index 0f4aa78ddd..f63ad5730b 100644 --- a/runtime/autoload/provider/clipboard.vim +++ b/runtime/autoload/provider/clipboard.vim @@ -31,34 +31,51 @@ function! s:try_cmd(cmd, ...) endfunction let s:cache_enabled = 1 -if executable('pbcopy') - let s:copy['+'] = 'pbcopy' - let s:paste['+'] = 'pbpaste' - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] - let s:cache_enabled = 0 -elseif exists('$DISPLAY') && executable('xsel') - let s:copy['+'] = 'xsel --nodetach -i -b' - let s:paste['+'] = 'xsel -o -b' - let s:copy['*'] = 'xsel --nodetach -i -p' - let s:paste['*'] = 'xsel -o -p' -elseif exists('$DISPLAY') && executable('xclip') - let s:copy['+'] = 'xclip -quiet -i -selection clipboard' - let s:paste['+'] = 'xclip -o -selection clipboard' - let s:copy['*'] = 'xclip -quiet -i -selection primary' - let s:paste['*'] = 'xclip -o -selection primary' -elseif executable('lemonade') - let s:copy['+'] = 'lemonade copy' - let s:paste['+'] = 'lemonade paste' - let s:copy['*'] = 'lemonade copy' - let s:paste['*'] = 'lemonade paste' -elseif executable('doitclient') - let s:copy['+'] = 'doitclient wclip' - let s:paste['+'] = 'doitclient wclip -r' - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] -else - echom 'clipboard: No clipboard tool available. See :help clipboard' +let s:err = '' + +function! provider#clipboard#Error() abort + return s:err +endfunction + +function! provider#clipboard#Executable() abort + if executable('pbcopy') + let s:copy['+'] = 'pbcopy' + let s:paste['+'] = 'pbpaste' + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + let s:cache_enabled = 0 + return 'pbcopy' + elseif exists('$DISPLAY') && executable('xsel') + let s:copy['+'] = 'xsel --nodetach -i -b' + let s:paste['+'] = 'xsel -o -b' + let s:copy['*'] = 'xsel --nodetach -i -p' + let s:paste['*'] = 'xsel -o -p' + return 'xsel' + elseif exists('$DISPLAY') && executable('xclip') + let s:copy['+'] = 'xclip -quiet -i -selection clipboard' + let s:paste['+'] = 'xclip -o -selection clipboard' + let s:copy['*'] = 'xclip -quiet -i -selection primary' + let s:paste['*'] = 'xclip -o -selection primary' + return 'xclip' + elseif executable('lemonade') + let s:copy['+'] = 'lemonade copy' + let s:paste['+'] = 'lemonade paste' + let s:copy['*'] = 'lemonade copy' + let s:paste['*'] = 'lemonade paste' + return 'lemonade' + elseif executable('doitclient') + let s:copy['+'] = 'doitclient wclip' + let s:paste['+'] = 'doitclient wclip -r' + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + return 'doitclient' + endif + + let s:err = 'clipboard: No clipboard tool available. See :help clipboard' + return '' +endfunction + +if empty(provider#clipboard#Executable()) finish endif |