1
0
mirror of https://github.com/amix/vimrc synced 2025-07-27 23:45:00 +08:00

Update coc.nvim

This commit is contained in:
Kurtis Moxley
2022-06-17 14:39:48 +08:00
parent 27c01e54fa
commit 9c0283f83b
16 changed files with 1897 additions and 1615 deletions

View File

@ -2,7 +2,7 @@
" Description: Client api used by vim8
" Author: Qiming Zhao <chemzqm@gmail.com>
" Licence: Anti 996 licence
" Last Modified: Mar 08, 2022
" Last Modified: Jun 03, 2022
" ============================================================================
if has('nvim') | finish | endif
scriptencoding utf-8
@ -10,6 +10,11 @@ let s:funcs = {}
let s:prop_offset = get(g:, 'coc_text_prop_offset', 1000)
let s:namespace_id = 1
let s:namespace_cache = {}
let s:max_src_id = 1000
" bufnr => max textprop id
let s:buffer_id = {}
" srcId => list of types
let s:id_types = {}
" helper {{
function! s:buf_line_count(bufnr) abort
@ -96,7 +101,7 @@ function! s:funcs.call_atomic(calls)
try
call add(res, call(s:funcs[name], arglist))
catch /.*/
return [res, [i, "VimException(".s:inspect_type(v:exception).")", v:exception]]
return [res, [i, "VimException(".s:inspect_type(v:exception).")", v:exception . ' on '.v:throwpoint]]
endtry
endfor
return [res, v:null]
@ -270,42 +275,27 @@ function! s:funcs.buf_add_highlight(bufnr, srcId, hlGroup, line, colStart, colEn
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
if a:srcId == 0
let srcId = s:max_src_id + 1
let s:max_src_id = srcId
else
let end = min([end, total])
let srcId = a:srcId
endif
if end <= a:colStart
let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
let type = a:hlGroup.'_'.srcId
let types = get(s:id_types, srcId, [])
if index(types, type) == -1
call add(types, type)
let s:id_types[srcId] = types
call prop_type_add(type, extend({'highlight': a:hlGroup}, get(a:, 1, {})))
endif
let end = a:colEnd == -1 ? strlen(getbufline(bufnr, a:line + 1)[0]) + 1 : a:colEnd + 1
if end < a:colStart + 1
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
let id = s:generate_id(a:bufnr)
try
call prop_add(a:line + 1, a:colStart + 1, {'length': end - a:colStart, 'bufnr': bufnr, 'type': type, 'id': id})
call prop_add(a:line + 1, a:colStart + 1, {'bufnr': bufnr, 'type': type, 'id': id, 'end_col': end})
catch /^Vim\%((\a\+)\)\=:E967/
" ignore 967
endtry
@ -323,13 +313,18 @@ function! s:funcs.buf_clear_namespace(bufnr, srcId, startLine, endLine) abort
let start = a:startLine + 1
let end = a:endLine == -1 ? len(getbufline(bufnr, 1, '$')) : a:endLine
if a:srcId == -1
if has_key(s:buffer_id, a:bufnr)
unlet s:buffer_id[a:bufnr]
endif
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
for type in get(s:id_types, a:srcId, [])
try
call prop_remove({'bufnr': bufnr, 'all': 1, 'type': type}, start, end)
catch /^Vim\%((\a\+)\)\=:E968/
" ignore 968
endtry
endfor
endif
endfunction
@ -640,8 +635,19 @@ function! s:funcs.tabpage_get_win(tabnr)
let wnr = tabpagewinnr(a:tabnr)
return win_getid(wnr, a:tabnr)
endfunction
function! s:generate_id(bufnr) abort
let max = get(s:buffer_id, a:bufnr, s:prop_offset)
let id = max + 1
let s:buffer_id[a:bufnr] = id
return id
endfunction
" }}
function! coc#api#get_types(srcId) abort
return get(s:id_types, a:srcId, [])
endfunction
function! coc#api#func_names() abort
return keys(s:funcs)
endfunction
@ -652,7 +658,7 @@ function! coc#api#call(method, args) abort
try
let res = call(s:funcs[a:method], a:args)
catch /.*/
let err = v:exception
let err = v:exception .' on api "'.a:method.'" '.json_encode(a:args)
endtry
return [err, res]
endfunction
@ -662,6 +668,11 @@ function! coc#api#exec(method, args) abort
endfunction
function! coc#api#notify(method, args) abort
call call(s:funcs[a:method], a:args)
try
call call(s:funcs[a:method], a:args)
catch /.*/
let g:b = v:exception
call coc#rpc#notify('nvim_error_event', [0, v:exception.' on api "'.a:method.'" '.json_encode(a:args)])
endtry
endfunction
" vim: set sw=2 ts=2 sts=2 et tw=78 foldmarker={{,}} foldmethod=marker foldlevel=0:

View File

@ -5,7 +5,7 @@ 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
echohl WarningMsg | echo '[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)
@ -43,9 +43,13 @@ function! s:start() dict
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
if get(g:, 'node_client_debug', 0)
let file = tmpdir . '/coc.log'
call ch_logfile(file, 'w')
echohl MoreMsg | echo '[coc.nvim] channel log to '.file | echohl None
endif
let options = {
\ 'in_mode': 'json',
\ 'out_mode': 'json',

View File

@ -74,7 +74,7 @@ function! coc#dialog#create_cursor_float(winid, bufnr, lines, config) abort
if index(modes, mode) == -1
return v:null
endif
if has('nvim') && mode ==# 'i'
if !s:is_vim && !has('nvim-0.5.0') && mode ==# 'i'
" helps to fix undo issue, don't know why.
call feedkeys("\<C-g>u", 'n')
endif
@ -676,5 +676,7 @@ endfunction
function! s:place_sign(bufnr, line) abort
call sign_unplace(s:sign_group, { 'buffer': a:bufnr })
call sign_place(6, s:sign_group, 'CocCurrentLine', a:bufnr, {'lnum': a:line})
if a:line > 0
call sign_place(6, s:sign_group, 'CocCurrentLine', a:bufnr, {'lnum': a:line})
endif
endfunction

View File

@ -2,7 +2,6 @@ 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
@ -82,46 +81,43 @@ function! coc#highlight#update_highlights(bufnr, key, highlights, ...) abort
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])
let removeIndexes = []
while currIndex != total
let hi = a:highlights[currIndex]
if hi['lnum'] == lnum
let findIndex = -1
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)
let findIndex = idx
break
elseif item[2] > hi['colStart']
break
endif
endfor
if findIndex != -1
call filter(currIndexes, 'v:val != '.findIndex)
endif
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)
for idx in currIndexes
if s:is_vim
call prop_remove({'bufnr': bufnr, 'id': items[idx][4]})
else
call add(clearLnums, lnum)
call nvim_buf_del_extmark(bufnr, ns, items[idx][4])
endif
else
" all highlights of current line exists, not clear.
call extend(exists, indexes)
endif
endfor
call extend(exists, indexes)
endfor
endif
call coc#highlight#clear(bufnr, a:key, clearLnums)
else
call coc#highlight#clear_highlight(bufnr, a:key, start, end)
endif
@ -131,19 +127,19 @@ function! coc#highlight#update_highlights(bufnr, key, highlights, ...) abort
endif
for idx in indexes
let hi = a:highlights[idx]
let opts = {}
let opts = {
\ 'combine': get(hi, 'combine', 0),
\ 'start_incl': get(hi, 'start_incl', 0),
\ 'end_incl': get(hi, 'end_incl', 0),
\ }
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
" Get list of highlights by range or all buffer.
" 0 based line, start_col and end_col
" 0 based start & end line, end inclusive.
function! coc#highlight#get_highlights(bufnr, key, ...) abort
@ -158,17 +154,21 @@ function! coc#highlight#get_highlights(bufnr, key, ...) abort
let res = []
let ns = s:namespace_map[a:key]
if exists('*prop_list')
" Could filter by end_lnum and ids
let types = coc#api#get_types(ns)
if empty(types)
return res
endif
" Could filter by end_lnum and types
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})
for prop in prop_list(start + 1, {'bufnr': a:bufnr, 'types': types, '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])
call add(res, [s:prop_type_hlgroup(prop['type']), prop['lnum'] - 1, startCol, endCol, prop['id']])
endfor
else
if end == -1
@ -176,16 +176,15 @@ function! coc#highlight#get_highlights(bufnr, key, ...) abort
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
if index(types, prop['type']) == -1 || 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])
call add(res, [s:prop_type_hlgroup(prop['type']), line - 1, startCol, endCol, prop['id']])
endfor
endfor
endif
@ -237,7 +236,7 @@ endfunction
" Clear highlights by 0 based line numbers.
function! coc#highlight#clear(bufnr, key, lnums) abort
if !bufloaded(a:bufnr)
if !bufloaded(a:bufnr) || empty(a:lnums)
return
endif
let ns = coc#highlight#create_namespace(a:key)
@ -245,7 +244,7 @@ function! coc#highlight#clear(bufnr, key, lnums) abort
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])
call coc#api#exec('buf_clear_namespace', [a:bufnr, ns, lnum, lnum + 1])
endif
endfor
" clear highlights in invalid line.
@ -261,7 +260,11 @@ function! coc#highlight#del_markers(bufnr, key, ids) abort
endif
let ns = coc#highlight#create_namespace(a:key)
for id in a:ids
call nvim_buf_del_extmark(a:bufnr, ns, id)
if s:is_vim
call prop_remove({'bufnr': a:bufnr, 'id': id})
else
call nvim_buf_del_extmark(a:bufnr, ns, id)
endif
endfor
endfunction
@ -323,7 +326,7 @@ function! coc#highlight#add_highlight(bufnr, src_id, hl_group, line, col_start,
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])
call coc#api#exec('buf_add_highlight', [a:bufnr, a:src_id, a:hl_group, a:line, a:col_start, a:col_end, opts])
endif
endfunction
@ -336,7 +339,7 @@ function! coc#highlight#clear_highlight(bufnr, key, start_line, end_line) abort
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])
call coc#api#exec('buf_clear_namespace', [a:bufnr, src_id, a:start_line, a:end_line])
endif
endfunction
@ -354,6 +357,9 @@ endfunction
" endLine: number
" }
function! coc#highlight#add_highlights(winid, codes, highlights) abort
if get(g:, 'coc_node_env', '') ==# 'test'
call setwinvar(a:winid, 'highlights', a:highlights)
endif
" clear highlights
call coc#compat#execute(a:winid, 'syntax clear')
let bufnr = winbufnr(a:winid)
@ -595,7 +601,7 @@ function! coc#highlight#clear_all() abort
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])
call coc#api#exec('buf_clear_namespace', [bufnr, src_id, 0, -1])
endif
endfor
endfor
@ -622,10 +628,7 @@ function! coc#highlight#get_syntax_name(lnum, col)
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', '')
return substitute(a:type, '_\d\+$', '', '')
endfunction
function! s:update_highlights_timer(bufnr, changedtick, key, priority, groups, idx) abort

