Added vimtex and plug, color changes

This commit is contained in:
TuDatTr
2019-11-25 17:58:42 +01:00
parent 92001234c6
commit cf00862daa
28 changed files with 79487 additions and 6 deletions

View File

@@ -0,0 +1,196 @@
let g:coc#_context = {'start': 0, 'preselect': -1,'candidates': []}
let g:coc_user_config = get(g:, 'coc_user_config', {})
let g:coc_global_extensions = get(g:, 'coc_global_extensions', [])
let g:coc_cygqwin_path_prefixes = get(g:, 'coc_cygqwin_path_prefixes', {})
let g:coc_selected_text = ''
let g:coc_vim_commands = []
let s:watched_keys = []
let s:is_vim = !has('nvim')
let s:error_sign = get(g:, 'coc_status_error_sign', has('mac') ? '❌ ' : 'E')
let s:warning_sign = get(g:, 'coc_status_warning_sign', has('mac') ? '⚠️ ' : 'W')
let s:select_api = exists('*nvim_select_popupmenu_item')
let s:callbacks = {}
function! coc#expandable() abort
return coc#rpc#request('snippetCheck', [1, 0])
endfunction
function! coc#jumpable() abort
return coc#rpc#request('snippetCheck', [0, 1])
endfunction
function! coc#expandableOrJumpable() abort
return coc#rpc#request('snippetCheck', [1, 1])
endfunction
" add vim command to CocCommand list
function! coc#add_command(id, cmd, ...)
let config = {'id':a:id, 'cmd':a:cmd, 'title': get(a:,1,'')}
call add(g:coc_vim_commands, config)
if !coc#rpc#ready() | return | endif
call coc#rpc#notify('addCommand', [config])
endfunction
function! coc#refresh() abort
return "\<c-r>=coc#start()\<CR>"
endfunction
function! coc#on_enter()
if !coc#rpc#ready()
return ''
endif
if s:is_vim
call coc#rpc#notify('CocAutocmd', ['Enter', bufnr('%')])
else
call coc#rpc#request('CocAutocmd', ['Enter', bufnr('%')])
endif
return ''
endfunction
function! coc#_insert_key(method, key, ...) abort
if get(a:, 1, 1)
call coc#_cancel()
endif
return "\<c-r>=coc#rpc#".a:method."('doKeymap', ['".a:key."'])\<CR>"
endfunction
function! coc#_complete() abort
let items = get(g:coc#_context, 'candidates', [])
let preselect = get(g:coc#_context, 'preselect', -1)
call complete(
\ g:coc#_context.start + 1,
\ items)
if s:select_api && len(items) && preselect != -1
call nvim_select_popupmenu_item(preselect, v:false, v:false, {})
endif
return ''
endfunction
function! coc#_do_complete(start, items, preselect)
let g:coc#_context = {
\ 'start': a:start,
\ 'candidates': a:items,
\ 'preselect': a:preselect
\}
if mode() =~# 'i' && &paste != 1
call feedkeys("\<Plug>CocRefresh", 'i')
endif
endfunction
function! coc#_select_confirm()
if !exists('##TextChangedP')
return "\<C-y>"
endif
let hasSelected = coc#rpc#request('hasSelected', [])
if hasSelected | return "\<C-y>" | endif
return "\<down>\<C-y>"
endfunction
function! coc#_selected()
if !pumvisible() | return 0 | endif
return coc#rpc#request('hasSelected', [])
endfunction
function! coc#_hide() abort
if !pumvisible() | return | endif
call feedkeys("\<C-e>", 'in')
endfunction
function! coc#_cancel()
call coc#util#close_popup()
" hack for close pum
if pumvisible() && &paste != 1
let g:coc#_context = {'start': 0, 'preselect': -1,'candidates': []}
call feedkeys("\<Plug>CocRefresh", 'i')
endif
endfunction
function! coc#_select() abort
if !pumvisible() | return | endif
call feedkeys("\<C-y>", 'in')
endfunction
function! coc#start(...)
let opt = coc#util#get_complete_option()
call CocActionAsync('startCompletion', extend(opt, get(a:, 1, {})))
return ''
endfunction
" used for statusline
function! coc#status()
let info = get(b:, 'coc_diagnostic_info', {})
let msgs = []
if get(info, 'error', 0)
call add(msgs, s:error_sign . info['error'])
endif
if get(info, 'warning', 0)
call add(msgs, s:warning_sign . info['warning'])
endif
return s:trim(join(msgs, ' ') . ' ' . get(g:, 'coc_status', ''))
endfunction
function! s:trim(str)
if exists('*trim')
return trim(a:str)
endif
return substitute(a:str, '\s\+$', '', '')
endfunction
function! coc#config(section, value)
let g:coc_user_config[a:section] = a:value
call coc#rpc#notify('updateConfig', [a:section, a:value])
endfunction
function! coc#add_extension(...)
if a:0 == 0 | return | endif
call extend(g:coc_global_extensions, a:000)
endfunction
function! coc#_watch(key)
if s:is_vim | return | endif
if index(s:watched_keys, a:key) == -1
call add(s:watched_keys, a:key)
call dictwatcheradd(g:, a:key, function('s:GlobalChange'))
endif
endfunction
function! coc#_unwatch(key)
if s:is_vim | return | endif
let idx = index(s:watched_keys, a:key)
if idx != -1
call remove(s:watched_keys, idx)
call dictwatcherdel(g:, a:key, function('s:GlobalChange'))
endif
endfunction
function! s:GlobalChange(dict, key, val)
call coc#rpc#notify('GlobalChange', [a:key, get(a:val, 'old', v:null), get(a:val, 'new', v:null)])
endfunction
function! coc#_map()
if !s:select_api | return | endif
for i in range(1, 9)
exe 'inoremap <buffer> '.i.' <Cmd>call nvim_select_popupmenu_item('.(i - 1).', v:true, v:true, {})<cr>'
endfor
endfunction
function! coc#_unmap()
if !s:select_api | return | endif
for i in range(1, 9)
exe 'silent! iunmap <buffer> '.i
endfor
endfunction
function! coc#on_notify(id, method, Cb)
let key = a:id. '-'.a:method
let s:callbacks[key] = a:Cb
call coc#rpc#notify('registNotification', [a:id, a:method])
endfunction
function! coc#do_notify(id, method, result)
let key = a:id. '-'.a:method
let Fn = s:callbacks[key]
if !empty(Fn)
call Fn(a:result)
endif
endfunction

View File

@@ -0,0 +1,591 @@
" ============================================================================
" Description: Client api used by vim8
" Author: Qiming Zhao <chemzqm@gmail.com>
" Licence: MIT licence
" Last Modified: June 28, 2019
" ============================================================================
if has('nvim') | finish | endif
let s:funcs = {}
let s:prop_id = 1000
let s:namespace_id = 1
let s:namespace_cache = {}
" helper {{
function! s:buf_line_count(bufnr) abort
if bufnr('%') == a:bufnr
return line('$')
endif
if exists('*getbufline')
let lines = getbufline(a:bufnr, 1, '$')
return len(lines)
endif
let curr = bufnr('%')
execute 'buffer '.a:bufnr
let n = line('$')
execute 'buffer '.curr
return n
endfunction
function! s:execute(cmd)
if a:cmd =~# '^echo'
execute a:cmd
else
silent! execute a:cmd
endif
endfunction
" }}"
" nvim client methods {{
function! s:funcs.set_current_dir(dir) abort
execute 'cd '.a:dir
endfunction
function! s:funcs.set_var(name, value) abort
execute 'let g:'.a:name.'= a:value'
endfunction
function! s:funcs.del_var(name) abort
execute 'unlet g:'.a:name
endfunction
function! s:funcs.set_option(name, value) abort
execute 'let &'.a:name.' = a:value'
endfunction
function! s:funcs.set_current_buf(bufnr) abort
if !bufexists(a:bufnr) | return | endif
execute 'buffer '.a:bufnr
endfunction
function! s:funcs.set_current_win(win_id) abort
let [tabnr, winnr] = win_id2tabwin(a:win_id)
if tabnr == 0 | return | endif
execute 'normal! '.tabnr.'gt'
execute winnr.' wincmd w'
endfunction
function! s:funcs.set_current_tabpage(tabnr) abort
execute 'normal! '.a:tabnr.'gt'
endfunction
function! s:funcs.list_wins() abort
return map(getwininfo(), 'v:val["winid"]')
endfunction
function! s:funcs.call_atomic(calls)
let res = []
for [key, arglist] in a:calls
let name = key[5:]
try
call add(res, call(s:funcs[name], arglist))
catch /.*/
return [res, v:exception]
endtry
endfor
return [res, v:null]
endfunction
function! s:funcs.set_client_info(...) abort
endfunction
function! s:funcs.subscribe(...) abort
endfunction
function! s:funcs.unsubscribe(...) abort
endfunction
function! s:funcs.call_function(method, args) abort
return call(a:method, a:args)
endfunction
function! s:funcs.call_dict_function(dict, method, args) abort
return call(a:method, a:args, a:dict)
endfunction
function! s:funcs.command(command) abort
" command that could cause cursor vanish
if a:command =~# '^echo' || a:command =~# '^redraw' || a:command =~# '^sign place'
call timer_start(0, {-> s:execute(a:command)})
else
execute a:command
endif
endfunction
function! s:funcs.eval(expr) abort
return eval(a:expr)
endfunction
function! s:funcs.get_api_info()
let names = coc#api#func_names()
return [1, {'functions': map(names, '{"name": "nvim_".v:val}')}]
endfunction
function! s:funcs.list_bufs()
return map(getbufinfo({'buflisted': 1}), 'v:val["bufnr"]')
endfunction
function! s:funcs.feedkeys(keys, mode, escape_csi)
call feedkeys(a:keys, a:mode)
endfunction
function! s:funcs.list_runtime_paths()
return split(&runtimepath, ',')
endfunction
function! s:funcs.command_output(cmd)
return execute(a:cmd)
endfunction
function! s:funcs.get_current_line()
return getline('.')
endfunction
function! s:funcs.set_current_line(line)
call setline('.', a:line)
endfunction
function! s:funcs.del_current_line(line)
execute 'normal! dd'
endfunction
function! s:funcs.get_var(var)
return get(g:, a:var, v:null)
endfunction
function! s:funcs.get_vvar(var)
return get(v:, a:var, v:null)
endfunction
function! s:funcs.get_option(name)
return eval('&'.a:name)
endfunction
function! s:funcs.get_current_buf()
return bufnr('%')
endfunction
function! s:funcs.get_current_win()
return win_getid()
endfunction
function! s:funcs.get_current_tabpage()
return tabpagenr()
endfunction
function! s:funcs.list_tabpages()
return range(1, tabpagenr('$'))
endfunction
function! s:funcs.get_mode()
return {'blocking': v:false, 'mode': mode()}
endfunction
function! s:funcs.strwidth(str)
return strwidth(a:str)
endfunction
function! s:funcs.out_write(str)
echon a:str
endfunction
function! s:funcs.err_write(str)
echoerr a:str
endfunction
function! s:funcs.err_writeln(str)
echoerr a:str
endfunction
function! s:funcs.create_namespace(name) abort
if empty(a:name)
let id = s:namespace_id
let s:namespace_id = s:namespace_id + 1
return id
endif
let id = get(s:namespace_cache, a:name, 0)
if !id
let id = s:namespace_id
let s:namespace_id = s:namespace_id + 1
let s:namespace_cache[a:name] = id
endif
return id
endfunction
" }}
" buffer methods {{
function! s:funcs.buf_set_option(bufnr, name, val)
let val = a:val
if type(val) == type(v:true)
if val == v:true
let val = 1
else
let val = 0
endif
endif
return setbufvar(a:bufnr, '&'.a:name, val)
endfunction
function! s:funcs.buf_get_changedtick(bufnr)
return getbufvar(a:bufnr, 'changedtick')
endfunction
function! s:funcs.buf_is_valid(bufnr)
return bufloaded(a:bufnr) ? v:true : v:false
endfunction
function! s:funcs.buf_get_mark(bufnr, name)
let nr = bufnr('%')
if a:bufnr != 0 || a:bufnr != nr
throw 'buf_get_mark support current buffer only'
endif
return [line("'" . a:name), col("'" . a:name)]
endfunction
function! s:funcs.buf_add_highlight(bufnr, srcId, hlGroup, line, colStart, colEnd) abort
if !has('textprop')
return
endif
let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
let key = 'Coc'.a:hlGroup
if empty(prop_type_get(key))
call prop_type_add(key, {'highlight': a:hlGroup, 'combine': 1})
endif
let total = strlen(getbufline(bufnr, a:line + 1)[0])
let end = a:colEnd
if end == -1
let end = total
else
let end = min([end, total])
endif
if end <= a:colStart
return
endif
let id = 0
if a:srcId != -1
let cached = getbufvar(bufnr, 'prop_namespace_'.a:srcId, [])
let id = s:prop_id
let s:prop_id = id + 1
call add(cached, id)
call setbufvar(bufnr, 'prop_namespace_'.a:srcId, cached)
endif
try
call prop_add(a:line + 1, a:colStart + 1, {'length': end - a:colStart, 'bufnr': bufnr, 'type': key, 'id': id})
catch /^Vim\%((\a\+)\)\=:E967/
" ignore 967
endtry
endfunction
function! s:funcs.buf_clear_namespace(bufnr, srcId, startLine, endLine) abort
if !has('textprop')
return
endif
if a:srcId == -1
if a:endLine == -1
call prop_clear(a:startLine + 1, {'bufnr': a:bufnr})
else
call prop_clear(a:startLine + 1, a:endLine + 1, {'bufnr': a:bufnr})
endif
else
let cached = getbufvar(a:bufnr, 'prop_namespace_'.a:srcId, [])
if empty(cached)
return
endif
call setbufvar(a:bufnr, 'prop_namespace_'.a:srcId, [])
for id in cached
if a:endLine == -1
if a:startLine == 0 && a:endLine == -1
call prop_remove({'id':id, 'bufnr': a:bufnr})
elseif a:endLine != -1
call prop_remove({'id':id, 'bufnr': a:bufnr}, a:startLine, a:endLine)
else
let len = s:buf_line_count(a:bufnr)
call prop_remove({'id':id, 'bufnr': a:bufnr}, a:startLine, len)
endif
else
endif
endfor
endif
endfunction
function! s:funcs.buf_line_count(bufnr) abort
return s:buf_line_count(a:bufnr)
endfunction
function! s:funcs.buf_attach(...)
" not supported
return 1
endfunction
function! s:funcs.buf_detach()
" not supported
return 1
endfunction
function! s:funcs.buf_get_lines(bufnr, start, end, strict) abort
let lines = getbufline(a:bufnr, 1, '$')
let start = a:start < 0 ? a:start + 1 : a:start
let end = a:end < 0 ? a:end + 1 : a:end
if a:strict && end > len(lines)
throw 'line number out of range: '. end
endif
return lines[start : end - 1]
endfunction
function! s:funcs.buf_set_lines(bufnr, start, end, strict, ...) abort
let replacement = get(a:, 1, [])
let lineCount = s:buf_line_count(a:bufnr)
let startLnum = a:start >= 0 ? a:start + 1 : lineCount + a:start + 1
let end = a:end >= 0 ? a:end : lineCount + a:end + 1
if end == lineCount + 1
let end = lineCount
endif
let delCount = end - (startLnum - 1)
let changeBuffer = 0
let curr = bufnr('%')
if a:bufnr != curr && !exists('*setbufline')
let changeBuffer = 1
exe 'buffer '.a:bufnr
endif
if a:bufnr == curr || changeBuffer
" replace
if delCount == len(replacement)
call setline(startLnum, replacement)
else
if len(replacement)
call append(startLnum - 1, replacement)
endif
if delCount
let start = startLnum + len(replacement)
let saved_reg = @"
silent execute start . ','.(start + delCount - 1).'d'
let @" = saved_reg
endif
endif
if changeBuffer
exe 'buffer '.curr
endif
elseif exists('*setbufline')
" replace
if delCount == len(replacement)
" 8.0.1039
call setbufline(a:bufnr, startLnum, replacement)
else
if len(replacement)
" 8.10037
call appendbufline(a:bufnr, startLnum - 1, replacement)
endif
if delCount
let start = startLnum + len(replacement)
"8.1.0039
call deletebufline(a:bufnr, start, start + delCount - 1)
endif
endif
endif
endfunction
function! s:funcs.buf_set_name(bufnr, name) abort
let nr = bufnr('%')
if a:bufnr != nr
throw 'buf_set_name support current buffer only'
else
execute '0f'
execute 'file '.fnameescape(a:name)
endif
endfunction
function! s:funcs.buf_get_var(bufnr, name)
return getbufvar(a:bufnr, a:name)
endfunction
function! s:funcs.buf_set_var(bufnr, name, val)
if !bufloaded(a:bufnr) | return | endif
call setbufvar(a:bufnr, a:name, a:val)
endfunction
function! s:funcs.buf_del_var(bufnr, name)
call setbufvar(a:bufnr, a:name, v:null)
endfunction
function! s:funcs.buf_get_option(bufnr, name)
return getbufvar(a:bufnr, '&'.a:name)
endfunction
function! s:funcs.buf_get_name(bufnr)
return bufname(a:bufnr)
endfunction
" }}
" window methods {{
function! s:funcs.win_get_buf(winid)
return winbufnr(a:winid)
endfunction
function! s:funcs.win_get_position(win_id) abort
let [row, col] = win_screenpos(a:win_id)
if row == 0 && col == 0
throw 'Invalid window '.a:win_id
endif
return [row - 1, col - 1]
endfunction
function! s:funcs.win_get_height(win_id) abort
return winheight(a:win_id)
endfunction
function! s:funcs.win_get_width(win_id) abort
return winwidth(a:win_id)
endfunction
function! s:funcs.win_get_cursor(win_id) abort
let winid = win_getid()
call win_gotoid(a:win_id)
let pos = [line('.'), col('.')-1]
call win_gotoid(winid)
return pos
endfunction
function! s:funcs.win_get_var(win_id, name) abort
return gettabwinvar(0, a:win_id, a:name)
endfunction
function! s:funcs.win_set_width(win_id, width) abort
let winid = win_getid()
call win_gotoid(a:win_id)
execute 'vertical resize '.a:width
call win_gotoid(winid)
endfunction
function! s:funcs.win_get_option(win_id, name) abort
return gettabwinvar(0, a:win_id, '&'.a:name)
endfunction
function! s:funcs.win_set_height(win_id, height) abort
let winnr = win_id2win(a:win_id)
if winnr != 0
let curr = winnr()
if winnr == curr
execute 'resize '.a:height
else
execute winnr.'wincmd w'
execute 'resize '.a:height
wincmd p
endif
endif
endfunction
function! s:funcs.win_set_option(win_id, name, value) abort
let val = a:value
if type(val) == type(v:true)
if val == v:true
let val = 1
else
let val = 0
endif
endif
call setwinvar(a:win_id, '&'.a:name, val)
endfunction
function! s:funcs.win_set_var(win_id, name, value) abort
call setwinvar(a:win_id, a:name, a:value)
endfunction
function! s:funcs.win_del_var(win_id, name) abort
call settabwinvar(0, a:win_id, a:name, v:null)
endfunction
function! s:funcs.win_is_valid(win_id) abort
let info = getwininfo(a:win_id)
return !empty(info)
endfunction
function! s:funcs.win_get_number(win_id) abort
let info = getwininfo(a:win_id)
if empty(info)
throw 'Invalid window id '.a:win_id
endif
return info[0]['winnr']
endfunction
function! s:funcs.win_set_cursor(win_id, pos) abort
let winnr = win_id2win(a:win_id)
if winnr != 0
let [line, col] = a:pos
let curr = winnr()
if winnr == curr
call cursor(line, col + 1)
else
execute winnr.'wincmd w'
call cursor(line, col + 1)
execute curr.'wincmd w'
endif
endif
endfunction
function! s:funcs.win_close(win_id, ...) abort
let curr = win_getid(a:win_id)
call win_gotoid(a:win_id)
close!
call win_gotoid(curr)
endfunction
function! s:funcs.win_get_tabpage(win_id) abort
let info = getwininfo(a:win_id)
if !info
throw 'Invalid window id '.a:win_id
endif
return info[0]['tabnr']
endfunction
" }}
" tabpage methods {{
function! s:funcs.tabpage_get_number(id)
return a:id
endfunction
function! s:funcs.tabpage_list_wins(tabnr)
let info = getwininfo()
return map(filter(info, 'v:val["tabnr"] == a:tabnr'), 'v:val["winid"]')
endfunction
function! s:funcs.tabpage_get_var(tabnr, name)
return gettabvar(a:tabnr, a:name, v:null)
endfunction
function! s:funcs.tabpage_set_var(tabnr, name, value)
call settabvar(a:tabnr, a:name, a:value)
endfunction
function! s:funcs.tabpage_del_var(tabnr, name)
call settabvar(a:tabnr, a:name, v:null)
endfunction
function! s:funcs.tabpage_is_valid(tabnr)
let max = tabpagenr('$')
return a:tabnr <= max
endfunction
function! s:funcs.tabpage_get_win(tabnr)
let wnr = tabpagewinnr(a:tabnr)
return win_getid(wnr, a:tabnr)
endfunction
" }}
function! coc#api#func_names() abort
return keys(s:funcs)
endfunction
function! coc#api#call(method, args) abort
let err = v:null
let res = v:null
try
let res = call(s:funcs[a:method], a:args)
catch /.*/
let err = v:exception
endtry
return [err, res]
endfunction
function! coc#api#notify(method, args) abort
call call(s:funcs[a:method], a:args)
endfunction
" vim: set sw=2 ts=2 sts=2 et tw=78 foldmarker={{,}} foldmethod=marker foldlevel=0:

View File

@@ -0,0 +1,267 @@
let s:root = expand('<sfile>:h:h:h')
let s:is_vim = !has('nvim')
let s:is_win = has("win32") || has("win64")
let s:clients = {}
let s:logfile = tempname()
if s:is_vim && get(g:, 'node_client_debug', 0)
call ch_logfile(s:logfile, 'w')
endif
" create a client
function! coc#client#create(name, command)
let client = {}
let client['command'] = a:command
let client['name'] = a:name
let client['running'] = 0
let client['async_req_id'] = 1
let client['async_callbacks'] = {}
" vim only
let client['channel'] = v:null
" neovim only
let client['chan_id'] = 0
let client['start'] = function('s:start', [], client)
let client['request'] = function('s:request', [], client)
let client['notify'] = function('s:notify', [], client)
let client['request_async'] = function('s:request_async', [], client)
let client['on_async_response'] = function('s:on_async_response', [], client)
let s:clients[a:name] = client
return client
endfunction
function! s:start() dict
if self.running | return | endif
if s:is_vim
let $VIM_NODE_RPC = 1
let $COC_NVIM = 1
let options = {
\ 'in_mode': 'json',
\ 'out_mode': 'json',
\ 'err_mode': 'nl',
\ 'err_cb': {channel, message -> s:on_stderr(self.name, split(message, "\n"))},
\ 'exit_cb': {channel, code -> s:on_exit(self.name, code)},
\}
if has("patch-8.1.350")
let options['noblock'] = 1
endif
let job = job_start(self.command, options)
let status = job_status(job)
if status !=# 'run'
let self.running = 0
echohl Error | echom 'Failed to start '.self.name.' service' | echohl None
return
endif
let self['running'] = 1
let self['channel'] = job_getchannel(job)
else
let chan_id = jobstart(self.command, {
\ 'rpc': 1,
\ 'on_stderr': {channel, msgs -> s:on_stderr(self.name, msgs)},
\ 'on_exit': {channel, code -> s:on_exit(self.name, code)},
\})
if chan_id <= 0
echohl Error | echom 'Failed to start '.self.name.' service' | echohl None
return
endif
let self['chan_id'] = chan_id
let self['running'] = 1
endif
endfunction
function! s:on_stderr(name, msgs)
if get(g:, 'coc_vim_leaving', 0) | return | endif
let data = filter(copy(a:msgs), '!empty(v:val)')
if empty(data) | return | endif
let client = a:name ==# 'coc' ? '' : ' client '.a:name
let data[0] = '[coc.nvim]'.client.' error: ' . data[0]
call coc#util#echo_messages('Error', data)
endfunction
function! s:on_exit(name, code) abort
if get(g:, 'coc_vim_leaving', 0) | return | endif
let client = get(s:clients, a:name, v:null)
if empty(client) | return | endif
if client['running'] != 1 | return | endif
let client['running'] = 0
let client['chan_id'] = 0
let client['channel'] = v:null
let client['async_req_id'] = 1
if a:code != 0 && a:code != 143
echohl Error | echom 'client '.a:name. ' abnormal exit with: '.a:code | echohl None
endif
endfunction
function! s:get_channel(client)
if s:is_vim
return a:client['channel']
endif
return a:client['chan_id']
endfunction
function! s:request(method, args) dict
let channel = s:get_channel(self)
if empty(channel) | return '' | endif
try
if s:is_vim
let res = ch_evalexpr(channel, [a:method, a:args], {'timeout': 30000})
if type(res) == 1 && res ==# ''
throw 'timeout after 30s'
endif
let [l:errmsg, res] = res
if !empty(l:errmsg)
throw l:errmsg
else
return res
endif
endif
return call('rpcrequest', [channel, a:method] + a:args)
catch /.*/
if v:exception =~# 'E475'
if get(g:, 'coc_vim_leaving', 0) | return | endif
echohl Error | echom '['.self.name.'] server connection lost' | echohl None
let name = self.name
call s:on_exit(name, 0)
execute 'silent do User ConnectionLost'.toupper(name[0]).name[1:]
elseif v:exception =~# 'E12'
" neovim's bug, ignore it
else
echohl Error | echo 'Error on request ('.a:method.'): '.v:exception | echohl None
endif
endtry
endfunction
function! s:notify(method, args) dict
let channel = s:get_channel(self)
if empty(channel) | return '' | endif
try
if s:is_vim
call ch_sendraw(channel, json_encode([0, [a:method, a:args]])."\n")
else
call call('rpcnotify', [channel, a:method] + a:args)
endif
catch /.*/
if v:exception =~# 'E475'
if get(g:, 'coc_vim_leaving', 0) | return | endif
echohl Error | echom '['.self.name.'] server connection lost' | echohl None
let name = self.name
call s:on_exit(name, 0)
execute 'silent do User ConnectionLost'.toupper(name[0]).name[1:]
elseif v:exception =~# 'E12'
" neovim's bug, ignore it
else
echohl Error | echo 'Error on notify ('.a:method.'): '.v:exception | echohl None
endif
endtry
endfunction
function! s:request_async(method, args, cb) dict
let channel = s:get_channel(self)
if empty(channel) | return '' | endif
if type(a:cb) != 2
echohl Error | echom '['.self['name'].'] Callback should be function' | echohl None
return
endif
let id = self.async_req_id
let self.async_req_id = id + 1
let self.async_callbacks[id] = a:cb
call self['notify']('nvim_async_request_event', [id, a:method, a:args])
endfunction
function! s:on_async_response(id, resp, isErr) dict
let Callback = get(self.async_callbacks, a:id, v:null)
if empty(Callback)
" should not happen
echohl Error | echom 'callback not found' | echohl None
return
endif
call remove(self.async_callbacks, a:id)
if a:isErr
call call(Callback, [a:resp, v:null])
else
call call(Callback, [v:null, a:resp])
endif
endfunction
function! coc#client#is_running(name) abort
let client = get(s:clients, a:name, v:null)
if empty(client) | return 0 | endif
if !client['running'] | return 0 | endif
if s:is_vim
let status = job_status(ch_getjob(client['channel']))
return status ==# 'run'
else
let chan_id = client['chan_id']
let [code] = jobwait([chan_id], 10)
return code == -1
endif
endfunction
function! coc#client#stop(name) abort
let client = get(s:clients, a:name, v:null)
if empty(client) | return 1 | endif
let running = coc#client#is_running(a:name)
if !running
echohl WarningMsg | echom 'client '.a:name. ' not running.' | echohl None
return 1
endif
if s:is_vim
call job_stop(ch_getjob(client['channel']), 'term')
else
call jobstop(client['chan_id'])
endif
sleep 200m
if coc#client#is_running(a:name)
echohl Error | echom 'client '.a:name. ' stop failed.' | echohl None
return 0
endif
call s:on_exit(a:name, 0)
echohl MoreMsg | echom 'client '.a:name.' stopped!' | echohl None
return 1
endfunction
function! coc#client#request(name, method, args)
let client = get(s:clients, a:name, v:null)
if !empty(client)
return client['request'](a:method, a:args)
endif
endfunction
function! coc#client#notify(name, method, args)
let client = get(s:clients, a:name, v:null)
if !empty(client)
call client['notify'](a:method, a:args)
endif
endfunction
function! coc#client#request_async(name, method, args, cb)
let client = get(s:clients, a:name, v:null)
if !empty(client)
call client['request_async'](a:method, a:args, a:cb)
endif
endfunction
function! coc#client#on_response(name, id, resp, isErr)
let client = get(s:clients, a:name, v:null)
if !empty(client)
call client['on_async_response'](a:id, a:resp, a:isErr)
endif
endfunction
function! coc#client#restart(name) abort
let stopped = coc#client#stop(a:name)
if !stopped | return | endif
let client = get(s:clients, a:name, v:null)
if !empty(client)
call client['start']()
endif
endfunction
function! coc#client#restart_all()
for key in keys(s:clients)
call coc#client#restart(key)
endfor
endfunction
function! coc#client#open_log()
execute 'vs '.s:logfile
endfunction

View File

@@ -0,0 +1,257 @@
let s:activated = 0
let s:is_vim = !has('nvim')
let s:saved_ve = &t_ve
let s:saved_cursor = &guicursor
let s:gui = has('gui_running') || has('nvim')
function! coc#list#get_chars()
return {
\ '<plug>': "\<Plug>",
\ '<esc>': "\<Esc>",
\ '<tab>': "\<Tab>",
\ '<s-tab>': "\<S-Tab>",
\ '<bs>': "\<bs>",
\ '<right>': "\<right>",
\ '<left>': "\<left>",
\ '<up>': "\<up>",
\ '<down>': "\<down>",
\ '<home>': "\<home>",
\ '<end>': "\<end>",
\ '<cr>': "\<cr>",
\ '<PageUp>' : "\<PageUp>",
\ '<PageDown>' : "\<PageDown>",
\ '<FocusGained>' : "\<FocusGained>",
\ '<ScrollWheelUp>': "\<ScrollWheelUp>",
\ '<ScrollWheelDown>': "\<ScrollWheelDown>",
\ '<LeftMouse>': "\<LeftMouse>",
\ '<LeftDrag>': "\<LeftDrag>",
\ '<LeftRelease>': "\<LeftRelease>",
\ '<2-LeftMouse>': "\<2-LeftMouse>",
\ '<C-a>': "\<C-a>",
\ '<C-b>': "\<C-b>",
\ '<C-c>': "\<C-c>",
\ '<C-d>': "\<C-d>",
\ '<C-e>': "\<C-e>",
\ '<C-f>': "\<C-f>",
\ '<C-g>': "\<C-g>",
\ '<C-h>': "\<C-h>",
\ '<C-i>': "\<C-i>",
\ '<C-j>': "\<C-j>",
\ '<C-k>': "\<C-k>",
\ '<C-l>': "\<C-l>",
\ '<C-m>': "\<C-m>",
\ '<C-n>': "\<C-n>",
\ '<C-o>': "\<C-o>",
\ '<C-p>': "\<C-p>",
\ '<C-q>': "\<C-q>",
\ '<C-r>': "\<C-r>",
\ '<C-s>': "\<C-s>",
\ '<C-t>': "\<C-t>",
\ '<C-u>': "\<C-u>",
\ '<C-v>': "\<C-v>",
\ '<C-w>': "\<C-w>",
\ '<C-x>': "\<C-x>",
\ '<C-y>': "\<C-y>",
\ '<C-z>': "\<C-z>",
\ '<A-a>': "\<A-a>",
\ '<A-b>': "\<A-b>",
\ '<A-c>': "\<A-c>",
\ '<A-d>': "\<A-d>",
\ '<A-e>': "\<A-e>",
\ '<A-f>': "\<A-f>",
\ '<A-g>': "\<A-g>",
\ '<A-h>': "\<A-h>",
\ '<A-i>': "\<A-i>",
\ '<A-j>': "\<A-j>",
\ '<A-k>': "\<A-k>",
\ '<A-l>': "\<A-l>",
\ '<A-m>': "\<A-m>",
\ '<A-n>': "\<A-n>",
\ '<A-o>': "\<A-o>",
\ '<A-p>': "\<A-p>",
\ '<A-q>': "\<A-q>",
\ '<A-r>': "\<A-r>",
\ '<A-s>': "\<A-s>",
\ '<A-t>': "\<A-t>",
\ '<A-u>': "\<A-u>",
\ '<A-v>': "\<A-v>",
\ '<A-w>': "\<A-w>",
\ '<A-x>': "\<A-x>",
\ '<A-y>': "\<A-y>",
\ '<A-z>': "\<A-z>",
\}
endfunction
function! coc#list#getc() abort
let c = getchar()
return type(c) == type(0) ? nr2char(c) : c
endfunction
function! coc#list#getchar() abort
let input = coc#list#getc()
if 1 != &iminsert
return input
endif
"a language keymap is activated, so input must be resolved to the mapped values.
let partial_keymap = mapcheck(input, "l")
while partial_keymap !=# ""
let full_keymap = maparg(input, "l")
if full_keymap ==# "" && len(input) >= 3 "HACK: assume there are no keymaps longer than 3.
return input
elseif full_keymap ==# partial_keymap
return full_keymap
endif
let c = coc#list#getc()
if c ==# "\<Esc>" || c ==# "\<CR>"
"if the short sequence has a valid mapping, return that.
if !empty(full_keymap)
return full_keymap
endif
return input
endif
let input .= c
let partial_keymap = mapcheck(input, "l")
endwhile
return input
endfunction
function! coc#list#prompt_start() abort
call timer_start(100, {-> coc#list#start_prompt()})
endfunction
function! coc#list#start_prompt()
if s:activated | return | endif
if s:gui && !empty(s:saved_cursor)
set guicursor+=a:ver1-Cursor-blinkoff999
elseif s:is_vim
set t_ve=
endif
let s:activated = 1
try
while s:activated
let ch = coc#list#getchar()
if ch ==# "\u26d4"
break
endif
if ch ==# "\<FocusLost>" || ch ==# "\<FocusGained>" || ch ==# "\<CursorHold>"
continue
else
call coc#rpc#notify('InputChar', [ch, getcharmod()])
endif
endwhile
catch /^Vim:Interrupt$/
let s:activated = 0
call coc#rpc#notify('InputChar', ["\<C-c>"])
return
endtry
let s:activated = 0
endfunction
function! coc#list#setlines(lines, append)
let total = line('$')
if a:append
silent call append(line('$'), a:lines)
else
silent call append(0, a:lines)
let n = len(a:lines) + 1
let saved_reg = @"
silent execute n.',$d'
let @" = saved_reg
endif
endfunction
function! coc#list#options(...)
let list = ['--top', '--tab', '--normal', '--no-sort', '--input', '--strict',
\ '--regex', '--interactive', '--number-select', '--auto-preview']
if get(g:, 'coc_enabled', 0)
let names = coc#rpc#request('listNames', [])
call extend(list, names)
endif
return join(list, "\n")
endfunction
function! coc#list#stop_prompt(...)
if get(a:, 1, 0) == 0
if s:gui
let &guicursor = s:saved_cursor
elseif s:is_vim
let &t_ve = s:saved_ve
endif
endif
if s:activated
let s:activated = 0
call feedkeys("\u26d4", 'int')
endif
endfunction
function! coc#list#status(name)
if !exists('b:list_status') | return '' | endif
return get(b:list_status, a:name, '')
endfunction
function! coc#list#create(position, height, name, numberSelect)
nohlsearch
if a:position ==# 'tab'
execute 'silent tabe list:///'.a:name
else
execute 'silent keepalt '.(a:position ==# 'top' ? '' : 'botright').a:height.'sp list:///'.a:name
execute 'resize '.a:height
endif
if a:numberSelect
setl number
else
setl nonumber
setl foldcolumn=2
endif
return [bufnr('%'), win_getid()]
endfunction
function! coc#list#setup(source)
let b:list_status = {}
let statusParts = [
\ '%#CocListMode#-- %{get(b:list_status, "mode")} --%*',
\ '%{get(g:, "coc_list_loading_status", "")}',
\ '%{get(b:list_status, "args", "")}',
\ '(%L/%{get(b:list_status, "total", "")})',
\ '%=',
\ '%#CocListPath# %{get(b:list_status, "cwd", "")} %l/%L%*'
\ ]
call setwinvar(winnr(), '&statusline', join(statusParts, ' '))
setl buftype=nofile nobuflisted nofen nowrap
setl norelativenumber bufhidden=wipe cursorline winfixheight
setl tabstop=1 nolist nocursorcolumn
setl signcolumn=auto
setl filetype=list
syntax case ignore
let source = a:source[8:]
let name = toupper(source[0]).source[1:]
execute 'syntax match Coc'.name.'Line /\v^.*$/'
nnoremap <silent><nowait><buffer> <esc> <C-w>c
endfunction
function! coc#list#has_preview()
for i in range(1, winnr('$'))
let preview = getwinvar(i, '&previewwindow')
if preview
return 1
endif
endfor
return 0
endfunction
function! coc#list#restore(winid, height)
let res = win_gotoid(a:winid)
if res == 0 | return | endif
if winnr('$') == 1
return
endif
execute 'resize '.a:height
if s:is_vim
redraw
endif
endfunction
function! coc#list#set_height(height) abort
if winnr('$') == 1| return | endif
execute 'resize '.a:height
endfunction

View File

@@ -0,0 +1,130 @@
let s:is_win = has("win32") || has("win64")
let s:client = v:null
let s:name = 'coc'
let s:is_vim = !has('nvim')
function! coc#rpc#start_server()
if $NODE_ENV ==# 'test'
" server already started
let s:client = coc#client#create(s:name, [])
let s:client['running'] = 1
let s:client['chan_id'] = get(g:, 'coc_node_channel_id', 0)
call dictwatcheradd(g:, 'coc_node_channel_id', function('s:ChannelSet'))
return
endif
if empty(s:client)
let cmd = coc#util#job_command()
if empty(cmd) | return | endif
let $COC_VIMCONFIG = coc#util#get_config_home()
let s:client = coc#client#create(s:name, cmd)
endif
if !coc#client#is_running('coc')
call s:client['start']()
endif
endfunction
function! coc#rpc#started() abort
return !empty(s:client)
endfunction
function! coc#rpc#ready()
if empty(s:client) || s:client['running'] == 0
return 0
endif
return 1
endfunction
function! s:ChannelSet(dict, key, val)
let chan_id = get(a:val, 'new', 0)
if empty(s:client) | return | endif
let s:client['running'] = 1
let s:client['chan_id'] = chan_id
call dictwatcherdel(g:, 'coc_node_channel_id', function('s:ChannelSet'))
endfunction
function! coc#rpc#kill()
let pid = get(g:, 'coc_process_pid', 0)
if !pid | return | endif
if s:is_win
call system('taskkill /PID '.pid)
else
call system('kill -9 '.pid)
endif
endfunction
function! coc#rpc#get_errors()
return split(execute('messages'), "\n")
endfunction
function! coc#rpc#stop()
if empty(s:client)
return
endif
try
if s:is_vim
call job_stop(ch_getjob(s:client['channel']), 'term')
else
call jobstop(s:client['chan_id'])
endif
catch /.*/
" ignore
endtry
endfunction
function! coc#rpc#restart()
if empty(s:client)
call coc#rpc#start_server()
else
for i in range(1, winnr('$'))
if getwinvar(i, 'float')
execute i.'wincmd c'
endif
endfor
call coc#rpc#request('detach', [])
sleep 100m
let s:client['command'] = coc#util#job_command()
call coc#client#restart(s:name)
echohl MoreMsg | echom 'starting coc.nvim service' | echohl None
endif
endfunction
function! coc#rpc#request(method, args) abort
if !coc#rpc#ready()
return ''
endif
return s:client['request'](a:method, a:args)
endfunction
function! coc#rpc#notify(method, args) abort
if !coc#rpc#ready()
return ''
endif
call s:client['notify'](a:method, a:args)
return ''
endfunction
function! coc#rpc#request_async(method, args, cb) abort
if !coc#rpc#ready()
return cb('coc.nvim service not started.')
endif
call s:client['request_async'](a:method, a:args, a:cb)
endfunction
" receive async response
function! coc#rpc#async_response(id, resp, isErr) abort
if empty(s:client)
return
endif
call coc#client#on_response(s:name, a:id, a:resp, a:isErr)
endfunction
" send async response to server
function! coc#rpc#async_request(id, method, args)
let l:Cb = {err, res -> coc#rpc#notify('nvim_async_response_event', [a:id, err, res])}
let args = a:args + [l:Cb]
try
call call(a:method, args)
catch /.*/
call coc#rpc#notify('nvim_async_response_event', [a:id, v:exception])
endtry
endfunction

View File

@@ -0,0 +1,66 @@
let s:is_vim = !has('nvim')
let s:map_next = 1
function! coc#snippet#_select_mappings()
if !get(g:, 'coc_selectmode_mapping', 1)
return
endif
redir => mappings
silent! smap
redir END
for map in map(filter(split(mappings, '\n'),
\ "v:val !~# '^s' && v:val !~# '^\\a*\\s*<\\S\\+>'"),
\ "matchstr(v:val, '^\\a*\\s*\\zs\\S\\+')")
silent! execute 'sunmap' map
silent! execute 'sunmap <buffer>' map
endfor
" same behaviour of ultisnips
snoremap <silent> <BS> <c-g>c
snoremap <silent> <DEL> <c-g>c
snoremap <silent> <c-h> <c-g>c
snoremap <c-r> <c-g>"_c<c-r>
endfunction
function! coc#snippet#show_choices(lnum, col, len, values) abort
let m = mode()
call cursor(a:lnum, a:col + a:len)
if m !=# 'i' | startinsert | endif
call timer_start(20, { -> coc#_do_complete(a:col - 1, a:values, 0)})
redraw
endfunction
function! coc#snippet#enable()
let b:coc_snippet_active = 1
call coc#snippet#_select_mappings()
let nextkey = get(g:, 'coc_snippet_next', '<C-j>')
let prevkey = get(g:, 'coc_snippet_prev', '<C-k>')
nnoremap <buffer> <silent> <esc> :call coc#rpc#request('snippetCancel', [])<cr>
if maparg(nextkey, 'i') =~# 'expand-jump'
let s:map_next = 0
endif
if s:map_next
execute 'inoremap <buffer><nowait><silent>'.nextkey." <C-R>=coc#rpc#request('snippetNext', [])<cr>"
endif
execute 'inoremap <buffer><nowait><silent>'.prevkey." <C-R>=coc#rpc#request('snippetPrev', [])<cr>"
execute 'snoremap <buffer><nowait><silent>'.prevkey." <Esc>:call coc#rpc#request('snippetPrev', [])<cr>"
execute 'snoremap <buffer><nowait><silent>'.nextkey." <Esc>:call coc#rpc#request('snippetNext', [])<cr>"
endfunction
function! coc#snippet#disable()
if get(b:, 'coc_snippet_active', 0) == 0
return
endif
let b:coc_snippet_active = 0
let nextkey = get(g:, 'coc_snippet_next', '<C-j>')
let prevkey = get(g:, 'coc_snippet_prev', '<C-k>')
silent! nunmap <buffer> <esc>
if s:map_next
silent! execute 'iunmap <buffer> <silent> '.nextkey
endif
silent! execute 'iunmap <buffer> <silent> '.prevkey
silent! execute 'sunmap <buffer> <silent> '.prevkey
silent! execute 'sunmap <buffer> <silent> '.nextkey
endfunction

View File

@@ -0,0 +1,109 @@
" ============================================================================
" Description: Manage long running tasks.
" Author: Qiming Zhao <chemzqm@gmail.com>
" Licence: MIT licence
" Version: 0.1
" Last Modified: April 08, 2019
" ============================================================================
let s:is_vim = !has('nvim')
let s:running_task = {}
function! coc#task#start(id, opts)
if coc#task#running(a:id)
call coc#task#stop(a:id)
endif
let cmd = [a:opts['cmd']] + get(a:opts, 'args', [])
let cwd = get(a:opts, 'cwd', getcwd())
" cmd args cwd pty
if s:is_vim
let options = {
\ 'cwd': cwd,
\ 'err_mode': 'nl',
\ 'out_mode': 'nl',
\ 'err_cb': {channel, message -> s:on_stderr(a:id, [message])},
\ 'out_cb': {channel, message -> s:on_stdout(a:id, [message])},
\ 'exit_cb': {channel, code -> s:on_exit(a:id, code)},
\}
if has("patch-8.1.350")
let options['noblock'] = 1
endif
if get(a:opts, 'pty', 0)
let options['pty'] = 1
endif
let job = job_start(cmd, options)
let status = job_status(job)
if status !=# 'run'
echohl Error | echom 'Failed to start '.a:id.' task' | echohl None
return v:false
endif
let s:running_task[a:id] = job
else
let options = {
\ 'cwd': cwd,
\ 'on_stderr': {channel, msgs -> s:on_stderr(a:id, filter(msgs, 'v:val !=""'))},
\ 'on_stdout': {channel, msgs -> s:on_stdout(a:id, filter(msgs, 'v:val !=""'))},
\ 'on_exit': {channel, code -> s:on_exit(a:id, code)},
\ 'detach': get(a:opts, 'detach', 0),
\}
if get(a:opts, 'pty', 0)
let options['pty'] = 1
endif
let chan_id = jobstart(cmd, options)
if chan_id <= 0
echohl Error | echom 'Failed to start '.a:id.' task' | echohl None
return v:false
endif
let s:running_task[a:id] = chan_id
endif
return v:true
endfunction
function! coc#task#stop(id)
let job = get(s:running_task, a:id, v:null)
if !job | return | endif
if s:is_vim
call job_stop(job, 'term')
else
call jobstop(job)
endif
sleep 50m
let running = coc#task#running(a:id)
if running
echohl Error | echom 'job '.a:id. ' stop failed.' | echohl None
endif
endfunction
function! s:on_exit(id, code) abort
if get(g:, 'coc_vim_leaving', 0) | return | endif
if has_key(s:running_task, a:id)
call remove(s:running_task, a:id)
endif
call coc#rpc#notify('TaskExit', [a:id, a:code])
endfunction
function! s:on_stderr(id, msgs)
if get(g:, 'coc_vim_leaving', 0) | return | endif
if len(a:msgs)
call coc#rpc#notify('TaskStderr', [a:id, a:msgs])
endif
endfunction
function! s:on_stdout(id, msgs)
if len(a:msgs)
call coc#rpc#notify('TaskStdout', [a:id, a:msgs])
endif
endfunction
function! coc#task#running(id)
if !has_key(s:running_task, a:id) == 1
return v:false
endif
let job = s:running_task[a:id]
if s:is_vim
let status = job_status(job)
return status ==# 'run'
endif
let [code] = jobwait([job], 10)
return code == -1
endfunction

View File

@@ -0,0 +1,96 @@
let s:is_vim = !has('nvim')
let s:channel_map = {}
let s:is_win = has('win32') || has('win64')
" start terminal, return [bufnr, pid]
function! coc#terminal#start(cmd, cwd, env) abort
if s:is_vim && !has('terminal')
throw 'terminal feature not supported by current vim.'
endif
let cwd = empty(a:cwd) ? getcwd() : a:cwd
execute 'belowright 8new +setl\ buftype=nofile'
setl winfixheight
setl norelativenumber
setl nonumber
setl bufhidden=hide
if exists('#User#CocTerminalOpen')
exe 'doautocmd User CocTerminalOpen'
endif
let bufnr = bufnr('%')
function! s:OnExit(status) closure
if a:status == 0
execute 'silent! bd! '.bufnr
endif
endfunction
if has('nvim')
if !empty(a:env)
for key in keys(a:env)
execute 'let $'.key." = '".a:env[key]."'"
endfor
endif
let job_id = termopen(a:cmd, {
\ 'cwd': cwd,
\ 'pty': 1,
\ 'on_exit': {job, status -> s:OnExit(status)},
\ })
if job_id == 0
throw 'create terminal job failed'
endif
wincmd p
let s:channel_map[bufnr] = job_id
return [bufnr, jobpid(job_id)]
else
let cmd = s:is_win ? join(a:cmd, ' ') : a:cmd
let res = term_start(cmd, {
\ 'cwd': cwd,
\ 'term_kill': s:is_win ? 'kill' : 'term',
\ 'term_finish': 'close',
\ 'exit_cb': {job, status -> s:OnExit(status)},
\ 'curwin': 1,
\ 'env': a:env,
\})
if res == 0
throw 'create terminal job failed'
endif
let job = term_getjob(bufnr)
let s:channel_map[bufnr] = job_getchannel(job)
wincmd p
return [bufnr, job_info(job).process]
endif
endfunction
function! coc#terminal#send(bufnr, text, add_new_line) abort
let chan = get(s:channel_map, a:bufnr, v:null)
if empty(chan) | return| endif
if has('nvim')
let lines = split(a:text, '\v\r?\n')
if a:add_new_line && !empty(lines[len(lines) - 1])
call add(lines, '')
endif
call chansend(chan, lines)
let winnr = bufwinnr(a:bufnr)
if winnr != -1
exe 'noa '.winnr.'wincmd w'
exe 'noa normal! G'
exe 'noa '.wincmd p
endif
else
if !a:add_new_line
call ch_sendraw(chan, a:text)
else
call ch_sendraw(chan, a:text.(s:is_win ? "\r\n" : "\n"))
endif
endif
endfunction
function! coc#terminal#close(bufnr) abort
if has('nvim')
let job_id = get(s:channel_map, a:bufnr, 0)
if !empty(job_id)
silent! call chanclose(job_id)
endif
endif
exe 'silent! bd! '.a:bufnr
endfunction

View File

@@ -0,0 +1,971 @@
let s:root = expand('<sfile>:h:h:h')
let s:is_win = has('win32') || has('win64')
let s:is_vim = !has('nvim')
let s:activate = ""
let s:quit = ""
if has("gui_macvim") && has('gui_running')
let s:app = "MacVim"
elseif $TERM_PROGRAM ==# "Apple_Terminal"
let s:app = "Terminal"
elseif $TERM_PROGRAM ==# "iTerm.app"
let s:app = "iTerm2"
elseif has('mac')
let s:app = "System Events"
let s:quit = "quit"
let s:activate = 'activate'
endif
function! coc#util#has_preview()
for i in range(1, winnr('$'))
if getwinvar(i, '&previewwindow')
return i
endif
endfor
return 0
endfunction
function! coc#util#has_float()
for i in range(1, winnr('$'))
if getwinvar(i, 'float')
return 1
endif
endfor
return 0
endfunction
function! coc#util#get_float()
for i in range(1, winnr('$'))
if getwinvar(i, 'float')
return win_getid(i)
endif
endfor
return 0
endfunction
function! coc#util#float_hide()
for i in range(1, winnr('$'))
if getwinvar(i, 'float')
let winid = win_getid(i)
call coc#util#close_win(winid)
endif
endfor
endfunction
function! coc#util#float_jump()
for i in range(1, winnr('$'))
if getwinvar(i, 'float')
exe i.'wincmd w'
return
endif
endfor
endfunction
function! coc#util#float_scrollable()
let winnr = winnr()
for i in range(1, winnr('$'))
if getwinvar(i, 'float')
let wid = win_getid(i)
let h = nvim_win_get_height(wid)
let buf = nvim_win_get_buf(wid)
let lineCount = nvim_buf_line_count(buf)
return lineCount > h
endif
endfor
return 0
endfunction
function! coc#util#float_scroll(forward)
let key = a:forward ? "\<C-f>" : "\<C-b>"
let winnr = winnr()
for i in range(1, winnr('$'))
if getwinvar(i, 'float')
return i."\<C-w>w".key."\<C-w>p"
endif
endfor
return ""
endfunction
" get cursor position
function! coc#util#cursor()
let pos = getcurpos()
let content = pos[2] == 1 ? '' : getline('.')[0: pos[2] - 2]
return [pos[1] - 1, strchars(content)]
endfunction
function! coc#util#close_win(id)
if !has('nvim') && exists('*popup_close')
call popup_close(a:id)
return
endif
if exists('*nvim_win_close')
if nvim_win_is_valid(a:id)
call nvim_win_close(a:id, 1)
endif
else
let winnr = win_id2win(a:id)
if winnr > 0
execute winnr.'close!'
endif
endif
endfunction
function! coc#util#close(id) abort
if exists('*nvim_win_close')
if nvim_win_is_valid(a:id)
call nvim_win_close(a:id, 1)
endif
else
let winnr = win_id2win(a:id)
if winnr > 0
execute winnr.'close!'
endif
endif
endfunction
function! coc#util#win_position()
let nr = winnr()
let [row, col] = win_screenpos(nr)
return [row + winline() - 2, col + wincol() - 2]
endfunction
function! coc#util#close_popup()
if s:is_vim
if exists('*popup_close')
call popup_close(get(g:, 'coc_popup_id', 0))
endif
else
for winnr in range(1, winnr('$'))
if getwinvar(winnr, 'popup', 0)
exe winnr.'close!'
endif
endfor
endif
endfunction
function! coc#util#version()
let c = execute('silent version')
return matchstr(c, 'NVIM v\zs[^\n-]*')
endfunction
function! coc#util#valid_state()
if s:is_vim && mode() !=# 'n'
return 0
endif
if get(g: , 'EasyMotion_loaded', 0)
return EasyMotion#is_active() != 1
endif
return 1
endfunction
function! coc#util#open_file(cmd, file)
let file = fnameescape(a:file)
execute a:cmd .' '.file
endfunction
function! coc#util#platform()
if s:is_win
return 'windows'
endif
if has('mac') || has('macvim')
return 'mac'
endif
return 'linux'
endfunction
function! coc#util#remote_fns(name)
let fns = ['init', 'complete', 'should_complete', 'refresh', 'get_startcol', 'on_complete', 'on_enter']
let res = []
for fn in fns
if exists('*coc#source#'.a:name.'#'.fn)
call add(res, fn)
endif
endfor
return res
endfunction
function! coc#util#job_command()
let node = get(g:, 'coc_node_path', 'node')
if !executable(node)
echohl Error | echom '[coc.nvim] '.node.' is not executable, checkout https://nodejs.org/en/download/' | echohl None
return
endif
let bundle = s:root.'/build/index.js'
if filereadable(bundle) && !get(g:, 'coc_force_debug', 0)
return [node] + get(g:, 'coc_node_args', ['--no-warnings']) + [s:root.'/build/index.js']
endif
let file = s:root.'/lib/attach.js'
if !filereadable(file)
if !filereadable(bundle)
echohl Error | echom '[coc.nvim] javascript file not found, please compile the code or use release branch.' | echohl None
else
echohl Error | echom '[coc.nvim] compiled javascript file not found, remove let g:coc_force_debug = 1 in your vimrc.' | echohl None
endif
return
endif
return [node] + get(g:, 'coc_node_args', ['--no-warnings']) + [s:root.'/bin/server.js']
endfunction
function! coc#util#echo_hover(msg)
echohl MoreMsg
echo a:msg
echohl None
let g:coc_last_hover_message = a:msg
endfunction
function! coc#util#execute(cmd)
silent exe a:cmd
if &filetype ==# ''
filetype detect
endif
if s:is_vim
redraw!
endif
endfunction
function! coc#util#jump(cmd, filepath, ...) abort
let path = a:filepath
if (has('win32unix'))
let path = substitute(a:filepath, '\v\\', '/', 'g')
endif
let file = fnamemodify(path, ":~:.")
if a:cmd =~# '^tab'
exe a:cmd.' '.fnameescape(file)
if !empty(get(a:, 1, []))
call cursor(a:1[0], a:1[1])
endif
else
if !empty(get(a:, 1, []))
exe a:cmd.' +call\ cursor('.a:1[0].','.a:1[1].')'.' '.fnameescape(file)
else
exe a:cmd.' '.fnameescape(file)
endif
endif
if &l:filetype ==# ''
filetype detect
endif
if s:is_vim
redraw
endif
endfunction
function! coc#util#jumpTo(line, character) abort
let content = getline(a:line + 1)
let pre = strcharpart(content, 0, a:character)
let col = strlen(pre) + 1
call cursor(a:line + 1, col)
if s:is_vim
redraw
endif
endfunction
function! coc#util#echo_messages(hl, msgs)
if empty(a:msgs) | return | endif
if a:hl !~# 'Error' && (mode() !~# '\v^(i|n)$')
return
endif
execute 'echohl '.a:hl
let msgs = filter(copy(a:msgs), '!empty(v:val)')
for msg in msgs
echom msg
endfor
echohl None
endfunction
function! coc#util#echo_lines(lines)
echo join(a:lines, "\n")
endfunction
function! coc#util#timer(method, args)
call timer_start(0, { -> s:Call(a:method, a:args)})
endfunction
function! s:Call(method, args)
try
call call(a:method, a:args)
redraw
catch /.*/
return 0
endtry
endfunction
function! coc#util#is_preview(bufnr)
let wnr = bufwinnr(a:bufnr)
if wnr == -1 | return 0 | endif
return getwinvar(wnr, '&previewwindow')
endfunction
function! coc#util#get_bufoptions(bufnr) abort
if !bufloaded(a:bufnr) | return v:null | endif
let bufname = bufname(a:bufnr)
return {
\ 'bufname': bufname,
\ 'eol': getbufvar(a:bufnr, '&eol'),
\ 'variables': s:variables(a:bufnr),
\ 'fullpath': empty(bufname) ? '' : fnamemodify(bufname, ':p'),
\ 'buftype': getbufvar(a:bufnr, '&buftype'),
\ 'filetype': getbufvar(a:bufnr, '&filetype'),
\ 'iskeyword': getbufvar(a:bufnr, '&iskeyword'),
\ 'changedtick': getbufvar(a:bufnr, 'changedtick'),
\}
endfunction
function! s:variables(bufnr) abort
let info = getbufinfo({'bufnr':a:bufnr, 'variables': 1})
let variables = copy(info[0]['variables'])
for key in keys(variables)
if key !~# '\v^coc'
unlet variables[key]
endif
endfor
return variables
endfunction
function! coc#util#root_patterns()
return coc#rpc#request('rootPatterns', [bufnr('%')])
endfunction
function! coc#util#on_error(msg) abort
echohl Error | echom '[coc.nvim] '.a:msg | echohl None
endfunction
function! coc#util#preview_info(info, ...) abort
let filetype = get(a:, 1, 'markdown')
pclose
keepalt new +setlocal\ previewwindow|setlocal\ buftype=nofile|setlocal\ noswapfile|setlocal\ wrap [Document]
setl bufhidden=wipe
setl nobuflisted
setl nospell
exe 'setl filetype='.filetype
setl conceallevel=2
setl nofoldenable
let lines = a:info
call append(0, lines)
exe "normal! z" . len(lines) . "\<cr>"
exe "normal! gg"
wincmd p
endfunction
function! coc#util#get_config_home()
if !empty(get(g:, 'coc_config_home', ''))
return g:coc_config_home
endif
if exists('$VIMCONFIG')
return resolve($VIMCONFIG)
endif
if has('nvim')
if exists('$XDG_CONFIG_HOME')
return resolve($XDG_CONFIG_HOME."/nvim")
endif
if s:is_win
return resolve($HOME.'/AppData/Local/nvim')
endif
return resolve($HOME.'/.config/nvim')
else
if s:is_win
return resolve($HOME."/vimfiles")
endif
return resolve($HOME.'/.vim')
endif
endfunction
function! coc#util#get_input()
let pos = getcurpos()
let line = getline('.')
let l:start = pos[2] - 1
while l:start > 0 && line[l:start - 1] =~# '\k'
let l:start -= 1
endwhile
return pos[2] == 1 ? '' : line[l:start : pos[2] - 2]
endfunction
function! coc#util#move_cursor(delta)
let pos = getcurpos()
call cursor(pos[1], pos[2] + a:delta)
endfunction
function! coc#util#get_complete_option()
let disabled = get(b:, 'coc_suggest_disable', 0)
if disabled | return | endif
let blacklist = get(b:, 'coc_suggest_blacklist', [])
let pos = getcurpos()
let l:start = pos[2] - 1
let line = getline(pos[1])
for char in reverse(split(line[0: l:start - 1], '\zs'))
if l:start > 0 && char =~# '\k'
let l:start = l:start - strlen(char)
else
break
endif
endfor
let input = pos[2] == 1 ? '' : line[l:start : pos[2] - 2]
if !empty(blacklist) && index(blacklist, input) >= 0
return
endif
let synname = synIDattr(synID(pos[1], l:start, 1),"name")
if !synname
let synname = ''
endif
return {
\ 'word': matchstr(line[l:start : ], '^\k\+'),
\ 'input': input,
\ 'line': line,
\ 'filetype': &filetype,
\ 'filepath': expand('%:p'),
\ 'bufnr': bufnr('%'),
\ 'linenr': pos[1],
\ 'colnr' : pos[2],
\ 'col': l:start,
\ 'synname': synname,
\ 'blacklist': blacklist,
\}
endfunction
function! coc#util#with_callback(method, args, cb)
function! s:Cb() closure
try
let res = call(a:method, a:args)
call a:cb(v:null, res)
catch /.*/
call a:cb(v:exception)
endtry
endfunction
let timeout = s:is_vim ? 10 : 0
call timer_start(timeout, {-> s:Cb() })
endfunction
function! coc#util#add_matchids(ids)
let w:coc_matchids = get(w:, 'coc_matchids', []) + a:ids
endfunction
function! coc#util#prompt_confirm(title)
if exists('*confirm') && !s:is_vim
let choice = confirm(a:title, "&Yes\n&No")
return choice == 1
else
echohl MoreMsg
echom a:title.' (y/n)'
echohl None
let confirm = nr2char(getchar())
redraw!
if !(confirm ==? "y" || confirm ==? "\r")
echohl Moremsg | echo 'Cancelled.' | echohl None
return 0
end
return 1
endif
endfunction
function! coc#util#get_syntax_name(lnum, col)
return synIDattr(synIDtrans(synID(a:lnum,a:col,1)),"name")
endfunction
function! coc#util#echo_signatures(signatures) abort
if pumvisible() | return | endif
echo ""
for i in range(len(a:signatures))
call s:echo_signature(a:signatures[i])
if i != len(a:signatures) - 1
echon "\n"
endif
endfor
endfunction
function! s:echo_signature(parts)
for part in a:parts
let hl = get(part, 'type', 'Normal')
let text = get(part, 'text', '')
if !empty(text)
execute 'echohl '.hl
execute "echon '".substitute(text, "'", "''", 'g')."'"
echohl None
endif
endfor
endfunction
function! coc#util#unplace_signs(bufnr, sign_ids)
if !bufloaded(a:bufnr) | return | endif
for id in a:sign_ids
execute 'silent! sign unplace '.id.' buffer='.a:bufnr
endfor
endfunction
function! coc#util#setline(lnum, line)
keepjumps call setline(a:lnum, a:line)
endfunction
" cmd, cwd
function! coc#util#open_terminal(opts) abort
if s:is_vim && !exists('*term_start')
echohl WarningMsg | echon "Your vim doesn't have termnial support!" | echohl None
return
endif
if get(a:opts, 'position', 'bottom') ==# 'bottom'
let p = '5new'
else
let p = 'vnew'
endif
execute 'belowright '.p.' +setl\ buftype=nofile '
setl buftype=nofile
setl winfixheight
setl norelativenumber
setl nonumber
setl bufhidden=wipe
let cmd = get(a:opts, 'cmd', '')
let autoclose = get(a:opts, 'autoclose', 1)
if empty(cmd)
throw 'command required!'
endif
let cwd = get(a:opts, 'cwd', getcwd())
let keepfocus = get(a:opts, 'keepfocus', 0)
let bufnr = bufnr('%')
let Callback = get(a:opts, 'Callback', v:null)
function! s:OnExit(status) closure
let content = join(getbufline(bufnr, 1, '$'), "\n")
if a:status == 0 && autoclose == 1
execute 'silent! bd! '.bufnr
endif
if !empty(Callback)
call call(Callback, [a:status, bufnr, content])
endif
endfunction
if has('nvim')
call termopen(cmd, {
\ 'cwd': cwd,
\ 'on_exit': {job, status -> s:OnExit(status)},
\})
else
if s:is_win
let cmd = 'cmd.exe /C "'.cmd.'"'
endif
call term_start(cmd, {
\ 'cwd': cwd,
\ 'exit_cb': {job, status -> s:OnExit(status)},
\ 'curwin': 1,
\})
endif
if keepfocus
wincmd p
endif
return bufnr
endfunction
" run command in terminal
function! coc#util#run_terminal(opts, cb)
let cmd = get(a:opts, 'cmd', '')
if empty(cmd)
return a:cb('command required for terminal')
endif
let opts = {
\ 'cmd': cmd,
\ 'cwd': get(a:opts, 'cwd', getcwd()),
\ 'keepfocus': get(a:opts, 'keepfocus', 0),
\ 'Callback': {status, bufnr, content -> a:cb(v:null, {'success': status == 0 ? v:true : v:false, 'bufnr': bufnr, 'content': content})}
\}
call coc#util#open_terminal(opts)
endfunction
function! coc#util#getpid()
if !has('win32unix')
return getpid()
endif
let cmd = 'cat /proc/' . getpid() . '/winpid'
return substitute(system(cmd), '\v\n', '', 'gi')
endfunction
function! coc#util#vim_info()
return {
\ 'mode': mode(),
\ 'floating': has('nvim') && exists('*nvim_open_win') ? v:true : v:false,
\ 'extensionRoot': coc#util#extension_root(),
\ 'watchExtensions': get(g:, 'coc_watch_extensions', []),
\ 'globalExtensions': get(g:, 'coc_global_extensions', []),
\ 'config': get(g:, 'coc_user_config', {}),
\ 'pid': coc#util#getpid(),
\ 'columns': &columns,
\ 'lines': &lines,
\ 'cmdheight': &cmdheight,
\ 'filetypeMap': get(g:, 'coc_filetype_map', {}),
\ 'version': coc#util#version(),
\ 'completeOpt': &completeopt,
\ 'pumevent': exists('##MenuPopupChanged') || exists('##CompleteChanged'),
\ 'isVim': has('nvim') ? v:false : v:true,
\ 'isCygwin': has('win32unix') ? v:true : v:false,
\ 'isMacvim': has('gui_macvim') ? v:true : v:false,
\ 'colorscheme': get(g:, 'colors_name', ''),
\ 'workspaceFolders': get(g:, 'WorkspaceFolders', v:null),
\ 'background': &background,
\ 'runtimepath': &runtimepath,
\ 'locationlist': get(g:,'coc_enable_locationlist', 1),
\ 'progpath': v:progpath,
\ 'textprop': has('textprop') && has('patch-8.1.1522') && !has('nvim') ? v:true : v:false,
\}
endfunction
function! coc#util#highlight_options()
return {
\ 'colorscheme': get(g:, 'colors_name', ''),
\ 'background': &background,
\ 'runtimepath': &runtimepath,
\}
endfunction
" used by vim
function! coc#util#get_content(bufnr)
if !bufexists(a:bufnr) | return '' | endif
return {
\ 'content': join(getbufline(a:bufnr, 1, '$'), "\n"),
\ 'changedtick': getbufvar(a:bufnr, 'changedtick')
\ }
endfunction
" used for TextChangedI with InsertCharPre
function! coc#util#get_changeinfo()
return {
\ 'lnum': line('.'),
\ 'line': getline('.'),
\ 'changedtick': b:changedtick,
\}
endfunction
" show diff of current buffer
function! coc#util#diff_content(lines) abort
let tmpfile = tempname()
setl foldenable
call writefile(a:lines, tmpfile)
let ft = &filetype
diffthis
execute 'vs '.tmpfile
execute 'setf ' . ft
diffthis
setl foldenable
endfunction
function! coc#util#clear_signs()
let buflist = filter(range(1, bufnr('$')), 'buflisted(v:val)')
for b in buflist
let signIds = []
let lines = split(execute('sign place buffer='.b), "\n")
for line in lines
let ms = matchlist(line, 'id=\(\d\+\)\s\+name=Coc')
if len(ms) > 0
call add(signIds, ms[1])
endif
endfor
call coc#util#unplace_signs(b, signIds)
endfor
endfunction
function! coc#util#clearmatches(ids, ...)
let winid = get(a:, 1, 0)
if winid != 0 && win_getid() != winid
return
endif
for id in a:ids
try
call matchdelete(id)
catch /.*/
" matches have been cleared in other ways,
endtry
endfor
let exists = get(w:, 'coc_matchids', [])
if !empty(exists)
call filter(w:coc_matchids, 'index(a:ids, v:val) == -1')
endif
endfunction
function! coc#util#open_url(url)
if has('mac') && executable('open')
call system('open '.a:url)
return
endif
if executable('xdg-open')
call system('xdg-open '.a:url)
return
endif
call system('cmd /c start "" /b '. substitute(a:url, '&', '^&', 'g'))
if v:shell_error
echohl Error | echom 'Failed to open '.a:url | echohl None
return
endif
endfunction
function! coc#util#install(...) abort
let opts = get(a:, 1, {})
if !isdirectory(s:root.'/src')
echohl WarningMsg | echon '[coc.nvim] coc#util#install not needed for release branch.' | echohl None
return
endif
let cmd = (s:is_win ? 'install.cmd' : './install.sh') . ' nightly'
let cwd = getcwd()
exe 'lcd '.s:root
exe '!'.cmd
exe 'lcd '.cwd
call coc#rpc#restart()
endfunction
function! coc#util#do_complete(name, opt, cb) abort
let handler = 'coc#source#'.a:name.'#complete'
let l:Cb = {res -> a:cb(v:null, res)}
let args = [a:opt, l:Cb]
call call(handler, args)
endfunction
function! coc#util#extension_root() abort
if !empty($COC_TEST)
return s:root.'/src/__tests__/extensions'
endif
let dir = get(g:, 'coc_extension_root', '')
if empty(dir)
if s:is_win
let dir = $HOME.'/AppData/Local/coc/extensions'
else
let dir = $HOME.'/.config/coc/extensions'
endif
endif
return dir
endfunction
function! coc#util#update_extensions(...) abort
let async = get(a:, 1, 0)
if async
call coc#rpc#notify('updateExtensions', [])
else
call coc#rpc#request('updateExtensions', [])
endif
endfunction
function! coc#util#install_extension(args) abort
let names = filter(copy(a:args), 'v:val !~# "^-"')
let isRequest = index(a:args, '-sync') != -1
if isRequest
call coc#rpc#request('installExtensions', names)
else
call coc#rpc#notify('installExtensions', names)
endif
endfunction
function! coc#util#do_autocmd(name) abort
if exists('#User#'.a:name)
exe 'doautocmd User '.a:name
endif
endfunction
function! coc#util#rebuild()
let dir = coc#util#extension_root()
if !isdirectory(dir) | return | endif
call coc#util#open_terminal({
\ 'cwd': dir,
\ 'cmd': 'npm rebuild',
\ 'keepfocus': 1,
\})
endfunction
" content of first echo line
function! coc#util#echo_line()
let str = ''
let line = &lines - (&cmdheight - 1)
for i in range(1, &columns - 1)
let nr = screenchar(line, i)
let str = str . nr2char(nr)
endfor
return str
endfunction
" [r, g, b] ['255', '255', '255']
" return ['65535', '65535', '65535'] or return v:false to cancel
function! coc#util#pick_color(default_color)
if has('mac')
let default_color = map(a:default_color, {idx, val -> str2nr(val) * 65535 / 255 })
" This is the AppleScript magic:
let s:ascrpt = ['-e "tell application \"' . s:app . '\""',
\ '-e "' . s:activate . '"',
\ "-e \"set AppleScript's text item delimiters to {\\\",\\\"}\"",
\ '-e "set theColor to (choose color default color {' . default_color[0] . ", " . default_color[1] . ", " . default_color[2] . '}) as text"',
\ '-e "' . s:quit . '"',
\ '-e "end tell"',
\ '-e "return theColor"']
let res = trim(system("osascript " . join(s:ascrpt, ' ') . " 2>/dev/null"))
if empty(res)
return v:false
else
return split(trim(res), ',')
endif
endif
let hex_color = printf('#%02x%02x%02x', a:default_color[0], a:default_color[1], a:default_color[2])
if has('unix')
if executable('zenity')
let res = trim(system('zenity --title="Select a color" --color-selection --color="' . hex_color . '" 2> /dev/null'))
if empty(res)
return v:false
else
" res format is rgb(255,255,255)
return map(split(res[4:-2], ','), {idx, val -> string(str2nr(trim(val)) * 65535 / 255)})
endif
endif
endif
let rgb = v:false
if !has('python')
echohl Error | echom 'python support required, checkout :echo has(''python'')' | echohl None
return
endif
try
execute 'py import gtk'
catch /.*/
echohl Error | echom 'python gtk module not found' | echohl None
return
endtry
python << endpython
import vim
import gtk, sys
# message strings
wnd_title_insert = "Insert a color"
csd = gtk.ColorSelectionDialog(wnd_title_insert)
cs = csd.colorsel
cs.set_current_color(gtk.gdk.color_parse(vim.eval("hex_color")))
cs.set_current_alpha(65535)
cs.set_has_opacity_control(False)
# cs.set_has_palette(int(vim.eval("s:display_palette")))
if csd.run()==gtk.RESPONSE_OK:
c = cs.get_current_color()
s = [str(int(c.red)),',',str(int(c.green)),',',str(int(c.blue))]
thecolor = ''.join(s)
vim.command(":let rgb = split('%s',',')" % thecolor)
csd.destroy()
endpython
return rgb
endfunction
function! coc#util#iterm_open(dir)
return s:osascript(
\ 'if application "iTerm2" is not running',
\ 'error',
\ 'end if') && s:osascript(
\ 'tell application "iTerm2"',
\ 'tell current window',
\ 'create tab with default profile',
\ 'tell current session',
\ 'write text "cd ' . a:dir . '"',
\ 'write text "clear"',
\ 'activate',
\ 'end tell',
\ 'end tell',
\ 'end tell')
endfunction
function! s:osascript(...) abort
let args = join(map(copy(a:000), '" -e ".shellescape(v:val)'), '')
call s:system('osascript'. args)
return !v:shell_error
endfunction
function! s:system(cmd)
let output = system(a:cmd)
if v:shell_error && output !=# ""
echohl Error | echom output | echohl None
return
endif
return output
endfunction
function! coc#util#pclose()
for i in range(1, winnr('$'))
if getwinvar(i, '&previewwindow')
pclose
redraw
endif
endfor
endfunction
function! coc#util#init_virtual_hl()
let names = ['Error', 'Warning', 'Info', 'Hint']
for name in names
if !hlexists('Coc'.name.'VirtualText')
exe 'hi default link Coc'.name.'VirtualText Coc'.name.'Sign'
endif
endfor
endfunction
function! coc#util#set_buf_var(bufnr, name, val) abort
if !bufloaded(a:bufnr) | return | endif
call setbufvar(a:bufnr, a:name, a:val)
endfunction
function! coc#util#change_lines(bufnr, list) abort
if !bufloaded(a:bufnr) | return | endif
let bufnr = bufnr('%')
let changeBuffer = bufnr != a:bufnr
if changeBuffer
exe 'buffer '.a:bufnr
endif
for [lnum, line] in a:list
call setline(lnum + 1, line)
endfor
if changeBuffer
exe 'buffer '.bufnr
endif
if s:is_vim
redraw
endif
endfunction
function! coc#util#unmap(bufnr, keys) abort
if bufnr('%') == a:bufnr
for key in a:keys
exe 'silent! nunmap <buffer> '.key
endfor
endif
endfunction
function! coc#util#open_files(files)
let bufnrs = []
" added on latest vim8
if exists('*bufadd') && exists('*bufload')
for file in a:files
let bufnr = bufadd(file)
call bufload(file)
call add(bufnrs, bufnr(file))
endfor
else
noa keepalt 1new +setl\ bufhidden=wipe
for file in a:files
execute 'noa edit +setl\ bufhidden=hide '.fnameescape(file)
if &filetype ==# ''
filetype detect
endif
call add(bufnrs, bufnr('%'))
endfor
noa close
endif
return bufnrs
endfunction
function! coc#util#refactor_foldlevel(lnum) abort
if a:lnum <= 2 | return 0 | endif
let line = getline(a:lnum)
if line =~# '^\%u3000\s*$' | return 0 | endif
return 1
endfunction
function! coc#util#refactor_fold_text(lnum) abort
let range = ''
let info = get(b:line_infos, a:lnum, [])
if !empty(info)
let range = info[0].':'.info[1]
endif
return trim(getline(a:lnum)[3:]).' '.range
endfunction

View File

@@ -0,0 +1,87 @@
let s:root = expand('<sfile>:h:h:h')
function! s:checkEnvironment() abort
let valid = 1
if !has('nvim-0.3.0')
let valid = 0
call health#report_error('Neovim version not satisfied, 0.3.0 and above required')
endif
let node = get(g:, 'coc_node_path', 'node')
if !executable(node)
let valid = 0
call health#report_error('Executable node.js not found, install node.js from http://nodejs.org/')
endif
let output = system(node . ' --version')
if v:shell_error && output !=# ""
echohl Error | echom output | echohl None
return
endif
let ms = matchlist(output, 'v\(\d\+\).\(\d\+\).\(\d\+\)')
if empty(ms) || str2nr(ms[1]) < 8 || (str2nr(ms[1]) == 8 && str2nr(ms[2]) < 10)
let valid = 0
call health#report_error('Node.js version '.output.' < 8.10.0, please upgrade node.js')
endif
if valid
call health#report_ok('Environment check passed')
endif
if has('pythonx')
try
silent pyx print("")
catch /.*/
call health#report_warn('pyx command not work, some extensions may fail to work, checkout ":h pythonx"')
endtry
endif
return valid
endfunction
function! s:checkCommand()
let file = s:root.'/build/index.js'
if filereadable(file) && !get(g:, 'coc_force_debug', 0)
call health#report_ok('Javascript bundle found')
return
endif
let file = s:root.'/lib/attach.js'
if !filereadable(file)
call health#report_error('Javascript entry not found, run ":call coc#util#install()" to fix it.')
else
call health#report_ok('Build javascript found')
endif
endfunction
function! s:checkAutocmd()
let cmds = ['CursorHold', 'CursorHoldI', 'CursorMovedI', 'InsertCharPre', 'TextChangedI']
for cmd in cmds
let lines = split(execute('verbose autocmd '.cmd), '\n')
let n = 0
for line in lines
if line =~# 'CocAction(' && n < len(lines) - 1
let next = lines[n + 1]
let ms = matchlist(next, 'Last set from \(.*\)')
if !empty(ms)
call health#report_warn('Use CocActionAsync to replace CocAction for better performance on '.cmd)
call health#report_warn('Checkout the file '.ms[1])
endif
endif
let n = n + 1
endfor
endfor
endfunction
function! s:checkInitailize() abort
if coc#client#is_running('coc')
call health#report_ok('Service started')
return 1
endif
call health#report_error('service could not be initialized', [
\ 'Use command ":messages" to get error messages.',
\ 'Open a issue at https://github.com/neoclide/coc.nvim/issues for feedback.'
\])
return 0
endfunction
function! health#coc#check() abort
call s:checkEnvironment()
call s:checkCommand()
call s:checkInitailize()
call s:checkAutocmd()
endfunction