All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
4 Async autocompletion for Vim 8 and Neovim with |timers|.
6 This is inspired by [nvim-complete-manager](https://github.com/roxma/nvim-complete-manager) but written
12 Plug 'prabirshrestha/asyncomplete.vim'
18 inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
19 inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
20 inoremap <expr> <cr> pumvisible() ? asyncomplete#close_popup() : "\<cr>"
23 If you prefer the enter key to always insert a new line (even if the popup menu is visible) then
24 you can amend the above mapping as follows:
27 inoremap <expr> <cr> pumvisible() ? asyncomplete#close_popup() . "\<cr>" : "\<cr>"
30 ### Force refresh completion
33 imap <c-space> <Plug>(asyncomplete_force_refresh)
34 " For Vim 8 (<c-@> corresponds to <c-space>):
35 " imap <c-@> <Plug>(asyncomplete_force_refresh)
39 By default asyncomplete will automatically show the autocomplete popup menu as you start typing.
40 If you would like to disable the default behavior set `g:asyncomplete_auto_popup` to 0.
43 let g:asyncomplete_auto_popup = 0
46 You can use the above `<Plug>(asyncomplete_force_refresh)` to show the popup
47 or you can tab to show the autocomplete.
50 let g:asyncomplete_auto_popup = 0
52 function! s:check_back_space() abort
53 let col = col('.') - 1
54 return !col || getline('.')[col - 1] =~ '\s'
57 inoremap <silent><expr> <TAB>
58 \ pumvisible() ? "\<C-n>" :
59 \ <SID>check_back_space() ? "\<TAB>" :
60 \ asyncomplete#force_refresh()
61 inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
66 To enable preview window:
69 " allow modifying the completeopt variable, or it will
70 " be overridden all the time
71 let g:asyncomplete_auto_completeopt = 0
73 set completeopt=menuone,noinsert,noselect,preview
76 To auto close preview window when completion is done.
79 autocmd! CompleteDone * if pumvisible() == 0 | pclose | endif
84 asyncomplete.vim deliberately does not contain any sources. Please use one of the following sources or create your own.
86 #### Language Server Protocol (LSP)
87 [Language Server Protocol](https://github.com/Microsoft/language-server-protocol) via [vim-lsp](https://github.com/prabirshrestha/vim-lsp) and [asyncomplete-lsp.vim](https://github.com/prabirshrestha/asyncomplete-lsp.vim)
89 **Please note** that vim-lsp setup for neovim requires neovim v0.2.0 or higher, since it uses lambda setup.
92 Plug 'prabirshrestha/asyncomplete.vim'
93 Plug 'prabirshrestha/vim-lsp'
94 Plug 'prabirshrestha/asyncomplete-lsp.vim'
97 " pip install python-language-server
98 au User lsp_setup call lsp#register_server({
100 \ 'cmd': {server_info->['pyls']},
101 \ 'allowlist': ['python'],
106 **Refer to [vim-lsp wiki](https://github.com/prabirshrestha/vim-lsp/wiki/Servers) for configuring other language servers.** Besides auto-complete language server support other features such as go to definition, find references, renaming symbols, document symbols, find workspace symbols, formatting and so on.
108 *in alphabetical order*
110 | Languages/FileType/Source | Links |
111 |-------------------------------|----------------------------------------------------------------------------------------------------|
112 | [Ale][ale] | [asyncomplete-ale.vim](https://github.com/andreypopp/asyncomplete-ale.vim) |
113 | Buffer | [asyncomplete-buffer.vim](https://github.com/prabirshrestha/asyncomplete-buffer.vim) |
114 | C/C++ | [asyncomplete-clang.vim](https://github.com/keremc/asyncomplete-clang.vim) |
115 | Clojure | [async-clj-omni](https://github.com/clojure-vim/async-clj-omni) |
116 | Common Lisp (vlime) | [vlime](https://github.com/vlime/vlime) |
117 | Dictionary (look) | [asyncomplete-look](https://github.com/htlsne/asyncomplete-look) |
118 | [Emmet][emmet-vim] | [asyncomplete-emmet.vim](https://github.com/prabirshrestha/asyncomplete-emmet.vim) |
119 | English | [asyncomplete-nextword.vim](https://github.com/high-moctane/asyncomplete-nextword.vim) |
120 | Emoji | [asyncomplete-emoji.vim](https://github.com/prabirshrestha/asyncomplete-emoji.vim) |
121 | Filenames / directories | [asyncomplete-file.vim](https://github.com/prabirshrestha/asyncomplete-file.vim) |
122 | [NeoInclude][neoinclude] | [asyncomplete-neoinclude.vim](https://github.com/kyouryuukunn/asyncomplete-neoinclude.vim) |
123 | Go | [asyncomplete-gocode.vim](https://github.com/prabirshrestha/asyncomplete-gocode.vim) |
124 | Git commit message | [asyncomplete-gitcommit](https://github.com/laixintao/asyncomplete-gitcommit) |
125 | JavaScript (Flow) | [asyncomplete-flow.vim](https://github.com/prabirshrestha/asyncomplete-flow.vim) |
126 | [Neosnippet][neosnippet] | [asyncomplete-neosnippet.vim](https://github.com/prabirshrestha/asyncomplete-neosnippet.vim) |
127 | Omni | [asyncomplete-omni.vim](https://github.com/yami-beta/asyncomplete-omni.vim) |
128 | PivotalTracker stories | [asyncomplete-pivotaltracker.vim](https://github.com/hauleth/asyncomplete-pivotaltracker.vim) |
129 | Rust (racer) | [asyncomplete-racer.vim](https://github.com/keremc/asyncomplete-racer.vim) |
130 | [TabNine][TabNine] powered by AI | [asyncomplete-tabnine.vim](https://github.com/kitagry/asyncomplete-tabnine.vim) |
131 | [tmux complete][tmuxcomplete] | [tmux-complete.vim][tmuxcomplete] |
132 | Typescript | [asyncomplete-tscompletejob.vim](https://github.com/prabirshrestha/asyncomplete-tscompletejob.vim) |
133 | [UltiSnips][ultisnips] | [asyncomplete-ultisnips.vim](https://github.com/prabirshrestha/asyncomplete-ultisnips.vim) |
134 | User (compl-function) | [asyncomplete-user.vim](https://github.com/jsit/asyncomplete-user.vim) |
135 | Vim Syntax | [asyncomplete-necosyntax.vim](https://github.com/prabirshrestha/asyncomplete-necosyntax.vim) |
136 | Vim tags | [asyncomplete-tags.vim](https://github.com/prabirshrestha/asyncomplete-tags.vim) |
137 | Vim | [asyncomplete-necovim.vim](https://github.com/prabirshrestha/asyncomplete-necovim.vim) |
139 [ale]: https://github.com/dense-analysis/ale
140 [emmet-vim]: https://github.com/mattn/emmet-vim
141 [neosnippet]: https://github.com/Shougo/neosnippet.vim
142 [neoinclude]: https://github.com/Shougo/neoinclude.vim
143 [TabNine]: https://www.tabnine.com/
144 [tmuxcomplete]: https://github.com/wellle/tmux-complete.vim
145 [ultisnips]: https://github.com/SirVer/ultisnips
147 *can't find what you are looking for? write one instead an send a PR to be included here or search github topics tagged with asyncomplete at https://github.com/topics/asyncomplete.*
149 #### Using existing vim plugin sources
151 Rather than writing your own completion source from scratch you could also suggests other plugin authors to provide a async completion api that works for asyncomplete.vim or any other async autocomplete libraries without taking a dependency on asyncomplete.vim. The plugin can provide a function that takes a callback which returns the list of candidates and the startcol from where it must show the popup. Candidates can be list of words or vim's `complete-items`.
154 function s:completor(opt, ctx)
155 call mylanguage#get_async_completions({candidates, startcol -> asyncomplete#complete(a:opt['name'], a:ctx, startcol, candidates) })
158 au User asyncomplete_setup call asyncomplete#register_source({
159 \ 'name': 'mylanguage',
160 \ 'allowlist': ['*'],
161 \ 'completor': function('s:completor'),
168 function! s:js_completor(opt, ctx) abort
169 let l:col = a:ctx['col']
170 let l:typed = a:ctx['typed']
172 let l:kw = matchstr(l:typed, '\v\S+$')
173 let l:kwlen = len(l:kw)
175 let l:startcol = l:col - l:kwlen
178 \ "do", "if", "in", "for", "let", "new", "try", "var", "case", "else", "enum", "eval", "null", "this", "true",
179 \ "void", "with", "await", "break", "catch", "class", "const", "false", "super", "throw", "while", "yield",
180 \ "delete", "export", "import", "public", "return", "static", "switch", "typeof", "default", "extends",
181 \ "finally", "package", "private", "continue", "debugger", "function", "arguments", "interface", "protected",
182 \ "implements", "instanceof"
185 call asyncomplete#complete(a:opt['name'], a:ctx, l:startcol, l:matches)
188 au User asyncomplete_setup call asyncomplete#register_source({
189 \ 'name': 'javascript',
190 \ 'allowlist': ['javascript'],
191 \ 'completor': function('s:js_completor'),
195 The above sample shows synchronous completion. If you would like to make it async just call `asyncomplete#complete` whenever you have the results ready.
198 call timer_start(2000, {timer-> asyncomplete#complete(a:opt['name'], a:ctx, l:startcol, l:matches)})
201 If you are returning incomplete results and would like to trigger completion on the next keypress pass `1` as the fifth parameter to `asyncomplete#complete`
202 which signifies the result is incomplete.
205 call asyncomplete#complete(a:opt['name'], a:ctx, l:startcol, l:matches, 1)
208 As a source author you do not have to worry about synchronization issues in case the server returns the async completion after the user has typed more
209 characters. asyncomplete.vim uses partial caching as well as ignores if the context changes when calling `asyncomplete#complete`.
210 This is one of the core reason why the original context must be passed when calling `asyncomplete#complete`.
213 All the credit goes to the following projects
214 * [https://github.com/roxma/nvim-complete-manager](https://github.com/roxma/nvim-complete-manager)
215 * [https://github.com/maralla/completor.vim](https://github.com/maralla/completor.vim)
219 ### Code Contributors
221 This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
222 <a href="https://github.com/prabirshrestha/asyncomplete.vim/graphs/contributors"><img src="https://opencollective.com/asyncomplete/contributors.svg?width=890&button=false" /></a>
224 ### Financial Contributors
226 Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/asyncomplete/contribute)]
230 <a href="https://opencollective.com/asyncomplete"><img src="https://opencollective.com/asyncomplete/individuals.svg?width=890"></a>
234 Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/asyncomplete/contribute)]
236 <a href="https://opencollective.com/asyncomplete/organization/0/website"><img src="https://opencollective.com/asyncomplete/organization/0/avatar.svg"></a>
237 <a href="https://opencollective.com/asyncomplete/organization/1/website"><img src="https://opencollective.com/asyncomplete/organization/1/avatar.svg"></a>
238 <a href="https://opencollective.com/asyncomplete/organization/2/website"><img src="https://opencollective.com/asyncomplete/organization/2/avatar.svg"></a>
239 <a href="https://opencollective.com/asyncomplete/organization/3/website"><img src="https://opencollective.com/asyncomplete/organization/3/avatar.svg"></a>
240 <a href="https://opencollective.com/asyncomplete/organization/4/website"><img src="https://opencollective.com/asyncomplete/organization/4/avatar.svg"></a>
241 <a href="https://opencollective.com/asyncomplete/organization/5/website"><img src="https://opencollective.com/asyncomplete/organization/5/avatar.svg"></a>
242 <a href="https://opencollective.com/asyncomplete/organization/6/website"><img src="https://opencollective.com/asyncomplete/organization/6/avatar.svg"></a>
243 <a href="https://opencollective.com/asyncomplete/organization/7/website"><img src="https://opencollective.com/asyncomplete/organization/7/avatar.svg"></a>
244 <a href="https://opencollective.com/asyncomplete/organization/8/website"><img src="https://opencollective.com/asyncomplete/organization/8/avatar.svg"></a>
245 <a href="https://opencollective.com/asyncomplete/organization/9/website"><img src="https://opencollective.com/asyncomplete/organization/9/avatar.svg"></a>