I broke up with neovim....vim is my best friend now
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
" Find a nearest to a `path` parent directory `directoryname` by traversing the
|
||||
" filesystem upwards
|
||||
function! asyncomplete#utils#find_nearest_parent_directory(path, directoryname) abort
|
||||
let l:relative_path = finddir(a:directoryname, a:path . ';')
|
||||
|
||||
if !empty(l:relative_path)
|
||||
return fnamemodify(l:relative_path, ':p')
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
endfunction
|
||||
|
||||
if exists('*matchstrpos')
|
||||
function! asyncomplete#utils#matchstrpos(expr, pattern) abort
|
||||
return matchstrpos(a:expr, a:pattern)
|
||||
endfunction
|
||||
else
|
||||
function! asyncomplete#utils#matchstrpos(expr, pattern) abort
|
||||
return [matchstr(a:expr, a:pattern), match(a:expr, a:pattern), matchend(a:expr, a:pattern)]
|
||||
endfunction
|
||||
endif
|
||||
@@ -0,0 +1,81 @@
|
||||
let s:callbacks = []
|
||||
|
||||
function! asyncomplete#utils#_on_change#textchangedp#init() abort
|
||||
if exists('##TextChangedP')
|
||||
call s:setup_if_required()
|
||||
return {
|
||||
\ 'name': 'TextChangedP',
|
||||
\ 'register': function('s:register'),
|
||||
\ 'unregister': function('s:unregister'),
|
||||
\ }
|
||||
else
|
||||
return { 'name': 'TextChangedP', 'error': 'Requires vim with TextChangedP support' }
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:setup_if_required() abort
|
||||
augroup asyncomplete_utils_on_change_text_changed_p
|
||||
autocmd!
|
||||
autocmd InsertEnter * call s:on_insert_enter()
|
||||
autocmd InsertLeave * call s:on_insert_leave()
|
||||
autocmd TextChangedI * call s:on_text_changed_i()
|
||||
autocmd TextChangedP * call s:on_text_changed_p()
|
||||
augroup END
|
||||
endfunction
|
||||
|
||||
function! s:register(cb) abort
|
||||
call add(s:callbacks , a:cb)
|
||||
endfunction
|
||||
|
||||
function! s:unregister(obj, cb) abort
|
||||
" TODO: remove from s:callbacks
|
||||
endfunction
|
||||
|
||||
function! s:on_insert_enter() abort
|
||||
let l:context = asyncomplete#context()
|
||||
let s:previous_context = {
|
||||
\ 'lnum': l:context['lnum'],
|
||||
\ 'col': l:context['col'],
|
||||
\ 'typed': l:context['typed'],
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! s:on_insert_leave() abort
|
||||
unlet! s:previous_context
|
||||
endfunction
|
||||
|
||||
function! s:on_text_changed_i() abort
|
||||
call s:maybe_notify_on_change()
|
||||
endfunction
|
||||
|
||||
function! s:on_text_changed_p() abort
|
||||
call s:maybe_notify_on_change()
|
||||
endfunction
|
||||
|
||||
function! s:maybe_notify_on_change() abort
|
||||
if !exists('s:previous_context')
|
||||
return
|
||||
endif
|
||||
" We notify on_change callbacks only when the cursor position
|
||||
" has changed.
|
||||
" Unfortunatelly we need this check because in insert mode it
|
||||
" is possible to have TextChangedI triggered when the completion
|
||||
" context is not changed at all: When we close the completion
|
||||
" popup menu via <C-e> or <C-y>. If we still let on_change
|
||||
" do the completion in this case we never close the menu.
|
||||
" Vim doesn't allow programmatically changing buffer content
|
||||
" in insert mode, so by comparing the cursor's position and the
|
||||
" completion base we know whether the context has changed.
|
||||
let l:context = asyncomplete#context()
|
||||
let l:previous_context = s:previous_context
|
||||
let s:previous_context = {
|
||||
\ 'lnum': l:context['lnum'],
|
||||
\ 'col': l:context['col'],
|
||||
\ 'typed': l:context['typed'],
|
||||
\ }
|
||||
if l:previous_context !=# s:previous_context
|
||||
for l:Cb in s:callbacks
|
||||
call l:Cb()
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
@@ -0,0 +1,83 @@
|
||||
let s:callbacks = []
|
||||
|
||||
let s:change_timer = -1
|
||||
let s:last_tick = []
|
||||
|
||||
function! asyncomplete#utils#_on_change#timer#init() abort
|
||||
call s:setup_if_required()
|
||||
return {
|
||||
\ 'name': 'timer',
|
||||
\ 'register': function('s:register'),
|
||||
\ 'unregister': function('s:unregister'),
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! s:setup_if_required() abort
|
||||
augroup asyncomplete_utils_on_change_timer
|
||||
autocmd!
|
||||
autocmd InsertEnter * call s:on_insert_enter()
|
||||
autocmd InsertLeave * call s:on_insert_leave()
|
||||
autocmd TextChangedI * call s:on_text_changed_i()
|
||||
augroup END
|
||||
endfunction
|
||||
|
||||
function! s:register(cb) abort
|
||||
call add(s:callbacks , a:cb)
|
||||
endfunction
|
||||
|
||||
function! s:unregister(obj, cb) abort
|
||||
" TODO: remove from s:callbacks
|
||||
endfunction
|
||||
|
||||
function! s:on_insert_enter() abort
|
||||
let s:previous_position = getcurpos()
|
||||
call s:change_tick_start()
|
||||
endfunction
|
||||
|
||||
function! s:on_insert_leave() abort
|
||||
unlet s:previous_position
|
||||
call s:change_tick_stop()
|
||||
endfunction
|
||||
|
||||
function! s:on_text_changed_i() abort
|
||||
call s:check_changes()
|
||||
endfunction
|
||||
|
||||
function! s:change_tick_start() abort
|
||||
if !exists('s:change_timer')
|
||||
let s:last_tick = s:change_tick()
|
||||
" changes every 30ms, which is 0.03s, it should be fast enough
|
||||
let s:change_timer = timer_start(30, function('s:check_changes'), { 'repeat': -1 })
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:change_tick_stop() abort
|
||||
if exists('s:change_timer')
|
||||
call timer_stop(s:change_timer)
|
||||
unlet s:change_timer
|
||||
let s:last_tick = []
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:check_changes(...) abort
|
||||
let l:tick = s:change_tick()
|
||||
if l:tick != s:last_tick
|
||||
let s:last_tick = l:tick
|
||||
call s:maybe_notify_on_change()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:maybe_notify_on_change() abort
|
||||
" enter to new line or backspace to previous line shouldn't cause change trigger
|
||||
let l:previous_position = s:previous_position
|
||||
let s:previous_position = getcurpos()
|
||||
if l:previous_position[1] ==# getcurpos()[1]
|
||||
for l:Cb in s:callbacks
|
||||
call l:Cb()
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:change_tick() abort
|
||||
return [b:changedtick, getcurpos()]
|
||||
endfunction
|
||||
Reference in New Issue
Block a user