mirror of
https://github.com/prabirshrestha/asyncomplete.vim.git
synced 2025-12-14 20:35:41 +01:00
initial commit
* forked off from https://github.com/maralla/completor.vim d475b42c92a000ff9eeb6b4b311eb06f457e71a3
This commit is contained in:
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto
|
||||
27
README.md
Normal file
27
README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
asyncomplete.vim (exprimental)
|
||||
==============================
|
||||
|
||||
Provide async autocompletion for vim8 with `lambda` and `timers`.
|
||||
This should work in Neovim once [lambda support](https://github.com/neovim/neovim/pull/5771) is merged in master.
|
||||
This repository is fork of [https://github.com/maralla/completor.vim](https://github.com/maralla/completor.vim) in pure vim script with python dependency removed.
|
||||
|
||||
**Do not depend on this repository. This is me trying out async completion in vim so I will be pushing random things that may break**
|
||||
|
||||
### Installing
|
||||
|
||||
```viml
|
||||
Plug 'prabirshrestha/asyncomplete.vim'
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
```viml
|
||||
function! s:js_completor(args)
|
||||
call timer_start(2000, {t->a:args.done([{'word': 'class'}, {'word': 'function'}, {'word': 'value'}])})
|
||||
endfunction
|
||||
|
||||
call asyncomplete#register('javascript', ['.', ' '], function('s:js_completor'))
|
||||
```
|
||||
|
||||
### Credits
|
||||
All the credit goes to [https://github.com/maralla/completor.vim](https://github.com/maralla/completor.vim)
|
||||
149
autoload/asyncomplete.vim
Normal file
149
autoload/asyncomplete.vim
Normal file
@@ -0,0 +1,149 @@
|
||||
let s:char_inserted = v:false
|
||||
let s:completions = {'words': [], 'refresh': 'always'}
|
||||
let s:status = {'pos': [], 'nr': -1, 'input': '', 'ft': ''}
|
||||
let s:completors = {}
|
||||
|
||||
function! s:completions.set(comps) abort
|
||||
let self.words = a:comps
|
||||
endfunction
|
||||
|
||||
function! s:completions.clear() abort
|
||||
let self.words = []
|
||||
endfunction
|
||||
|
||||
function! s:completions.empty() abort
|
||||
return empty(self.words)
|
||||
endfunction
|
||||
|
||||
function! s:get_start_column(findstart, findbase, triggers)
|
||||
let l:line_string = getline('.')
|
||||
let l:line = line('.')
|
||||
let l:col = col('.')
|
||||
let l:start = l:col - 1
|
||||
while l:start > 0
|
||||
let l:char = l:line_string[l:start - 1]
|
||||
for l:trigger_char in a:triggers
|
||||
if l:char == l:trigger_char
|
||||
return l:start
|
||||
endif
|
||||
endfor
|
||||
let l:start -= 1
|
||||
endwhile
|
||||
return l:start
|
||||
endfunction
|
||||
|
||||
function! asyncomplete#completefunc(findstart, findbase)
|
||||
if a:findstart
|
||||
if s:completions.empty()
|
||||
return -3
|
||||
endif
|
||||
if has_key(s:completors, s:status.ft) && has_key(s:completors[s:status.ft], 'triggers')
|
||||
return s:get_start_column(a:findstart, a:findbase, s:completors[s:status.ft].triggers)
|
||||
else
|
||||
return -3
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:completions = copy(s:completions)
|
||||
call s:completions.clear()
|
||||
let l:results = []
|
||||
for l:item in l:completions.words
|
||||
if l:item.word =~ '^' . a:findbase
|
||||
call add(l:results, l:item)
|
||||
endif
|
||||
endfor
|
||||
return l:results
|
||||
endfunction
|
||||
|
||||
function! s:consistent() abort
|
||||
return s:status.nr == bufnr('') && s:status.pos == getcurpos() && s:status.ft == &ft
|
||||
endfunction
|
||||
|
||||
function! s:trigger(items) abort
|
||||
if !s:consistent()
|
||||
call s:completions.clear()
|
||||
else
|
||||
call s:completions.set(a:items)
|
||||
endif
|
||||
if s:completions.empty() | return | endif
|
||||
setlocal completefunc=asyncomplete#completefunc
|
||||
setlocal completeopt-=longest
|
||||
setlocal completeopt+=menuone
|
||||
setlocal completeopt-=menu
|
||||
if &completeopt !~# 'noinsert\|noselect'
|
||||
setlocal completeopt+=noselect
|
||||
endif
|
||||
call feedkeys("\<C-x>\<C-u>\<C-p>", 'n')
|
||||
endfunction
|
||||
|
||||
function! s:reset() abort
|
||||
call s:completions.clear()
|
||||
endfunction
|
||||
|
||||
function! s:complete() abort
|
||||
call s:reset()
|
||||
if !s:consistent() | return | endif
|
||||
|
||||
if has_key(s:completors, s:status.ft)
|
||||
call s:completors[s:status.ft].completor({'info': s:status, 'done': {items->s:trigger(items)}})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:skip() abort
|
||||
let l:buftype = &buftype
|
||||
let l:skip = empty(&ft) || buftype == 'nofile' || buftype == 'quickfix'
|
||||
return l:skip || !s:char_inserted
|
||||
endfunction
|
||||
|
||||
function! s:on_text_change() abort
|
||||
if s:skip() | return | endif
|
||||
let s:char_inserted = v:false
|
||||
|
||||
if exists('s:timer')
|
||||
let l:info = timer_info(s:timer)
|
||||
if !empty(l:info)
|
||||
call timer_stop(s:timer)
|
||||
endif
|
||||
endif
|
||||
|
||||
let e = col('.') - 2
|
||||
let inputted = e >= 0 ? getline('.')[:e] : ''
|
||||
|
||||
let s:status = {'input':inputted, 'pos': getcurpos(), 'nr': bufnr(''), 'ft': &ft}
|
||||
let s:timer = timer_start(g:asyncomplete_completion_delay, {t->s:complete()})
|
||||
endfunction
|
||||
|
||||
function! s:on_insert_char_pre() abort
|
||||
let s:char_inserted = v:true
|
||||
endfunction
|
||||
|
||||
function! s:set_events() abort
|
||||
augroup asyncomplete
|
||||
autocmd!
|
||||
autocmd TextChangedI * call s:on_text_change()
|
||||
autocmd InsertCharPre * call s:on_insert_char_pre()
|
||||
augroup END
|
||||
endfunction
|
||||
|
||||
" public apis {{{
|
||||
|
||||
function! asyncomplete#enable() abort
|
||||
" remove this check when nvim supports lambda
|
||||
if !has('nvim')
|
||||
call s:set_events()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! asyncomplete#disable() abort
|
||||
autocmd! asyncomplete
|
||||
endfunction
|
||||
|
||||
function! asyncomplete#register(filetype, triggers, completor) abort
|
||||
let s:completors[a:filetype] = { 'triggers': a:triggers, 'completor': a:completor }
|
||||
endfunction
|
||||
|
||||
function! asyncomplete#unregister(filetype) abort
|
||||
call remove(s:completors, a:filetype)
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
11
plugin/asyncomplete.vim
Normal file
11
plugin/asyncomplete.vim
Normal file
@@ -0,0 +1,11 @@
|
||||
if exists('g:asyncomplete_loaded')
|
||||
finish
|
||||
endif
|
||||
let g:asyncomplete_loaded = 1
|
||||
let g:asyncomplete_completion_delay = get(g:, 'asyncomplete_completion_delay', 80)
|
||||
|
||||
augroup asyncomplete
|
||||
autocmd!
|
||||
autocmd InsertEnter * call asyncomplete#enable()
|
||||
augroup END
|
||||
|
||||
Reference in New Issue
Block a user