" vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 : " " apc.vim - auto popup completion window " " Created by skywind on 2020/03/05 " Last Modified: 2022/12/05 21:22 " " Features: " " - auto popup complete window without select the first one " - tab/s-tab to cycle suggestions, to cancel " - use ApcEnable/ApcDisable to toggle for certiain file. " " Usage: " " set cpt=.,k,b " set completeopt=menu,menuone,noselect " let g:apc_enable_ft = {'text':1, 'markdown':1, 'php':1} let g:apc_enable_ft = get(g:, 'apc_enable_ft', {}) " enable filetypes let g:apc_enable_tab = get(g:, 'apc_enable_tab', 1) " remap tab let g:apc_min_length = get(g:, 'apc_min_length', 2) " minimal length to open popup let g:apc_key_ignore = get(g:, 'apc_key_ignore', []) " ignore keywords let g:apc_trigger = get(g:, 'apc_trigger', "\") " which key to trigger popmenu " get word before cursor function! s:get_context() return strpart(getline('.'), 0, col('.') - 1) endfunc function! s:meets_keyword(context) if g:apc_min_length <= 0 return 0 endif let matches = matchlist(a:context, '\(\k\{' . g:apc_min_length . ',}\)$') if empty(matches) return 0 endif for ignore in g:apc_key_ignore if stridx(ignore, matches[1]) == 0 return 0 endif endfor return 1 endfunc function! s:check_back_space() abort return col('.') < 2 || getline('.')[col('.') - 2] =~# '\s' endfunc function! s:on_backspace() if pumvisible() == 0 return "\" endif let text = matchstr(s:get_context(), '.*\ze.') return s:meets_keyword(text)? "\" : "\\" endfunc " autocmd for CursorMovedI function! s:feed_popup() let enable = get(b:, 'apc_enable', 0) let lastx = get(b:, 'apc_lastx', -1) let lasty = get(b:, 'apc_lasty', -1) let tick = get(b:, 'apc_tick', -1) if &bt != '' || enable == 0 || &paste return -1 endif let x = col('.') - 1 let y = line('.') - 1 if pumvisible() let context = s:get_context() if s:meets_keyword(context) == 0 call feedkeys("\", 'n') endif let b:apc_lastx = x let b:apc_lasty = y let b:apc_tick = b:changedtick return 0 elseif lastx == x && lasty == y return -2 elseif b:changedtick == tick let lastx = x let lasty = y return -3 endif let context = s:get_context() if s:meets_keyword(context) silent! call feedkeys(get(b:, 'apc_trigger', g:apc_trigger), 'n') let b:apc_lastx = x let b:apc_lasty = y let b:apc_tick = b:changedtick endif return 0 endfunc " autocmd for CompleteDone function! s:complete_done() let b:apc_lastx = col('.') - 1 let b:apc_lasty = line('.') - 1 let b:apc_tick = b:changedtick endfunc " enable apc function! s:apc_enable() call s:apc_disable() augroup ApcEventGroup au! au CursorMovedI nested call s:feed_popup() au CompleteDone call s:complete_done() augroup END let b:apc_init_autocmd = 1 if g:apc_enable_tab inoremap \ pumvisible()? "\" : \ check_back_space() ? "\" : \ get(b:, 'apc_trigger', g:apc_trigger) inoremap \ pumvisible()? "\" : "\" let b:apc_init_tab = 1 endif if get(g:, 'apc_cr_confirm', 0) == 0 inoremap \ pumvisible()? "\\" : "\" else inoremap \ pumvisible()? "\" : "\" endif inoremap on_backspace() let b:apc_init_bs = 1 let b:apc_init_cr = 1 let b:apc_save_infer = &infercase setlocal infercase let b:apc_enable = 1 endfunc " disable apc function! s:apc_disable() if get(b:, 'apc_init_autocmd', 0) augroup ApcEventGroup au! augroup END endif if get(b:, 'apc_init_tab', 0) silent! iunmap silent! iunmap endif if get(b:, 'apc_init_bs', 0) silent! iunmap endif if get(b:, 'apc_init_cr', 0) silent! iunmap endif if get(b:, 'apc_save_infer', '') != '' let &l:infercase = b:apc_save_infer endif let b:apc_init_autocmd = 0 let b:apc_init_tab = 0 let b:apc_init_bs = 0 let b:apc_init_cr = 0 let b:apc_save_infer = '' let b:apc_enable = 0 endfunc " check if need to be enabled function! s:apc_check_init() if &bt != '' || get(b:, 'apc_enable', 1) == 0 return endif if get(g:apc_enable_ft, &ft, 0) != 0 ApcEnable elseif get(g:apc_enable_ft, '*', 0) != 0 ApcEnable elseif get(b:, 'apc_enable', 0) ApcEnable endif endfunc " commands & autocmd command! -nargs=0 ApcEnable call s:apc_enable() command! -nargs=0 ApcDisable call s:apc_disable() augroup ApcInitGroup au! au FileType * call s:apc_check_init() au BufEnter * call s:apc_check_init() au TabEnter * call s:apc_check_init() augroup END