View File

@ -1,6 +1,7 @@
scriptencoding utf-8
let s:is_vim = !has('nvim')
let s:prefix = '[List Preview]'
let s:sign_group = 'CocList'
" filetype detect could be slow.
let s:filetype_map = {
\ 'c': 'c',
@ -66,7 +67,6 @@ function! coc#list#create(position, height, name, numberSelect)
else
setl nonumber
setl norelativenumber
setl signcolumn=yes
endif
return [bufnr('%'), win_getid(), tabpagenr()]
endfunction
@ -84,15 +84,12 @@ endfunction
function! coc#list#setup(source)
let b:list_status = {}
setl buftype=nofile nobuflisted nofen nowrap
setl norelativenumber bufhidden=wipe cursorline winfixheight
setl norelativenumber bufhidden=wipe nocursorline 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:]
@ -104,6 +101,13 @@ function! coc#list#setup(source)
endif
endfunction
function! coc#list#select(bufnr, line) abort
call sign_unplace(s:sign_group, { 'buffer': a:bufnr })
if a:line > 0
call sign_place(6, s:sign_group, 'CocListCurrent', a:bufnr, {'lnum': a:line})
endif
endfunction
" Check if previewwindow exists on current tab.
function! coc#list#has_preview()
for i in range(1, winnr('$'))
@ -163,20 +167,12 @@ endfunction
" 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
let lines = bufnr == 0 ? [''] : getbufline(bufnr, 1, '$')
else
" Show empty lines so not close window.
let lines = ['']
@ -221,11 +217,7 @@ function! coc#list#preview(lines, config) abort
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)
call s:set_preview_options(winid)
noa call win_gotoid(curr)
else
let height = s:get_height(lines, a:config)
@ -262,17 +254,16 @@ function! coc#list#preview(lines, config) abort
let s:filetype_map[extname] = ft
endif
endif
call sign_unplace('coc', {'buffer': bufnr})
call sign_unplace('CocCursorLine', {'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 sign_place(1, 'CocCursorLine', 'CocCurrentLine', bufnr, {'lnum': lnum})
call coc#highlight#match_ranges(winid, bufnr, [range], hlGroup, 10)
endif
redraw
endfunction
function! s:get_height(lines, config) abort
@ -301,3 +292,11 @@ function! s:get_topline(config, lnum, winid) abort
let toplineOffset = get(a:config, 'toplineOffset', 3)
return max([1, a:lnum - toplineOffset])
endfunction
function! s:set_preview_options(winid) abort
call setwinvar(a:winid, '&signcolumn', 'no')
call setwinvar(a:winid, '&number', 1)
call setwinvar(a:winid, '&cursorline', 0)
call setwinvar(a:winid, '&relativenumber', 0)
call setwinvar(a:winid, 'previewwindow', 1)
endfunction

View File

@ -78,6 +78,7 @@ function! coc#rpc#restart()
call coc#rpc#start_server()
else
call coc#highlight#clear_all()
call coc#ui#sign_unplace()
call coc#float#close_all()
call coc#rpc#request('detach', [])
sleep 100m

View File

@ -1,6 +1,8 @@
let s:is_vim = !has('nvim')
let s:is_win = has('win32') || has('win64')
let s:is_mac = has('mac')
let s:sign_api = exists('*sign_getplaced') && exists('*sign_place')
let s:sign_groups = []
function! coc#ui#quickpick(title, items, cb) abort
if exists('*popup_menu')
@ -374,3 +376,51 @@ function! coc#ui#safe_rename(bufnr, oldPath, newPath, write) abort
call win_gotoid(winid)
return bufnr
endfunction
function! coc#ui#sign_unplace() abort
if exists('*sign_unplace')
for group in s:sign_groups
call sign_unplace(group)
endfor
endif
endfunction
function! coc#ui#update_signs(bufnr, group, signs) abort
if !s:sign_api || !bufloaded(a:bufnr)
return
endif
if len(a:signs)
call add(s:sign_groups, a:group)
endif
let current = get(get(sign_getplaced(a:bufnr, {'group': a:group}), 0, {}), 'signs', [])
let exists = []
let unplaceList = []
for item in current
let index = 0
let placed = 0
for def in a:signs
if def['name'] ==# item['name'] && def['lnum'] == item['lnum']
let placed = 1
call add(exists, index)
break
endif
let index = index + 1
endfor
if !placed
call add(unplaceList, item['id'])
endif
endfor
for idx in range(0, len(a:signs) - 1)
if index(exists, idx) == -1
let def = a:signs[idx]
let opts = {'lnum': def['lnum']}
if has_key(def, 'priority')
let opts['priority'] = def['priority']
endif
call sign_place(0, a:group, def['name'], a:bufnr, opts)
endif
endfor
for id in unplaceList
call sign_unplace(a:group, {'buffer': a:bufnr, 'id': id})
endfor
endfunction