123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- " ___vital___
- " NOTE: lines between '" ___vital___' is generated by :Vitalize.
- " Do not mofidify the code nor insert new lines before '" ___vital___'
- if v:version > 703 || v:version == 703 && has('patch1170')
- function! vital#_neocomplete#Process#import() abort
- return map({'shellescape': '', 'has_vimproc': '', 'system': '', 'iconv': '', 'spawn': '', 'get_last_status': ''}, 'function("s:" . v:key)')
- endfunction
- else
- function! s:_SID() abort
- return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
- endfunction
- execute join(['function! vital#_neocomplete#Process#import() abort', printf("return map({'shellescape': '', 'has_vimproc': '', 'system': '', 'iconv': '', 'spawn': '', 'get_last_status': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
- delfunction s:_SID
- endif
- " ___vital___
- " TODO: move all comments to doc file.
- "
- "
- " FIXME: This module name should be Vital.System ?
- " But the name has been already taken.
- let s:save_cpo = &cpo
- set cpo&vim
- " FIXME: Unfortunately, can't use s:_vital_loaded() for this purpose.
- " Because these variables are used when this script file is loaded.
- let s:is_windows = has('win16') || has('win32') || has('win64') || has('win95')
- let s:is_unix = has('unix')
- " As of 7.4.122, the system()'s 1st argument is converted internally by Vim.
- " Note that Patch 7.4.122 does not convert system()'s 2nd argument and
- " return-value. We must convert them manually.
- let s:need_trans = v:version < 704 || (v:version == 704 && !has('patch122'))
- let s:TYPE_DICT = type({})
- let s:TYPE_LIST = type([])
- let s:TYPE_STRING = type('')
- function! s:spawn(expr, ...) abort
- let shellslash = 0
- if s:is_windows
- let shellslash = &l:shellslash
- setlocal noshellslash
- endif
- try
- if type(a:expr) is s:TYPE_LIST
- let special = 1
- let cmdline = join(map(a:expr, 'shellescape(v:val, special)'), ' ')
- elseif type(a:expr) is s:TYPE_STRING
- let cmdline = a:expr
- if a:0 && a:1
- " for :! command
- let cmdline = substitute(cmdline, '\([!%#]\|<[^<>]\+>\)', '\\\1', 'g')
- endif
- else
- throw 'Process.spawn(): invalid argument (value type:'.type(a:expr).')'
- endif
- if s:is_windows
- silent execute '!start' cmdline
- else
- silent execute '!' cmdline '&'
- endif
- finally
- if s:is_windows
- let &l:shellslash = shellslash
- endif
- endtry
- return ''
- endfunction
- " iconv() wrapper for safety.
- function! s:iconv(expr, from, to) abort
- if a:from ==# '' || a:to ==# '' || a:from ==? a:to
- return a:expr
- endif
- let result = iconv(a:expr, a:from, a:to)
- return result !=# '' ? result : a:expr
- endfunction
- " Check vimproc.
- function! s:has_vimproc() abort
- if !exists('s:exists_vimproc')
- try
- call vimproc#version()
- let s:exists_vimproc = 1
- catch
- let s:exists_vimproc = 0
- endtry
- endif
- return s:exists_vimproc
- endfunction
- " * {command} [, {input} [, {timeout}]]
- " * {command} [, {dict}]
- " {dict} = {
- " use_vimproc: bool,
- " input: string,
- " timeout: bool,
- " background: bool,
- " }
- function! s:system(str, ...) abort
- " Process optional arguments at first
- " because use_vimproc is required later
- " for a:str argument.
- let input = ''
- let use_vimproc = s:has_vimproc()
- let background = 0
- let args = []
- if a:0 ==# 1
- " {command} [, {dict}]
- " a:1 = {dict}
- if type(a:1) is s:TYPE_DICT
- if has_key(a:1, 'use_vimproc')
- let use_vimproc = a:1.use_vimproc
- endif
- if has_key(a:1, 'input')
- let args += [s:iconv(a:1.input, &encoding, 'char')]
- endif
- if use_vimproc && has_key(a:1, 'timeout')
- " ignores timeout unless you have vimproc.
- let args += [a:1.timeout]
- endif
- if has_key(a:1, 'background')
- let background = a:1.background
- endif
- elseif type(a:1) is s:TYPE_STRING
- let args += [s:iconv(a:1, &encoding, 'char')]
- else
- throw 'Process.system(): invalid argument (value type:'.type(a:1).')'
- endif
- elseif a:0 >= 2
- " {command} [, {input} [, {timeout}]]
- " a:000 = [{input} [, {timeout}]]
- let [input; rest] = a:000
- let input = s:iconv(input, &encoding, 'char')
- let args += [input] + rest
- endif
- " Process a:str argument.
- if type(a:str) is s:TYPE_LIST
- let expr = use_vimproc ? '"''" . v:val . "''"' : 's:shellescape(v:val)'
- let command = join(map(copy(a:str), expr), ' ')
- elseif type(a:str) is s:TYPE_STRING
- let command = a:str
- else
- throw 'Process.system(): invalid argument (value type:'.type(a:str).')'
- endif
- if s:need_trans
- let command = s:iconv(command, &encoding, 'char')
- endif
- let args = [command] + args
- if background && (use_vimproc || !s:is_windows)
- let args[0] = args[0] . ' &'
- endif
- let funcname = use_vimproc ? 'vimproc#system' : 'system'
- let output = call(funcname, args)
- let output = s:iconv(output, 'char', &encoding)
- return output
- endfunction
- function! s:get_last_status() abort
- return s:has_vimproc() ?
- \ vimproc#get_last_status() : v:shell_error
- endfunction
- if s:is_windows
- function! s:shellescape(command) abort
- return substitute(a:command, '[&()[\]{}^=;!''+,`~]', '^\0', 'g')
- endfunction
- else
- function! s:shellescape(...) abort
- return call('shellescape', a:000)
- endfunction
- endif
- let &cpo = s:save_cpo
- unlet s:save_cpo
- " vim:set et ts=2 sts=2 sw=2 tw=0:
|