Possible fix for rare completion-repeat bug

On rare occasions a bug can occur where the user is trying to type text but the
completion system is erasing it as he types. I believe this new approach should
fix that problem. It also replaces the old system for preventing an infinite
loop to occur when there are no completions to show to the user.
This commit is contained in:
Strahinja Val Markovic 2012-08-11 21:20:17 -07:00
parent d793919969
commit de8f45c202

View File

@ -25,6 +25,8 @@ let s:searched_and_no_results_found = 0
let s:should_use_filetype_completion = 0 let s:should_use_filetype_completion = 0
let s:completion_start_column = 0 let s:completion_start_column = 0
let s:omnifunc_mode = 0 let s:omnifunc_mode = 0
let s:old_cursor_position = []
let s:cursor_moved = 0
function! youcompleteme#Enable() function! youcompleteme#Enable()
" When vim is in diff mode, don't run " When vim is in diff mode, don't run
@ -50,6 +52,7 @@ function! youcompleteme#Enable()
autocmd BufRead,BufEnter * call s:OnBufferVisit() autocmd BufRead,BufEnter * call s:OnBufferVisit()
autocmd CursorHold,CursorHoldI * call s:OnCursorHold() autocmd CursorHold,CursorHoldI * call s:OnCursorHold()
autocmd InsertLeave * call s:OnInsertLeave() autocmd InsertLeave * call s:OnInsertLeave()
autocmd InsertEnter * call s:OnInsertEnter()
augroup END augroup END
" We need menuone in completeopt, otherwise when there's only one candidate " We need menuone in completeopt, otherwise when there's only one candidate
@ -127,6 +130,7 @@ endfunction
function! s:OnCursorMovedInsertMode() function! s:OnCursorMovedInsertMode()
call s:UpdateCursorMoved()
call s:IdentifierFinishedOperations() call s:IdentifierFinishedOperations()
call s:ClosePreviewWindowIfNeeded() call s:ClosePreviewWindowIfNeeded()
call s:InvokeCompletion() call s:InvokeCompletion()
@ -146,6 +150,18 @@ function! s:OnInsertLeave()
endfunction endfunction
function! s:OnInsertEnter()
let s:old_cursor_position = []
endfunction
function! s:UpdateCursorMoved()
let current_position = getpos('.')
let s:cursor_moved = current_position != s:old_cursor_position
let s:old_cursor_position = current_position
endfunction
function! s:ClosePreviewWindowIfNeeded() function! s:ClosePreviewWindowIfNeeded()
if !g:ycm_autoclose_preview_window_after_completion if !g:ycm_autoclose_preview_window_after_completion
return return
@ -199,21 +215,12 @@ function! s:InvokeCompletion()
" This is tricky. First, having 'refresh' set to 'always' in the dictionary " This is tricky. First, having 'refresh' set to 'always' in the dictionary
" that our completion function returns makes sure that our completion function " that our completion function returns makes sure that our completion function
" is called on every keystroke when the completion menu is showing " is called on every keystroke. Secondly, when the sequence of characters the user typed produces no
" (pumvisible() == true). So there's no point in invoking the completion menu
" with our feedkeys call then.
" Secondly, when the sequence of characters the user typed produces no
" results in our search an infinite loop can occur. The problem is that our " results in our search an infinite loop can occur. The problem is that our
" feedkeys call triggers the OnCursorMovedI event which we are tied to. " feedkeys call triggers the OnCursorMovedI event which we are tied to.
" So we solve this with the searched_and_no_results_found script-scope " We prevent this infinite loop from starting by making sure that the user has
" variable that prevents this infinite loop from starting. " moved the cursor since the last time we provided completion results.
if pumvisible() || s:searched_and_no_results_found if !s:cursor_moved
" TODO: try a different approach where after we return some completions to
" Vim we don't trigger the feedkeys call UNLESS the user has moved in
" insert/normal mode; this could help with that insidious and impossible to
" reproduce completion-blocking-typing bug; we could implement this by
" storing the last line & column
let s:searched_and_no_results_found = 0
return return
endif endif
@ -264,6 +271,15 @@ function! youcompleteme#Complete( findstart, base )
endif endif
if a:findstart if a:findstart
" InvokeCompletion has this check but we also need it here because of random
" Vim bugs and unfortunate interactions with the autocommands of other
" plugins
if !s:cursor_moved
" for vim, -2 means not found but don't trigger an error message
" see :h complete-functions
return -2
endif
let s:completion_start_column = pyeval( 'ycm.CompletionStartColumn()' ) let s:completion_start_column = pyeval( 'ycm.CompletionStartColumn()' )
let s:should_use_filetype_completion = let s:should_use_filetype_completion =
\ pyeval( 'ycm_state.ShouldUseFiletypeCompleter(' . \ pyeval( 'ycm_state.ShouldUseFiletypeCompleter(' .