Skip to content

Commit

Permalink
[WIP] Custom completion menu (#3862)
Browse files Browse the repository at this point in the history
* feat(completion): use custom pum

* fix(health): fix checked version

* fix(events): fix pumvisible could be wrong

* fix(snippets): close pum by coc#pum#close()

* fix(completion): fix detail window not closed

* fix(plugin): add default key-mappings for completion

* fix(dialog): scroll current line into view

* fix(completion): avoid unexpected broken completion

* fix(completion): fix bad detail window position with border

* pref(completion): delay resolve on pum shown

* fix(pum): fix possible bad height

* feat(plugin): add default mappings for <up> and <down>

* fix(pum): fix bad position on neovim, increase timer

* fix(dialog): fix bad cursor position on vim8

* fix(highlight): give search higher priority

* feat(float): support for cursor index

* fix(pum): adjust width of pum not position

* chore(doc): improve coc-complete

* fix(float): fix scroll winid could be wrong

* fix(completion): synchronzie content after completion

* feat(float): add rounded support for floatConfig

* chore(util): change api version

* feat(completion): configuration suggest.ambiguousIsNarrow

* fix(pum): fix wrong col

* fix(dialog): use coc#string#content_height for content height

* refactor(completion): get variables on doComplete

Avoid use CursorHold which may not work

* fix(completion): fix selection not work as expected

* fix(document): use insert property from cursor

* fix(completion): avoid unnecessary resolve

* fix(float): fix popup options on old vim

* fix(completion): not save prefix when not starts of word

* fix(completion): not cancel when input not changed

* fix(pum): fix bad firstline on vim

- lastline may not exists with popup_getpos.
- consider minimal first line of pum.

* fix(completion): show pum after snippet synchronize

* fix(pum): fix possible bad firstline

* refactor(completion): not persist recent selected items

* feat(completion): select word around as fallback

* refactor(plugin): remove unused <Plug>CocRefresh

* fix(completion): not select around item as fallback

Possible bad selection

* refactor(float): use s:get_borderhighlight()

* feat(float): support change float highlight

* fix(completion): avoid unexpected completion stop

* refactor(snippets): not check pumvisible on synchronize

* fix(document): fix cursor undefined

* feat(completion): add coc#pum#info() & coc#pum#select()

Check realtime pum dimension instead of transport values.

* chore(tests): fix failure tests

* chore(doc): simplified README

* feat(completion): create pum on insert mode only

* fix(pum): create pum as fixed direction

* refactor(completion): move resolve logic to floating

* feat(completion): indent after completion when necessary

* feat(pum): support scroll pum by <PageUp> and <PageDown>

* feat(completion): add virtual_text support

* feat(pum): add coc#pum#insert

* chore(doc): doc of functions

* fix(pum) use win col for virt_text

* chore(doc): add coc-locations

* chore(doc): fix example and version

* chore(plugin): remove unused <Plug>CocRefresh

* refactor(float): improve default options

* chore(types): fix lint issue

* fix(completion): avoid add mru item on cancel

* feat(pum): support index to be -1

* feat(pum): support suggest.noselect

* refactor(plugin): use ts highlights for CocSymbol

* feat(plugin): make CocSymbol highlights foreground color only

* feat(completion): support suggest.enablePreselect

* refactor(completion): not add shortcut to menu

Remove suggest.disableMenuShortcut

* feat(completion): support suggest.formatItems

* feat(completion): fill minimal width

* refactor(completion): avoid change word of complete item

* refactor(completion): improve check for filter

* fix(test): fix workspaceFolder test

* fix(pum): use `in` to check if property exists (#3895)

* fix(pum): fix pum col when exceeded

* feat(pum): make redo work after confirm completion

* fix(source-language): fix undefined filetype

* fix(snippets): check undefined value

* feat(pum): support repeat by complete()

Works on nvim 0.4.0

* feat(pum): add warning for obsolete key-mappings

* refactor(completion): avoid check filtered sources

Co-authored-by: wongxy <xiyao.wong@foxmail.com>

Closes #3480
Closes #3568
  • Loading branch information
chemzqm authored Jul 31, 2022
1 parent 3440021 commit 7a50d4d
Show file tree
Hide file tree
Showing 55 changed files with 2,461 additions and 1,571 deletions.
58 changes: 11 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,13 @@

---

<img alt="Gif" src="https://user-images.githubusercontent.com/251450/55285193-400a9000-53b9-11e9-8cff-ffe4983c5947.gif" width="60%" />

_True snippet and additional text editing support_

## Why?

- 🚀 **Fast**: [instant increment completion](https://github.com/neoclide/coc.nvim/wiki/Completion-with-sources), increment buffer sync using buffer update events.
- 💎 **Reliable**: typed language, tested with CI.
- 🌟 **Featured**: [full LSP support](https://github.com/neoclide/coc.nvim/wiki/Language-servers#supported-features)
- ❤️ **Flexible**: [configured like VSCode](https://github.com/neoclide/coc.nvim/wiki/Using-the-configuration-file), [extensions work like in VSCode](https://github.com/neoclide/coc.nvim/wiki/Using-coc-extensions)

**Gold Sponsors**

<a href="https://opencollective.com/cocnvim#platinum-sponsors">
<img src="https://opencollective.com/cocnvim/tiers/gold-sponsors.svg?avatarHeight=36&width=600">
</a>

**Silver Sponsors**

<a href="https://opencollective.com/cocnvim#platinum-sponsors">
<img src="https://opencollective.com/cocnvim/tiers/silver-sponsors.svg?avatarHeight=36&width=600">
</a>

**Bronze Sponsors**

<a href="https://opencollective.com/cocnvim#platinum-sponsors">
<img src="https://opencollective.com/cocnvim/tiers/bronze-sponsors.svg?avatarHeight=36&width=600">
</a>

## Quick Start

Install [nodejs](https://nodejs.org/en/download/) >= 12.12:
Expand Down Expand Up @@ -110,44 +88,30 @@ possible to avoid conflict with your other plugins.
command like`:verbose imap <tab>` to make sure that your keymap has taken effect.

```vim
" Set internal encoding of vim, not needed on neovim, since coc.nvim using some
" unicode characters in the file autoload/float.vim
set encoding=utf-8
" TextEdit might fail if hidden is not set.
set hidden
" Some servers have issues with backup files, see #649.
set nobackup
set nowritebackup
" Give more space for displaying messages.
set cmdheight=2
" Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable
" delays and poor user experience.
set updatetime=300
" Don't pass messages to |ins-completion-menu|.
set shortmess+=c
" Always show the signcolumn, otherwise it would shift the text each time
" diagnostics appear/become resolved.
if has("nvim-0.5.0") || has("patch-8.1.1564")
" Recently vim can merge signcolumn and number column into one
set signcolumn=number
else
set signcolumn=yes
endif
set signcolumn=yes
"Use <C-n> and <C-p> for navigate completion list like built in completion.
inoremap <silent><expr> <C-n> coc#pum#visible() ? coc#pum#next(1) : "\<C-n>"
inoremap <silent><expr> <C-p> coc#pum#visible() ? coc#pum#prev(1) : "\<C-n>"
" Use tab for trigger completion with characters ahead and navigate.
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
" other plugin before putting this into your config.
inoremap <silent><expr> <TAB>
\ pumvisible() ? "\<C-n>" :
\ CheckBackspace() ? "\<TAB>" :
\ coc#pum#visible() ? coc#pum#next(1):
\ <SID>CheckBackspace() ? "\<Tab>" :
\ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
inoremap <expr><S-TAB> coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"
function! CheckBackspace() abort
let col = col('.') - 1
Expand All @@ -161,9 +125,9 @@ else
inoremap <silent><expr> <c-@> coc#refresh()
endif
" Make <CR> auto-select the first completion item and notify coc.nvim to
" format on enter, <cr> could be remapped by other vim plugin
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
" Make <CR> to accept selected completion item or notify coc.nvim to format
" <C-g>u starts a new undo break, please make your own choice.
inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm()
\: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
" Use `[g` and `]g` to navigate diagnostics
Expand Down
99 changes: 19 additions & 80 deletions autoload/coc.vim
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ let s:is_vim = !has('nvim')
let s:error_sign = get(g:, 'coc_status_error_sign', has('mac') ? '' : 'E')
let s:warning_sign = get(g:, 'coc_status_warning_sign', has('mac') ? '⚠️ ' : 'W')
let s:select_api = exists('*nvim_select_popupmenu_item')
let s:complete_info_api = exists('*complete_info')
let s:callbacks = {}
let s:hide_pum = has('nvim-0.6.1') || has('patch-8.2.3389')

Expand All @@ -33,10 +32,6 @@ function! coc#add_command(id, cmd, ...)
call coc#rpc#notify('addCommand', [config])
endfunction

function! coc#refresh() abort
return "\<c-r>=coc#start()\<CR>"
endfunction

function! coc#on_enter()
call coc#rpc#notify('CocAutocmd', ['Enter', bufnr('%')])
return ''
Expand All @@ -46,7 +41,6 @@ function! coc#_insert_key(method, key, ...) abort
let prefix = ''
if get(a:, 1, 1)
if pumvisible()
let g:coc_hide_pum = 1
if s:hide_pum
let prefix = "\<C-x>\<C-z>"
else
Expand Down Expand Up @@ -86,77 +80,12 @@ function! coc#_do_complete(start, items, preselect, changedtick)
\ 'preselect': a:preselect
\}
if mode() =~# 'i'
if s:is_vim
" when the completeopt has longest, the input would be removed sometimes when not use feedkeys!
call feedkeys("\<Plug>CocRefresh", 'i')
else
call coc#_complete()
endif
endif
endfunction

function! coc#_select_confirm() abort
if !exists('*complete_info')
throw 'coc#_select_confirm requires complete_info function to work'
endif
let selected = complete_info()['selected']
if selected != -1
return "\<C-y>"
elseif pumvisible()
return "\<down>\<C-y>"
endif
return ''
endfunction

function! coc#_selected()
if !pumvisible() | return 0 | endif
return coc#rpc#request('hasSelected', [])
endfunction

" Deprecated
function! coc#_hide() abort
if pumvisible()
call feedkeys("\<C-e>", 'in')
call coc#_complete()
endif
endfunction

function! coc#_cancel(...)
" hack for close pum
" Use of <C-e> could cause bad insert when cursor just moved.
let g:coc#_context = {'start': 0, 'preselect': -1,'candidates': []}
if pumvisible()
let g:coc_hide_pum = 1
if get(a:, 1, 0)
" Avoid delayed CompleteDone cancel new completion
let g:coc_disable_complete_done = 1
endif
if s:hide_pum
call feedkeys("\<C-x>\<C-z>", 'in')
else
let g:coc_disable_space_report = 1
call feedkeys("\<space>\<bs>", 'in')
endif
endif
for winid in coc#float#get_float_win_list()
if getwinvar(winid, 'kind', '') ==# 'pum'
call coc#float#close(winid)
endif
endfor
let opt = get(a:, 2, '')
if !empty(opt)
execute 'noa set completeopt='.opt
endif
endfunction

function! coc#_select() abort
if !pumvisible() | return | endif
call feedkeys("\<C-y>", 'in')
endfunction

function! coc#start(...)
let opt = coc#util#get_complete_option()
call CocActionAsync('startCompletion', extend(opt, get(a:, 1, {})))
return ''
call coc#pum#close()
endfunction

" used for statusline
Expand Down Expand Up @@ -217,10 +146,22 @@ function! coc#do_notify(id, method, result)
endif
endfunction

function! coc#start(...)
let opt = coc#util#get_complete_option()
call CocActionAsync('startCompletion', extend(opt, get(a:, 1, {})))
return ''
endfunction

function! coc#refresh() abort
return "\<c-r>=coc#start()\<CR>"
endfunction

function! coc#_select_confirm() abort
call timer_start(10, { -> coc#pum#select_confirm()})
return s:is_vim || has('nvim-0.5.0') ? "\<Ignore>" : "\<space>\<bs>"
endfunction

function! coc#complete_indent() abort
if has('patch-8.2.3100')
return 0
endif
let curpos = getcurpos()
let indent_len = len(matchstr(getline('.'), '^\s*'))
let startofline = &startofline
Expand All @@ -234,11 +175,9 @@ function! coc#complete_indent() abort
let curpos[2] += shift
let curpos[4] += shift
call cursor(curpos[1:])
if shift != 0
if shift != 0
if s:is_vim
doautocmd TextChangedP
call timer_start(0, { -> execute('redraw')})
endif
return 1
endif
return 0
endfunction
Loading

0 comments on commit 7a50d4d

Please sign in to comment.