Better handling of crashed ycmd; restart command
Previously the YCM Vim client would go bonkers when ycmd crashed. Now the user can continue using Vim just without YCM functionality. Also added a :YcmRestartServer command to let the user restart ycmd if it crashed. With a little luck, this will be rarely necessary.
This commit is contained in:
parent
436017bd4d
commit
18002e17df
@ -566,7 +566,11 @@ function! youcompleteme#Complete( findstart, base )
|
||||
return -2
|
||||
endif
|
||||
|
||||
return pyeval( 'ycm_state.CreateCompletionRequest().CompletionStartColumn()' )
|
||||
py request = ycm_state.CreateCompletionRequest()
|
||||
if !pyeval( 'bool(request)' )
|
||||
return -2
|
||||
endif
|
||||
return pyeval( 'request.CompletionStartColumn()' )
|
||||
else
|
||||
return s:CompletionsForQuery( a:base )
|
||||
endif
|
||||
@ -584,6 +588,13 @@ function! youcompleteme#OmniComplete( findstart, base )
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:RestartServer()
|
||||
py ycm_state.RestartServer()
|
||||
endfunction
|
||||
|
||||
command! YcmRestartServer call s:RestartServer()
|
||||
|
||||
|
||||
function! s:ShowDetailedDiagnostic()
|
||||
py ycm_state.ShowDetailedDiagnostic()
|
||||
endfunction
|
||||
|
@ -198,6 +198,7 @@ def _GetCompleterForRequestData( request_data ):
|
||||
|
||||
@atexit.register
|
||||
def _ServerShutdown():
|
||||
LOGGER.info( 'Server shutting down' )
|
||||
if SERVER_STATE:
|
||||
SERVER_STATE.Shutdown()
|
||||
extra_conf_store.Shutdown()
|
||||
|
@ -88,12 +88,18 @@ class YouCompleteMe( object ):
|
||||
self._server_popen = subprocess.Popen( args,
|
||||
stdout = fstdout,
|
||||
stderr = fstderr )
|
||||
self._CheckIfServerCrashed()
|
||||
self._NotifyUserIfServerCrashed()
|
||||
|
||||
|
||||
def _CheckIfServerCrashed( self ):
|
||||
server_crashed = self._server_popen.poll()
|
||||
if server_crashed:
|
||||
def _IsServerAlive( self ):
|
||||
returncode = self._server_popen.poll()
|
||||
# When the process hasn't finished yet, poll() returns None.
|
||||
return returncode is None
|
||||
|
||||
|
||||
def _NotifyUserIfServerCrashed( self ):
|
||||
if self._IsServerAlive():
|
||||
return
|
||||
if self._server_stderr:
|
||||
with open( self._server_stderr, 'r' ) as server_stderr_file:
|
||||
vimsupport.PostMultiLineNotice( SERVER_CRASH_MESSAGE_STDERR_FILE +
|
||||
@ -102,6 +108,12 @@ class YouCompleteMe( object ):
|
||||
vimsupport.PostVimMessage( SERVER_CRASH_MESSAGE_SAME_STDERR )
|
||||
|
||||
|
||||
def RestartServer( self ):
|
||||
vimsupport.PostVimMessage( 'Restarting ycmd server...' )
|
||||
self.OnVimLeave()
|
||||
self._SetupServer()
|
||||
|
||||
|
||||
def CreateCompletionRequest( self, force_semantic = False ):
|
||||
# We have to store a reference to the newly created CompletionRequest
|
||||
# because VimScript can't store a reference to a Python object across
|
||||
@ -111,17 +123,23 @@ class YouCompleteMe( object ):
|
||||
self._omnicomp.ShouldUseNow() ):
|
||||
self._latest_completion_request = OmniCompletionRequest( self._omnicomp )
|
||||
else:
|
||||
self._latest_completion_request = CompletionRequest( force_semantic )
|
||||
self._latest_completion_request = ( CompletionRequest( force_semantic )
|
||||
if self._IsServerAlive() else
|
||||
None )
|
||||
return self._latest_completion_request
|
||||
|
||||
|
||||
def SendCommandRequest( self, arguments, completer ):
|
||||
if self._IsServerAlive():
|
||||
return SendCommandRequest( arguments, completer )
|
||||
|
||||
|
||||
def GetDefinedSubcommands( self ):
|
||||
if self._IsServerAlive():
|
||||
return BaseRequest.PostDataToHandler( BuildRequestData(),
|
||||
'defined_subcommands' )
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def GetCurrentCompletionRequest( self ):
|
||||
@ -143,9 +161,11 @@ class YouCompleteMe( object ):
|
||||
|
||||
|
||||
def OnFileReadyToParse( self ):
|
||||
self._CheckIfServerCrashed()
|
||||
self._omnicomp.OnFileReadyToParse( None )
|
||||
|
||||
if not self._IsServerAlive():
|
||||
self._NotifyUserIfServerCrashed()
|
||||
|
||||
extra_data = {}
|
||||
if self._user_options[ 'collect_identifiers_from_tags_files' ]:
|
||||
extra_data[ 'tag_files' ] = _GetTagFiles()
|
||||
@ -159,26 +179,35 @@ class YouCompleteMe( object ):
|
||||
|
||||
|
||||
def OnBufferUnload( self, deleted_buffer_file ):
|
||||
if not self._IsServerAlive():
|
||||
return
|
||||
SendEventNotificationAsync( 'BufferUnload',
|
||||
{ 'unloaded_buffer': deleted_buffer_file } )
|
||||
|
||||
|
||||
def OnBufferVisit( self ):
|
||||
if not self._IsServerAlive():
|
||||
return
|
||||
extra_data = {}
|
||||
_AddUltiSnipsDataIfNeeded( extra_data )
|
||||
SendEventNotificationAsync( 'BufferVisit', extra_data )
|
||||
|
||||
|
||||
def OnInsertLeave( self ):
|
||||
if not self._IsServerAlive():
|
||||
return
|
||||
SendEventNotificationAsync( 'InsertLeave' )
|
||||
|
||||
|
||||
def OnVimLeave( self ):
|
||||
if self._IsServerAlive():
|
||||
self._server_popen.terminate()
|
||||
os.remove( self._temp_options_filename )
|
||||
|
||||
|
||||
def OnCurrentIdentifierFinished( self ):
|
||||
if not self._IsServerAlive():
|
||||
return
|
||||
SendEventNotificationAsync( 'CurrentIdentifierFinished' )
|
||||
|
||||
|
||||
@ -200,6 +229,8 @@ class YouCompleteMe( object ):
|
||||
|
||||
|
||||
def ShowDetailedDiagnostic( self ):
|
||||
if not self._IsServerAlive():
|
||||
return
|
||||
debug_info = BaseRequest.PostDataToHandler( BuildRequestData(),
|
||||
'detailed_diagnostic' )
|
||||
if 'message' in debug_info:
|
||||
@ -207,8 +238,11 @@ class YouCompleteMe( object ):
|
||||
|
||||
|
||||
def DebugInfo( self ):
|
||||
if self._IsServerAlive():
|
||||
debug_info = BaseRequest.PostDataToHandler( BuildRequestData(),
|
||||
'debug_info' )
|
||||
else:
|
||||
debug_info = 'Server crashed, no debug info from server'
|
||||
debug_info += '\nServer running at: {0}'.format(
|
||||
BaseRequest.server_location )
|
||||
if self._server_stderr or self._server_stdout:
|
||||
|
Loading…
Reference in New Issue
Block a user