mirror of
https://github.com/amix/vimrc
synced 2025-07-27 23:45:00 +08:00
Add support for Coc.nvim.
This commit is contained in:
666
sources_non_forked/coc.nvim/autoload/coc/api.vim
Normal file
666
sources_non_forked/coc.nvim/autoload/coc/api.vim
Normal file
@ -0,0 +1,666 @@
|
||||
" ============================================================================
|
||||
" Description: Client api used by vim8
|
||||
" Author: Qiming Zhao <chemzqm@gmail.com>
|
||||
" Licence: Anti 996 licence
|
||||
" Last Modified: Mar 08, 2022
|
||||
" ============================================================================
|
||||
if has('nvim') | finish | endif
|
||||
scriptencoding utf-8
|
||||
let s:funcs = {}
|
||||
let s:prop_offset = get(g:, 'coc_text_prop_offset', 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('*getbufinfo')
|
||||
let info = getbufinfo(a:bufnr)
|
||||
if empty(info)
|
||||
return 0
|
||||
endif
|
||||
" vim 8.1 has getbufinfo but no linecount
|
||||
if has_key(info[0], 'linecount')
|
||||
return info[0]['linecount']
|
||||
endif
|
||||
endif
|
||||
if exists('*getbufline')
|
||||
let lines = getbufline(a:bufnr, 1, '$')
|
||||
return len(lines)
|
||||
endif
|
||||
let curr = bufnr('%')
|
||||
execute 'noa buffer '.a:bufnr
|
||||
let n = line('$')
|
||||
execute 'noa 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:inspect_type(v) abort
|
||||
let types = ['Number', 'String', 'Funcref', 'List', 'Dictionary', 'Float', 'Boolean', 'Null']
|
||||
return get(types, type(a:v), 'Unknown')
|
||||
endfunction
|
||||
|
||||
function! s:funcs.call_atomic(calls)
|
||||
let res = []
|
||||
for i in range(len(a:calls))
|
||||
let [key, arglist] = a:calls[i]
|
||||
let name = key[5:]
|
||||
try
|
||||
call add(res, call(s:funcs[name], arglist))
|
||||
catch /.*/
|
||||
return [res, [i, "VimException(".s:inspect_type(v:exception).")", 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
|
||||
let err = get(g:, 'errmsg', '')
|
||||
" get error from python script run.
|
||||
if !empty(err)
|
||||
unlet g:errmsg
|
||||
throw err
|
||||
endif
|
||||
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({'bufloaded': 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 globpath(&runtimepath, '', 0, 1)
|
||||
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
|
||||
call timer_start(0, {-> s:execute('redraw')})
|
||||
endfunction
|
||||
|
||||
function! s:funcs.err_write(str)
|
||||
"echoerr a:str
|
||||
endfunction
|
||||
|
||||
function! s:funcs.err_writeln(str)
|
||||
echohl ErrorMsg
|
||||
echom a:str
|
||||
echohl None
|
||||
call timer_start(0, {-> s:execute('redraw')})
|
||||
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 val is v:true
|
||||
let val = 1
|
||||
elseif val is v:false
|
||||
let val = 0
|
||||
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('patch-8.1.1719')
|
||||
return
|
||||
endif
|
||||
let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
|
||||
let type = 'CocHighlight'.a:hlGroup
|
||||
if empty(prop_type_get(type))
|
||||
let opts = get(a:, 1, 0)
|
||||
let priority = get(opts, 'priority', 0)
|
||||
call prop_type_add(type, {
|
||||
\ 'highlight': a:hlGroup,
|
||||
\ 'priority': type(priority) == 0 ? priority : 0,
|
||||
\ 'combine': get(opts, 'combine', 1),
|
||||
\ 'start_incl': get(opts, 'start_incl', 0),
|
||||
\ 'end_incl': get(opts, 'end_incl', 0),
|
||||
\ })
|
||||
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 srcId = a:srcId
|
||||
if srcId == 0
|
||||
while v:true
|
||||
let srcId = srcId + 1
|
||||
if empty(prop_find({'id': s:prop_offset + srcId, 'lnum' : 1}))
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
" generate srcId
|
||||
endif
|
||||
let id = srcId == -1 ? 0 : s:prop_offset + srcId
|
||||
try
|
||||
call prop_add(a:line + 1, a:colStart + 1, {'length': end - a:colStart, 'bufnr': bufnr, 'type': type, 'id': id})
|
||||
catch /^Vim\%((\a\+)\)\=:E967/
|
||||
" ignore 967
|
||||
endtry
|
||||
if a:srcId == 0
|
||||
" return generated srcId
|
||||
return srcId
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:funcs.buf_clear_namespace(bufnr, srcId, startLine, endLine) abort
|
||||
if !has('patch-8.1.1719')
|
||||
return
|
||||
endif
|
||||
let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
|
||||
let start = a:startLine + 1
|
||||
let end = a:endLine == -1 ? len(getbufline(bufnr, 1, '$')) : a:endLine
|
||||
if a:srcId == -1
|
||||
call prop_clear(start, end, {'bufnr' : bufnr})
|
||||
else
|
||||
try
|
||||
call prop_remove({'bufnr': bufnr, 'all': 1, 'id': s:prop_offset + a:srcId}, start, end)
|
||||
catch /^Vim\%((\a\+)\)\=:E968/
|
||||
" ignore 968
|
||||
endtry
|
||||
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
|
||||
if !bufloaded(a:bufnr)
|
||||
return
|
||||
endif
|
||||
let replacement = get(a:, 1, [])
|
||||
let lineCount = s:buf_line_count(a:bufnr)
|
||||
let startLnum = a:start >= 0 ? a:start + 1 : lineCount + a:start + 2
|
||||
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
|
||||
let storeView = winsaveview()
|
||||
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 = @"
|
||||
let system_reg = @*
|
||||
if exists('*deletebufline')
|
||||
silent call deletebufline(curr, start, start + delCount - 1)
|
||||
else
|
||||
silent execute start . ','.(start + delCount - 1).'d'
|
||||
endif
|
||||
let @" = saved_reg
|
||||
let @* = system_reg
|
||||
endif
|
||||
endif
|
||||
call winrestview(storeView)
|
||||
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)
|
||||
let saved_reg = @"
|
||||
let system_reg = @*
|
||||
"8.1.0039
|
||||
silent call deletebufline(a:bufnr, start, start + delCount - 1)
|
||||
let @" = saved_reg
|
||||
let @* = system_reg
|
||||
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)
|
||||
if bufnr == bufnr('%')
|
||||
execute 'unlet! b:'.a:name
|
||||
elseif exists('*win_execute')
|
||||
let winid = coc#compat#buf_win_id(a:bufnr)
|
||||
if winid != -1
|
||||
call win_execute(winid, 'unlet! b:'.a:name)
|
||||
endif
|
||||
endif
|
||||
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
|
||||
|
||||
if exists('*win_execute')
|
||||
function! s:win_execute(win_id, cmd, ...) abort
|
||||
let ref = get(a:000, 0, v:null)
|
||||
let cmd = ref is v:null ? a:cmd : 'let ref["out"] = ' . a:cmd
|
||||
call win_execute(a:win_id, cmd)
|
||||
endfunction
|
||||
else
|
||||
function! s:win_execute(win_id, cmd, ...) abort
|
||||
let ref = get(a:000, 0, v:null)
|
||||
let cmd = ref is v:null ? a:cmd : 'let ref["out"] = ' . a:cmd
|
||||
let winid = win_getid()
|
||||
if winid == a:win_id
|
||||
execute cmd
|
||||
else
|
||||
let goto_status = win_gotoid(a:win_id)
|
||||
if !goto_status
|
||||
return
|
||||
endif
|
||||
execute cmd
|
||||
call win_gotoid(winid)
|
||||
endif
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:get_tabnr(winid) abort
|
||||
let ref = {}
|
||||
call s:win_execute(a:winid, 'tabpagenr()', ref)
|
||||
return get(ref, 'out', 0)
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_get_cursor(win_id) abort
|
||||
let ref = {}
|
||||
call s:win_execute(a:win_id, "[line('.'), col('.')-1]", ref)
|
||||
return get(ref, 'out', 0)
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_get_var(win_id, name, ...) abort
|
||||
let tabnr = s:get_tabnr(a:win_id)
|
||||
if tabnr
|
||||
return gettabwinvar(tabnr, a:win_id, a:name, get(a:, 1, v:null))
|
||||
endif
|
||||
throw 'window '.a:win_id. ' not a visible window'
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_set_width(win_id, width) abort
|
||||
call s:win_execute(a:win_id, 'vertical resize '.a:width)
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_set_buf(win_id, buf_id) abort
|
||||
call s:win_execute(a:win_id, 'buffer '.a:buf_id)
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_get_option(win_id, name) abort
|
||||
let tabnr = s:get_tabnr(a:win_id)
|
||||
if tabnr
|
||||
return gettabwinvar(tabnr, a:win_id, '&'.a:name)
|
||||
endif
|
||||
throw 'window '.a:win_id. ' not a valid window'
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_set_height(win_id, height) abort
|
||||
return s:win_execute(a:win_id, 'resize '.a:height)
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_set_option(win_id, name, value) abort
|
||||
let val = a:value
|
||||
if val is v:true
|
||||
let val = 1
|
||||
elseif val is v:false
|
||||
let val = 0
|
||||
endif
|
||||
let tabnr = s:get_tabnr(a:win_id)
|
||||
if tabnr
|
||||
call settabwinvar(tabnr, a:win_id, '&'.a:name, val)
|
||||
else
|
||||
throw 'window '.a:win_id. ' not a valid window'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_set_var(win_id, name, value) abort
|
||||
let tabnr = s:get_tabnr(a:win_id)
|
||||
if tabnr
|
||||
call settabwinvar(tabnr, a:win_id, a:name, a:value)
|
||||
else
|
||||
throw "Invalid window id ".a:win_id
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_del_var(win_id, name) abort
|
||||
call s:win_execute(a:win_id, 'unlet! w:'.a:name)
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_is_valid(win_id) abort
|
||||
let info = getwininfo(a:win_id)
|
||||
return empty(info) ? v:false : v:true
|
||||
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 [line, col] = a:pos
|
||||
call s:win_execute(a:win_id, 'call cursor('.line.','.(col + 1).')')
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_close(win_id, ...) abort
|
||||
let force = get(a:, 1, 0)
|
||||
call s:win_execute(a:win_id, 'close'.(force ? '!' : ''))
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_get_tabpage(win_id) abort
|
||||
let tabnr = s:get_tabnr(a:win_id)
|
||||
if !tabnr
|
||||
throw 'Invalid window id '.a:win_id
|
||||
endif
|
||||
return 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#exec(method, args) abort
|
||||
return call(s:funcs[a:method], a:args)
|
||||
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:
|
336
sources_non_forked/coc.nvim/autoload/coc/client.vim
Normal file
336
sources_non_forked/coc.nvim/autoload/coc/client.vim
Normal file
@ -0,0 +1,336 @@
|
||||
scriptencoding utf-8
|
||||
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 = {}
|
||||
|
||||
if get(g:, 'node_client_debug', 0)
|
||||
echohl WarningMsg | echon '[coc.nvim] Enable g:node_client_debug could impact your vim experience' | echohl None
|
||||
let $NODE_CLIENT_LOG_LEVEL = 'debug'
|
||||
if exists('$NODE_CLIENT_LOG_FILE')
|
||||
let s:logfile = resolve($NODE_CLIENT_LOG_FILE)
|
||||
else
|
||||
let s:logfile = tempname()
|
||||
let $NODE_CLIENT_LOG_FILE = s:logfile
|
||||
endif
|
||||
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 !isdirectory(getcwd())
|
||||
echohl Error | echon '[coc.nvim] Current cwd is not a valid directory.' | echohl None
|
||||
return
|
||||
endif
|
||||
let timeout = string(get(g:, 'coc_channel_timeout', 30))
|
||||
let disable_warning = string(get(g:, 'coc_disable_startup_warning', 0))
|
||||
let tmpdir = fnamemodify(tempname(), ':p:h')
|
||||
if s:is_vim
|
||||
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)},
|
||||
\ 'env': {
|
||||
\ 'NODE_NO_WARNINGS': '1',
|
||||
\ 'VIM_NODE_RPC': '1',
|
||||
\ 'COC_NVIM': '1',
|
||||
\ 'COC_CHANNEL_TIMEOUT': timeout,
|
||||
\ 'TMPDIR': tmpdir,
|
||||
\ }
|
||||
\}
|
||||
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 original = {}
|
||||
let opts = {
|
||||
\ 'rpc': 1,
|
||||
\ 'on_stderr': {channel, msgs -> s:on_stderr(self.name, msgs)},
|
||||
\ 'on_exit': {channel, code -> s:on_exit(self.name, code)},
|
||||
\ }
|
||||
if has('nvim-0.5.0')
|
||||
" could use env option
|
||||
let opts['env'] = {
|
||||
\ 'COC_NVIM': '1',
|
||||
\ 'NODE_NO_WARNINGS': '1',
|
||||
\ 'COC_CHANNEL_TIMEOUT': timeout,
|
||||
\ 'TMPDIR': tmpdir
|
||||
\ }
|
||||
else
|
||||
if exists('*getenv')
|
||||
let original = {
|
||||
\ 'NODE_NO_WARNINGS': getenv('NODE_NO_WARNINGS'),
|
||||
\ 'TMPDIR': getenv('TMPDIR'),
|
||||
\ }
|
||||
endif
|
||||
if exists('*setenv')
|
||||
call setenv('COC_NVIM', '1')
|
||||
call setenv('NODE_NO_WARNINGS', '1')
|
||||
call setenv('COC_CHANNEL_TIMEOUT', timeout)
|
||||
call setenv('TMPDIR', tmpdir)
|
||||
else
|
||||
let $NODE_NO_WARNINGS = 1
|
||||
let $TMPDIR = tmpdir
|
||||
endif
|
||||
endif
|
||||
let chan_id = jobstart(self.command, opts)
|
||||
if !empty(original)
|
||||
if exists('*setenv')
|
||||
for key in keys(original)
|
||||
call setenv(key, original[key])
|
||||
endfor
|
||||
else
|
||||
let $TMPDIR = original['TMPDIR']
|
||||
endif
|
||||
endif
|
||||
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
|
||||
if get(g:, 'coc_disable_uncaught_error', 0) | return | endif
|
||||
let data = filter(copy(a:msgs), '!empty(v:val)')
|
||||
if empty(data) | return | endif
|
||||
let client = a:name ==# 'coc' ? '[coc.nvim]' : '['.a:name.']'
|
||||
let data[0] = client.': '.data[0]
|
||||
call coc#ui#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! coc#client#get_client(name) abort
|
||||
return get(s:clients, a:name, v:null)
|
||||
endfunction
|
||||
|
||||
function! coc#client#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 = coc#client#get_channel(self)
|
||||
if empty(channel) | return '' | endif
|
||||
try
|
||||
if s:is_vim
|
||||
let res = ch_evalexpr(channel, [a:method, a:args], {'timeout': 60 * 1000})
|
||||
if type(res) == 1 && res ==# ''
|
||||
throw 'request '.a:method. ' '.string(a:args).' timeout after 60s'
|
||||
endif
|
||||
let [l:errmsg, res] = res
|
||||
if !empty(l:errmsg)
|
||||
throw l:errmsg
|
||||
else
|
||||
return res
|
||||
endif
|
||||
else
|
||||
return call('rpcrequest', [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 request ('.a:method.'): '.v:exception | echohl None
|
||||
endif
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:notify(method, args) dict
|
||||
let channel = coc#client#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 = coc#client#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()
|
||||
if !get(g:, 'node_client_debug', 0)
|
||||
echohl Error | echon '[coc.nvim] use let g:node_client_debug = 1 in your vimrc to enabled debug mode.' | echohl None
|
||||
return
|
||||
endif
|
||||
execute 'vs '.s:logfile
|
||||
endfunction
|
283
sources_non_forked/coc.nvim/autoload/coc/color.vim
Normal file
283
sources_non_forked/coc.nvim/autoload/coc/color.vim
Normal file
@ -0,0 +1,283 @@
|
||||
scriptencoding utf-8
|
||||
|
||||
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
|
||||
|
||||
" Returns an approximate grey index for the given grey level
|
||||
fun! s:grey_number(x)
|
||||
if &t_Co == 88
|
||||
if a:x < 23
|
||||
return 0
|
||||
elseif a:x < 69
|
||||
return 1
|
||||
elseif a:x < 103
|
||||
return 2
|
||||
elseif a:x < 127
|
||||
return 3
|
||||
elseif a:x < 150
|
||||
return 4
|
||||
elseif a:x < 173
|
||||
return 5
|
||||
elseif a:x < 196
|
||||
return 6
|
||||
elseif a:x < 219
|
||||
return 7
|
||||
elseif a:x < 243
|
||||
return 8
|
||||
else
|
||||
return 9
|
||||
endif
|
||||
else
|
||||
if a:x < 14
|
||||
return 0
|
||||
else
|
||||
let l:n = (a:x - 8) / 10
|
||||
let l:m = (a:x - 8) % 10
|
||||
if l:m < 5
|
||||
return l:n
|
||||
else
|
||||
return l:n + 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfun
|
||||
|
||||
" Returns the actual grey level represented by the grey index
|
||||
fun! s:grey_level(n)
|
||||
if &t_Co == 88
|
||||
if a:n == 0
|
||||
return 0
|
||||
elseif a:n == 1
|
||||
return 46
|
||||
elseif a:n == 2
|
||||
return 92
|
||||
elseif a:n == 3
|
||||
return 115
|
||||
elseif a:n == 4
|
||||
return 139
|
||||
elseif a:n == 5
|
||||
return 162
|
||||
elseif a:n == 6
|
||||
return 185
|
||||
elseif a:n == 7
|
||||
return 208
|
||||
elseif a:n == 8
|
||||
return 231
|
||||
else
|
||||
return 255
|
||||
endif
|
||||
else
|
||||
if a:n == 0
|
||||
return 0
|
||||
else
|
||||
return 8 + (a:n * 10)
|
||||
endif
|
||||
endif
|
||||
endfun
|
||||
|
||||
" Returns the palette index for the given grey index
|
||||
fun! s:grey_colour(n)
|
||||
if &t_Co == 88
|
||||
if a:n == 0
|
||||
return 16
|
||||
elseif a:n == 9
|
||||
return 79
|
||||
else
|
||||
return 79 + a:n
|
||||
endif
|
||||
else
|
||||
if a:n == 0
|
||||
return 16
|
||||
elseif a:n == 25
|
||||
return 231
|
||||
else
|
||||
return 231 + a:n
|
||||
endif
|
||||
endif
|
||||
endfun
|
||||
|
||||
" Returns an approximate colour index for the given colour level
|
||||
fun! s:rgb_number(x)
|
||||
if &t_Co == 88
|
||||
if a:x < 69
|
||||
return 0
|
||||
elseif a:x < 172
|
||||
return 1
|
||||
elseif a:x < 230
|
||||
return 2
|
||||
else
|
||||
return 3
|
||||
endif
|
||||
else
|
||||
if a:x < 75
|
||||
return 0
|
||||
else
|
||||
let l:n = (a:x - 55) / 40
|
||||
let l:m = (a:x - 55) % 40
|
||||
if l:m < 20
|
||||
return l:n
|
||||
else
|
||||
return l:n + 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfun
|
||||
|
||||
" Returns the palette index for the given R/G/B colour indices
|
||||
fun! s:rgb_colour(x, y, z)
|
||||
if &t_Co == 88
|
||||
return 16 + (a:x * 16) + (a:y * 4) + a:z
|
||||
else
|
||||
return 16 + (a:x * 36) + (a:y * 6) + a:z
|
||||
endif
|
||||
endfun
|
||||
|
||||
" Returns the actual colour level for the given colour index
|
||||
fun! s:rgb_level(n)
|
||||
if &t_Co == 88
|
||||
if a:n == 0
|
||||
return 0
|
||||
elseif a:n == 1
|
||||
return 139
|
||||
elseif a:n == 2
|
||||
return 205
|
||||
else
|
||||
return 255
|
||||
endif
|
||||
else
|
||||
if a:n == 0
|
||||
return 0
|
||||
else
|
||||
return 55 + (a:n * 40)
|
||||
endif
|
||||
endif
|
||||
endfun
|
||||
|
||||
" Returns the palette index to approximate the given R/G/B colour levels
|
||||
fun! s:colour(r, g, b)
|
||||
" Get the closest grey
|
||||
let l:gx = s:grey_number(a:r)
|
||||
let l:gy = s:grey_number(a:g)
|
||||
let l:gz = s:grey_number(a:b)
|
||||
|
||||
" Get the closest colour
|
||||
let l:x = s:rgb_number(a:r)
|
||||
let l:y = s:rgb_number(a:g)
|
||||
let l:z = s:rgb_number(a:b)
|
||||
|
||||
if l:gx == l:gy && l:gy == l:gz
|
||||
" There are two possibilities
|
||||
let l:dgr = s:grey_level(l:gx) - a:r
|
||||
let l:dgg = s:grey_level(l:gy) - a:g
|
||||
let l:dgb = s:grey_level(l:gz) - a:b
|
||||
let l:dgrey = (l:dgr * l:dgr) + (l:dgg * l:dgg) + (l:dgb * l:dgb)
|
||||
let l:dr = s:rgb_level(l:gx) - a:r
|
||||
let l:dg = s:rgb_level(l:gy) - a:g
|
||||
let l:db = s:rgb_level(l:gz) - a:b
|
||||
let l:drgb = (l:dr * l:dr) + (l:dg * l:dg) + (l:db * l:db)
|
||||
if l:dgrey < l:drgb
|
||||
" Use the grey
|
||||
return s:grey_colour(l:gx)
|
||||
else
|
||||
" Use the colour
|
||||
return s:rgb_colour(l:x, l:y, l:z)
|
||||
endif
|
||||
else
|
||||
" Only one possibility
|
||||
return s:rgb_colour(l:x, l:y, l:z)
|
||||
endif
|
||||
endfun
|
||||
|
||||
function! coc#color#rgb2term(rgb)
|
||||
let l:r = ("0x" . strpart(a:rgb, 0, 2)) + 0
|
||||
let l:g = ("0x" . strpart(a:rgb, 2, 2)) + 0
|
||||
let l:b = ("0x" . strpart(a:rgb, 4, 2)) + 0
|
||||
return s:colour(l:r, l:g, l:b)
|
||||
endfun
|
||||
|
||||
" [r, g, b] ['255', '255', '255']
|
||||
" return ['65535', '65535', '65535'] or return v:false to cancel
|
||||
function! coc#color#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 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(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
|
||||
|
244
sources_non_forked/coc.nvim/autoload/coc/compat.vim
Normal file
244
sources_non_forked/coc.nvim/autoload/coc/compat.vim
Normal file
@ -0,0 +1,244 @@
|
||||
scriptencoding utf-8
|
||||
let s:is_vim = !has('nvim')
|
||||
|
||||
" first window id for bufnr
|
||||
" builtin bufwinid returns window of current tab only
|
||||
function! coc#compat#buf_win_id(bufnr) abort
|
||||
let info = filter(getwininfo(), 'v:val["bufnr"] =='.a:bufnr)
|
||||
if empty(info)
|
||||
return -1
|
||||
endif
|
||||
return info[0]['winid']
|
||||
endfunction
|
||||
|
||||
function! coc#compat#buf_set_lines(bufnr, start, end, replacement) abort
|
||||
if s:is_vim
|
||||
call coc#api#notify('buf_set_lines', [a:bufnr, a:start, a:end, 0, a:replacement])
|
||||
else
|
||||
call nvim_buf_set_lines(a:bufnr, a:start, a:end, 0, a:replacement)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#compat#buf_line_count(bufnr) abort
|
||||
if exists('*nvim_buf_line_count')
|
||||
return nvim_buf_line_count(a:bufnr)
|
||||
endif
|
||||
if bufnr('%') == a:bufnr
|
||||
return line('$')
|
||||
endif
|
||||
if exists('*getbufinfo')
|
||||
let info = getbufinfo(a:bufnr)
|
||||
if empty(info)
|
||||
return 0
|
||||
endif
|
||||
" vim 8.1 has getbufinfo but no linecount
|
||||
if has_key(info[0], 'linecount')
|
||||
return info[0]['linecount']
|
||||
endif
|
||||
endif
|
||||
if exists('*getbufline')
|
||||
let lines = getbufline(a:bufnr, 1, '$')
|
||||
return len(lines)
|
||||
endif
|
||||
let curr = bufnr('%')
|
||||
execute 'noa buffer '.a:bufnr
|
||||
let n = line('$')
|
||||
execute 'noa buffer '.curr
|
||||
return n
|
||||
endfunction
|
||||
|
||||
function! coc#compat#prepend_lines(bufnr, replacement) abort
|
||||
if exists('*appendbufline')
|
||||
call appendbufline(a:bufnr, 0, a:replacement)
|
||||
elseif !s:is_vim
|
||||
call nvim_buf_set_lines(a:bufnr, 0, 0, 0, a:replacement)
|
||||
else
|
||||
throw 'appendbufline() required for prepend lines.'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#compat#win_is_valid(winid) abort
|
||||
if exists('*nvim_win_is_valid')
|
||||
return nvim_win_is_valid(a:winid)
|
||||
endif
|
||||
return !empty(getwininfo(a:winid))
|
||||
endfunction
|
||||
|
||||
" clear matches by window id, not throw on none exists window.
|
||||
" may not work on vim < 8.1.1084 & neovim < 0.4.0
|
||||
function! coc#compat#clear_matches(winid) abort
|
||||
if !coc#compat#win_is_valid(a:winid)
|
||||
return
|
||||
endif
|
||||
let curr = win_getid()
|
||||
if curr == a:winid
|
||||
call clearmatches()
|
||||
return
|
||||
endif
|
||||
if s:is_vim
|
||||
if has('patch-8.1.1084')
|
||||
call clearmatches(a:winid)
|
||||
endif
|
||||
else
|
||||
if exists('*nvim_set_current_win')
|
||||
noa call nvim_set_current_win(a:winid)
|
||||
call clearmatches()
|
||||
noa call nvim_set_current_win(curr)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#compat#matchaddpos(group, pos, priority, winid) abort
|
||||
let curr = win_getid()
|
||||
if curr == a:winid
|
||||
call matchaddpos(a:group, a:pos, a:priority, -1)
|
||||
else
|
||||
if s:is_vim
|
||||
if has('patch-8.1.0218')
|
||||
call matchaddpos(a:group, a:pos, a:priority, -1, {'window': a:winid})
|
||||
endif
|
||||
else
|
||||
if has('nvim-0.4.0')
|
||||
call matchaddpos(a:group, a:pos, a:priority, -1, {'window': a:winid})
|
||||
elseif exists('*nvim_set_current_win')
|
||||
noa call nvim_set_current_win(a:winid)
|
||||
call matchaddpos(a:group, a:pos, a:priority, -1)
|
||||
noa call nvim_set_current_win(curr)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#compat#buf_del_var(bufnr, name) abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return
|
||||
endif
|
||||
if exists('*nvim_buf_del_var')
|
||||
silent! call nvim_buf_del_var(a:bufnr, a:name)
|
||||
else
|
||||
if a:bufnr == bufnr('%')
|
||||
execute 'unlet! b:'.a:name
|
||||
elseif exists('*win_execute')
|
||||
let winid = coc#compat#buf_win_id(a:bufnr)
|
||||
if winid != -1
|
||||
call win_execute(winid, 'unlet! b:'.a:name)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" hlGroup, pos, priority
|
||||
function! coc#compat#matchaddgroups(winid, groups) abort
|
||||
" add by winid
|
||||
if has('patch-8.1.0218') || has('nvim-0.4.0')
|
||||
for group in a:groups
|
||||
call matchaddpos(group['hlGroup'], [group['pos']], group['priority'], -1, {'window': a:winid})
|
||||
endfor
|
||||
return
|
||||
endif
|
||||
let curr = win_getid()
|
||||
if curr == a:winid
|
||||
for group in a:groups
|
||||
call matchaddpos(group['hlGroup'], [group['pos']], group['priority'], -1)
|
||||
endfor
|
||||
elseif exists('*nvim_set_current_win')
|
||||
noa call nvim_set_current_win(a:winid)
|
||||
for group in a:groups
|
||||
call matchaddpos(group['hlGroup'], [group['pos']], group['priority'], -1)
|
||||
endfor
|
||||
noa call nvim_set_current_win(curr)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#compat#del_var(name) abort
|
||||
if exists('*nvim_del_var')
|
||||
silent! call nvim_del_var(a:name)
|
||||
else
|
||||
execute 'unlet! '.a:name
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" remove keymap for specific buffer
|
||||
function! coc#compat#buf_del_keymap(bufnr, mode, lhs) abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return
|
||||
endif
|
||||
if exists('*nvim_buf_del_keymap')
|
||||
try
|
||||
call nvim_buf_del_keymap(a:bufnr, a:mode, a:lhs)
|
||||
catch /^Vim\%((\a\+)\)\=:E5555/
|
||||
" ignore keymap doesn't exist
|
||||
endtry
|
||||
return
|
||||
endif
|
||||
if bufnr == a:bufnr
|
||||
execute 'silent! '.a:mode.'unmap <buffer> '.a:lhs
|
||||
return
|
||||
endif
|
||||
if exists('*win_execute')
|
||||
let winid = coc#compat#buf_win_id(a:bufnr)
|
||||
if winid != -1
|
||||
call win_execute(winid, a:mode.'unmap <buffer> '.a:lhs, 'silent!')
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#compat#buf_add_keymap(bufnr, mode, lhs, rhs, opts) abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return
|
||||
endif
|
||||
if exists('*nvim_buf_set_keymap')
|
||||
call nvim_buf_set_keymap(a:bufnr, a:mode, a:lhs, a:rhs, a:opts)
|
||||
else
|
||||
let cmd = a:mode . 'noremap '
|
||||
for key in keys(a:opts)
|
||||
if get(a:opts, key, 0)
|
||||
let cmd .= '<'.key.'>'
|
||||
endif
|
||||
endfor
|
||||
let cmd .= '<buffer> '.a:lhs.' '.a:rhs
|
||||
if bufnr('%') == a:bufnr
|
||||
execute cmd
|
||||
elseif exists('*win_execute')
|
||||
let winid = coc#compat#buf_win_id(a:bufnr)
|
||||
if winid != -1
|
||||
call win_execute(winid, cmd)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" execute command or list of commands in window
|
||||
function! coc#compat#execute(winid, command, ...) abort
|
||||
if exists('*win_execute')
|
||||
if type(a:command) == v:t_string
|
||||
keepalt call win_execute(a:winid, a:command, get(a:, 1, ''))
|
||||
elseif type(a:command) == v:t_list
|
||||
keepalt call win_execute(a:winid, join(a:command, "\n"), get(a:, 1, ''))
|
||||
endif
|
||||
elseif has('nvim')
|
||||
if !nvim_win_is_valid(a:winid)
|
||||
return
|
||||
endif
|
||||
let curr = nvim_get_current_win()
|
||||
noa keepalt call nvim_set_current_win(a:winid)
|
||||
if type(a:command) == v:t_string
|
||||
exe get(a:, 1, '').' '.a:command
|
||||
elseif type(a:command) == v:t_list
|
||||
for cmd in a:command
|
||||
exe get(a:, 1, '').' '.cmd
|
||||
endfor
|
||||
endif
|
||||
noa keepalt call nvim_set_current_win(curr)
|
||||
else
|
||||
throw 'win_execute does not exist, please upgrade vim.'
|
||||
endif
|
||||
endfunc
|
||||
|
||||
function! coc#compat#trim(str)
|
||||
if exists('*trim')
|
||||
return trim(a:str)
|
||||
endif
|
||||
" TODO trim from beginning
|
||||
return substitute(a:str, '\s\+$', '', '')
|
||||
endfunction
|
60
sources_non_forked/coc.nvim/autoload/coc/cursor.vim
Normal file
60
sources_non_forked/coc.nvim/autoload/coc/cursor.vim
Normal file
@ -0,0 +1,60 @@
|
||||
scriptencoding utf-8
|
||||
|
||||
" Position of cursor relative to screen cell
|
||||
function! coc#cursor#screen_pos() abort
|
||||
let nr = winnr()
|
||||
let [row, col] = win_screenpos(nr)
|
||||
return [row + winline() - 2, col + wincol() - 2]
|
||||
endfunction
|
||||
|
||||
function! coc#cursor#move_by_col(delta)
|
||||
let pos = getcurpos()
|
||||
call cursor(pos[1], pos[2] + a:delta)
|
||||
endfunction
|
||||
|
||||
" Get cursor position.
|
||||
function! coc#cursor#position()
|
||||
return [line('.') - 1, strchars(strpart(getline('.'), 0, col('.') - 1))]
|
||||
endfunction
|
||||
|
||||
" Move cursor to position.
|
||||
function! coc#cursor#move_to(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)
|
||||
endfunction
|
||||
|
||||
" Character offset of current cursor, vim provide bytes offset only.
|
||||
function! coc#cursor#char_offset() abort
|
||||
let offset = 0
|
||||
let lnum = line('.')
|
||||
for i in range(1, lnum)
|
||||
if i == lnum
|
||||
let offset += strchars(strpart(getline('.'), 0, col('.')-1))
|
||||
else
|
||||
let offset += strchars(getline(i)) + 1
|
||||
endif
|
||||
endfor
|
||||
return offset
|
||||
endfunction
|
||||
|
||||
" Returns latest selection range
|
||||
function! coc#cursor#get_selection(char) abort
|
||||
let m = a:char ? 'char' : visualmode()
|
||||
if empty(m)
|
||||
return v:null
|
||||
endif
|
||||
let [_, sl, sc, soff] = getpos(m ==# 'char' ? "'[" : "'<")
|
||||
let [_, el, ec, eoff] = getpos(m ==# 'char' ? "']" : "'>")
|
||||
let start_idx = coc#string#get_character(getline(sl), sc)
|
||||
if m ==# 'V'
|
||||
return [sl - 1, start_idx, el, 0]
|
||||
endif
|
||||
let line = getline(el)
|
||||
let end_idx = coc#string#get_character(line, ec)
|
||||
if m !=# 'char'
|
||||
let end_idx = end_idx == strchars(line) ? end_idx : end_idx + 1
|
||||
endif
|
||||
return [sl - 1, start_idx, el - 1, end_idx]
|
||||
endfunction
|
580
sources_non_forked/coc.nvim/autoload/coc/dialog.vim
Normal file
580
sources_non_forked/coc.nvim/autoload/coc/dialog.vim
Normal file
@ -0,0 +1,580 @@
|
||||
scriptencoding utf-8
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:root = expand('<sfile>:h:h:h')
|
||||
let s:prompt_win_bufnr = 0
|
||||
let s:prompt_win_width = get(g:, 'coc_prompt_win_width', 32)
|
||||
let s:float_supported = exists('*nvim_open_win') || has('patch-8.1.1719')
|
||||
let s:frames = ['· ', '·· ', '···', ' ··', ' ·', ' ']
|
||||
|
||||
" Float window aside pum
|
||||
function! coc#dialog#create_pum_float(winid, bufnr, lines, config) abort
|
||||
if !pumvisible() || !s:float_supported
|
||||
return v:null
|
||||
endif
|
||||
let pumbounding = a:config['pumbounding']
|
||||
let pw = pumbounding['width'] + get(pumbounding, 'scrollbar', 0)
|
||||
let rp = &columns - pumbounding['col'] - pw
|
||||
let showRight = pumbounding['col'] > rp ? 0 : 1
|
||||
let maxWidth = showRight ? coc#math#min(rp - 1, a:config['maxWidth']) : coc#math#min(pumbounding['col'] - 1, a:config['maxWidth'])
|
||||
let border = get(a:config, 'border', [])
|
||||
let bh = get(border, 0 ,0) + get(border, 2, 0)
|
||||
let maxHeight = &lines - pumbounding['row'] - &cmdheight - 1 - bh
|
||||
if maxWidth <= 2 || maxHeight < 1
|
||||
return v:null
|
||||
endif
|
||||
let ch = 0
|
||||
let width = 0
|
||||
for line in a:lines
|
||||
let dw = max([1, strdisplaywidth(line)])
|
||||
let width = max([width, dw + 2])
|
||||
let ch += float2nr(ceil(str2float(string(dw))/(maxWidth - 2)))
|
||||
endfor
|
||||
let width = float2nr(coc#math#min(maxWidth, width))
|
||||
let height = float2nr(coc#math#min(maxHeight, ch))
|
||||
let lines = map(a:lines, {_, s -> s =~# '^─' ? repeat('─', width - 2 + (s:is_vim && ch > height ? -1 : 0)) : s})
|
||||
let opts = {
|
||||
\ 'lines': lines,
|
||||
\ 'highlights': get(a:config, 'highlights', []),
|
||||
\ 'relative': 'editor',
|
||||
\ 'col': showRight ? pumbounding['col'] + pw : pumbounding['col'] - width - 1,
|
||||
\ 'row': pumbounding['row'],
|
||||
\ 'height': height,
|
||||
\ 'width': width - 2 + (s:is_vim && ch > height ? -1 : 0),
|
||||
\ 'codes': get(a:config, 'codes', []),
|
||||
\ }
|
||||
for key in ['border', 'highlight', 'borderhighlight', 'winblend', 'focusable', 'shadow']
|
||||
if has_key(a:config, key)
|
||||
let opts[key] = a:config[key]
|
||||
endif
|
||||
endfor
|
||||
call s:close_auto_hide_wins(a:winid)
|
||||
let res = coc#float#create_float_win(a:winid, a:bufnr, opts)
|
||||
if empty(res)
|
||||
return v:null
|
||||
endif
|
||||
call setwinvar(res[0], 'kind', 'pum')
|
||||
if has('nvim')
|
||||
call coc#float#nvim_scrollbar(res[0])
|
||||
endif
|
||||
return res
|
||||
endfunction
|
||||
|
||||
" Float window below/above cursor
|
||||
function! coc#dialog#create_cursor_float(winid, bufnr, lines, config) abort
|
||||
if !s:float_supported || coc#prompt#activated()
|
||||
return v:null
|
||||
endif
|
||||
let pumAlignTop = get(a:config, 'pumAlignTop', 0)
|
||||
let modes = get(a:config, 'modes', ['n', 'i', 'ic', 's'])
|
||||
let mode = mode()
|
||||
let currbuf = bufnr('%')
|
||||
let pos = [line('.'), col('.')]
|
||||
if index(modes, mode) == -1
|
||||
return v:null
|
||||
endif
|
||||
if has('nvim') && mode ==# 'i'
|
||||
" helps to fix undo issue, don't know why.
|
||||
call feedkeys("\<C-g>u", 'n')
|
||||
endif
|
||||
let dimension = coc#dialog#get_config_cursor(a:lines, a:config)
|
||||
if empty(dimension)
|
||||
return v:null
|
||||
endif
|
||||
if pumvisible() && ((pumAlignTop && dimension['row'] <0)|| (!pumAlignTop && dimension['row'] > 0))
|
||||
return v:null
|
||||
endif
|
||||
let width = dimension['width']
|
||||
let lines = map(a:lines, {_, s -> s =~# '^─' ? repeat('─', width) : s})
|
||||
let config = extend(extend({'lines': lines, 'relative': 'cursor'}, a:config), dimension)
|
||||
call s:close_auto_hide_wins(a:winid)
|
||||
let res = coc#float#create_float_win(a:winid, a:bufnr, config)
|
||||
if empty(res)
|
||||
return v:null
|
||||
endif
|
||||
let alignTop = dimension['row'] < 0
|
||||
let winid = res[0]
|
||||
let bufnr = res[1]
|
||||
redraw
|
||||
if has('nvim')
|
||||
call coc#float#nvim_scrollbar(winid)
|
||||
endif
|
||||
return [currbuf, pos, winid, bufnr, alignTop]
|
||||
endfunction
|
||||
|
||||
" Create float window for input
|
||||
function! coc#dialog#create_prompt_win(title, default, opts) abort
|
||||
call s:close_auto_hide_wins()
|
||||
let bufnr = has('nvim') ? s:prompt_win_bufnr : 0
|
||||
if s:is_vim
|
||||
execute 'hi link CocPopupTerminal '.get(a:opts, 'highlight', 'CocFloating')
|
||||
let node = expand(get(g:, 'coc_node_path', 'node'))
|
||||
let bufnr = term_start([node, s:root . '/bin/prompt.js', a:default], {
|
||||
\ 'term_highlight': 'CocPopupTerminal',
|
||||
\ 'hidden': 1,
|
||||
\ 'term_finish': 'close'
|
||||
\ })
|
||||
call term_setapi(bufnr, 'Coc')
|
||||
call timer_start(100, { -> s:check_term_buffer(a:default, bufnr)})
|
||||
endif
|
||||
let config = s:get_prompt_dimension(a:title, a:default, a:opts)
|
||||
let res = coc#float#create_float_win(0, bufnr, extend(config, {
|
||||
\ 'style': 'minimal',
|
||||
\ 'border': get(a:opts, 'border', [1,1,1,1]),
|
||||
\ 'rounded': get(a:opts, 'rounded', 1),
|
||||
\ 'prompt': 1,
|
||||
\ 'title': a:title,
|
||||
\ 'lines': s:is_vim ? v:null : [a:default],
|
||||
\ 'highlight': get(a:opts, 'highlight', 'CocFloating'),
|
||||
\ 'borderhighlight': [get(a:opts, 'borderhighlight', 'CocFloating')],
|
||||
\ }))
|
||||
if empty(res)
|
||||
return
|
||||
endif
|
||||
let winid = res[0]
|
||||
let bufnr = res[1]
|
||||
if has('nvim')
|
||||
let s:prompt_win_bufnr = res[1]
|
||||
execute 'sign unplace 6 buffer='.s:prompt_win_bufnr
|
||||
call nvim_set_current_win(winid)
|
||||
inoremap <buffer> <C-a> <Home>
|
||||
inoremap <buffer><expr><C-e> pumvisible() ? "\<C-e>" : "\<End>"
|
||||
exe 'imap <silent><buffer> <esc> <esc><esc>'
|
||||
exe 'nnoremap <silent><buffer> <esc> :call coc#float#close('.winid.')<CR>'
|
||||
exe 'inoremap <silent><expr><nowait><buffer> <cr> "\<C-r>=coc#dialog#prompt_insert(getline(''.''))\<cr>\<esc>"'
|
||||
call feedkeys('A', 'in')
|
||||
endif
|
||||
call coc#util#do_autocmd('CocOpenFloatPrompt')
|
||||
if s:is_vim
|
||||
let pos = popup_getpos(winid)
|
||||
" width height row col
|
||||
let dimension = [pos['width'], pos['height'], pos['line'], pos['col'] - 1]
|
||||
else
|
||||
let id = coc#float#get_related(winid, 'border')
|
||||
let pos = nvim_win_get_position(id)
|
||||
let dimension = [nvim_win_get_width(id), nvim_win_get_height(id), pos[0], pos[1]]
|
||||
endif
|
||||
return [bufnr, winid, dimension]
|
||||
endfunction
|
||||
|
||||
" Create menu picker for pick single item
|
||||
function! coc#dialog#create_menu(lines, config) abort
|
||||
call s:close_auto_hide_wins()
|
||||
let highlight = get(a:config, 'highlight', 'CocFloating')
|
||||
let borderhighlight = get(a:config, 'borderhighlight', [highlight])
|
||||
let relative = get(a:config, 'relative', 'cursor')
|
||||
let opts = {
|
||||
\ 'lines': a:lines,
|
||||
\ 'highlight': highlight,
|
||||
\ 'title': get(a:config, 'title', ''),
|
||||
\ 'borderhighlight': borderhighlight,
|
||||
\ 'maxWidth': get(a:config, 'maxWidth', 80),
|
||||
\ 'maxHeight': get(a:config, 'maxHeight', 80),
|
||||
\ 'rounded': get(a:config, 'rounded', 0),
|
||||
\ 'border': [1, 1, 1, 1],
|
||||
\ 'highlights': get(a:config, 'highlights', []),
|
||||
\ 'relative': relative,
|
||||
\ }
|
||||
if s:is_vim
|
||||
let opts['cursorline'] = 1
|
||||
endif
|
||||
if relative ==# 'editor'
|
||||
let dimension = coc#dialog#get_config_editor(a:lines, opts)
|
||||
else
|
||||
let dimension = coc#dialog#get_config_cursor(a:lines, opts)
|
||||
endif
|
||||
call extend(opts, dimension)
|
||||
let res = coc#float#create_float_win(0, s:prompt_win_bufnr, opts)
|
||||
if empty(res)
|
||||
return
|
||||
endif
|
||||
let s:prompt_win_bufnr = res[1]
|
||||
redraw
|
||||
if has('nvim')
|
||||
call coc#float#nvim_scrollbar(res[0])
|
||||
execute 'sign unplace 6 buffer='.s:prompt_win_bufnr
|
||||
execute 'sign place 6 line=1 name=CocCurrentLine buffer='.s:prompt_win_bufnr
|
||||
endif
|
||||
return res
|
||||
endfunction
|
||||
|
||||
" Create dialog at center of screen
|
||||
function! coc#dialog#create_dialog(lines, config) abort
|
||||
call s:close_auto_hide_wins()
|
||||
" dialog always have borders
|
||||
let title = get(a:config, 'title', '')
|
||||
let buttons = get(a:config, 'buttons', [])
|
||||
let highlight = get(a:config, 'highlight', 'CocFloating')
|
||||
let borderhighlight = get(a:config, 'borderhighlight', [highlight])
|
||||
let opts = {
|
||||
\ 'title': title,
|
||||
\ 'rounded': get(a:config, 'rounded', 0),
|
||||
\ 'relative': 'editor',
|
||||
\ 'border': [1,1,1,1],
|
||||
\ 'close': get(a:config, 'close', 1),
|
||||
\ 'highlight': highlight,
|
||||
\ 'highlights': get(a:config, 'highlights', []),
|
||||
\ 'buttons': buttons,
|
||||
\ 'borderhighlight': borderhighlight,
|
||||
\ 'getchar': get(a:config, 'getchar', 0)
|
||||
\ }
|
||||
if get(a:config, 'cursorline', 0)
|
||||
let opts['cursorline'] = 1
|
||||
endif
|
||||
call extend(opts, coc#dialog#get_config_editor(a:lines, a:config))
|
||||
let bufnr = coc#float#create_buf(0, a:lines)
|
||||
let res = coc#float#create_float_win(0, bufnr, opts)
|
||||
if empty(res)
|
||||
return
|
||||
endif
|
||||
if has('nvim')
|
||||
if get(a:config, 'cursorline', 0)
|
||||
execute 'sign place 6 line=1 name=CocCurrentLine buffer='.bufnr
|
||||
endif
|
||||
redraw
|
||||
call coc#float#nvim_scrollbar(res[0])
|
||||
endif
|
||||
return res
|
||||
endfunction
|
||||
|
||||
function! coc#dialog#prompt_confirm(title, cb) abort
|
||||
call s:close_auto_hide_wins()
|
||||
if s:is_vim && exists('*popup_dialog')
|
||||
try
|
||||
call popup_dialog(a:title. ' (y/n)?', {
|
||||
\ 'highlight': 'Normal',
|
||||
\ 'filter': 'popup_filter_yesno',
|
||||
\ 'callback': {id, res -> a:cb(v:null, res)},
|
||||
\ 'borderchars': get(g:, 'coc_borderchars', ['─', '│', '─', '│', '╭', '╮', '╯', '╰']),
|
||||
\ 'borderhighlight': ['MoreMsg']
|
||||
\ })
|
||||
catch /.*/
|
||||
call a:cb(v:exception)
|
||||
endtry
|
||||
return
|
||||
endif
|
||||
if has('nvim-0.4.0')
|
||||
let text = ' '. a:title . ' (y/n)? '
|
||||
let maxWidth = coc#math#min(78, &columns - 2)
|
||||
let width = coc#math#min(maxWidth, strdisplaywidth(text))
|
||||
let maxHeight = &lines - &cmdheight - 1
|
||||
let height = coc#math#min(maxHeight, float2nr(ceil(str2float(string(strdisplaywidth(text)))/width)))
|
||||
let arr = coc#float#create_float_win(0, s:prompt_win_bufnr, {
|
||||
\ 'col': &columns/2 - width/2 - 1,
|
||||
\ 'row': maxHeight/2 - height/2 - 1,
|
||||
\ 'width': width,
|
||||
\ 'height': height,
|
||||
\ 'border': [1,1,1,1],
|
||||
\ 'focusable': v:false,
|
||||
\ 'relative': 'editor',
|
||||
\ 'highlight': 'Normal',
|
||||
\ 'borderhighlight': ['MoreMsg'],
|
||||
\ 'style': 'minimal',
|
||||
\ 'lines': [text],
|
||||
\ })
|
||||
if empty(arr)
|
||||
call a:cb('Window create failed!')
|
||||
return
|
||||
endif
|
||||
let winid = arr[0]
|
||||
let s:prompt_win_bufnr = arr[1]
|
||||
let res = 0
|
||||
redraw
|
||||
" same result as vim
|
||||
while 1
|
||||
let key = nr2char(getchar())
|
||||
if key == "\<C-c>"
|
||||
let res = -1
|
||||
break
|
||||
elseif key == "\<esc>" || key == 'n' || key == 'N'
|
||||
let res = 0
|
||||
break
|
||||
elseif key == 'y' || key == 'Y'
|
||||
let res = 1
|
||||
break
|
||||
endif
|
||||
endw
|
||||
call coc#float#close(winid)
|
||||
call a:cb(v:null, res)
|
||||
" use relative editor since neovim doesn't support center position
|
||||
elseif exists('*confirm')
|
||||
let choice = confirm(a:title, "&Yes\n&No")
|
||||
call a:cb(v:null, 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
|
||||
call a:cb(v:null, 0)
|
||||
end
|
||||
call a:cb(v:null, 1)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#dialog#get_config_editor(lines, config) abort
|
||||
let title = get(a:config, 'title', '')
|
||||
let maxheight = min([get(a:config, 'maxHeight', 78), &lines - &cmdheight - 6])
|
||||
let maxwidth = min([get(a:config, 'maxWidth', 78), &columns - 2])
|
||||
let buttons = get(a:config, 'buttons', [])
|
||||
let minwidth = s:min_btns_width(buttons)
|
||||
if maxheight <= 0 || maxwidth <= 0 || minwidth > maxwidth
|
||||
throw 'Not enough spaces for float window'
|
||||
endif
|
||||
let ch = 0
|
||||
let width = min([strdisplaywidth(title) + 1, maxwidth])
|
||||
for line in a:lines
|
||||
let dw = max([1, strdisplaywidth(line)])
|
||||
if dw < maxwidth && dw > width
|
||||
let width = dw
|
||||
elseif dw >= maxwidth
|
||||
let width = maxwidth
|
||||
endif
|
||||
let ch += float2nr(ceil(str2float(string(dw))/maxwidth))
|
||||
endfor
|
||||
let width = max([minwidth, width])
|
||||
let height = coc#math#min(ch ,maxheight)
|
||||
return {
|
||||
\ 'row': &lines/2 - (height + 4)/2,
|
||||
\ 'col': &columns/2 - (width + 2)/2,
|
||||
\ 'width': width,
|
||||
\ 'height': height,
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! coc#dialog#prompt_insert(text) abort
|
||||
call coc#rpc#notify('PromptInsert', [a:text, bufnr('%')])
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Dimension of window with lines relative to cursor
|
||||
" Width & height excludes border & padding
|
||||
function! coc#dialog#get_config_cursor(lines, config) abort
|
||||
let preferTop = get(a:config, 'preferTop', 0)
|
||||
let title = get(a:config, 'title', '')
|
||||
let border = get(a:config, 'border', [])
|
||||
if empty(border) && len(title)
|
||||
let border = [1, 1, 1, 1]
|
||||
endif
|
||||
let bh = get(border, 0, 0) + get(border, 2, 0)
|
||||
let vh = &lines - &cmdheight - 1
|
||||
if vh <= 0
|
||||
return v:null
|
||||
endif
|
||||
let maxWidth = coc#math#min(get(a:config, 'maxWidth', &columns - 1), &columns - 1)
|
||||
if maxWidth < 3
|
||||
return v:null
|
||||
endif
|
||||
let maxHeight = coc#math#min(get(a:config, 'maxHeight', vh), vh)
|
||||
let ch = 0
|
||||
let width = coc#math#min(40, strdisplaywidth(title)) + 3
|
||||
for line in a:lines
|
||||
let dw = max([1, strdisplaywidth(line)])
|
||||
let width = max([width, dw + 2])
|
||||
let ch += float2nr(ceil(str2float(string(dw))/(maxWidth - 2)))
|
||||
endfor
|
||||
let width = coc#math#min(maxWidth, width)
|
||||
let [lineIdx, colIdx] = coc#cursor#screen_pos()
|
||||
" How much we should move left
|
||||
let offsetX = coc#math#min(get(a:config, 'offsetX', 0), colIdx)
|
||||
let showTop = 0
|
||||
let hb = vh - lineIdx -1
|
||||
if lineIdx > bh + 2 && (preferTop || (lineIdx > hb && hb < ch + bh))
|
||||
let showTop = 1
|
||||
endif
|
||||
let height = coc#math#min(maxHeight, ch + bh, showTop ? lineIdx - 1 : hb)
|
||||
if height <= bh
|
||||
return v:null
|
||||
endif
|
||||
let col = - max([offsetX, colIdx - (&columns - 1 - width)])
|
||||
let row = showTop ? - height + bh : 1
|
||||
return {
|
||||
\ 'row': row,
|
||||
\ 'col': col,
|
||||
\ 'width': width - 2,
|
||||
\ 'height': height - bh
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! coc#dialog#change_border_hl(winid, hlgroup) abort
|
||||
if !hlexists(a:hlgroup)
|
||||
return
|
||||
endif
|
||||
if s:is_vim
|
||||
if coc#float#valid(a:winid)
|
||||
call popup_setoptions(a:winid, {'borderhighlight': repeat([a:hlgroup], 4)})
|
||||
redraw
|
||||
endif
|
||||
else
|
||||
let winid = coc#float#get_related(a:winid, 'border')
|
||||
if winid > 0
|
||||
call setwinvar(winid, '&winhl', 'Normal:'.a:hlgroup.',NormalNC:'.a:hlgroup)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#dialog#change_title(winid, title) abort
|
||||
if s:is_vim
|
||||
if coc#float#valid(a:winid)
|
||||
call popup_setoptions(a:winid, {'title': a:title})
|
||||
redraw
|
||||
endif
|
||||
else
|
||||
let winid = coc#float#get_related(a:winid, 'border')
|
||||
if winid > 0
|
||||
let bufnr = winbufnr(winid)
|
||||
let line = getbufline(bufnr, 1)[0]
|
||||
let top = strcharpart(line, 0, 1)
|
||||
\.repeat('─', strchars(line) - 2)
|
||||
\.strcharpart(line, strchars(line) - 1, 1)
|
||||
if !empty(a:title)
|
||||
let top = coc#string#compose(top, 1, a:title.' ')
|
||||
endif
|
||||
call nvim_buf_set_lines(bufnr, 0, 1, v:false, [top])
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#dialog#change_loading(winid, loading) abort
|
||||
if coc#float#valid(a:winid)
|
||||
let winid = coc#float#get_related(a:winid, 'loading')
|
||||
if !a:loading && winid > 0
|
||||
call coc#float#close(winid)
|
||||
endif
|
||||
if a:loading && winid == 0
|
||||
let bufnr = s:create_loading_buf()
|
||||
if s:is_vim
|
||||
let pos = popup_getpos(a:winid)
|
||||
let winid = popup_create(bufnr, {
|
||||
\ 'line': pos['line'] + 1,
|
||||
\ 'col': pos['col'] + pos['width'] - 4,
|
||||
\ 'maxheight': 1,
|
||||
\ 'maxwidth': 3,
|
||||
\ 'zindex': 999,
|
||||
\ 'highlight': get(popup_getoptions(a:winid), 'highlight', 'CocFloating')
|
||||
\ })
|
||||
else
|
||||
let pos = nvim_win_get_position(a:winid)
|
||||
let width = nvim_win_get_width(a:winid)
|
||||
let opts = {
|
||||
\ 'relative': 'editor',
|
||||
\ 'row': pos[0],
|
||||
\ 'col': pos[1] + width - 3,
|
||||
\ 'focusable': v:false,
|
||||
\ 'width': 3,
|
||||
\ 'height': 1,
|
||||
\ 'style': 'minimal',
|
||||
\ }
|
||||
if has('nvim-0.5.1')
|
||||
let opts['zindex'] = 900
|
||||
endif
|
||||
let winid = nvim_open_win(bufnr, v:false, opts)
|
||||
call setwinvar(winid, '&winhl', getwinvar(a:winid, '&winhl'))
|
||||
endif
|
||||
call setwinvar(winid, 'kind', 'loading')
|
||||
call setbufvar(bufnr, 'target', a:winid)
|
||||
call setbufvar(bufnr, 'popup', winid)
|
||||
call coc#float#add_related(winid, a:winid)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Could be center(with optional marginTop) or cursor
|
||||
function! s:get_prompt_dimension(title, default, opts) abort
|
||||
let relative = get(a:opts, 'position', 'cursor') ==# 'cursor' ? 'cursor' : 'editor'
|
||||
let curr = win_screenpos(winnr())[1] + wincol() - 2
|
||||
let minWidth = get(a:opts, 'minWidth', s:prompt_win_width)
|
||||
let width = min([max([strwidth(a:default) + 2, strwidth(a:title) + 2, minWidth]), &columns - 2])
|
||||
if get(a:opts, 'maxWidth', 0)
|
||||
let width = min([width, a:opts['maxWidth']])
|
||||
endif
|
||||
if relative ==# 'cursor'
|
||||
let [lineIdx, colIdx] = coc#cursor#screen_pos()
|
||||
if width == &columns - 2
|
||||
let col = 0 - curr
|
||||
else
|
||||
let col = curr + width <= &columns - 2 ? 0 : curr + width - &columns + 2
|
||||
endif
|
||||
let config = {
|
||||
\ 'row': lineIdx == 0 ? 1 : 0,
|
||||
\ 'col': colIdx == 0 ? 0 : col - 1,
|
||||
\ }
|
||||
else
|
||||
let marginTop = get(a:opts, 'marginTop', v:null)
|
||||
if marginTop is v:null
|
||||
let row = (&lines - &cmdheight - 2) / 2
|
||||
else
|
||||
let row = marginTop < 2 ? 1 : min([marginTop, &columns - &cmdheight])
|
||||
endif
|
||||
let config = {
|
||||
\ 'col': float2nr((&columns - width) / 2),
|
||||
\ 'row': row,
|
||||
\ }
|
||||
endif
|
||||
return extend(config, {'relative': relative, 'width': width, 'height': 1})
|
||||
endfunction
|
||||
|
||||
function! s:check_term_buffer(current, bufnr) abort
|
||||
if bufloaded(a:bufnr)
|
||||
let text = term_getline(a:bufnr, '.')
|
||||
if text !=# a:current
|
||||
let cursor = term_getcursor(a:bufnr)
|
||||
let info = {
|
||||
\ 'lnum': cursor[0],
|
||||
\ 'col': cursor[1],
|
||||
\ 'line': text ==# ' ' && cursor[1] == 1 ? '' : text,
|
||||
\ 'changedtick': 0
|
||||
\ }
|
||||
call coc#rpc#notify('CocAutocmd', ['TextChangedI', a:bufnr, info])
|
||||
endif
|
||||
call timer_start(50, { -> s:check_term_buffer(text, a:bufnr)})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:min_btns_width(buttons) abort
|
||||
if empty(a:buttons)
|
||||
return 0
|
||||
endif
|
||||
let minwidth = len(a:buttons)*3 - 1
|
||||
for txt in a:buttons
|
||||
let minwidth = minwidth + strdisplaywidth(txt)
|
||||
endfor
|
||||
return minwidth
|
||||
endfunction
|
||||
|
||||
" Close windows that should auto hide
|
||||
function! s:close_auto_hide_wins(...) abort
|
||||
let winids = coc#float#get_float_win_list()
|
||||
let except = get(a:, 1, 0)
|
||||
for id in winids
|
||||
if except && id == except
|
||||
continue
|
||||
endif
|
||||
if coc#window#get_var(id, 'autohide', 0)
|
||||
call coc#float#close(id)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:create_loading_buf() abort
|
||||
let bufnr = coc#float#create_buf(0)
|
||||
call s:change_loading_buf(bufnr, 0)
|
||||
return bufnr
|
||||
endfunction
|
||||
|
||||
function! s:change_loading_buf(bufnr, idx) abort
|
||||
if bufloaded(a:bufnr)
|
||||
let target = getbufvar(a:bufnr, 'target', v:null)
|
||||
if !empty(target) && !coc#float#valid(target)
|
||||
call coc#float#close(getbufvar(a:bufnr, 'popup'))
|
||||
return
|
||||
endif
|
||||
let line = get(s:frames, a:idx, ' ')
|
||||
call setbufline(a:bufnr, 1, line)
|
||||
call coc#highlight#add_highlight(a:bufnr, -1, 'CocNotificationProgress', 0, 0, -1)
|
||||
let idx = a:idx == len(s:frames) - 1 ? 0 : a:idx + 1
|
||||
call timer_start(100, { -> s:change_loading_buf(a:bufnr, idx)})
|
||||
endif
|
||||
endfunction
|
32
sources_non_forked/coc.nvim/autoload/coc/dict.vim
Normal file
32
sources_non_forked/coc.nvim/autoload/coc/dict.vim
Normal file
@ -0,0 +1,32 @@
|
||||
scriptencoding utf-8
|
||||
|
||||
function! coc#dict#equal(one, two) abort
|
||||
for key in keys(a:one)
|
||||
if a:one[key] != a:two[key]
|
||||
return 0
|
||||
endif
|
||||
endfor
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
" Return new dict with keys removed
|
||||
function! coc#dict#omit(dict, keys) abort
|
||||
let res = {}
|
||||
for key in keys(a:dict)
|
||||
if index(a:keys, key) == -1
|
||||
let res[key] = a:dict[key]
|
||||
endif
|
||||
endfor
|
||||
return res
|
||||
endfunction
|
||||
|
||||
" Return new dict with keys only
|
||||
function! coc#dict#pick(dict, keys) abort
|
||||
let res = {}
|
||||
for key in keys(a:dict)
|
||||
if index(a:keys, key) != -1
|
||||
let res[key] = a:dict[key]
|
||||
endif
|
||||
endfor
|
||||
return res
|
||||
endfunction
|
1331
sources_non_forked/coc.nvim/autoload/coc/float.vim
Normal file
1331
sources_non_forked/coc.nvim/autoload/coc/float.vim
Normal file
File diff suppressed because it is too large
Load Diff
148
sources_non_forked/coc.nvim/autoload/coc/helper.vim
Normal file
148
sources_non_forked/coc.nvim/autoload/coc/helper.vim
Normal file
@ -0,0 +1,148 @@
|
||||
scriptencoding utf-8
|
||||
" Helper methods for viml
|
||||
|
||||
function! coc#helper#get_charactor(line, col) abort
|
||||
return strchars(strpart(a:line, 0, a:col - 1))
|
||||
endfunction
|
||||
|
||||
function! coc#helper#last_character(line) abort
|
||||
return strcharpart(a:line, strchars(a:line) - 1, 1)
|
||||
endfunction
|
||||
|
||||
function! coc#helper#obj_equal(one, two) abort
|
||||
for key in keys(a:one)
|
||||
if a:one[key] != a:two[key]
|
||||
return 0
|
||||
endif
|
||||
endfor
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
" get change between two lines
|
||||
function! coc#helper#str_diff(curr, previous, col) abort
|
||||
let end = strpart(a:curr, a:col - 1)
|
||||
let start = strpart(a:curr, 0, a:col -1)
|
||||
let endOffset = 0
|
||||
let startOffset = 0
|
||||
let currLen = strchars(a:curr)
|
||||
let prevLen = strchars(a:previous)
|
||||
if len(end)
|
||||
let endLen = strchars(end)
|
||||
for i in range(min([prevLen, endLen]))
|
||||
if strcharpart(end, endLen - 1 - i, 1) ==# strcharpart(a:previous, prevLen -1 -i, 1)
|
||||
let endOffset = endOffset + 1
|
||||
else
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
let remain = endOffset == 0 ? a:previous : strcharpart(a:previous, 0, prevLen - endOffset)
|
||||
if len(remain)
|
||||
for i in range(min([strchars(remain), strchars(start)]))
|
||||
if strcharpart(remain, i, 1) ==# strcharpart(start, i ,1)
|
||||
let startOffset = startOffset + 1
|
||||
else
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
return {
|
||||
\ 'start': startOffset,
|
||||
\ 'end': prevLen - endOffset,
|
||||
\ 'text': strcharpart(a:curr, startOffset, currLen - startOffset - endOffset)
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! coc#helper#str_apply(content, diff) abort
|
||||
let totalLen = strchars(a:content)
|
||||
let endLen = totalLen - a:diff['end']
|
||||
return strcharpart(a:content, 0, a:diff['start']).a:diff['text'].strcharpart(a:content, a:diff['end'], endLen)
|
||||
endfunction
|
||||
|
||||
" insert inserted to line at position, use ... when result is too long
|
||||
" line should only contains character has strwidth equals 1
|
||||
function! coc#helper#str_compose(line, position, inserted) abort
|
||||
let width = strwidth(a:line)
|
||||
let text = a:inserted
|
||||
let res = a:line
|
||||
let need_truncate = a:position + strwidth(text) + 1 > width
|
||||
if need_truncate
|
||||
let remain = width - a:position - 3
|
||||
if remain < 2
|
||||
" use text for full line, use first & end of a:line, ignore position
|
||||
let res = strcharpart(a:line, 0, 1)
|
||||
let w = strwidth(res)
|
||||
for i in range(strchars(text))
|
||||
let c = strcharpart(text, i, 1)
|
||||
let a = strwidth(c)
|
||||
if w + a <= width - 1
|
||||
let w = w + a
|
||||
let res = res.c
|
||||
endif
|
||||
endfor
|
||||
let res = res.strcharpart(a:line, w)
|
||||
else
|
||||
let res = strcharpart(a:line, 0, a:position)
|
||||
let w = strwidth(res)
|
||||
for i in range(strchars(text))
|
||||
let c = strcharpart(text, i, 1)
|
||||
let a = strwidth(c)
|
||||
if w + a <= width - 3
|
||||
let w = w + a
|
||||
let res = res.c
|
||||
endif
|
||||
endfor
|
||||
let res = res.'..'
|
||||
let w = w + 2
|
||||
let res = res.strcharpart(a:line, w)
|
||||
endif
|
||||
else
|
||||
let first = strcharpart(a:line, 0, a:position)
|
||||
let res = first.text.strcharpart(a:line, a:position + strwidth(text))
|
||||
endif
|
||||
return res
|
||||
endfunction
|
||||
|
||||
" Return new dict with keys removed
|
||||
function! coc#helper#dict_omit(dict, keys) abort
|
||||
let res = {}
|
||||
for key in keys(a:dict)
|
||||
if index(a:keys, key) == -1
|
||||
let res[key] = a:dict[key]
|
||||
endif
|
||||
endfor
|
||||
return res
|
||||
endfunction
|
||||
|
||||
" Return new dict with keys only
|
||||
function! coc#helper#dict_pick(dict, keys) abort
|
||||
let res = {}
|
||||
for key in keys(a:dict)
|
||||
if index(a:keys, key) != -1
|
||||
let res[key] = a:dict[key]
|
||||
endif
|
||||
endfor
|
||||
return res
|
||||
endfunction
|
||||
|
||||
" support for float values
|
||||
function! coc#helper#min(first, ...) abort
|
||||
let val = a:first
|
||||
for i in range(0, len(a:000) - 1)
|
||||
if a:000[i] < val
|
||||
let val = a:000[i]
|
||||
endif
|
||||
endfor
|
||||
return val
|
||||
endfunction
|
||||
|
||||
" support for float values
|
||||
function! coc#helper#max(first, ...) abort
|
||||
let val = a:first
|
||||
for i in range(0, len(a:000) - 1)
|
||||
if a:000[i] > val
|
||||
let val = a:000[i]
|
||||
endif
|
||||
endfor
|
||||
return val
|
||||
endfunction
|
729
sources_non_forked/coc.nvim/autoload/coc/highlight.vim
Normal file
729
sources_non_forked/coc.nvim/autoload/coc/highlight.vim
Normal file
@ -0,0 +1,729 @@
|
||||
scriptencoding utf-8
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:clear_match_by_window = has('nvim-0.6.0') || has('patch-8.1.1084')
|
||||
let s:set_extmark = has('nvim') && exists('*nvim_buf_set_extmark')
|
||||
let s:del_extmark = has('nvim') && exists('*nvim_buf_del_extmark')
|
||||
let s:prop_offset = get(g:, 'coc_text_prop_offset', 1000)
|
||||
let s:namespace_map = {}
|
||||
let s:ns_id = 1
|
||||
let s:diagnostic_hlgroups = ['CocErrorHighlight', 'CocWarningHighlight', 'CocInfoHighlight', 'CocHintHighlight', 'CocDeprecatedHighlight', 'CocUnusedHighlight']
|
||||
" Maximum count to highlight each time.
|
||||
let g:coc_highlight_maximum_count = get(g:, 'coc_highlight_maximum_count', 100)
|
||||
|
||||
if has('nvim-0.5.0') && s:clear_match_by_window == 0
|
||||
try
|
||||
call getmatches(0)
|
||||
let s:clear_match_by_window = 1
|
||||
catch /^Vim\%((\a\+)\)\=:E118/
|
||||
" ignored
|
||||
endtry
|
||||
endif
|
||||
|
||||
" Update buffer region by region.
|
||||
function! coc#highlight#buffer_update(bufnr, key, highlights, ...) abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return
|
||||
endif
|
||||
if empty(a:highlights)
|
||||
call coc#highlight#clear_highlight(a:bufnr, a:key, 0, -1)
|
||||
return
|
||||
endif
|
||||
let priority = get(a:, 1, v:null)
|
||||
let changedtick = getbufvar(a:bufnr, 'changedtick', 0)
|
||||
if type(get(a:, 2, v:null)) == 0 && changedtick > a:2
|
||||
return
|
||||
endif
|
||||
let hls = map(copy(a:highlights), "{'hlGroup':v:val[0],'lnum':v:val[1],'colStart':v:val[2],'colEnd':v:val[3],'combine':get(v:val,4,1),'start_incl':get(v:val,5,0),'end_incl':get(v:val,6,0)}")
|
||||
if len(hls) <= g:coc_highlight_maximum_count || get(g:, 'coc_node_env', '') ==# 'test'
|
||||
call coc#highlight#update_highlights(a:bufnr, a:key, hls, 0, -1, priority)
|
||||
return
|
||||
endif
|
||||
let linecount = coc#compat#buf_line_count(a:bufnr)
|
||||
let groups = s:group_hls(hls, linecount)
|
||||
call s:update_highlights_timer(a:bufnr, changedtick, a:key, priority, groups, 0)
|
||||
endfunction
|
||||
|
||||
" Update highlights by check exists highlights.
|
||||
" 0 based, end exclusive start and end
|
||||
function! coc#highlight#update_highlights(bufnr, key, highlights, ...) abort
|
||||
let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
|
||||
if !bufloaded(bufnr)
|
||||
return
|
||||
endif
|
||||
let start = get(a:, 1, 0)
|
||||
let end = get(a:, 2, -1)
|
||||
if end == 0
|
||||
return
|
||||
endif
|
||||
let linecount = coc#compat#buf_line_count(a:bufnr)
|
||||
if end >= linecount
|
||||
let end = -1
|
||||
endif
|
||||
if empty(a:highlights)
|
||||
call coc#highlight#clear_highlight(bufnr, a:key, start, end)
|
||||
return
|
||||
endif
|
||||
let priority = get(a:, 3, v:null)
|
||||
let total = len(a:highlights)
|
||||
" index list that exists with current highlights
|
||||
let exists = []
|
||||
let ns = coc#highlight#create_namespace(a:key)
|
||||
if has('nvim-0.5.0') || exists('*prop_list')
|
||||
let endLnum = end < 0 ? linecount - 1 : end - 1
|
||||
let firstLnum = a:highlights[0]['lnum']
|
||||
if firstLnum > start
|
||||
call coc#highlight#clear_highlight(bufnr, a:key, start, firstLnum)
|
||||
let start = firstLnum
|
||||
endif
|
||||
let lastLnum = a:highlights[total - 1]['lnum']
|
||||
if lastLnum < endLnum
|
||||
call coc#highlight#clear_highlight(bufnr, a:key, lastLnum + 1, endLnum + 1)
|
||||
let endLnum = lastLnum
|
||||
endif
|
||||
let current = coc#highlight#get_highlights(bufnr, a:key, start, endLnum)
|
||||
let currIndex = 0
|
||||
let clearLnums = []
|
||||
if !empty(current)
|
||||
for [lnum, items] in s:to_group(current)
|
||||
let indexes = []
|
||||
let currIndexes = range(0, len(items) - 1)
|
||||
"call coc#rpc#notify('Log', ['items:', lnum, items])
|
||||
while currIndex != total
|
||||
let hi = a:highlights[currIndex]
|
||||
if hi['lnum'] == lnum
|
||||
for idx in currIndexes
|
||||
let item = items[idx]
|
||||
if hi['hlGroup'] ==# item[0] && hi['colStart'] == item[2] && hi['colEnd'] == item[3]
|
||||
call add(indexes, currIndex)
|
||||
call filter(currIndexes, 'v:val != '.idx)
|
||||
break
|
||||
elseif item[2] > hi['colStart']
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
elseif hi['lnum'] > lnum
|
||||
break
|
||||
endif
|
||||
let currIndex = currIndex + 1
|
||||
endwhile
|
||||
if !empty(currIndexes)
|
||||
if s:del_extmark
|
||||
for idx in currIndexes
|
||||
call nvim_buf_del_extmark(bufnr, ns, items[idx][4])
|
||||
endfor
|
||||
call extend(exists, indexes)
|
||||
else
|
||||
call add(clearLnums, lnum)
|
||||
endif
|
||||
else
|
||||
" all highlights of current line exists, not clear.
|
||||
call extend(exists, indexes)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
call coc#highlight#clear(bufnr, a:key, clearLnums)
|
||||
else
|
||||
call coc#highlight#clear_highlight(bufnr, a:key, start, end)
|
||||
endif
|
||||
let indexes = range(0, total - 1)
|
||||
if !empty(exists)
|
||||
let indexes = filter(indexes, 'index(exists, v:val) == -1')
|
||||
endif
|
||||
for idx in indexes
|
||||
let hi = a:highlights[idx]
|
||||
let opts = {}
|
||||
if type(priority) == 0
|
||||
let opts['priority'] = s:get_priority(a:key, hi['hlGroup'], priority)
|
||||
endif
|
||||
for key in ['combine', 'start_incl', 'end_incl']
|
||||
if has_key(hi, key)
|
||||
let opts[key] = hi[key]
|
||||
endif
|
||||
endfor
|
||||
call coc#highlight#add_highlight(bufnr, ns, hi['hlGroup'], hi['lnum'], hi['colStart'], hi['colEnd'], opts)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" 0 based line, start_col and end_col
|
||||
" 0 based start & end line, end inclusive.
|
||||
function! coc#highlight#get_highlights(bufnr, key, ...) abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return v:null
|
||||
endif
|
||||
if !has_key(s:namespace_map, a:key)
|
||||
return []
|
||||
endif
|
||||
let start = get(a:, 1, 0)
|
||||
let end = get(a:, 2, -1)
|
||||
let res = []
|
||||
let ns = s:namespace_map[a:key]
|
||||
if exists('*prop_list')
|
||||
" Could filter by end_lnum and ids
|
||||
if has('patch-8.2.3652')
|
||||
let endLnum = end == -1 ? -1 : end + 1
|
||||
for prop in prop_list(start + 1, {'bufnr': a:bufnr, 'ids': [s:prop_offset + ns], 'end_lnum': endLnum})
|
||||
if prop['start'] == 0 || prop['end'] == 0
|
||||
" multi line textprop are not supported, simply ignore it
|
||||
continue
|
||||
endif
|
||||
let startCol = prop['col'] - 1
|
||||
let endCol = startCol + prop['length']
|
||||
call add(res, [s:prop_type_hlgroup(prop['type']), prop['lnum'] - 1, startCol, endCol])
|
||||
endfor
|
||||
else
|
||||
if end == -1
|
||||
let end = coc#compat#buf_line_count(a:bufnr)
|
||||
else
|
||||
let end = end + 1
|
||||
endif
|
||||
let id = s:prop_offset + ns
|
||||
for line in range(start + 1, end)
|
||||
for prop in prop_list(line, {'bufnr': a:bufnr})
|
||||
if prop['id'] != id || prop['start'] == 0 || prop['end'] == 0
|
||||
" multi line textprop are not supported, simply ignore it
|
||||
continue
|
||||
endif
|
||||
let startCol = prop['col'] - 1
|
||||
let endCol = startCol + prop['length']
|
||||
call add(res, [s:prop_type_hlgroup(prop['type']), line - 1, startCol, endCol])
|
||||
endfor
|
||||
endfor
|
||||
endif
|
||||
elseif has('nvim-0.5.0')
|
||||
let start = [start, 0]
|
||||
let maximum = end == -1 ? nvim_buf_line_count(a:bufnr) : end + 1
|
||||
let end = end == -1 ? -1 : [end + 1, 0]
|
||||
let markers = nvim_buf_get_extmarks(a:bufnr, ns, start, -1, {'details': v:true})
|
||||
for [marker_id, line, start_col, details] in markers
|
||||
if line >= maximum
|
||||
" Could be markers exceed end of line
|
||||
continue
|
||||
endif
|
||||
let delta = details['end_row'] - line
|
||||
if delta > 1 || (delta == 1 && details['end_col'] != 0)
|
||||
" can't handle, single line only
|
||||
continue
|
||||
endif
|
||||
let endCol = details['end_col']
|
||||
if endCol == start_col
|
||||
call nvim_buf_del_extmark(a:bufnr, ns, marker_id)
|
||||
continue
|
||||
endif
|
||||
if delta == 1
|
||||
let text = get(nvim_buf_get_lines(a:bufnr, line, line + 1, 0), 0, '')
|
||||
let endCol = strlen(text)
|
||||
endif
|
||||
call add(res, [details['hl_group'], line, start_col, endCol, marker_id])
|
||||
endfor
|
||||
else
|
||||
throw 'Get highlights requires neovim 0.5.0 or vim support prop_list'
|
||||
endif
|
||||
return res
|
||||
endfunction
|
||||
|
||||
" Add multiple highlights to buffer.
|
||||
" type HighlightItem = [hlGroup, lnum, colStart, colEnd, combine?, start_incl?, end_incl?]
|
||||
function! coc#highlight#set(bufnr, key, highlights, priority) abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return
|
||||
endif
|
||||
let ns = coc#highlight#create_namespace(a:key)
|
||||
if len(a:highlights) > g:coc_highlight_maximum_count
|
||||
call s:add_highlights_timer(a:bufnr, ns, a:highlights, a:priority)
|
||||
else
|
||||
call s:add_highlights(a:bufnr, ns, a:highlights, a:priority)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Clear highlights by 0 based line numbers.
|
||||
function! coc#highlight#clear(bufnr, key, lnums) abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return
|
||||
endif
|
||||
let ns = coc#highlight#create_namespace(a:key)
|
||||
for lnum in a:lnums
|
||||
if has('nvim')
|
||||
call nvim_buf_clear_namespace(a:bufnr, ns, lnum, lnum + 1)
|
||||
else
|
||||
call coc#api#call('buf_clear_namespace', [a:bufnr, ns, lnum, lnum + 1])
|
||||
endif
|
||||
endfor
|
||||
" clear highlights in invalid line.
|
||||
if has('nvim')
|
||||
let linecount = nvim_buf_line_count(a:bufnr)
|
||||
call nvim_buf_clear_namespace(a:bufnr, ns, linecount, -1)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#highlight#del_markers(bufnr, key, ids) abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return
|
||||
endif
|
||||
let ns = coc#highlight#create_namespace(a:key)
|
||||
for id in a:ids
|
||||
call nvim_buf_del_extmark(a:bufnr, ns, id)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" highlight LSP range,
|
||||
function! coc#highlight#ranges(bufnr, key, hlGroup, ranges, ...) abort
|
||||
let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
|
||||
if !bufloaded(bufnr) || !exists('*getbufline')
|
||||
return
|
||||
endif
|
||||
let opts = get(a:, 1, {})
|
||||
let synmaxcol = getbufvar(a:bufnr, '&synmaxcol', 1000)
|
||||
if synmaxcol == 0
|
||||
let synmaxcol = 1000
|
||||
endif
|
||||
let synmaxcol = min([synmaxcol, 1000])
|
||||
let srcId = coc#highlight#create_namespace(a:key)
|
||||
for range in a:ranges
|
||||
let start = range['start']
|
||||
let end = range['end']
|
||||
for lnum in range(start['line'] + 1, end['line'] + 1)
|
||||
let arr = getbufline(bufnr, lnum)
|
||||
let line = empty(arr) ? '' : arr[0]
|
||||
if empty(line)
|
||||
continue
|
||||
endif
|
||||
if start['character'] > synmaxcol || end['character'] > synmaxcol
|
||||
continue
|
||||
endif
|
||||
" TODO don't know how to count UTF16 code point, should work most cases.
|
||||
let colStart = lnum == start['line'] + 1 ? strlen(strcharpart(line, 0, start['character'])) : 0
|
||||
let colEnd = lnum == end['line'] + 1 ? strlen(strcharpart(line, 0, end['character'])) : strlen(line)
|
||||
if colStart == colEnd
|
||||
continue
|
||||
endif
|
||||
call coc#highlight#add_highlight(bufnr, srcId, a:hlGroup, lnum - 1, colStart, colEnd, opts)
|
||||
endfor
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! coc#highlight#add_highlight(bufnr, src_id, hl_group, line, col_start, col_end, ...) abort
|
||||
let opts = get(a:, 1, {})
|
||||
let priority = get(opts, 'priority', v:null)
|
||||
if has('nvim')
|
||||
if s:set_extmark && a:src_id != -1
|
||||
" get(opts, 'start_incl', 0) ? v:true : v:false,
|
||||
try
|
||||
call nvim_buf_set_extmark(a:bufnr, a:src_id, a:line, a:col_start, {
|
||||
\ 'end_col': a:col_end,
|
||||
\ 'hl_group': a:hl_group,
|
||||
\ 'hl_mode': get(opts, 'combine', 1) ? 'combine' : 'replace',
|
||||
\ 'right_gravity': v:true,
|
||||
\ 'end_right_gravity': v:false,
|
||||
\ 'priority': type(priority) == 0 ? min([priority, 4096]) : 4096,
|
||||
\ })
|
||||
catch /^Vim\%((\a\+)\)\=:E5555/
|
||||
" the end_col could be invalid, ignore this error
|
||||
endtry
|
||||
else
|
||||
call nvim_buf_add_highlight(a:bufnr, a:src_id, a:hl_group, a:line, a:col_start, a:col_end)
|
||||
endif
|
||||
else
|
||||
call coc#api#call('buf_add_highlight', [a:bufnr, a:src_id, a:hl_group, a:line, a:col_start, a:col_end, opts])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#highlight#clear_highlight(bufnr, key, start_line, end_line) abort
|
||||
let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
|
||||
if !bufloaded(bufnr)
|
||||
return
|
||||
endif
|
||||
let src_id = coc#highlight#create_namespace(a:key)
|
||||
if has('nvim')
|
||||
call nvim_buf_clear_namespace(a:bufnr, src_id, a:start_line, a:end_line)
|
||||
else
|
||||
call coc#api#call('buf_clear_namespace', [a:bufnr, src_id, a:start_line, a:end_line])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" highlight buffer in winid with CodeBlock &HighlightItems
|
||||
" export interface HighlightItem {
|
||||
" lnum: number // 0 based
|
||||
" hlGroup: string
|
||||
" colStart: number // 0 based
|
||||
" colEnd: number
|
||||
" }
|
||||
" export interface CodeBlock {
|
||||
" filetype?: string
|
||||
" hlGroup?: string
|
||||
" startLine: number // 0 based
|
||||
" endLine: number
|
||||
" }
|
||||
function! coc#highlight#add_highlights(winid, codes, highlights) abort
|
||||
" clear highlights
|
||||
call coc#compat#execute(a:winid, 'syntax clear')
|
||||
let bufnr = winbufnr(a:winid)
|
||||
call coc#highlight#clear_highlight(bufnr, -1, 0, -1)
|
||||
if !empty(a:codes)
|
||||
call coc#highlight#highlight_lines(a:winid, a:codes)
|
||||
endif
|
||||
if !empty(a:highlights)
|
||||
for item in a:highlights
|
||||
call coc#highlight#add_highlight(bufnr, -1, item['hlGroup'], item['lnum'], item['colStart'], item['colEnd'])
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
" Add highlights to line groups of winid, support hlGroup and filetype
|
||||
" config should have startLine, endLine (0 based, end excluded) and filetype or hlGroup
|
||||
" endLine should > startLine and endLine is excluded
|
||||
"
|
||||
" export interface CodeBlock {
|
||||
" filetype?: string
|
||||
" hlGroup?: string
|
||||
" startLine: number // 0 based
|
||||
" endLine: number
|
||||
" }
|
||||
function! coc#highlight#highlight_lines(winid, blocks) abort
|
||||
let region_id = 1
|
||||
let defined = []
|
||||
let cmds = []
|
||||
for config in a:blocks
|
||||
let start = config['startLine'] + 1
|
||||
let end = config['endLine'] == -1 ? len(getbufline(winbufnr(a:winid), 1, '$')) + 1 : config['endLine'] + 1
|
||||
let filetype = get(config, 'filetype', '')
|
||||
let hlGroup = get(config, 'hlGroup', '')
|
||||
if !empty(hlGroup)
|
||||
call add(cmds, 'syntax region '.hlGroup.' start=/\%'.start.'l/ end=/\%'.end.'l/')
|
||||
else
|
||||
let filetype = matchstr(filetype, '\v^\w+')
|
||||
if empty(filetype) || filetype == 'txt' || index(get(g:, 'coc_markdown_disabled_languages', []), filetype) != -1
|
||||
continue
|
||||
endif
|
||||
if index(defined, filetype) == -1
|
||||
call add(cmds, 'syntax include @'.toupper(filetype).' syntax/'.filetype.'.vim')
|
||||
call add(cmds, 'unlet! b:current_syntax')
|
||||
call add(defined, filetype)
|
||||
endif
|
||||
call add(cmds, 'syntax region CodeBlock'.region_id.' start=/\%'.start.'l/ end=/\%'.end.'l/ contains=@'.toupper(filetype).' keepend')
|
||||
let region_id = region_id + 1
|
||||
endif
|
||||
endfor
|
||||
if !empty(cmds)
|
||||
call coc#compat#execute(a:winid, cmds, 'silent!')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Compose hlGroups with foreground and background colors.
|
||||
function! coc#highlight#compose_hlgroup(fgGroup, bgGroup) abort
|
||||
let hlGroup = 'Fg'.a:fgGroup.'Bg'.a:bgGroup
|
||||
if a:fgGroup ==# a:bgGroup
|
||||
return a:fgGroup
|
||||
endif
|
||||
if hlexists(hlGroup)
|
||||
return hlGroup
|
||||
endif
|
||||
let fgId = synIDtrans(hlID(a:fgGroup))
|
||||
let bgId = synIDtrans(hlID(a:bgGroup))
|
||||
let isGuiReversed = synIDattr(fgId, 'reverse', 'gui') !=# '1' || synIDattr(bgId, 'reverse', 'gui') !=# '1'
|
||||
let guifg = isGuiReversed ? synIDattr(fgId, 'fg', 'gui') : synIDattr(fgId, 'bg', 'gui')
|
||||
let guibg = isGuiReversed ? synIDattr(bgId, 'bg', 'gui') : synIDattr(bgId, 'fg', 'gui')
|
||||
let isCtermReversed = synIDattr(fgId, 'reverse', 'cterm') !=# '1' || synIDattr(bgId, 'reverse', 'cterm') !=# '1'
|
||||
let ctermfg = isCtermReversed ? synIDattr(fgId, 'fg', 'cterm') : synIDattr(fgId, 'bg', 'cterm')
|
||||
let ctermbg = isCtermReversed ? synIDattr(bgId, 'bg', 'cterm') : synIDattr(bgId, 'fg', 'cterm')
|
||||
let bold = synIDattr(fgId, 'bold') ==# '1'
|
||||
let italic = synIDattr(fgId, 'italic') ==# '1'
|
||||
let underline = synIDattr(fgId, 'underline') ==# '1'
|
||||
let cmd = 'silent hi ' . hlGroup
|
||||
if !empty(guifg)
|
||||
let cmd .= ' guifg=' . guifg
|
||||
endif
|
||||
if !empty(ctermfg)
|
||||
let cmd .= ' ctermfg=' . ctermfg
|
||||
elseif guifg =~# '^#'
|
||||
let cmd .= ' ctermfg=' . coc#color#rgb2term(strpart(guifg, 1))
|
||||
endif
|
||||
if !empty(guibg)
|
||||
let cmd .= ' guibg=' . guibg
|
||||
endif
|
||||
if !empty(ctermbg)
|
||||
let cmd .= ' ctermbg=' . ctermbg
|
||||
elseif guibg =~# '^#'
|
||||
let cmd .= ' ctermbg=' . coc#color#rgb2term(strpart(guibg, 1))
|
||||
endif
|
||||
if bold
|
||||
let cmd .= ' cterm=bold gui=bold'
|
||||
elseif italic
|
||||
let cmd .= ' cterm=italic gui=italic'
|
||||
elseif underline
|
||||
let cmd .= ' cterm=underline gui=underline'
|
||||
endif
|
||||
if cmd ==# 'silent hi ' . hlGroup
|
||||
return 'Normal'
|
||||
endif
|
||||
execute cmd
|
||||
return hlGroup
|
||||
endfunction
|
||||
|
||||
" add matches for winid, use 0 for current window.
|
||||
function! coc#highlight#match_ranges(winid, bufnr, ranges, hlGroup, priority) abort
|
||||
let winid = a:winid == 0 ? win_getid() : a:winid
|
||||
let bufnr = a:bufnr == 0 ? winbufnr(winid) : a:bufnr
|
||||
if empty(getwininfo(winid)) || (a:bufnr != 0 && winbufnr(a:winid) != a:bufnr)
|
||||
" not valid
|
||||
return []
|
||||
endif
|
||||
if !s:clear_match_by_window
|
||||
let curr = win_getid()
|
||||
if has('nvim')
|
||||
noa call nvim_set_current_win(winid)
|
||||
else
|
||||
noa call win_gotoid(winid)
|
||||
endif
|
||||
endif
|
||||
let ids = []
|
||||
for range in a:ranges
|
||||
let pos = []
|
||||
let start = range['start']
|
||||
let end = range['end']
|
||||
for lnum in range(start['line'] + 1, end['line'] + 1)
|
||||
let arr = getbufline(bufnr, lnum)
|
||||
let line = empty(arr) ? '' : arr[0]
|
||||
if empty(line)
|
||||
continue
|
||||
endif
|
||||
let colStart = lnum == start['line'] + 1 ? strlen(strcharpart(line, 0, start['character'])) + 1 : 1
|
||||
let colEnd = lnum == end['line'] + 1 ? strlen(strcharpart(line, 0, end['character'])) + 1 : strlen(line) + 1
|
||||
if colStart == colEnd
|
||||
continue
|
||||
endif
|
||||
call add(pos, [lnum, colStart, colEnd - colStart])
|
||||
endfor
|
||||
if !empty(pos)
|
||||
let opts = s:clear_match_by_window ? {'window': a:winid} : {}
|
||||
let i = 1
|
||||
let l = []
|
||||
for p in pos
|
||||
call add(l, p)
|
||||
if i % 8 == 0
|
||||
let id = matchaddpos(a:hlGroup, l, a:priority, -1, opts)
|
||||
call add(ids, id)
|
||||
let l = []
|
||||
endif
|
||||
let i += 1
|
||||
endfor
|
||||
if !empty(l)
|
||||
let id = matchaddpos(a:hlGroup, l, a:priority, -1, opts)
|
||||
call add(ids, id)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
if !s:clear_match_by_window
|
||||
if has('nvim')
|
||||
noa call nvim_set_current_win(curr)
|
||||
else
|
||||
noa call win_gotoid(curr)
|
||||
endif
|
||||
endif
|
||||
return ids
|
||||
endfunction
|
||||
|
||||
" Clear matches by hlGroup regexp.
|
||||
function! coc#highlight#clear_match_group(winid, match) abort
|
||||
let winid = a:winid == 0 ? win_getid() : a:winid
|
||||
if empty(getwininfo(winid))
|
||||
" not valid
|
||||
return
|
||||
endif
|
||||
if s:clear_match_by_window
|
||||
let arr = filter(getmatches(winid), 'v:val["group"] =~# "'.a:match.'"')
|
||||
for item in arr
|
||||
call matchdelete(item['id'], winid)
|
||||
endfor
|
||||
else
|
||||
let curr = win_getid()
|
||||
let switch = exists('*nvim_set_current_win') && curr != winid
|
||||
if switch
|
||||
noa call nvim_set_current_win(a:winid)
|
||||
endif
|
||||
if win_getid() == winid
|
||||
let arr = filter(getmatches(), 'v:val["group"] =~# "'.a:match.'"')
|
||||
for item in arr
|
||||
call matchdelete(item['id'])
|
||||
endfor
|
||||
endif
|
||||
if switch
|
||||
noa call nvim_set_current_win(curr)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Clear matches by match ids, use 0 for current win.
|
||||
function! coc#highlight#clear_matches(winid, ids)
|
||||
let winid = a:winid == 0 ? win_getid() : a:winid
|
||||
if empty(getwininfo(winid))
|
||||
" not valid
|
||||
return
|
||||
endif
|
||||
if s:clear_match_by_window
|
||||
for id in a:ids
|
||||
try
|
||||
call matchdelete(id, winid)
|
||||
catch /^Vim\%((\a\+)\)\=:E803/
|
||||
" ignore
|
||||
endtry
|
||||
endfor
|
||||
else
|
||||
let curr = win_getid()
|
||||
let switch = exists('*nvim_set_current_win') && curr != winid
|
||||
if switch
|
||||
noa call nvim_set_current_win(a:winid)
|
||||
endif
|
||||
if win_getid() == winid
|
||||
for id in a:ids
|
||||
try
|
||||
call matchdelete(id)
|
||||
catch /^Vim\%((\a\+)\)\=:E803/
|
||||
" ignore
|
||||
endtry
|
||||
endfor
|
||||
endif
|
||||
if switch
|
||||
noa call nvim_set_current_win(curr)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#highlight#clear_all() abort
|
||||
for src_id in values(s:namespace_map)
|
||||
for bufnr in map(getbufinfo({'bufloaded': 1}), 'v:val["bufnr"]')
|
||||
if has('nvim')
|
||||
call nvim_buf_clear_namespace(bufnr, src_id, 0, -1)
|
||||
else
|
||||
call coc#api#call('buf_clear_namespace', [bufnr, src_id, 0, -1])
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! coc#highlight#create_namespace(key) abort
|
||||
if type(a:key) == 0
|
||||
return a:key
|
||||
endif
|
||||
if has_key(s:namespace_map, a:key)
|
||||
return s:namespace_map[a:key]
|
||||
endif
|
||||
if has('nvim')
|
||||
let s:namespace_map[a:key] = nvim_create_namespace('coc-'.a:key)
|
||||
else
|
||||
let s:namespace_map[a:key] = s:ns_id
|
||||
let s:ns_id = s:ns_id + 1
|
||||
endif
|
||||
return s:namespace_map[a:key]
|
||||
endfunction
|
||||
|
||||
function! coc#highlight#get_syntax_name(lnum, col)
|
||||
return synIDattr(synIDtrans(synID(a:lnum,a:col,1)),"name")
|
||||
endfunction
|
||||
|
||||
function! s:prop_type_hlgroup(type) abort
|
||||
if strpart(a:type, 0, 12) ==# 'CocHighlight'
|
||||
return strpart(a:type, 12)
|
||||
endif
|
||||
return get(prop_type_get(a:type), 'highlight', '')
|
||||
endfunction
|
||||
|
||||
function! s:update_highlights_timer(bufnr, changedtick, key, priority, groups, idx) abort
|
||||
if getbufvar(a:bufnr, 'changedtick', 0) != a:changedtick
|
||||
return
|
||||
endif
|
||||
let group = get(a:groups, a:idx, v:null)
|
||||
if empty(group)
|
||||
return
|
||||
endif
|
||||
if empty(group['highlights'])
|
||||
call coc#highlight#clear_highlight(a:bufnr, a:key, group['start'], group['end'])
|
||||
else
|
||||
call coc#highlight#update_highlights(a:bufnr, a:key, group['highlights'], group['start'], group['end'], a:priority)
|
||||
endif
|
||||
if a:idx < len(a:groups) - 1
|
||||
call timer_start(50, { -> s:update_highlights_timer(a:bufnr, a:changedtick, a:key, a:priority, a:groups, a:idx + 1)})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:add_highlights_timer(bufnr, ns, highlights, priority) abort
|
||||
let hls = []
|
||||
let next = []
|
||||
for i in range(0, len(a:highlights) - 1)
|
||||
if i < g:coc_highlight_maximum_count
|
||||
call add(hls, a:highlights[i])
|
||||
else
|
||||
call add(next, a:highlights[i])
|
||||
endif
|
||||
endfor
|
||||
call s:add_highlights(a:bufnr, a:ns, hls, a:priority)
|
||||
if len(next)
|
||||
call timer_start(30, {->s:add_highlights_timer(a:bufnr, a:ns, next, a:priority)})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:add_highlights(bufnr, ns, highlights, priority) abort
|
||||
for item in a:highlights
|
||||
let opts = {
|
||||
\ 'priority': a:priority,
|
||||
\ 'combine': get(item, 4, 1) ? 1 : 0,
|
||||
\ 'start_incl': get(item, 5, 0) ? 1 : 0,
|
||||
\ 'end_incl': get(item, 6, 0) ? 1 : 0,
|
||||
\ }
|
||||
call coc#highlight#add_highlight(a:bufnr, a:ns, item[0], item[1], item[2], item[3], opts)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:to_group(items) abort
|
||||
let res = []
|
||||
let before = v:null
|
||||
for item in a:items
|
||||
if empty(before) || before[0] != item[1]
|
||||
let before = [item[1], [item]]
|
||||
call add(res, before)
|
||||
else
|
||||
call add(before[1], item)
|
||||
endif
|
||||
endfor
|
||||
return res
|
||||
endfunction
|
||||
|
||||
function! s:get_priority(key, hlGroup, priority) abort
|
||||
if a:hlGroup ==# 'Search'
|
||||
return 999
|
||||
endif
|
||||
if strpart(a:key, 0, 10) !=# 'diagnostic'
|
||||
return a:priority
|
||||
endif
|
||||
return a:priority - index(s:diagnostic_hlgroups, a:hlGroup)
|
||||
endfunction
|
||||
|
||||
function! s:group_hls(hls, linecount) abort
|
||||
" start, end, highlights
|
||||
let groups = []
|
||||
if empty(a:hls)
|
||||
call add(groups, {'start': 0, 'end': a:linecount, 'highlights': []})
|
||||
return groups
|
||||
endif
|
||||
let start = 0
|
||||
let highlights = []
|
||||
let lastLnum = -1
|
||||
for item in a:hls
|
||||
let lnum = item['lnum']
|
||||
if lnum >= a:linecount
|
||||
break
|
||||
endif
|
||||
if len(highlights) < g:coc_highlight_maximum_count || lnum == lastLnum
|
||||
call add(highlights, item)
|
||||
let lastLnum = lnum
|
||||
else
|
||||
call add(groups, {'start': start, 'end': lastLnum + 1, 'highlights': highlights})
|
||||
let highlights = []
|
||||
let start = lastLnum + 1
|
||||
call add(highlights, item)
|
||||
let lastLnum = lnum
|
||||
endif
|
||||
endfor
|
||||
call add(groups, {'start': start, 'end': a:linecount, 'highlights': highlights})
|
||||
return groups
|
||||
endfunction
|
303
sources_non_forked/coc.nvim/autoload/coc/list.vim
Normal file
303
sources_non_forked/coc.nvim/autoload/coc/list.vim
Normal file
@ -0,0 +1,303 @@
|
||||
scriptencoding utf-8
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:prefix = '[List Preview]'
|
||||
" filetype detect could be slow.
|
||||
let s:filetype_map = {
|
||||
\ 'c': 'c',
|
||||
\ 'py': 'python',
|
||||
\ 'vim': 'vim',
|
||||
\ 'ts': 'typescript',
|
||||
\ 'js': 'javascript',
|
||||
\ 'html': 'html',
|
||||
\ 'css': 'css'
|
||||
\ }
|
||||
|
||||
function! coc#list#getchar() abort
|
||||
return coc#prompt#getchar()
|
||||
endfunction
|
||||
|
||||
function! coc#list#setlines(bufnr, lines, append)
|
||||
if a:append
|
||||
silent call appendbufline(a:bufnr, '$', a:lines)
|
||||
else
|
||||
if exists('*deletebufline')
|
||||
silent call deletebufline(a:bufnr, len(a:lines) + 1, '$')
|
||||
else
|
||||
let n = len(a:lines) + 1
|
||||
let saved_reg = @"
|
||||
silent execute n.',$d'
|
||||
let @" = saved_reg
|
||||
endif
|
||||
silent call setbufline(a:bufnr, 1, a:lines)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#list#options(...)
|
||||
let list = ['--top', '--tab', '--normal', '--no-sort', '--input', '--strict',
|
||||
\ '--regex', '--interactive', '--number-select', '--auto-preview',
|
||||
\ '--ignore-case', '--no-quit', '--first', '--reverse']
|
||||
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#names(...) abort
|
||||
let names = coc#rpc#request('listNames', [])
|
||||
return join(names, "\n")
|
||||
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)
|
||||
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 norelativenumber
|
||||
setl number
|
||||
else
|
||||
setl nonumber
|
||||
setl norelativenumber
|
||||
setl signcolumn=yes
|
||||
endif
|
||||
return [bufnr('%'), win_getid(), tabpagenr()]
|
||||
endfunction
|
||||
|
||||
" close list windows
|
||||
function! coc#list#clean_up() abort
|
||||
for i in range(1, winnr('$'))
|
||||
let bufname = bufname(winbufnr(i))
|
||||
if bufname =~# 'list://'
|
||||
execute i.'close!'
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! coc#list#setup(source)
|
||||
let b:list_status = {}
|
||||
setl buftype=nofile nobuflisted nofen nowrap
|
||||
setl norelativenumber bufhidden=wipe cursorline winfixheight
|
||||
setl tabstop=1 nolist nocursorcolumn undolevels=-1
|
||||
setl signcolumn=auto
|
||||
if has('nvim-0.5.0') || has('patch-8.1.0864')
|
||||
setl scrolloff=0
|
||||
endif
|
||||
if exists('&cursorlineopt')
|
||||
setl cursorlineopt=both
|
||||
endif
|
||||
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^.*$/'
|
||||
if !s:is_vim
|
||||
" Repeat press <C-f> and <C-b> would invoke <esc> on vim
|
||||
nnoremap <silent><nowait><buffer> <esc> <C-w>c
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Check if previewwindow exists on current tab.
|
||||
function! coc#list#has_preview()
|
||||
for i in range(1, winnr('$'))
|
||||
let preview = getwinvar(i, 'previewwindow', getwinvar(i, '&previewwindow', 0))
|
||||
if preview
|
||||
return i
|
||||
endif
|
||||
endfor
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" Get previewwindow from tabnr, use 0 for current tab
|
||||
function! coc#list#get_preview(...) abort
|
||||
let tabnr = get(a:, 1, 0) == 0 ? tabpagenr() : a:1
|
||||
let info = gettabinfo(tabnr)
|
||||
if !empty(info)
|
||||
for win in info[0]['windows']
|
||||
if gettabwinvar(tabnr, win, 'previewwindow', 0)
|
||||
return win
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
return -1
|
||||
endfunction
|
||||
|
||||
function! coc#list#scroll_preview(dir) abort
|
||||
let winnr = coc#list#has_preview()
|
||||
if !winnr
|
||||
return
|
||||
endif
|
||||
let winid = win_getid(winnr)
|
||||
if exists('*win_execute')
|
||||
call win_execute(winid, "normal! ".(a:dir ==# 'up' ? "\<C-u>" : "\<C-d>"))
|
||||
else
|
||||
let id = win_getid()
|
||||
noa call win_gotoid(winid)
|
||||
execute "normal! ".(a:dir ==# 'up' ? "\<C-u>" : "\<C-d>")
|
||||
noa call win_gotoid(id)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#list#close_preview(tabnr) abort
|
||||
let winid = coc#list#get_preview(a:tabnr)
|
||||
if winid != -1
|
||||
call coc#window#close(winid)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Improve preview performance by reused window & buffer.
|
||||
" lines - list of lines
|
||||
" config.position - could be 'below' 'top' 'tab'.
|
||||
" config.winid - id of original window.
|
||||
" config.name - (optional )name of preview buffer.
|
||||
" config.splitRight - (optional) split to right when 1.
|
||||
" config.lnum - (optional) current line number
|
||||
" config.filetype - (optional) filetype of lines.
|
||||
" config.hlGroup - (optional) highlight group.
|
||||
" config.maxHeight - (optional) max height of window, valid for 'below' & 'top' position.
|
||||
function! coc#list#preview(lines, config) abort
|
||||
if s:is_vim && !exists('*win_execute')
|
||||
throw 'win_execute function required for preview, please upgrade your vim.'
|
||||
return
|
||||
endif
|
||||
let name = fnamemodify(get(a:config, 'name', ''), ':.')
|
||||
let lines = a:lines
|
||||
if empty(lines)
|
||||
if get(a:config, 'scheme', 'file') != 'file'
|
||||
let bufnr = s:load_buffer(name)
|
||||
if bufnr != 0
|
||||
let lines = getbufline(bufnr, 1, '$')
|
||||
else
|
||||
let lines = ['']
|
||||
endif
|
||||
else
|
||||
" Show empty lines so not close window.
|
||||
let lines = ['']
|
||||
endif
|
||||
endif
|
||||
let winid = coc#list#get_preview(0)
|
||||
let bufnr = winid == -1 ? 0 : winbufnr(winid)
|
||||
" Try reuse buffer & window
|
||||
let bufnr = coc#float#create_buf(bufnr, lines)
|
||||
if bufnr == 0
|
||||
return
|
||||
endif
|
||||
call setbufvar(bufnr, '&synmaxcol', 500)
|
||||
let filetype = get(a:config, 'filetype', '')
|
||||
let extname = matchstr(name, '\.\zs[^.]\+$')
|
||||
if empty(filetype) && !empty(extname)
|
||||
let filetype = get(s:filetype_map, extname, '')
|
||||
endif
|
||||
let range = get(a:config, 'range', v:null)
|
||||
let hlGroup = get(a:config, 'hlGroup', 'Search')
|
||||
let lnum = get(a:config, 'lnum', 1)
|
||||
let position = get(a:config, 'position', 'below')
|
||||
let original = get(a:config, 'winid', -1)
|
||||
if winid == -1
|
||||
let change = position != 'tab' && get(a:config, 'splitRight', 0)
|
||||
let curr = win_getid()
|
||||
if change
|
||||
if original && win_id2win(original)
|
||||
noa call win_gotoid(original)
|
||||
else
|
||||
noa wincmd t
|
||||
endif
|
||||
execute 'noa belowright vert sb '.bufnr
|
||||
let winid = win_getid()
|
||||
elseif position == 'tab' || get(a:config, 'splitRight', 0)
|
||||
execute 'noa belowright vert sb '.bufnr
|
||||
let winid = win_getid()
|
||||
else
|
||||
let mod = position == 'top' ? 'below' : 'above'
|
||||
let height = s:get_height(lines, a:config)
|
||||
execute 'noa '.mod.' sb +resize\ '.height.' '.bufnr
|
||||
let winid = win_getid()
|
||||
endif
|
||||
noa call winrestview({"lnum": lnum ,"topline":s:get_topline(a:config, lnum, winid)})
|
||||
call setwinvar(winid, '&signcolumn', 'no')
|
||||
call setwinvar(winid, '&number', 1)
|
||||
call setwinvar(winid, '&cursorline', 0)
|
||||
call setwinvar(winid, '&relativenumber', 0)
|
||||
call setwinvar(winid, 'previewwindow', 1)
|
||||
noa call win_gotoid(curr)
|
||||
else
|
||||
let height = s:get_height(lines, a:config)
|
||||
if height > 0
|
||||
if s:is_vim
|
||||
let curr = win_getid()
|
||||
noa call win_gotoid(winid)
|
||||
execute 'silent! noa resize '.height
|
||||
noa call win_gotoid(curr)
|
||||
else
|
||||
call nvim_win_set_height(winid, height)
|
||||
endif
|
||||
endif
|
||||
call coc#compat#execute(winid, ['syntax clear', 'noa call winrestview({"lnum":'.lnum.',"topline":'.s:get_topline(a:config, lnum, winid).'})'])
|
||||
endif
|
||||
call setwinvar(winid, '&foldenable', 0)
|
||||
if s:prefix.' '.name != bufname(bufnr)
|
||||
if s:is_vim
|
||||
call win_execute(winid, 'noa file '.fnameescape(s:prefix.' '.name), 'silent!')
|
||||
else
|
||||
silent! noa call nvim_buf_set_name(bufnr, s:prefix.' '.name)
|
||||
endif
|
||||
endif
|
||||
" highlights
|
||||
if !empty(filetype)
|
||||
let start = max([0, lnum - 300])
|
||||
let end = min([len(lines), lnum + 300])
|
||||
call coc#highlight#highlight_lines(winid, [{'filetype': filetype, 'startLine': start, 'endLine': end}])
|
||||
call coc#compat#execute(winid, 'syn sync fromstart')
|
||||
else
|
||||
call coc#compat#execute(winid, 'filetype detect')
|
||||
let ft = getbufvar(bufnr, '&filetype', '')
|
||||
if !empty(extname) && !empty(ft)
|
||||
let s:filetype_map[extname] = ft
|
||||
endif
|
||||
endif
|
||||
call sign_unplace('coc', {'buffer': bufnr})
|
||||
call coc#compat#execute(winid, 'call clearmatches()')
|
||||
if !s:is_vim
|
||||
" vim send <esc> to buffer on FocusLost, <C-w> and other cases
|
||||
call coc#compat#execute(winid, 'nnoremap <silent><nowait><buffer> <esc> :call CocActionAsync("listCancel")<CR>')
|
||||
endif
|
||||
if !empty(range)
|
||||
call sign_place(1, 'coc', 'CocCurrentLine', bufnr, {'lnum': lnum})
|
||||
call coc#highlight#match_ranges(winid, bufnr, [range], hlGroup, 10)
|
||||
endif
|
||||
redraw
|
||||
endfunction
|
||||
|
||||
function! s:get_height(lines, config) abort
|
||||
if get(a:config, 'splitRight', 0) || get(a:config, 'position', 'below') == 'tab'
|
||||
return 0
|
||||
endif
|
||||
let height = min([get(a:config, 'maxHeight', 10), len(a:lines), &lines - &cmdheight - 2])
|
||||
return height
|
||||
endfunction
|
||||
|
||||
function! s:load_buffer(name) abort
|
||||
if exists('*bufadd') && exists('*bufload')
|
||||
let bufnr = bufadd(a:name)
|
||||
call bufload(bufnr)
|
||||
return bufnr
|
||||
endif
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:get_topline(config, lnum, winid) abort
|
||||
let toplineStyle = get(a:config, 'toplineStyle', 'offset')
|
||||
if toplineStyle == 'middle'
|
||||
return max([1, a:lnum - winheight(a:winid)/2])
|
||||
endif
|
||||
|
||||
let toplineOffset = get(a:config, 'toplineOffset', 3)
|
||||
return max([1, a:lnum - toplineOffset])
|
||||
endfunction
|
11
sources_non_forked/coc.nvim/autoload/coc/math.vim
Normal file
11
sources_non_forked/coc.nvim/autoload/coc/math.vim
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
" support for float values
|
||||
function! coc#math#min(first, ...) abort
|
||||
let val = a:first
|
||||
for i in range(0, len(a:000) - 1)
|
||||
if a:000[i] < val
|
||||
let val = a:000[i]
|
||||
endif
|
||||
endfor
|
||||
return val
|
||||
endfunction
|
531
sources_non_forked/coc.nvim/autoload/coc/notify.vim
Normal file
531
sources_non_forked/coc.nvim/autoload/coc/notify.vim
Normal file
@ -0,0 +1,531 @@
|
||||
scriptencoding utf-8
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:utf = &encoding =~# '^utf'
|
||||
let s:error_icon = get(g:, 'coc_notify_error_icon', s:utf ? '' : 'E')
|
||||
let s:warning_icon = get(g:, 'coc_notify_warning_icon', s:utf ? '⚠' : 'W')
|
||||
let s:info_icon = get(g:, 'coc_notify_info_icon', s:utf ? '' : 'I')
|
||||
let s:interval = get(g:, 'coc_notify_interval', s:is_vim ? 50 : 20)
|
||||
let s:phl = 'CocNotificationProgress'
|
||||
let s:progress_char = '─'
|
||||
let s:duration = 300.0
|
||||
let s:winids = []
|
||||
|
||||
" Valid notify winids on current tab
|
||||
function! coc#notify#win_list() abort
|
||||
call filter(s:winids, 'coc#float#valid(v:val)')
|
||||
return filter(copy(s:winids), '!empty(getwinvar(v:val,"float"))')
|
||||
endfunction
|
||||
|
||||
function! coc#notify#close_all() abort
|
||||
for winid in coc#notify#win_list()
|
||||
call coc#notify#close(winid)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Do action for winid or first notify window with actions.
|
||||
function! coc#notify#do_action(...) abort
|
||||
let winids = a:0 > 0 ? a:000 : coc#notify#win_list()
|
||||
for winid in winids
|
||||
if coc#float#valid(winid) && getwinvar(winid, 'closing', 0) != 1
|
||||
let actions = getwinvar(winid, 'actions', [])
|
||||
if !empty(actions)
|
||||
let items = map(copy(actions), '(v:key + 1).". ".v:val')
|
||||
let msg = join(getbufline(winbufnr(winid), 1, '$'), ' ')
|
||||
call coc#ui#quickpick(msg, items, {err, res -> s:on_action(err, res, winid) })
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Copy notification contents
|
||||
function! coc#notify#copy() abort
|
||||
let lines = []
|
||||
for winid in coc#notify#win_list()
|
||||
let key = getwinvar(winid, 'key', v:null)
|
||||
if type(key) == v:t_string
|
||||
call extend(lines, json_decode(key)['lines'])
|
||||
endif
|
||||
endfor
|
||||
if empty(lines)
|
||||
echohl WarningMsg | echon 'No content to copy' | echohl None
|
||||
return
|
||||
endif
|
||||
call setreg('*', join(lines, "\n"))
|
||||
endfunction
|
||||
|
||||
" Show source name in window
|
||||
function! coc#notify#show_sources() abort
|
||||
if !exists('*getbufline') || !exists('*appendbufline')
|
||||
throw "getbufline and appendbufline functions required, please upgrade your vim."
|
||||
endif
|
||||
let winids = filter(coc#notify#win_list(), 'coc#window#get_var(v:val,"closing") != 1')
|
||||
for winid in winids
|
||||
let key = getwinvar(winid, 'key', v:null)
|
||||
if type(key) == v:t_string
|
||||
let bufnr = winbufnr(winid)
|
||||
let obj = json_decode(key)
|
||||
let sourcename = get(obj, 'source', '')
|
||||
let lnum = get(obj, 'kind', '') ==# 'progress' ? 1 : 0
|
||||
let content = get(getbufline(bufnr, lnum + 1), 0, '')
|
||||
if empty(sourcename) || content ==# sourcename
|
||||
continue
|
||||
endif
|
||||
call appendbufline(bufnr, lnum, sourcename)
|
||||
call coc#highlight#add_highlight(bufnr, -1, 'Title', lnum, 0, -1)
|
||||
call coc#float#scroll_win(winid, 0, 1)
|
||||
endif
|
||||
endfor
|
||||
redra
|
||||
endfunction
|
||||
|
||||
function! coc#notify#close_by_source(source) abort
|
||||
let winids = filter(coc#notify#win_list(), 'coc#window#get_var(v:val,"closing") != 1')
|
||||
for winid in winids
|
||||
let key = getwinvar(winid, 'key', v:null)
|
||||
if type(key) == v:t_string
|
||||
let obj = json_decode(key)
|
||||
if get(obj, 'source', '') ==# a:source
|
||||
call coc#notify#close(winid)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Cancel auto hide
|
||||
function! coc#notify#keep() abort
|
||||
for winid in coc#notify#win_list()
|
||||
call s:cancel(winid, 'close_timer')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" borderhighlight - border highlight [string]
|
||||
" maxWidth - max content width, default 60 [number]
|
||||
" minWidth - minimal width [number]
|
||||
" maxHeight - max content height, default 10 [number]
|
||||
" highlight - default highlight [string]
|
||||
" winblend - winblend [number]
|
||||
" timeout - auto close timeout, default 5000 [number]
|
||||
" title - title text
|
||||
" marginRight - margin right, default 10 [number]
|
||||
" focusable - focusable [number]
|
||||
" source - source name [string]
|
||||
" kind - kind for create icon [string]
|
||||
" actions - action names [string[]]
|
||||
function! coc#notify#create(lines, config) abort
|
||||
let actions = get(a:config, 'actions', [])
|
||||
let key = json_encode(extend({'lines': a:lines}, a:config))
|
||||
let winid = s:find_win(key)
|
||||
let kind = get(a:config, 'kind', '')
|
||||
let row = 0
|
||||
if winid != -1
|
||||
let row = getwinvar(winid, 'top', 0)
|
||||
call filter(s:winids, 'v:val != '.winid)
|
||||
call coc#float#close(winid)
|
||||
let winid = v:null
|
||||
endif
|
||||
let opts = coc#dict#pick(a:config, ['highlight', 'borderhighlight', 'focusable', 'shadow'])
|
||||
let border = has_key(opts, 'borderhighlight') ? [1, 1, 1, 1] : []
|
||||
let icon = s:get_icon(kind, get(a:config, 'highlight', 'CocFloating'))
|
||||
let margin = get(a:config, 'marginRight', 10)
|
||||
let maxWidth = min([&columns - margin - 2, get(a:config, 'maxWidth', 80)])
|
||||
if maxWidth <= 0
|
||||
throw 'No enough spaces for notification'
|
||||
endif
|
||||
let lines = map(copy(a:lines), 'tr(v:val, "\t", " ")')
|
||||
if has_key(a:config, 'title')
|
||||
if !empty(border)
|
||||
let opts['title'] = a:config['title']
|
||||
else
|
||||
let lines = [a:config['title']] + lines
|
||||
endif
|
||||
endif
|
||||
let width = max(map(copy(lines), 'strwidth(v:val)')) + (empty(icon) ? 1 : 3)
|
||||
if width > maxWidth
|
||||
let lines = coc#string#reflow(lines, maxWidth)
|
||||
let width = max(map(copy(lines), 'strwidth(v:val)')) + (empty(icon) ? 1 : 3)
|
||||
endif
|
||||
let highlights = []
|
||||
if !empty(icon)
|
||||
let ic = icon['text']
|
||||
if empty(lines)
|
||||
call add(lines, ic)
|
||||
else
|
||||
let lines[0] = ic.' '.lines[0]
|
||||
endif
|
||||
call add(highlights, {'lnum': 0, 'hlGroup': icon['hl'], 'colStart': 0, 'colEnd': strlen(ic)})
|
||||
endif
|
||||
let actionText = join(actions, ' ')
|
||||
call map(lines, 'v:key == 0 ? v:val : repeat(" ", '.(empty(icon) ? 0 : 2).').v:val')
|
||||
let minWidth = get(a:config, 'minWidth', kind ==# 'progress' ? 30 : 10)
|
||||
let width = max(extend(map(lines + [get(opts, 'title', '').' '], 'strwidth(v:val)'), [minWidth, strwidth(actionText) + 1]))
|
||||
let width = min([maxWidth, width])
|
||||
let height = min([get(a:config, 'maxHeight', 3), len(lines)])
|
||||
if kind ==# 'progress'
|
||||
let lines = [repeat(s:progress_char, width)] + lines
|
||||
let height = height + 1
|
||||
endif
|
||||
if !empty(actions)
|
||||
let before = width - strwidth(actionText)
|
||||
let lines = lines + [repeat(' ', before).actionText]
|
||||
let height = height + 1
|
||||
call s:add_action_highlights(before, height - 1, highlights, actions)
|
||||
endif
|
||||
if row == 0
|
||||
let wintop = coc#notify#get_top()
|
||||
let row = wintop - height - (empty(border) ? 0 : 2) - 1
|
||||
if !s:is_vim && !empty(border)
|
||||
let row = row + 1
|
||||
endif
|
||||
endif
|
||||
let col = &columns - margin - width
|
||||
if s:is_vim && !empty(border)
|
||||
let col = col - 2
|
||||
endif
|
||||
let winblend = 60
|
||||
" Avoid animate for transparent background.
|
||||
if get(a:config, 'winblend', 30) == 0 && empty(synIDattr(synIDtrans(hlID(get(opts, 'highlight', 'CocFloating'))), 'bg', 'gui'))
|
||||
let winblend = 0
|
||||
endif
|
||||
call extend(opts, {
|
||||
\ 'relative': 'editor',
|
||||
\ 'width': width,
|
||||
\ 'height': height,
|
||||
\ 'col': col,
|
||||
\ 'row': row + 1,
|
||||
\ 'lines': lines,
|
||||
\ 'rounded': 1,
|
||||
\ 'highlights': highlights,
|
||||
\ 'winblend': winblend,
|
||||
\ 'border': border,
|
||||
\ })
|
||||
let result = coc#float#create_float_win(0, 0, opts)
|
||||
if empty(result)
|
||||
throw 'Unable to create notify window'
|
||||
endif
|
||||
let winid = result[0]
|
||||
let bufnr = result[1]
|
||||
call setwinvar(winid, 'right', 1)
|
||||
call setwinvar(winid, 'kind', 'notification')
|
||||
call setwinvar(winid, 'top', row)
|
||||
call setwinvar(winid, 'key', key)
|
||||
call setwinvar(winid, 'actions', actions)
|
||||
call setwinvar(winid, 'source', get(a:config, 'source', ''))
|
||||
call setwinvar(winid, 'border', !empty(border))
|
||||
call coc#float#nvim_scrollbar(winid)
|
||||
call add(s:winids, winid)
|
||||
let from = {'row': opts['row'], 'winblend': opts['winblend']}
|
||||
let to = {'row': row, 'winblend': get(a:config, 'winblend', 30)}
|
||||
call timer_start(s:interval, { -> s:animate(winid, from, to, 0)})
|
||||
if kind ==# 'progress'
|
||||
call timer_start(s:interval, { -> s:progress(winid, width, 0, -1)})
|
||||
endif
|
||||
if !s:is_vim
|
||||
call coc#compat#buf_add_keymap(bufnr, 'n', '<LeftRelease>', ':call coc#notify#nvim_click('.winid.')<CR>', {
|
||||
\ 'silent': v:true,
|
||||
\ 'nowait': v:true
|
||||
\ })
|
||||
endif
|
||||
" Enable auto close
|
||||
if empty(actions) && kind !=# 'progress'
|
||||
let timer = timer_start(get(a:config, 'timeout', 10000), { -> coc#notify#close(winid)})
|
||||
call setwinvar(winid, 'close_timer', timer)
|
||||
endif
|
||||
return [winid, bufnr]
|
||||
endfunction
|
||||
|
||||
function! coc#notify#nvim_click(winid) abort
|
||||
if getwinvar(a:winid, 'closing', 0)
|
||||
return
|
||||
endif
|
||||
call s:cancel(a:winid, 'close_timer')
|
||||
let actions = getwinvar(a:winid, 'actions', [])
|
||||
if !empty(actions)
|
||||
let character = strpart(getline('.'), col('.') - 1, 1)
|
||||
if character =~# '^\k'
|
||||
let word = expand('<cword>')
|
||||
let idx = index(actions, word)
|
||||
if idx != -1
|
||||
call coc#rpc#notify('FloatBtnClick', [winbufnr(a:winid), idx])
|
||||
call coc#notify#close(a:winid)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#notify#on_close(winid) abort
|
||||
if index(s:winids, a:winid) >= 0
|
||||
call filter(s:winids, 'v:val != '.a:winid)
|
||||
call coc#notify#reflow()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#notify#get_top() abort
|
||||
let mintop = min(map(coc#notify#win_list(), 'coc#notify#get_win_top(v:val)'))
|
||||
if mintop != 0
|
||||
return mintop
|
||||
endif
|
||||
return &lines - &cmdheight - (&laststatus == 0 ? 0 : 1 )
|
||||
endfunction
|
||||
|
||||
function! coc#notify#get_win_top(winid) abort
|
||||
let row = getwinvar(a:winid, 'top', 0)
|
||||
if row == 0
|
||||
return row
|
||||
endif
|
||||
return row - (s:is_vim ? 0 : getwinvar(a:winid, 'border', 0))
|
||||
endfunction
|
||||
|
||||
" Close with timer
|
||||
function! coc#notify#close(winid) abort
|
||||
if !coc#float#valid(a:winid) || coc#window#get_var(a:winid, 'closing', 0) == 1
|
||||
return
|
||||
endif
|
||||
if !coc#window#visible(a:winid)
|
||||
call coc#float#close(a:winid)
|
||||
return
|
||||
endif
|
||||
let row = coc#window#get_var(a:winid, 'top')
|
||||
if type(row) != v:t_number
|
||||
call coc#float#close(a:winid)
|
||||
return
|
||||
endif
|
||||
call coc#window#set_var(a:winid, 'closing', 1)
|
||||
call s:cancel(a:winid)
|
||||
let curr = s:is_vim ? {'row': row} : {'winblend': coc#window#get_var(a:winid, 'winblend', 30)}
|
||||
let dest = s:is_vim ? {'row': row + 1} : {'winblend': 60}
|
||||
call s:animate(a:winid, curr, dest, 0, 1)
|
||||
endfunction
|
||||
|
||||
function! s:add_action_highlights(before, lnum, highlights, actions) abort
|
||||
let colStart = a:before
|
||||
for text in a:actions
|
||||
let w = strwidth(text)
|
||||
call add(a:highlights, {
|
||||
\ 'lnum': a:lnum,
|
||||
\ 'hlGroup': 'CocNotificationButton',
|
||||
\ 'colStart': colStart,
|
||||
\ 'colEnd': colStart + w
|
||||
\ })
|
||||
let colStart = colStart + w + 1
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:on_action(err, idx, winid) abort
|
||||
if !empty(a:err)
|
||||
throw a:err
|
||||
endif
|
||||
if a:idx > 0
|
||||
call coc#rpc#notify('FloatBtnClick', [winbufnr(a:winid), a:idx - 1])
|
||||
call coc#notify#close(a:winid)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:cancel(winid, ...) abort
|
||||
let name = get(a:, 1, 'timer')
|
||||
let timer = coc#window#get_var(a:winid, name)
|
||||
if !empty(timer)
|
||||
call timer_stop(timer)
|
||||
call coc#window#set_var(a:winid, name, v:null)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:progress(winid, total, curr, index) abort
|
||||
if !coc#float#valid(a:winid)
|
||||
return
|
||||
endif
|
||||
if coc#window#visible(a:winid)
|
||||
let total = a:total
|
||||
let idx = float2nr(a:curr/5.0)%total
|
||||
if idx != a:index
|
||||
" update percent
|
||||
let bufnr = winbufnr(a:winid)
|
||||
let percent = coc#window#get_var(a:winid, 'percent')
|
||||
if !empty(percent)
|
||||
let width = strchars(getbufline(bufnr, 1)[0])
|
||||
let line = repeat(s:progress_char, width - 4).printf('%4s', percent)
|
||||
let total = width - 4
|
||||
call setbufline(bufnr, 1, line)
|
||||
endif
|
||||
let message = coc#window#get_var(a:winid, 'message')
|
||||
if !empty(message)
|
||||
let linecount = coc#compat#buf_line_count(bufnr)
|
||||
let hasAction = !empty(coc#window#get_var(a:winid, 'actions', []))
|
||||
if getbufvar(bufnr, 'message', 0) == 0
|
||||
call appendbufline(bufnr, linecount - hasAction, message)
|
||||
call setbufvar(bufnr, 'message', 1)
|
||||
call coc#float#change_height(a:winid, 1)
|
||||
let tabnr = coc#window#tabnr(a:winid)
|
||||
call coc#notify#reflow(tabnr)
|
||||
else
|
||||
call setbufline(bufnr, linecount - hasAction, message)
|
||||
endif
|
||||
endif
|
||||
let bytes = strlen(s:progress_char)
|
||||
call coc#highlight#clear_highlight(bufnr, -1, 0, 1)
|
||||
let colStart = bytes * idx
|
||||
if idx + 4 <= total
|
||||
let colEnd = bytes * (idx + 4)
|
||||
call coc#highlight#add_highlight(bufnr, -1, s:phl, 0, colStart, colEnd)
|
||||
else
|
||||
let colEnd = bytes * total
|
||||
call coc#highlight#add_highlight(bufnr, -1, s:phl, 0, colStart, colEnd)
|
||||
call coc#highlight#add_highlight(bufnr, -1, s:phl, 0, 0, bytes * (idx + 4 - total))
|
||||
endif
|
||||
endif
|
||||
call timer_start(s:interval, { -> s:progress(a:winid, total, a:curr + 1, idx)})
|
||||
else
|
||||
" Not block CursorHold event
|
||||
call timer_start(&updatetime + 100, { -> s:progress(a:winid, a:total, a:curr, a:index)})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Optional row & winblend
|
||||
function! s:config_win(winid, props) abort
|
||||
let change_row = has_key(a:props, 'row')
|
||||
if s:is_vim
|
||||
if change_row
|
||||
call popup_move(a:winid, {'line': a:props['row'] + 1})
|
||||
endif
|
||||
else
|
||||
if change_row
|
||||
let [row, column] = nvim_win_get_position(a:winid)
|
||||
call nvim_win_set_config(a:winid, {
|
||||
\ 'row': a:props['row'],
|
||||
\ 'col': column,
|
||||
\ 'relative': 'editor',
|
||||
\ })
|
||||
call s:nvim_move_related(a:winid, a:props['row'])
|
||||
endif
|
||||
call coc#float#nvim_set_winblend(a:winid, get(a:props, 'winblend', v:null))
|
||||
call coc#float#nvim_refresh_scrollbar(a:winid)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:nvim_move_related(winid, row) abort
|
||||
let winids = coc#window#get_var(a:winid, 'related')
|
||||
if empty(winids)
|
||||
return
|
||||
endif
|
||||
for winid in winids
|
||||
if nvim_win_is_valid(winid)
|
||||
let [row, column] = nvim_win_get_position(winid)
|
||||
let delta = coc#window#get_var(winid, 'delta', 0)
|
||||
call nvim_win_set_config(winid, {
|
||||
\ 'row': a:row + delta,
|
||||
\ 'col': column,
|
||||
\ 'relative': 'editor',
|
||||
\ })
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:animate(winid, from, to, prev, ...) abort
|
||||
if !coc#float#valid(a:winid)
|
||||
return
|
||||
endif
|
||||
let curr = a:prev + s:interval
|
||||
let percent = coc#math#min(curr / s:duration, 1)
|
||||
let props = s:get_props(a:from, a:to, percent)
|
||||
call s:config_win(a:winid, props)
|
||||
let close = get(a:, 1, 0)
|
||||
if percent < 1
|
||||
call timer_start(s:interval, { -> s:animate(a:winid, a:from, a:to, curr, close)})
|
||||
elseif close
|
||||
call filter(s:winids, 'v:val != '.a:winid)
|
||||
let tabnr = coc#window#tabnr(a:winid)
|
||||
if tabnr != -1
|
||||
call coc#float#close(a:winid)
|
||||
call coc#notify#reflow(tabnr)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#notify#reflow(...) abort
|
||||
let tabnr = get(a:, 1, tabpagenr())
|
||||
let winids = filter(copy(s:winids), 'coc#window#tabnr(v:val) == '.tabnr.' && coc#window#get_var(v:val,"closing") != 1')
|
||||
if empty(winids)
|
||||
return
|
||||
endif
|
||||
let animate = tabnr == tabpagenr()
|
||||
let wins = map(copy(winids), {_, val -> {
|
||||
\ 'winid': val,
|
||||
\ 'row': coc#window#get_var(val,'top',0),
|
||||
\ 'top': coc#window#get_var(val,'top',0) - (s:is_vim ? 0 : coc#window#get_var(val, 'border', 0)),
|
||||
\ 'height': coc#float#get_height(val),
|
||||
\ }})
|
||||
call sort(wins, {a, b -> b['top'] - a['top']})
|
||||
let bottom = &lines - &cmdheight - (&laststatus == 0 ? 0 : 1 )
|
||||
let moved = 0
|
||||
for item in wins
|
||||
let winid = item['winid']
|
||||
let delta = bottom - (item['top'] + item['height'] + 1)
|
||||
if delta != 0
|
||||
call s:cancel(winid)
|
||||
let dest = item['row'] + delta
|
||||
call coc#window#set_var(winid, 'top', dest)
|
||||
if animate
|
||||
call s:move_win_timer(winid, {'row': item['row']}, {'row': dest}, 0)
|
||||
else
|
||||
call s:config_win(winid, {'row': dest})
|
||||
endif
|
||||
let moved = moved + delta
|
||||
endif
|
||||
let bottom = item['top'] + delta
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:move_win_timer(winid, from, to, curr) abort
|
||||
if !coc#float#valid(a:winid)
|
||||
return
|
||||
endif
|
||||
if coc#window#get_var(a:winid, 'closing', 0) == 1
|
||||
return
|
||||
endif
|
||||
let percent = coc#math#min(a:curr / s:duration, 1)
|
||||
let next = a:curr + s:interval
|
||||
if a:curr > 0
|
||||
call s:config_win(a:winid, s:get_props(a:from, a:to, percent))
|
||||
endif
|
||||
if percent < 1
|
||||
let timer = timer_start(s:interval, { -> s:move_win_timer(a:winid, a:from, a:to, next)})
|
||||
call coc#window#set_var(a:winid, 'timer', timer)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:find_win(key) abort
|
||||
for winid in coc#notify#win_list()
|
||||
if getwinvar(winid, 'key', '') ==# a:key
|
||||
return winid
|
||||
endif
|
||||
endfor
|
||||
return -1
|
||||
endfunction
|
||||
|
||||
function! s:get_icon(kind, bg) abort
|
||||
if a:kind ==# 'info'
|
||||
return {'text': s:info_icon, 'hl': coc#highlight#compose_hlgroup('CocInfoSign', a:bg)}
|
||||
endif
|
||||
if a:kind ==# 'warning'
|
||||
return {'text': s:warning_icon, 'hl': coc#highlight#compose_hlgroup('CocWarningSign', a:bg)}
|
||||
endif
|
||||
if a:kind ==# 'error'
|
||||
return {'text': s:error_icon, 'hl': coc#highlight#compose_hlgroup('CocErrorSign', a:bg)}
|
||||
endif
|
||||
return v:null
|
||||
endfunction
|
||||
|
||||
" percent should be float
|
||||
function! s:get_props(from, to, percent) abort
|
||||
let obj = {}
|
||||
for key in keys(a:from)
|
||||
let changed = a:to[key] - a:from[key]
|
||||
if !s:is_vim && key ==# 'row'
|
||||
" Could be float
|
||||
let obj[key] = a:from[key] + changed * a:percent
|
||||
else
|
||||
let obj[key] = a:from[key] + float2nr(round(changed * a:percent))
|
||||
endif
|
||||
endfor
|
||||
return obj
|
||||
endfunction
|
214
sources_non_forked/coc.nvim/autoload/coc/prompt.vim
Normal file
214
sources_non_forked/coc.nvim/autoload/coc/prompt.vim
Normal file
@ -0,0 +1,214 @@
|
||||
scriptencoding utf-8
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:activated = 0
|
||||
let s:session_names = []
|
||||
let s:saved_ve = &t_ve
|
||||
let s:saved_cursor = &guicursor
|
||||
let s:gui = has('gui_running') || has('nvim')
|
||||
|
||||
let s:char_map = {
|
||||
\ "\<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>',
|
||||
\ "\<FocusLost>":'<FocusLost>',
|
||||
\ "\<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-j>": '<C-j>',
|
||||
\ "\<C-k>": '<C-k>',
|
||||
\ "\<C-l>": '<C-l>',
|
||||
\ "\<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>',
|
||||
\ }
|
||||
|
||||
function! coc#prompt#getc() abort
|
||||
let c = getchar()
|
||||
return type(c) is 0 ? nr2char(c) : c
|
||||
endfunction
|
||||
|
||||
function! coc#prompt#getchar() abort
|
||||
let input = coc#prompt#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 dict = maparg(input, 'l', 0, 1)
|
||||
if empty(dict) || get(dict, 'expr', 0)
|
||||
return input
|
||||
endif
|
||||
let full_keymap = get(dict, 'rhs', '')
|
||||
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#prompt#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#prompt#start_prompt(session) abort
|
||||
let s:session_names = s:filter(s:session_names, a:session)
|
||||
call add(s:session_names, a:session)
|
||||
if s:activated | return | endif
|
||||
if s:is_vim
|
||||
call s:start_prompt_vim()
|
||||
else
|
||||
call s:start_prompt()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:start_prompt_vim() abort
|
||||
call timer_start(10, {-> s:start_prompt()})
|
||||
endfunction
|
||||
|
||||
function! s:start_prompt()
|
||||
if s:activated | return | endif
|
||||
if !get(g:, 'coc_disable_transparent_cursor', 0)
|
||||
if s:gui
|
||||
if has('nvim-0.5.0') && !empty(s:saved_cursor)
|
||||
set guicursor+=a:ver1-CocCursorTransparent/lCursor
|
||||
endif
|
||||
elseif s:is_vim
|
||||
set t_ve=
|
||||
endif
|
||||
endif
|
||||
let s:activated = 1
|
||||
try
|
||||
while s:activated
|
||||
let ch = coc#prompt#getchar()
|
||||
if ch ==# "\<FocusLost>" || ch ==# "\<FocusGained>" || ch ==# "\<CursorHold>"
|
||||
continue
|
||||
else
|
||||
let curr = s:current_session()
|
||||
let mapped = get(s:char_map, ch, ch)
|
||||
if !empty(curr)
|
||||
call coc#rpc#notify('InputChar', [curr, mapped, getcharmod()])
|
||||
endif
|
||||
if mapped == '<esc>'
|
||||
let s:session_names = []
|
||||
call s:reset()
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
catch /^Vim:Interrupt$/
|
||||
let s:activated = 0
|
||||
call coc#rpc#notify('InputChar', [s:current_session(), '<esc>'])
|
||||
return
|
||||
endtry
|
||||
let s:activated = 0
|
||||
endfunction
|
||||
|
||||
function! coc#prompt#stop_prompt(session)
|
||||
let s:session_names = s:filter(s:session_names, a:session)
|
||||
if len(s:session_names)
|
||||
return
|
||||
endif
|
||||
if s:activated
|
||||
let s:activated = 0
|
||||
call s:reset()
|
||||
call feedkeys("\<esc>", 'int')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#prompt#activated() abort
|
||||
return s:activated
|
||||
endfunction
|
||||
|
||||
function! s:reset() abort
|
||||
if !get(g:, 'coc_disable_transparent_cursor',0)
|
||||
" neovim has bug with revert empty &guicursor
|
||||
if s:gui && !empty(s:saved_cursor)
|
||||
if has('nvim-0.5.0')
|
||||
set guicursor+=a:ver1-Cursor/lCursor
|
||||
let &guicursor = s:saved_cursor
|
||||
endif
|
||||
elseif s:is_vim
|
||||
let &t_ve = s:saved_ve
|
||||
endif
|
||||
endif
|
||||
echo ""
|
||||
endfunction
|
||||
|
||||
function! s:current_session() abort
|
||||
if empty(s:session_names)
|
||||
return v:null
|
||||
endif
|
||||
return s:session_names[len(s:session_names) - 1]
|
||||
endfunction
|
||||
|
||||
function! s:filter(list, id) abort
|
||||
return filter(copy(a:list), 'v:val !=# a:id')
|
||||
endfunction
|
129
sources_non_forked/coc.nvim/autoload/coc/rpc.vim
Normal file
129
sources_non_forked/coc.nvim/autoload/coc/rpc.vim
Normal file
@ -0,0 +1,129 @@
|
||||
scriptencoding utf-8
|
||||
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 get(g:, 'coc_node_env', '') ==# 'test'
|
||||
" server already started
|
||||
let s:client = coc#client#create(s:name, [])
|
||||
let chan_id = get(g:, 'coc_node_channel_id', 0)
|
||||
let s:client['running'] = chan_id != 0
|
||||
let s:client['chan_id'] = chan_id
|
||||
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 $COC_DATA_HOME = coc#util#get_data_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! coc#rpc#set_channel(chan_id) abort
|
||||
let g:coc_node_channel_id = a:chan_id
|
||||
if a:chan_id != 0
|
||||
let s:client['running'] = 1
|
||||
let s:client['chan_id'] = a:chan_id
|
||||
endif
|
||||
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
|
||||
call coc#highlight#clear_all()
|
||||
call coc#float#close_all()
|
||||
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, ... -> coc#rpc#notify('nvim_async_response_event', [a:id, err, get(a:000, 0, v:null)])}
|
||||
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, v:null])
|
||||
endtry
|
||||
endfunction
|
146
sources_non_forked/coc.nvim/autoload/coc/snippet.vim
Normal file
146
sources_non_forked/coc.nvim/autoload/coc/snippet.vim
Normal file
@ -0,0 +1,146 @@
|
||||
scriptencoding utf-8
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:map_next = 1
|
||||
let s:map_prev = 1
|
||||
let s:cmd_mapping = has('nvim') || has('patch-8.2.1978')
|
||||
|
||||
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'
|
||||
call feedkeys("\<Esc>i", 'in')
|
||||
endif
|
||||
let changedtick = b:changedtick
|
||||
call timer_start(20, { -> coc#_do_complete(a:col - 1, a:values, 0, changedtick)})
|
||||
redraw
|
||||
endfunction
|
||||
|
||||
function! coc#snippet#enable(...)
|
||||
if get(b:, 'coc_snippet_active', 0) == 1
|
||||
return
|
||||
endif
|
||||
let complete = get(a:, 1, 0)
|
||||
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>')
|
||||
if maparg(nextkey, 'i') =~# 'snippet'
|
||||
let s:map_next = 0
|
||||
endif
|
||||
if maparg(prevkey, 'i') =~# 'snippet'
|
||||
let s:map_prev = 0
|
||||
endif
|
||||
if !empty(nextkey)
|
||||
if s:map_next
|
||||
execute 'inoremap <buffer><nowait><silent>'.nextkey." <C-R>=coc#snippet#jump(1, ".complete.")<cr>"
|
||||
endif
|
||||
execute 'snoremap <buffer><nowait><silent>'.nextkey." <Esc>:call coc#snippet#jump(1, ".complete.")<cr>"
|
||||
endif
|
||||
if !empty(prevkey)
|
||||
if s:map_prev
|
||||
execute 'inoremap <buffer><nowait><silent>'.prevkey." <C-R>=coc#snippet#jump(0, ".complete.")<cr>"
|
||||
endif
|
||||
execute 'snoremap <buffer><nowait><silent>'.prevkey." <Esc>:call coc#snippet#jump(0, ".complete.")<cr>"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#snippet#prev() abort
|
||||
call coc#rpc#request('snippetPrev', [])
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! coc#snippet#next() abort
|
||||
call coc#rpc#request('snippetNext', [])
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! coc#snippet#jump(direction, complete) abort
|
||||
if a:direction == 1 && a:complete && pumvisible()
|
||||
let pre = exists('*complete_info') && complete_info()['selected'] == -1 ? "\<C-n>" : ''
|
||||
call feedkeys(pre."\<C-y>", 'in')
|
||||
return ''
|
||||
endif
|
||||
call coc#rpc#request(a:direction == 1 ? 'snippetNext' : 'snippetPrev', [])
|
||||
return ''
|
||||
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>')
|
||||
if s:map_next
|
||||
silent! execute 'iunmap <buffer> <silent> '.nextkey
|
||||
endif
|
||||
if s:map_prev
|
||||
silent! execute 'iunmap <buffer> <silent> '.prevkey
|
||||
endif
|
||||
silent! execute 'sunmap <buffer> <silent> '.prevkey
|
||||
silent! execute 'sunmap <buffer> <silent> '.nextkey
|
||||
endfunction
|
||||
|
||||
function! coc#snippet#select(position, text) abort
|
||||
if pumvisible()
|
||||
call coc#_cancel()
|
||||
endif
|
||||
if mode() == 's'
|
||||
call feedkeys("\<Esc>", 'in')
|
||||
endif
|
||||
let cursor = coc#snippet#to_cursor(a:position)
|
||||
call cursor([cursor[0], cursor[1] - (&selection !~# 'exclusive')])
|
||||
let len = strchars(a:text) - (&selection !~# 'exclusive')
|
||||
let cmd = ''
|
||||
let cmd .= mode()[0] ==# 'i' ? "\<Esc>l" : ''
|
||||
let cmd .= printf('v%s', len > 0 ? len . 'h' : '')
|
||||
let cmd .= "o\<C-g>"
|
||||
call feedkeys(cmd, 'n')
|
||||
endfunction
|
||||
|
||||
function! coc#snippet#move(position) abort
|
||||
let m = mode()
|
||||
if m == 's'
|
||||
call feedkeys("\<Esc>", 'in')
|
||||
elseif pumvisible()
|
||||
call coc#_cancel()
|
||||
endif
|
||||
let pos = coc#snippet#to_cursor(a:position)
|
||||
call cursor(pos)
|
||||
if pos[1] > strlen(getline(pos[0]))
|
||||
startinsert!
|
||||
else
|
||||
startinsert
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#snippet#to_cursor(position) abort
|
||||
let line = getline(a:position.line + 1)
|
||||
if line is v:null
|
||||
return [a:position.line + 1, a:position.character + 1]
|
||||
endif
|
||||
return [a:position.line + 1, byteidx(line, a:position.character) + 1]
|
||||
endfunction
|
125
sources_non_forked/coc.nvim/autoload/coc/string.vim
Normal file
125
sources_non_forked/coc.nvim/autoload/coc/string.vim
Normal file
@ -0,0 +1,125 @@
|
||||
scriptencoding utf-8
|
||||
|
||||
function! coc#string#get_character(line, col) abort
|
||||
return strchars(strpart(a:line, 0, a:col - 1))
|
||||
endfunction
|
||||
|
||||
function! coc#string#last_character(line) abort
|
||||
return strcharpart(a:line, strchars(a:line) - 1, 1)
|
||||
endfunction
|
||||
|
||||
function! coc#string#reflow(lines, width) abort
|
||||
let lines = []
|
||||
let currlen = 0
|
||||
let parts = []
|
||||
for line in a:lines
|
||||
for part in split(line, '\s\+')
|
||||
let w = strwidth(part)
|
||||
if currlen + w + 1 >= a:width
|
||||
if len(parts) > 0
|
||||
call add(lines, join(parts, ' '))
|
||||
endif
|
||||
if w >= a:width
|
||||
call add(lines, part)
|
||||
let currlen = 0
|
||||
let parts = []
|
||||
else
|
||||
let currlen = w
|
||||
let parts = [part]
|
||||
endif
|
||||
continue
|
||||
endif
|
||||
call add(parts, part)
|
||||
let currlen = currlen + w + 1
|
||||
endfor
|
||||
endfor
|
||||
if len(parts) > 0
|
||||
call add(lines, join(parts, ' '))
|
||||
endif
|
||||
return empty(lines) ? [''] : lines
|
||||
endfunction
|
||||
|
||||
" get change between two lines
|
||||
function! coc#string#diff(curr, previous, col) abort
|
||||
let end = strpart(a:curr, a:col - 1)
|
||||
let start = strpart(a:curr, 0, a:col -1)
|
||||
let endOffset = 0
|
||||
let startOffset = 0
|
||||
let currLen = strchars(a:curr)
|
||||
let prevLen = strchars(a:previous)
|
||||
if len(end)
|
||||
let endLen = strchars(end)
|
||||
for i in range(min([prevLen, endLen]))
|
||||
if strcharpart(end, endLen - 1 - i, 1) ==# strcharpart(a:previous, prevLen -1 -i, 1)
|
||||
let endOffset = endOffset + 1
|
||||
else
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
let remain = endOffset == 0 ? a:previous : strcharpart(a:previous, 0, prevLen - endOffset)
|
||||
if len(remain)
|
||||
for i in range(min([strchars(remain), strchars(start)]))
|
||||
if strcharpart(remain, i, 1) ==# strcharpart(start, i ,1)
|
||||
let startOffset = startOffset + 1
|
||||
else
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
return {
|
||||
\ 'start': startOffset,
|
||||
\ 'end': prevLen - endOffset,
|
||||
\ 'text': strcharpart(a:curr, startOffset, currLen - startOffset - endOffset)
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! coc#string#apply(content, diff) abort
|
||||
let totalLen = strchars(a:content)
|
||||
let endLen = totalLen - a:diff['end']
|
||||
return strcharpart(a:content, 0, a:diff['start']).a:diff['text'].strcharpart(a:content, a:diff['end'], endLen)
|
||||
endfunction
|
||||
|
||||
" insert inserted to line at position, use ... when result is too long
|
||||
" line should only contains character has strwidth equals 1
|
||||
function! coc#string#compose(line, position, inserted) abort
|
||||
let width = strwidth(a:line)
|
||||
let text = a:inserted
|
||||
let res = a:line
|
||||
let need_truncate = a:position + strwidth(text) + 1 > width
|
||||
if need_truncate
|
||||
let remain = width - a:position - 3
|
||||
if remain < 2
|
||||
" use text for full line, use first & end of a:line, ignore position
|
||||
let res = strcharpart(a:line, 0, 1)
|
||||
let w = strwidth(res)
|
||||
for i in range(strchars(text))
|
||||
let c = strcharpart(text, i, 1)
|
||||
let a = strwidth(c)
|
||||
if w + a <= width - 1
|
||||
let w = w + a
|
||||
let res = res . c
|
||||
endif
|
||||
endfor
|
||||
let res = res.strcharpart(a:line, w)
|
||||
else
|
||||
let res = strcharpart(a:line, 0, a:position)
|
||||
let w = strwidth(res)
|
||||
for i in range(strchars(text))
|
||||
let c = strcharpart(text, i, 1)
|
||||
let a = strwidth(c)
|
||||
if w + a <= width - 3
|
||||
let w = w + a
|
||||
let res = res . c
|
||||
endif
|
||||
endfor
|
||||
let res = res.'..'
|
||||
let w = w + 2
|
||||
let res = res . strcharpart(a:line, w)
|
||||
endif
|
||||
else
|
||||
let first = strcharpart(a:line, 0, a:position)
|
||||
let res = first . text . strcharpart(a:line, a:position + strwidth(text))
|
||||
endif
|
||||
return res
|
||||
endfunction
|
179
sources_non_forked/coc.nvim/autoload/coc/task.vim
Normal file
179
sources_non_forked/coc.nvim/autoload/coc/task.vim
Normal file
@ -0,0 +1,179 @@
|
||||
" ============================================================================
|
||||
" Description: Manage long running tasks.
|
||||
" Author: Qiming Zhao <chemzqm@gmail.com>
|
||||
" Licence: Anti 966 licence
|
||||
" Version: 0.1
|
||||
" Last Modified: Dec 12, 2020
|
||||
" ============================================================================
|
||||
scriptencoding utf-8
|
||||
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:running_task = {}
|
||||
" neovim emit strings that part of lines.
|
||||
let s:out_remain_text = {}
|
||||
let s:err_remain_text = {}
|
||||
|
||||
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())
|
||||
let env = get(a:opts, 'env', {})
|
||||
" 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)},
|
||||
\ 'env': env,
|
||||
\}
|
||||
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, msgs)},
|
||||
\ 'on_stdout': {channel, msgs -> s:on_stdout(a:id, msgs)},
|
||||
\ 'on_exit': {channel, code -> s:on_exit(a:id, code)},
|
||||
\ 'detach': get(a:opts, 'detach', 0),
|
||||
\}
|
||||
let original = {}
|
||||
if !empty(env)
|
||||
if has('nvim-0.5.0')
|
||||
let options['env'] = env
|
||||
elseif exists('*setenv') && exists('*getenv')
|
||||
for key in keys(env)
|
||||
let original[key] = getenv(key)
|
||||
call setenv(key, env[key])
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
if get(a:opts, 'pty', 0)
|
||||
let options['pty'] = 1
|
||||
endif
|
||||
let chan_id = jobstart(cmd, options)
|
||||
if !empty(original)
|
||||
for key in keys(original)
|
||||
call setenv(key, original[key])
|
||||
endfor
|
||||
endif
|
||||
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('nvim')
|
||||
let s:out_remain_text[a:id] = ''
|
||||
let s:err_remain_text[a:id] = ''
|
||||
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 empty(a:msgs)
|
||||
return
|
||||
endif
|
||||
if s:is_vim
|
||||
call coc#rpc#notify('TaskStderr', [a:id, a:msgs])
|
||||
else
|
||||
let remain = get(s:err_remain_text, a:id, '')
|
||||
let eof = (a:msgs == [''])
|
||||
let msgs = copy(a:msgs)
|
||||
if len(remain) > 0
|
||||
if msgs[0] == ''
|
||||
let msgs[0] = remain
|
||||
else
|
||||
let msgs[0] = remain . msgs[0]
|
||||
endif
|
||||
endif
|
||||
let last = msgs[len(msgs) - 1]
|
||||
let s:err_remain_text[a:id] = len(last) > 0 ? last : ''
|
||||
" all lines from 0 to n - 2
|
||||
if len(msgs) > 1
|
||||
call coc#rpc#notify('TaskStderr', [a:id, msgs[:len(msgs)-2]])
|
||||
elseif eof && len(msgs[0]) > 0
|
||||
call coc#rpc#notify('TaskStderr', [a:id, msgs])
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:on_stdout(id, msgs)
|
||||
if empty(a:msgs)
|
||||
return
|
||||
endif
|
||||
if s:is_vim
|
||||
call coc#rpc#notify('TaskStdout', [a:id, a:msgs])
|
||||
else
|
||||
let remain = get(s:out_remain_text, a:id, '')
|
||||
let eof = (a:msgs == [''])
|
||||
let msgs = copy(a:msgs)
|
||||
if len(remain) > 0
|
||||
if msgs[0] == ''
|
||||
let msgs[0] = remain
|
||||
else
|
||||
let msgs[0] = remain . msgs[0]
|
||||
endif
|
||||
endif
|
||||
let last = msgs[len(msgs) - 1]
|
||||
let s:out_remain_text[a:id] = len(last) > 0 ? last : ''
|
||||
" all lines from 0 to n - 2
|
||||
if len(msgs) > 1
|
||||
call coc#rpc#notify('TaskStdout', [a:id, msgs[:len(msgs)-2]])
|
||||
elseif eof && len(msgs[0]) > 0
|
||||
call coc#rpc#notify('TaskStdout', [a:id, msgs])
|
||||
endif
|
||||
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
|
115
sources_non_forked/coc.nvim/autoload/coc/terminal.vim
Normal file
115
sources_non_forked/coc.nvim/autoload/coc/terminal.vim
Normal file
@ -0,0 +1,115 @@
|
||||
scriptencoding utf-8
|
||||
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, strict) 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 '.get(g:, 'coc_terminal_height', 8).'new +setl\ buftype=nofile'
|
||||
setl winfixheight
|
||||
setl norelativenumber
|
||||
setl nonumber
|
||||
setl bufhidden=hide
|
||||
if exists('#User#CocTerminalOpen')
|
||||
exe 'doautocmd <nomodeline> User CocTerminalOpen'
|
||||
endif
|
||||
let bufnr = bufnr('%')
|
||||
let env = {}
|
||||
let original = {}
|
||||
if !empty(a:env)
|
||||
" use env option when possible
|
||||
if s:is_vim
|
||||
let env = copy(a:env)
|
||||
elseif exists('*setenv')
|
||||
for key in keys(a:env)
|
||||
let original[key] = getenv(key)
|
||||
call setenv(key, a:env[key])
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
|
||||
function! s:OnExit(status) closure
|
||||
call coc#rpc#notify('CocAutocmd', ['TermExit', bufnr, a:status])
|
||||
if a:status == 0
|
||||
execute 'silent! bd! '.bufnr
|
||||
endif
|
||||
endfunction
|
||||
|
||||
if has('nvim')
|
||||
let job_id = termopen(a:cmd, {
|
||||
\ 'cwd': cwd,
|
||||
\ 'pty': v:true,
|
||||
\ 'on_exit': {job, status -> s:OnExit(status)},
|
||||
\ 'env': env,
|
||||
\ 'clear_env': a:strict ? v:true : v:false
|
||||
\ })
|
||||
if !empty(original) && exists('*setenv')
|
||||
for key in keys(original)
|
||||
call setenv(key, original[key])
|
||||
endfor
|
||||
endif
|
||||
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': 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])
|
||||
if s:is_win
|
||||
call add(lines, "\r\n")
|
||||
else
|
||||
call add(lines, '')
|
||||
endif
|
||||
endif
|
||||
call chansend(chan, lines)
|
||||
let winid = bufwinid(a:bufnr)
|
||||
if winid != -1
|
||||
call coc#compat#execute(winid, 'noa normal! G')
|
||||
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
|
316
sources_non_forked/coc.nvim/autoload/coc/ui.vim
Normal file
316
sources_non_forked/coc.nvim/autoload/coc/ui.vim
Normal file
@ -0,0 +1,316 @@
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:is_win = has('win32') || has('win64')
|
||||
|
||||
function! coc#ui#quickpick(title, items, cb) abort
|
||||
if exists('*popup_menu')
|
||||
function! s:QuickpickHandler(id, result) closure
|
||||
call a:cb(v:null, a:result)
|
||||
endfunction
|
||||
function! s:QuickpickFilter(id, key) closure
|
||||
for i in range(1, len(a:items))
|
||||
if a:key == string(i)
|
||||
call popup_close(a:id, i)
|
||||
return 1
|
||||
endif
|
||||
endfor
|
||||
" No shortcut, pass to generic filter
|
||||
return popup_filter_menu(a:id, a:key)
|
||||
endfunction
|
||||
try
|
||||
call popup_menu(a:items, {
|
||||
\ 'title': a:title,
|
||||
\ 'filter': function('s:QuickpickFilter'),
|
||||
\ 'callback': function('s:QuickpickHandler'),
|
||||
\ })
|
||||
redraw
|
||||
catch /.*/
|
||||
call a:cb(v:exception)
|
||||
endtry
|
||||
else
|
||||
let res = inputlist([a:title] + a:items)
|
||||
call a:cb(v:null, res)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" cmd, cwd
|
||||
function! coc#ui#open_terminal(opts) abort
|
||||
if s:is_vim && !exists('*term_start')
|
||||
echohl WarningMsg | echon "Your vim doesn't have terminal 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
|
||||
if exists('#User#CocTerminalOpen')
|
||||
exe 'doautocmd <nomodeline> User CocTerminalOpen'
|
||||
endif
|
||||
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#ui#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#ui#open_terminal(opts)
|
||||
endfunction
|
||||
|
||||
function! coc#ui#echo_hover(msg)
|
||||
echohl MoreMsg
|
||||
echo a:msg
|
||||
echohl None
|
||||
let g:coc_last_hover_message = a:msg
|
||||
endfunction
|
||||
|
||||
function! coc#ui#echo_messages(hl, msgs)
|
||||
if a:hl !~# 'Error' && (mode() !~# '\v^(i|n)$')
|
||||
return
|
||||
endif
|
||||
let msgs = filter(copy(a:msgs), '!empty(v:val)')
|
||||
if empty(msgs)
|
||||
return
|
||||
endif
|
||||
execute 'echohl '.a:hl
|
||||
echom a:msgs[0]
|
||||
redraw
|
||||
echo join(msgs, "\n")
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
function! coc#ui#preview_info(lines, filetype, ...) abort
|
||||
pclose
|
||||
keepalt new +setlocal\ previewwindow|setlocal\ buftype=nofile|setlocal\ noswapfile|setlocal\ wrap [Document]
|
||||
setl bufhidden=wipe
|
||||
setl nobuflisted
|
||||
setl nospell
|
||||
exe 'setl filetype='.a:filetype
|
||||
setl conceallevel=0
|
||||
setl nofoldenable
|
||||
for command in a:000
|
||||
execute command
|
||||
endfor
|
||||
call append(0, a:lines)
|
||||
exe "normal! z" . len(a:lines) . "\<cr>"
|
||||
exe "normal! gg"
|
||||
wincmd p
|
||||
endfunction
|
||||
|
||||
function! coc#ui#open_files(files)
|
||||
let bufnrs = []
|
||||
" added on latest vim8
|
||||
if exists('*bufadd') && exists('*bufload')
|
||||
for file in a:files
|
||||
let file = fnamemodify(file, ':.')
|
||||
if bufloaded(file)
|
||||
call add(bufnrs, bufnr(file))
|
||||
else
|
||||
let bufnr = bufadd(file)
|
||||
call bufload(file)
|
||||
call add(bufnrs, bufnr)
|
||||
call setbufvar(bufnr, '&buflisted', 1)
|
||||
endif
|
||||
endfor
|
||||
else
|
||||
noa keepalt 1new +setl\ bufhidden=wipe
|
||||
for file in a:files
|
||||
let file = fnamemodify(file, ':.')
|
||||
execute 'noa edit +setl\ bufhidden=hide '.fnameescape(file)
|
||||
if &filetype ==# ''
|
||||
filetype detect
|
||||
endif
|
||||
call add(bufnrs, bufnr('%'))
|
||||
endfor
|
||||
noa close
|
||||
endif
|
||||
doautocmd BufEnter
|
||||
return bufnrs
|
||||
endfunction
|
||||
|
||||
function! coc#ui#echo_lines(lines)
|
||||
echo join(a:lines, "\n")
|
||||
endfunction
|
||||
|
||||
function! coc#ui#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#ui#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#ui#set_lines(bufnr, changedtick, original, replacement, start, end, changes, cursor, col) abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return
|
||||
endif
|
||||
let delta = 0
|
||||
if !empty(a:col)
|
||||
let delta = col('.') - a:col
|
||||
endif
|
||||
if getbufvar(a:bufnr, 'changedtick') != a:changedtick && bufnr('%') == a:bufnr
|
||||
" try apply current line change
|
||||
let lnum = line('.')
|
||||
let idx = a:start - lnum + 1
|
||||
let previous = get(a:original, idx, 0)
|
||||
if type(previous) == 1
|
||||
let content = getline('.')
|
||||
if previous !=# content
|
||||
let diff = coc#string#diff(content, previous, col('.'))
|
||||
let changed = get(a:replacement, idx, 0)
|
||||
if type(changed) == 1 && strcharpart(previous, 0, diff['end']) ==# strcharpart(changed, 0, diff['end'])
|
||||
let applied = coc#string#apply(changed, diff)
|
||||
let replacement = copy(a:replacement)
|
||||
let replacement[idx] = applied
|
||||
call coc#compat#buf_set_lines(a:bufnr, a:start, a:end, replacement)
|
||||
return
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if exists('*nvim_buf_set_text') && !empty(a:changes)
|
||||
for item in reverse(copy(a:changes))
|
||||
call nvim_buf_set_text(a:bufnr, item[1], item[2], item[3], item[4], item[0])
|
||||
endfor
|
||||
else
|
||||
call coc#compat#buf_set_lines(a:bufnr, a:start, a:end, a:replacement)
|
||||
endif
|
||||
if !empty(a:cursor)
|
||||
call cursor(a:cursor[0], a:cursor[1] + delta)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#ui#change_lines(bufnr, list) abort
|
||||
if !bufloaded(a:bufnr) | return v:null | endif
|
||||
undojoin
|
||||
if exists('*setbufline')
|
||||
for [lnum, line] in a:list
|
||||
call setbufline(a:bufnr, lnum + 1, line)
|
||||
endfor
|
||||
elseif a:bufnr == bufnr('%')
|
||||
for [lnum, line] in a:list
|
||||
call setline(lnum + 1, line)
|
||||
endfor
|
||||
else
|
||||
let bufnr = bufnr('%')
|
||||
exe 'noa buffer '.a:bufnr
|
||||
for [lnum, line] in a:list
|
||||
call setline(lnum + 1, line)
|
||||
endfor
|
||||
exe 'noa buffer '.bufnr
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#ui#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
|
601
sources_non_forked/coc.nvim/autoload/coc/util.vim
Normal file
601
sources_non_forked/coc.nvim/autoload/coc/util.vim
Normal file
@ -0,0 +1,601 @@
|
||||
scriptencoding utf-8
|
||||
let s:root = expand('<sfile>:h:h:h')
|
||||
let s:is_win = has('win32') || has('win64')
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:vim_api_version = 29
|
||||
|
||||
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#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#suggest_variables(bufnr) abort
|
||||
return {
|
||||
\ 'coc_suggest_disable': getbufvar(a:bufnr, 'coc_suggest_disable', 0),
|
||||
\ 'coc_disabled_sources': getbufvar(a:bufnr, 'coc_disabled_sources', []),
|
||||
\ 'coc_suggest_blacklist': getbufvar(a:bufnr, 'coc_suggest_blacklist', []),
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! coc#util#api_version() abort
|
||||
return s:vim_api_version
|
||||
endfunction
|
||||
|
||||
function! coc#util#semantic_hlgroups() abort
|
||||
let res = split(execute('hi'), "\n")
|
||||
let filtered = filter(res, "v:val =~# '^CocSem'")
|
||||
return map(filtered, "matchstr(v:val,'\\v^CocSem\\w+')")
|
||||
endfunction
|
||||
|
||||
" get cursor position
|
||||
function! coc#util#cursor()
|
||||
return [line('.') - 1, strchars(strpart(getline('.'), 0, col('.') - 1))]
|
||||
endfunction
|
||||
|
||||
function! coc#util#change_info() abort
|
||||
return {'lnum': line('.'), 'col': col('.'), 'line': getline('.'), 'changedtick': b:changedtick}
|
||||
endfunction
|
||||
|
||||
function! coc#util#jumpTo(line, character) abort
|
||||
echohl WarningMsg | echon 'coc#util#jumpTo is deprecated, use coc#cursor#move_to instead.' | echohl None
|
||||
call coc#cursor#move_to(a:line, a:character)
|
||||
endfunction
|
||||
|
||||
function! coc#util#root_patterns() abort
|
||||
return coc#rpc#request('rootPatterns', [bufnr('%')])
|
||||
endfunction
|
||||
|
||||
function! coc#util#get_config(key) abort
|
||||
return coc#rpc#request('getConfig', [a:key])
|
||||
endfunction
|
||||
|
||||
function! coc#util#open_terminal(opts) abort
|
||||
return coc#ui#open_terminal(a:opts)
|
||||
endfunction
|
||||
|
||||
function! coc#util#synname() abort
|
||||
return synIDattr(synID(line('.'), col('.') - 1, 1), 'name')
|
||||
endfunction
|
||||
|
||||
function! coc#util#setline(lnum, line)
|
||||
keepjumps call setline(a:lnum, a:line)
|
||||
endfunction
|
||||
|
||||
function! coc#util#path_replace_patterns() abort
|
||||
if has('win32unix') && exists('g:coc_cygqwin_path_prefixes')
|
||||
echohl WarningMsg
|
||||
echon 'g:coc_cygqwin_path_prefixes is deprecated, use g:coc_uri_prefix_replace_patterns instead'
|
||||
echohl None
|
||||
return g:coc_cygqwin_path_prefixes
|
||||
endif
|
||||
if exists('g:coc_uri_prefix_replace_patterns')
|
||||
return g:coc_uri_prefix_replace_patterns
|
||||
endif
|
||||
return v:null
|
||||
endfunction
|
||||
|
||||
function! coc#util#version()
|
||||
if s:is_vim
|
||||
return string(v:versionlong)
|
||||
endif
|
||||
let c = execute('silent version')
|
||||
let lines = split(matchstr(c, 'NVIM v\zs[^\n-]*'))
|
||||
return lines[0]
|
||||
endfunction
|
||||
|
||||
function! coc#util#check_refresh(bufnr)
|
||||
if !bufloaded(a:bufnr)
|
||||
return 0
|
||||
endif
|
||||
if getbufvar(a:bufnr, 'coc_diagnostic_disable', 0)
|
||||
return 0
|
||||
endif
|
||||
if get(g: , 'EasyMotion_loaded', 0)
|
||||
return EasyMotion#is_active() != 1
|
||||
endif
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! coc#util#diagnostic_info(bufnr, checkInsert) abort
|
||||
let checked = coc#util#check_refresh(a:bufnr)
|
||||
if !checked
|
||||
return v:null
|
||||
endif
|
||||
if a:checkInsert && mode() =~# '^i'
|
||||
return v:null
|
||||
endif
|
||||
let locationlist = ''
|
||||
let winid = -1
|
||||
for info in getwininfo()
|
||||
if info['bufnr'] == a:bufnr
|
||||
let winid = info['winid']
|
||||
let locationlist = get(getloclist(winid, {'title': 1}), 'title', '')
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
return {
|
||||
\ 'bufnr': bufnr('%'),
|
||||
\ 'winid': winid,
|
||||
\ 'lnum': line('.'),
|
||||
\ 'locationlist': locationlist
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! coc#util#open_file(cmd, file)
|
||||
let file = fnameescape(a:file)
|
||||
execute a:cmd .' '.file
|
||||
endfunction
|
||||
|
||||
function! coc#util#job_command()
|
||||
if (has_key(g:, 'coc_node_path'))
|
||||
let node = expand(g:coc_node_path)
|
||||
else
|
||||
let node = $COC_NODE_PATH == '' ? 'node' : $COC_NODE_PATH
|
||||
endif
|
||||
if !executable(node)
|
||||
echohl Error | echom '[coc.nvim] "'.node.'" is not executable, checkout https://nodejs.org/en/download/' | echohl None
|
||||
return
|
||||
endif
|
||||
if !filereadable(s:root.'/build/index.js')
|
||||
if isdirectory(s:root.'/src')
|
||||
echohl Error | echom '[coc.nvim] build/index.js not found, please install dependencies and compile coc.nvim by: yarn install' | echohl None
|
||||
else
|
||||
echohl Error | echon '[coc.nvim] your coc.nvim is broken.' | echohl None
|
||||
endif
|
||||
return
|
||||
endif
|
||||
return [node] + get(g:, 'coc_node_args', ['--no-warnings']) + [s:root.'/build/index.js']
|
||||
endfunction
|
||||
|
||||
function! coc#util#jump(cmd, filepath, ...) abort
|
||||
if a:cmd != 'pedit'
|
||||
silent! normal! m'
|
||||
endif
|
||||
let path = a:filepath
|
||||
if (has('win32unix'))
|
||||
let path = substitute(a:filepath, '\v\\', '/', 'g')
|
||||
endif
|
||||
let file = fnamemodify(path, ":~:.")
|
||||
if a:cmd == 'pedit'
|
||||
let extra = empty(get(a:, 1, [])) ? '' : '+'.(a:1[0] + 1)
|
||||
exe 'pedit '.extra.' '.fnameescape(file)
|
||||
return
|
||||
elseif a:cmd == 'drop' && exists('*bufadd')
|
||||
let dstbuf = bufadd(path)
|
||||
let binfo = getbufinfo(dstbuf)
|
||||
if len(binfo) == 1 && empty(binfo[0].windows)
|
||||
exec 'buffer '.dstbuf
|
||||
let &buflisted = 1
|
||||
else
|
||||
exec 'drop '.fnameescape(file)
|
||||
endif
|
||||
elseif a:cmd == 'edit'
|
||||
if bufloaded(file)
|
||||
exe 'b '.bufnr(file)
|
||||
else
|
||||
exe a:cmd.' '.fnameescape(file)
|
||||
endif
|
||||
else
|
||||
exe a:cmd.' '.fnameescape(file)
|
||||
endif
|
||||
if !empty(get(a:, 1, []))
|
||||
let line = getline(a:1[0] + 1)
|
||||
" TODO need to use utf16 here
|
||||
let col = byteidx(line, a:1[1]) + 1
|
||||
if col == 0
|
||||
let col = 999
|
||||
endif
|
||||
call cursor(a:1[0] + 1, col)
|
||||
endif
|
||||
if &filetype ==# ''
|
||||
filetype detect
|
||||
endif
|
||||
if s:is_vim
|
||||
redraw
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#util#variables(bufnr) abort
|
||||
let info = getbufinfo(a:bufnr)
|
||||
let variables = empty(info) ? {} : copy(info[0]['variables'])
|
||||
for key in keys(variables)
|
||||
if key !~# '\v^coc'
|
||||
unlet variables[key]
|
||||
endif
|
||||
endfor
|
||||
return variables
|
||||
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#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#vim_info()
|
||||
return {
|
||||
\ 'apiversion': s:vim_api_version,
|
||||
\ 'mode': mode(),
|
||||
\ 'config': get(g:, 'coc_user_config', {}),
|
||||
\ 'floating': has('nvim') && exists('*nvim_open_win') ? v:true : v:false,
|
||||
\ 'extensionRoot': coc#util#extension_root(),
|
||||
\ 'globalExtensions': get(g:, 'coc_global_extensions', []),
|
||||
\ 'lines': &lines,
|
||||
\ 'columns': &columns,
|
||||
\ 'cmdheight': &cmdheight,
|
||||
\ 'pid': coc#util#getpid(),
|
||||
\ '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,
|
||||
\ 'isiTerm': $TERM_PROGRAM ==# "iTerm.app",
|
||||
\ 'colorscheme': get(g:, 'colors_name', ''),
|
||||
\ 'workspaceFolders': get(g:, 'WorkspaceFolders', v:null),
|
||||
\ 'background': &background,
|
||||
\ 'runtimepath': join(globpath(&runtimepath, '', 0, 1), ','),
|
||||
\ 'locationlist': get(g:,'coc_enable_locationlist', 1),
|
||||
\ 'progpath': v:progpath,
|
||||
\ 'guicursor': &guicursor,
|
||||
\ 'tabCount': tabpagenr('$'),
|
||||
\ 'updateHighlight': has('nvim-0.5.0') || has('patch-8.1.1719') ? v:true : v:false,
|
||||
\ 'vimCommands': get(g:, 'coc_vim_commands', []),
|
||||
\ 'sign': exists('*sign_place') && exists('*sign_unplace'),
|
||||
\ 'textprop': has('textprop') && has('patch-8.1.1719') && !has('nvim') ? v:true : v:false,
|
||||
\ 'dialog': has('nvim-0.4.0') || has('patch-8.2.0750') ? v:true : v:false,
|
||||
\ 'semanticHighlights': coc#util#semantic_hlgroups()
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! coc#util#all_state()
|
||||
return {
|
||||
\ 'bufnr': bufnr('%'),
|
||||
\ 'winid': win_getid(),
|
||||
\ 'bufnrs': map(getbufinfo({'bufloaded': 1}),'v:val["bufnr"]'),
|
||||
\ 'winids': map(getwininfo(),'v:val["winid"]'),
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! coc#util#install() abort
|
||||
let yarncmd = get(g:, 'coc_install_yarn_cmd', executable('yarnpkg') ? 'yarnpkg' : 'yarn')
|
||||
call coc#ui#open_terminal({
|
||||
\ 'cwd': s:root,
|
||||
\ 'cmd': yarncmd.' install --frozen-lockfile --ignore-engines',
|
||||
\ 'autoclose': 0,
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
function! coc#util#extension_root() abort
|
||||
if get(g:, 'coc_node_env', '') ==# 'test'
|
||||
return s:root.'/src/__tests__/extensions'
|
||||
endif
|
||||
if !empty(get(g:, 'coc_extension_root', ''))
|
||||
echohl Error | echon 'g:coc_extension_root not used any more, use g:coc_data_home instead' | echohl None
|
||||
endif
|
||||
return coc#util#get_data_home().'/extensions'
|
||||
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', [v:true])
|
||||
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 <nomodeline> User '.a:name
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#util#rebuild()
|
||||
let dir = coc#util#extension_root()
|
||||
if !isdirectory(dir) | return | endif
|
||||
call coc#ui#open_terminal({
|
||||
\ 'cwd': dir,
|
||||
\ 'cmd': 'npm rebuild',
|
||||
\ 'keepfocus': 1,
|
||||
\})
|
||||
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#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
|
||||
|
||||
" get tabsize & expandtab option
|
||||
function! coc#util#get_format_opts(bufnr) abort
|
||||
let bufnr = a:bufnr && bufloaded(a:bufnr) ? a:bufnr : bufnr('%')
|
||||
let tabsize = getbufvar(bufnr, '&shiftwidth')
|
||||
if tabsize == 0
|
||||
let tabsize = getbufvar(bufnr, '&tabstop')
|
||||
endif
|
||||
return {
|
||||
\ 'tabsize': tabsize,
|
||||
\ 'expandtab': getbufvar(bufnr, '&expandtab'),
|
||||
\ 'insertFinalNewline': getbufvar(bufnr, '&eol'),
|
||||
\ 'trimTrailingWhitespace': getbufvar(bufnr, 'coc_trim_trailing_whitespace', 0),
|
||||
\ 'trimFinalNewlines': getbufvar(bufnr, 'coc_trim_final_newlines', 0)
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! coc#util#get_editoroption(winid) abort
|
||||
if !coc#compat#win_is_valid(a:winid)
|
||||
return v:null
|
||||
endif
|
||||
if has('nvim') && exists('*nvim_win_get_config')
|
||||
" avoid float window
|
||||
let config = nvim_win_get_config(a:winid)
|
||||
if !empty(get(config, 'relative', ''))
|
||||
return v:null
|
||||
endif
|
||||
endif
|
||||
let info = getwininfo(a:winid)[0]
|
||||
let bufnr = info['bufnr']
|
||||
let buftype = getbufvar(bufnr, '&buftype')
|
||||
" avoid window for other purpose.
|
||||
if buftype !=# '' && buftype !=# 'acwrite'
|
||||
return v:null
|
||||
endif
|
||||
let tabSize = getbufvar(bufnr, '&shiftwidth')
|
||||
if tabSize == 0
|
||||
let tabSize = getbufvar(bufnr, '&tabstop')
|
||||
endif
|
||||
return {
|
||||
\ 'bufnr': bufnr,
|
||||
\ 'winid': a:winid,
|
||||
\ 'winids': map(getwininfo(), 'v:val["winid"]'),
|
||||
\ 'tabpagenr': info['tabnr'],
|
||||
\ 'winnr': winnr(),
|
||||
\ 'visibleRanges': s:visible_ranges(a:winid),
|
||||
\ 'tabSize': tabSize,
|
||||
\ 'insertSpaces': getbufvar(bufnr, '&expandtab') ? v:true : v:false
|
||||
\ }
|
||||
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
|
||||
|
||||
" Get indentkeys for indent on TextChangedP, consider = for word indent only.
|
||||
function! coc#util#get_indentkeys() abort
|
||||
if empty(&indentexpr)
|
||||
return ''
|
||||
endif
|
||||
if &indentkeys !~# '='
|
||||
return ''
|
||||
endif
|
||||
return &indentkeys
|
||||
endfunction
|
||||
|
||||
function! coc#util#get_bufoptions(bufnr) abort
|
||||
if !bufloaded(a:bufnr) | return v:null | endif
|
||||
let bufname = bufname(a:bufnr)
|
||||
let buftype = getbufvar(a:bufnr, '&buftype')
|
||||
let winid = bufwinid(a:bufnr)
|
||||
let size = -1
|
||||
if bufnr('%') == a:bufnr
|
||||
let size = line2byte(line("$") + 1)
|
||||
elseif !empty(bufname)
|
||||
let size = getfsize(bufname)
|
||||
endif
|
||||
let lines = v:null
|
||||
if getbufvar(a:bufnr, 'coc_enabled', 1) && (buftype == '' || buftype == 'acwrite') && size < get(g:, 'coc_max_filesize', 2097152)
|
||||
let lines = getbufline(a:bufnr, 1, '$')
|
||||
endif
|
||||
return {
|
||||
\ 'bufnr': a:bufnr,
|
||||
\ 'size': size,
|
||||
\ 'lines': lines,
|
||||
\ 'winid': winid,
|
||||
\ 'bufname': bufname,
|
||||
\ 'buftype': buftype,
|
||||
\ 'previewwindow': v:false,
|
||||
\ 'eol': getbufvar(a:bufnr, '&eol'),
|
||||
\ 'indentkeys': coc#util#get_indentkeys(),
|
||||
\ 'variables': coc#util#variables(a:bufnr),
|
||||
\ 'filetype': getbufvar(a:bufnr, '&filetype'),
|
||||
\ 'iskeyword': getbufvar(a:bufnr, '&iskeyword'),
|
||||
\ 'changedtick': getbufvar(a:bufnr, 'changedtick'),
|
||||
\ 'fullpath': empty(bufname) ? '' : fnamemodify(bufname, ':p'),
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! coc#util#get_config_home()
|
||||
if !empty(get(g:, 'coc_config_home', ''))
|
||||
return resolve(expand(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_data_home()
|
||||
if !empty(get(g:, 'coc_data_home', ''))
|
||||
let dir = resolve(expand(g:coc_data_home))
|
||||
else
|
||||
if exists('$XDG_CONFIG_HOME')
|
||||
let dir = resolve($XDG_CONFIG_HOME."/coc")
|
||||
else
|
||||
if s:is_win
|
||||
let dir = resolve(expand('~/AppData/Local/coc'))
|
||||
else
|
||||
let dir = resolve(expand('~/.config/coc'))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if !isdirectory(dir)
|
||||
call coc#notify#create(['creating data directory: '.dir], {
|
||||
\ 'borderhighlight': 'CocInfoSign',
|
||||
\ 'timeout': 5000,
|
||||
\ 'kind': 'info',
|
||||
\ })
|
||||
call mkdir(dir, "p", 0755)
|
||||
endif
|
||||
return dir
|
||||
endfunction
|
||||
|
||||
function! coc#util#get_complete_option()
|
||||
if get(b:,"coc_suggest_disable",0)
|
||||
return v:null
|
||||
endif
|
||||
let pos = getcurpos()
|
||||
let line = getline(pos[1])
|
||||
let input = matchstr(strpart(line, 0, pos[2] - 1), '\k*$')
|
||||
let col = pos[2] - strlen(input)
|
||||
return {
|
||||
\ 'word': matchstr(strpart(line, col - 1), '^\k\+'),
|
||||
\ 'input': empty(input) ? '' : input,
|
||||
\ 'line': line,
|
||||
\ 'filetype': &filetype,
|
||||
\ 'filepath': expand('%:p'),
|
||||
\ 'bufnr': bufnr('%'),
|
||||
\ 'linenr': pos[1],
|
||||
\ 'colnr' : pos[2],
|
||||
\ 'col': col - 1,
|
||||
\ 'changedtick': b:changedtick,
|
||||
\ 'blacklist': get(b:, 'coc_suggest_blacklist', []),
|
||||
\ 'disabled': get(b:, 'coc_disabled_sources', []),
|
||||
\ 'indentkeys': coc#util#get_indentkeys()
|
||||
\}
|
||||
endfunction
|
||||
|
||||
" used by vim
|
||||
function! coc#util#get_buf_lines(bufnr, changedtick)
|
||||
if !bufloaded(a:bufnr)
|
||||
return v:null
|
||||
endif
|
||||
let changedtick = getbufvar(a:bufnr, 'changedtick')
|
||||
if changedtick == a:changedtick
|
||||
return v:null
|
||||
endif
|
||||
return {
|
||||
\ 'lines': getbufline(a:bufnr, 1, '$'),
|
||||
\ 'changedtick': getbufvar(a:bufnr, 'changedtick')
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
" used for TextChangedI with InsertCharPre
|
||||
function! coc#util#get_changeinfo()
|
||||
return {
|
||||
\ 'bufnr': bufnr('%'),
|
||||
\ 'lnum': line('.'),
|
||||
\ 'line': getline('.'),
|
||||
\ 'changedtick': b:changedtick,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! s:visible_ranges(winid) abort
|
||||
let info = getwininfo(a:winid)[0]
|
||||
let res = []
|
||||
if !has_key(info, 'topline') || !has_key(info, 'botline')
|
||||
return res
|
||||
endif
|
||||
let begin = 0
|
||||
let curr = info['topline']
|
||||
let max = info['botline']
|
||||
if win_getid() != a:winid
|
||||
return [[curr, max]]
|
||||
endif
|
||||
while curr <= max
|
||||
let closedend = foldclosedend(curr)
|
||||
if closedend == -1
|
||||
let begin = begin == 0 ? curr : begin
|
||||
if curr == max
|
||||
call add(res, [begin, curr])
|
||||
endif
|
||||
let curr = curr + 1
|
||||
else
|
||||
if begin != 0
|
||||
call add(res, [begin, curr - 1])
|
||||
let begin = closedend + 1
|
||||
endif
|
||||
let curr = closedend + 1
|
||||
endif
|
||||
endwhile
|
||||
return res
|
||||
endfunction
|
198
sources_non_forked/coc.nvim/autoload/coc/window.vim
Normal file
198
sources_non_forked/coc.nvim/autoload/coc/window.vim
Normal file
@ -0,0 +1,198 @@
|
||||
let g:coc_max_treeview_width = get(g:, 'coc_max_treeview_width', 40)
|
||||
let s:is_vim = !has('nvim')
|
||||
|
||||
" Get tabpagenr of winid, return -1 if window doesn't exist
|
||||
function! coc#window#tabnr(winid) abort
|
||||
if exists('*nvim_win_get_tabpage')
|
||||
try
|
||||
return nvim_win_get_tabpage(a:winid)
|
||||
catch /Invalid window id/
|
||||
return -1
|
||||
endtry
|
||||
endif
|
||||
if exists('*win_execute')
|
||||
let ref = {}
|
||||
call win_execute(a:winid, 'let ref["out"] = tabpagenr()')
|
||||
return get(ref, 'out', -1)
|
||||
elseif !s:is_vim
|
||||
let info = getwininfo(a:winid)
|
||||
return empty(info) ? -1 : info[0]['tabnr']
|
||||
else
|
||||
throw 'win_execute() does not exist, please upgrade your vim.'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Check if winid visible on current tabpage
|
||||
function! coc#window#visible(winid) abort
|
||||
if s:is_vim
|
||||
if coc#window#tabnr(a:winid) != tabpagenr()
|
||||
return 0
|
||||
endif
|
||||
" Check possible hidden popup
|
||||
try
|
||||
return get(popup_getpos(a:winid), 'visible', 0) == 1
|
||||
catch /^Vim\%((\a\+)\)\=:E993/
|
||||
return 1
|
||||
endtry
|
||||
endif
|
||||
if !nvim_win_is_valid(a:winid)
|
||||
return 0
|
||||
endif
|
||||
return coc#window#tabnr(a:winid) == tabpagenr()
|
||||
endfunction
|
||||
|
||||
" Return v:null when name or window doesn't exist,
|
||||
" 'getwinvar' only works on window of current tab
|
||||
function! coc#window#get_var(winid, name, ...) abort
|
||||
if !s:is_vim
|
||||
try
|
||||
if a:name =~# '^&'
|
||||
return nvim_win_get_option(a:winid, a:name[1:])
|
||||
else
|
||||
return nvim_win_get_var(a:winid, a:name)
|
||||
endif
|
||||
catch /E5555/
|
||||
return get(a:, 1, v:null)
|
||||
endtry
|
||||
else
|
||||
try
|
||||
return coc#api#exec('win_get_var', [a:winid, a:name, get(a:, 1, v:null)])
|
||||
catch /.*/
|
||||
return get(a:, 1, v:null)
|
||||
endtry
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Not throw like setwinvar
|
||||
function! coc#window#set_var(winid, name, value) abort
|
||||
try
|
||||
if !s:is_vim
|
||||
if a:name =~# '^&'
|
||||
call nvim_win_set_option(a:winid, a:name[1:], a:value)
|
||||
else
|
||||
call nvim_win_set_var(a:winid, a:name, a:value)
|
||||
endif
|
||||
else
|
||||
call coc#api#exec('win_set_var', [a:winid, a:name, a:value])
|
||||
endif
|
||||
catch /Invalid window id/
|
||||
" ignore
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! coc#window#is_float(winid) abort
|
||||
if s:is_vim
|
||||
if exists('*popup_list')
|
||||
return index(popup_list(), a:winid) != -1
|
||||
else
|
||||
try
|
||||
return !empty(popup_getpos(a:winid))
|
||||
catch /^Vim\%((\a\+)\)\=:E993/
|
||||
return 0
|
||||
endtry
|
||||
endif
|
||||
return 0
|
||||
elseif exists('*nvim_win_get_config')
|
||||
let config = nvim_win_get_config(a:winid)
|
||||
return !empty(config) && !empty(get(config, 'relative', ''))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#window#set_height(winid, height) abort
|
||||
if empty(getwininfo(a:winid))
|
||||
return
|
||||
endif
|
||||
if exists('*nvim_win_set_height')
|
||||
call nvim_win_set_height(a:winid, a:height)
|
||||
else
|
||||
call coc#compat#execute(a:winid, 'noa resize '.a:height, 'silent')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#window#adjust_width(winid) abort
|
||||
let bufnr = winbufnr(a:winid)
|
||||
if bufloaded(bufnr)
|
||||
let maxwidth = 0
|
||||
let lines = getbufline(bufnr, 1, '$')
|
||||
if len(lines) > 2
|
||||
call coc#compat#execute(a:winid, 'setl nowrap')
|
||||
for line in lines
|
||||
let w = strwidth(line)
|
||||
if w > maxwidth
|
||||
let maxwidth = w
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
if maxwidth > winwidth(a:winid)
|
||||
call coc#compat#execute(a:winid, 'vertical resize '.min([maxwidth, g:coc_max_treeview_width]))
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Get single window by window variable, current tab only
|
||||
function! coc#window#find(key, val) abort
|
||||
for i in range(1, winnr('$'))
|
||||
let res = getwinvar(i, a:key)
|
||||
if res == a:val
|
||||
return win_getid(i)
|
||||
endif
|
||||
endfor
|
||||
return -1
|
||||
endfunction
|
||||
|
||||
" Visible buffer numbers
|
||||
function! coc#window#bufnrs() abort
|
||||
let winids = []
|
||||
if exists('*nvim_list_wins')
|
||||
let winids = nvim_list_wins()
|
||||
else
|
||||
let winids = map(getwininfo(), 'v:val["winid"]')
|
||||
endif
|
||||
return uniq(map(winids, 'winbufnr(v:val)'))
|
||||
endfunction
|
||||
|
||||
" Avoid errors
|
||||
function! coc#window#close(winid) abort
|
||||
if empty(a:winid) || a:winid == -1
|
||||
return
|
||||
endif
|
||||
if exists('*nvim_win_is_valid') && exists('*nvim_win_close')
|
||||
if nvim_win_is_valid(a:winid)
|
||||
call nvim_win_close(a:winid, 1)
|
||||
endif
|
||||
elseif exists('*win_execute')
|
||||
call coc#compat#execute(a:winid, 'noa close!', 'silent!')
|
||||
else
|
||||
let curr = win_getid()
|
||||
if curr == a:winid
|
||||
silent! close!
|
||||
else
|
||||
let res = win_gotoid(a:winid)
|
||||
if res
|
||||
silent! close!
|
||||
call win_gotoid(curr)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#window#visible_range(bufnr) abort
|
||||
let winid = bufwinid(a:bufnr)
|
||||
if winid == -1
|
||||
return v:null
|
||||
endif
|
||||
let info = getwininfo(winid)[0]
|
||||
return [info['topline'], info['botline']]
|
||||
endfunction
|
||||
|
||||
function! coc#window#visible_ranges(bufnr) abort
|
||||
let wins = gettabinfo(tabpagenr())[0]['windows']
|
||||
let res = []
|
||||
for id in wins
|
||||
let info = getwininfo(id)[0]
|
||||
if info['bufnr'] == a:bufnr
|
||||
call add(res, [info['topline'], info['botline']])
|
||||
endif
|
||||
endfor
|
||||
return res
|
||||
endfunction
|
Reference in New Issue
Block a user