Auto merge of #2547 - micbou:server-becomes-ready, r=vheon

[RFC] Send requests again when server becomes ready

Since PR #2517, the `BufferVisit` and `FileReadyToParse` requests are ignored until the server is ready. We need to send them again when it becomes ready so that identifiers and snippets for the current buffer are properly parsed. This is done in the `s:OnFileReadyToParse` function since this function is regularly called. We also try to set the omnifunc since it depends on a response from the server and is only set when entering a buffer or changing its filetype. This replaces the code that consisted of setting the omnifunc when entering insert mode for the first time.

A cleaner solution would be to do that asynchronously but we can't with our Vim version requirement.

Fixes #2541.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2547)
<!-- Reviewable:end -->
This commit is contained in:
Homu 2017-02-19 10:13:08 +09:00
commit 164165f0c8
2 changed files with 31 additions and 29 deletions

View File

@ -22,7 +22,6 @@ set cpo&vim
" This needs to be called outside of a function
let s:script_folder_path = escape( expand( '<sfile>:p:h' ), '\' )
let s:omnifunc_mode = 0
let s:defer_omnifunc = 1
let s:old_cursor_position = []
let s:cursor_moved = 0
@ -98,19 +97,6 @@ function! youcompleteme#Enable()
autocmd CompleteDone * call s:OnCompleteDone()
augroup END
" Setting the omnifunc require us to ask the server if it has a Native
" Semantic Completer for the current buffer's filetype. When vim first start
" this mean that we have to wait for the server to be up and running which
" would block vim's GUI. To avoid this we defer setting the omnifunc the
" first time to when we enter Insert mode and then update it on every
" BufferVisit as normal.
if s:defer_omnifunc
augroup ycm_defer_omnifunc
autocmd!
autocmd InsertEnter * call s:DeferredUntilInsertEnter()
augroup END
endif
" Calling this once solves the problem of BufRead/BufEnter not triggering for
" the first loaded file. This should be the last command executed in this
" function!
@ -118,16 +104,6 @@ function! youcompleteme#Enable()
endfunction
function s:DeferredUntilInsertEnter()
let s:defer_omnifunc = 0
autocmd! ycm_defer_omnifunc
if s:AllowedToCompleteInCurrentBuffer()
call s:SetOmnicompleteFunc()
endif
endfunction
function! youcompleteme#EnableCursorMovedAutocommands()
augroup ycmcompletemecursormove
autocmd!
@ -470,10 +446,7 @@ function! s:OnBufferRead()
call s:SetUpCompleteopt()
call s:SetCompleteFunc()
if !s:defer_omnifunc
call s:SetOmnicompleteFunc()
endif
call s:SetOmnicompleteFunc()
exec s:python_command "ycm_state.OnBufferVisit()"
call s:OnFileReadyToParse()
@ -514,6 +487,19 @@ endfunction
function! s:OnFileReadyToParse()
if s:Pyeval( 'ycm_state.ServerBecomesReady()' )
" Server was not ready until now and could not parse previous requests for
" the current buffer. We need to send them again.
exec s:python_command "ycm_state.OnBufferVisit()"
exec s:python_command "ycm_state.OnFileReadyToParse()"
" Setting the omnifunc requires us to ask the server if it has a native
" semantic completer for the current buffer's filetype. Since we only set it
" when entering a buffer or changing the filetype, we try to set it again
" now that the server is ready.
call s:SetOmnicompleteFunc()
return
endif
" We need to call this just in case there is no b:ycm_changetick; this can
" happen for special buffers.
call s:SetUpYcmChangedTick()
@ -610,6 +596,8 @@ function! s:OnInsertEnter()
endif
let s:old_cursor_position = []
call s:OnFileReadyToParse()
endfunction

View File

@ -127,6 +127,7 @@ class YouCompleteMe( object ):
self._server_popen = None
self._filetypes_with_keywords_loaded = set()
self._ycmd_keepalive = YcmdKeepalive()
self._server_is_ready_with_cache = False
self._SetupLogging()
self._SetupServer()
self._ycmd_keepalive.Start()
@ -137,6 +138,9 @@ class YouCompleteMe( object ):
def _SetupServer( self ):
self._available_completers = {}
self._user_notified_about_crash = False
self._filetypes_with_keywords_loaded = set()
self._server_is_ready_with_cache = False
server_port = utils.GetUnusedLocalhostPort()
# The temp options file is deleted by ycmd during startup
with NamedTemporaryFile( delete = False, mode = 'w+' ) as options_file:
@ -339,6 +343,15 @@ class YouCompleteMe( object ):
self.NativeFiletypeCompletionAvailable() )
def ServerBecomesReady( self ):
if not self._server_is_ready_with_cache:
with HandleServerException( display = False ):
self._server_is_ready_with_cache = BaseRequest.GetDataFromHandler(
'ready' )
return self._server_is_ready_with_cache
return False
def OnFileReadyToParse( self ):
if not self.IsServerAlive():
self._NotifyUserIfServerCrashed()
@ -720,7 +733,8 @@ class YouCompleteMe( object ):
if filetype in self._filetypes_with_keywords_loaded:
return
self._filetypes_with_keywords_loaded.add( filetype )
if self._server_is_ready_with_cache:
self._filetypes_with_keywords_loaded.add( filetype )
extra_data[ 'syntax_keywords' ] = list(
syntax_parse.SyntaxKeywordsForCurrentBuffer() )