最适合我的补全插件

  一个186行代码的代码补全系统,可以根据,历史输入,字典,tags 等多个源提供类似 YouCompleteMe 的补全操作体验,且最重要的是,无需费尽心思地安装各种后端的补全 LSP 服务器。该插件主要利用 Vim 内建补全系统,它能从当前文件收集单词,能从 dict 文件以及 tags 文件收集单词,当按下 <c-n> 或者 <c-x><c-k> 时弹出补全框,或者输入 1-2 个字符的时候为你自动弹出补全窗口用的,并且提供类似 YouComplete 的补全体验(点击查看 GIF 动图):

 

合理使用字典、历史补全能更好的辅助英文写作,主要包括:

  • 自动弹出补全框。
  • 使用 TAB 和 SHIFT+TAB 来循环选择补全内容,<c-e> 关闭补全框。
  • 提供同 YouCompleteMe 完全一致的体验(针对:buffer, dict, tags 几个源)。
  • 纯绿色,所有操作都是对当前 buffer 生效,不会影响其他 buffer。
  • 能够和其他补全系统一起共存(可以设置只对某些文件或者 buffer 生效)。
  • 无需种量级补全服务,无需编译后台 LSP 模块。
  • 轻量级,响应快,比大部分补全系统反应都要灵敏。
  • 只有一个 160 行的 apc.vim 文件,你甚至可以直接把内容拷出来粘贴到你 vimrc 里。
  • 适合作为各种大型补全系统的一个理想备份方案。

如何使用?

只需要这样就行了:

Plug 'skywind3000/vim-auto-popmenu'

" 设定需要生效的文件类型,如果是 "*" 的话,代表所有类型
let g:apc_enable_ft = {'text':1, 'markdown':1, 'php':1}

" 设定从字典文件以及当前打开的文件里收集补全单词,详情看 ':help cpt'
set cpt=.,k,w,b

" 不要自动选中第一个选项。
set completeopt=menu,menuone,noselect

" 禁止在下方显示一些啰嗦的提示
set shortmess+=c

也许你还会需要一个字典插件,为众多语言提供字典数据,还有一份英文单词字典,能在你编写文本文件和 markdown 的时候提供英文单词补全(类似上面的 GIF 截图里的效果):

Plug 'skywind3000/vim-dict'

这就是你所需要的全部了。

常用命令

  • ApcEnable:为当前文档开启补全(比如你没有设置上面的 g:apc_enable_ft 时)。
  • ApcDisable:为当前文档禁用补全

只有上面两条命令,并且只对当前文档生效,不会影响其他文件。

或者将186 行的 apc.vim 脚本,只要放到到 ~/.vim/plugins 目录下面就能自动运行了,或者在 vimrc 最后:

source /path/to/apc.vim

甚至可以把 apc.vim 内容拷贝出来,直接粘贴在你 vimrc 里面也行,本身也没几行。

  1 " vim: set noet fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :
  2 "
  3 " apc.vim - auto popup completion window
  4 "
  5 " Created by skywind on 2020/03/05
  6 " Last Modified: 2021/03/11 08:45
  7 "
  8 " Features:
  9 "
 10 " - auto popup complete window without select the first one
 11 " - tab/s-tab to cycle suggestions, <c-e> to cancel
 12 " - use ApcEnable/ApcDisable to toggle for certiain file.
 13 "
 14 " Usage:
 15 "
 16 " set cpt=.,k,b
 17 " set completeopt=menu,menuone,noselect
 18 " let g:apc_enable_ft = {'text':1, 'markdown':1, 'php':1}
 19 
 20 let g:apc_enable_ft = get(g:, 'apc_enable_ft', {})    " enable filetypes
 21 let g:apc_enable_tab = get(g:, 'apc_enable_tab', 1)   " remap tab
 22 let g:apc_min_length = get(g:, 'apc_min_length', 2)   " minimal length to open popup
 23 let g:apc_key_ignore = get(g:, 'apc_key_ignore', [])  " ignore keywords
 24 
 25 " get word before cursor
 26 function! s:get_context()
 27     return strpart(getline('.'), 0, col('.') - 1)
 28 endfunc
 29 
 30 function! s:meets_keyword(context)
 31     if g:apc_min_length <= 0
 32         return 0
 33     endif
 34     let matches = matchlist(a:context, '\(\k\{' . g:apc_min_length . ',}\)$')
 35     if empty(matches)
 36         return 0
 37     endif
 38     for ignore in g:apc_key_ignore
 39         if stridx(ignore, matches[1]) == 0
 40             return 0
 41         endif
 42     endfor
 43     return 1
 44 endfunc
 45 
 46 function! s:check_back_space() abort
 47       return col('.') < 2 || getline('.')[col('.') - 2]  =~# '\s'
 48 endfunc
 49 
 50 function! s:on_backspace()
 51     if pumvisible() == 0
 52         return "\<BS>"
 53     endif
 54     let text = matchstr(s:get_context(), '.*\ze.')
 55     return s:meets_keyword(text)? "\<BS>" : "\<c-e>\<bs>"
 56 endfunc
 57 
 58 
 59 " autocmd for CursorMovedI
 60 function! s:feed_popup()
 61     let enable = get(b:, 'apc_enable', 0)
 62     let lastx = get(b:, 'apc_lastx', -1)
 63     let lasty = get(b:, 'apc_lasty', -1)
 64     let tick = get(b:, 'apc_tick', -1)
 65     if &bt != '' || enable == 0 || &paste
 66         return -1
 67     endif
 68     let x = col('.') - 1
 69     let y = line('.') - 1
 70     if pumvisible()
 71         let context = s:get_context()
 72         if s:meets_keyword(context) == 0
 73             call feedkeys("\<c-e>", 'n')
 74         endif
 75         let b:apc_lastx = x
 76         let b:apc_lasty = y
 77         let b:apc_tick = b:changedtick
 78         return 0
 79     elseif lastx == x && lasty == y
 80         return -2
 81     elseif b:changedtick == tick
 82         let lastx = x
 83         let lasty = y
 84         return -3
 85     endif
 86     let context = s:get_context()
 87     if s:meets_keyword(context)
 88         silent! call feedkeys("\<c-n>", 'n')
 89         let b:apc_lastx = x
 90         let b:apc_lasty = y
 91         let b:apc_tick = b:changedtick
 92     endif
 93     return 0
 94 endfunc
 95 
 96 " autocmd for CompleteDone
 97 function! s:complete_done()
 98     let b:apc_lastx = col('.') - 1
 99     let b:apc_lasty = line('.') - 1
100     let b:apc_tick = b:changedtick
101 endfunc
102 
103 " enable apc
104 function! s:apc_enable()
105     call s:apc_disable()
106     augroup ApcEventGroup
107         au!
108         au CursorMovedI <buffer> nested call s:feed_popup()
109         au CompleteDone <buffer> call s:complete_done()
110     augroup END
111     let b:apc_init_autocmd = 1
112     if g:apc_enable_tab
113         inoremap <silent><buffer><expr> <tab>
114                     \ pumvisible()? "\<c-n>" :
115                     \ <SID>check_back_space() ? "\<tab>" : "\<c-n>"
116         inoremap <silent><buffer><expr> <s-tab>
117                     \ pumvisible()? "\<c-p>" : "\<s-tab>"
118         let b:apc_init_tab = 1
119     endif
120     if get(g:, 'apc_cr_confirm', 0) == 0
121         inoremap <silent><buffer><expr> <cr>
122                     \ pumvisible()? "\<c-y>\<cr>" : "\<cr>"
123     else
124         inoremap <silent><buffer><expr> <cr>
125                     \ pumvisible()? "\<c-y>" : "\<cr>"
126     endif
127     inoremap <silent><buffer><expr> <bs> <SID>on_backspace()
128     let b:apc_init_bs = 1
129     let b:apc_init_cr = 1
130     let b:apc_save_infer = &infercase
131     setlocal infercase
132     let b:apc_enable = 1
133 endfunc
134 
135 " disable apc
136 function! s:apc_disable()
137     if get(b:, 'apc_init_autocmd', 0)
138         augroup ApcEventGroup
139             au!
140         augroup END
141     endif
142     if get(b:, 'apc_init_tab', 0)
143         silent! iunmap <buffer><expr> <tab>
144         silent! iunmap <buffer><expr> <s-tab>
145     endif
146     if get(b:, 'apc_init_bs', 0)
147         silent! iunmap <buffer><expr> <bs>
148     endif
149     if get(b:, 'apc_init_cr', 0)
150         silent! iunmap <buffer><expr> <cr>
151     endif
152     if get(b:, 'apc_save_infer', '') != ''
153         let &l:infercase = b:apc_save_infer
154     endif
155     let b:apc_init_autocmd = 0
156     let b:apc_init_tab = 0
157     let b:apc_init_bs = 0
158     let b:apc_init_cr = 0
159     let b:apc_save_infer = ''
160     let b:apc_enable = 0
161 endfunc
162 
163 " check if need to be enabled
164 function! s:apc_check_init()
165     if &bt != ''
166         return
167     endif
168     if get(g:apc_enable_ft, &ft, 0) != 0
169         ApcEnable
170     elseif get(g:apc_enable_ft, '*', 0) != 0
171         ApcEnable
172     elseif get(b:, 'apc_enable', 0)
173         ApcEnable
174     endif
175 endfunc
176 
177 " commands & autocmd
178 command! -nargs=0 ApcEnable call s:apc_enable()
179 command! -nargs=0 ApcDisable call s:apc_disable()
180 
181 augroup ApcInitGroup
182     au!
183     au FileType * call s:apc_check_init()
184     au BufEnter * call s:apc_check_init()
185     au TabEnter * call s:apc_check_init()
186 augroup END

 

地址: 

 
下载git clone https://github.com/skywind3000/vim-auto-popmenu.git,插件就可以使用了
 
posted @ 2022-02-05 11:24  叕叒双又  阅读(286)  评论(0编辑  收藏  举报