From 30036ca8e2cd978f72daa353b617e442378fba7d Mon Sep 17 00:00:00 2001 From: Andrea Cedraro Date: Thu, 11 Jun 2015 22:10:40 +0200 Subject: [PATCH 1/4] Defer setting the omnifunc. When we enter a new buffer we need to know if the ycmd server has a native completer for the current filetype, this means that when we start vim we need to know if the server has a completer available for the buffer which means that we have to wait for the server to be up and running. To mitigate this defer the setting of the omnifunction closer to its need which is when we enter insert mode; this should give room for the ycmd server to start before we ask for anything or at least should reduce the time waiting. ref: #1529 --- autoload/youcompleteme.vim | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/autoload/youcompleteme.vim b/autoload/youcompleteme.vim index 38515418..2fed7eed 100644 --- a/autoload/youcompleteme.vim +++ b/autoload/youcompleteme.vim @@ -423,7 +423,10 @@ endfunction function! s:SetCompleteFunc() let &completefunc = 'youcompleteme#Complete' let &l:completefunc = 'youcompleteme#Complete' +endfunction + +function! s:SetOmnicompleteFunc() if pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' ) let &omnifunc = 'youcompleteme#OmniComplete' let &l:omnifunc = 'youcompleteme#OmniComplete' @@ -505,6 +508,11 @@ function! s:OnInsertEnter() return endif + if get( b:, 'ycm_omnicomplete', 0 ) + let b:ycm_omnicomplete = 1 + call s:SetOmnicompleteFunc() + endif + let s:old_cursor_position = [] endfunction From 4104f7be824b1c27f31e52f5d3544dcdcd20fa4a Mon Sep 17 00:00:00 2001 From: Andrea Cedraro Date: Thu, 11 Jun 2015 23:32:13 +0200 Subject: [PATCH 2/4] Push check for NativeFiletypeCompletionUsable down Another way in which the commit d768447 forced the client to wait for the server to start was the UpdateDiagnosticNotifications call from the FileReadyToParse which is called right after a buffer is loaded. In any way if we don't have any previous FileReadyToParse request done for the current file we bail out, so we we can wait for a FileReadyToParse response to be available before asking if a completer is usable for the current filetype. ref: #1529 --- autoload/youcompleteme.vim | 3 +-- python/ycm/youcompleteme.py | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/autoload/youcompleteme.vim b/autoload/youcompleteme.vim index 2fed7eed..1f8a6a15 100644 --- a/autoload/youcompleteme.vim +++ b/autoload/youcompleteme.vim @@ -567,8 +567,7 @@ endfunction function! s:UpdateDiagnosticNotifications() let should_display_diagnostics = g:ycm_show_diagnostics_ui && - \ s:DiagnosticUiSupportedForCurrentFiletype() && - \ pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' ) + \ s:DiagnosticUiSupportedForCurrentFiletype() if !should_display_diagnostics return diff --git a/python/ycm/youcompleteme.py b/python/ycm/youcompleteme.py index 58cdb2e1..e4700bd1 100644 --- a/python/ycm/youcompleteme.py +++ b/python/ycm/youcompleteme.py @@ -299,7 +299,8 @@ class YouCompleteMe( object ): def UpdateDiagnosticInterface( self ): - if not self.DiagnosticsForCurrentFileReady(): + if ( not self.DiagnosticsForCurrentFileReady() or + not self.NativeFiletypeCompletionUsable() ): return self._diag_interface.UpdateWithNewDiagnostics( self.GetDiagnosticsFromStoredRequest() ) From 3dd24201f3ead4b7ffeeef257dc6a723e25dc96e Mon Sep 17 00:00:00 2001 From: Andrea Cedraro Date: Fri, 12 Jun 2015 00:04:56 +0200 Subject: [PATCH 3/4] Revert "Revert "Check the server end point for available completer"" This reverts commit f5e2fc6958c9561e27abfc0aea2ae6f62d46cc6f. --- .../ycm/client/completer_available_request.py | 48 +++++++++++++++++++ python/ycm/youcompleteme.py | 17 ++++++- 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 python/ycm/client/completer_available_request.py diff --git a/python/ycm/client/completer_available_request.py b/python/ycm/client/completer_available_request.py new file mode 100644 index 00000000..3b12b6b2 --- /dev/null +++ b/python/ycm/client/completer_available_request.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# +# Copyright (C) 2013 Google Inc. +# +# This file is part of YouCompleteMe. +# +# YouCompleteMe is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# YouCompleteMe is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with YouCompleteMe. If not, see . + +from ycm.client.base_request import ( BaseRequest, BuildRequestData, + HandleServerException ) + +class CompleterAvailableRequest( BaseRequest ): + def __init__( self, filetypes ): + super( CompleterAvailableRequest, self ).__init__() + self.filetypes = filetypes + self._response = None + + + def Start( self ): + request_data = BuildRequestData() + request_data.update( { 'filetypes': self.filetypes } ) + try: + self._response = self.PostDataToHandler( request_data, + 'semantic_completion_available' ) + except Exception as e: + HandleServerException( e ) + + + def Response( self ): + return self._response + + +def SendCompleterAvailableRequest( filetypes ): + request = CompleterAvailableRequest( filetypes ) + # This is a blocking call. + request.Start() + return request.Response() diff --git a/python/ycm/youcompleteme.py b/python/ycm/youcompleteme.py index e4700bd1..9d2340d0 100644 --- a/python/ycm/youcompleteme.py +++ b/python/ycm/youcompleteme.py @@ -30,9 +30,9 @@ from ycmd.request_wrap import RequestWrap from ycm.diagnostic_interface import DiagnosticInterface from ycm.omni_completer import OmniCompleter from ycm import syntax_parse -from ycmd.completers.completer_utils import FiletypeCompleterExistsForFiletype from ycm.client.ycmd_keepalive import YcmdKeepalive from ycm.client.base_request import BaseRequest, BuildRequestData +from ycm.client.completer_available_request import SendCompleterAvailableRequest from ycm.client.command_request import SendCommandRequest from ycm.client.completion_request import CompletionRequest from ycm.client.omni_completion_request import OmniCompletionRequest @@ -98,6 +98,7 @@ class YouCompleteMe( object ): self._ycmd_keepalive.Start() def _SetupServer( self ): + self._available_completers = {} server_port = utils.GetUnusedLocalhostPort() # The temp options file is deleted by ycmd during startup with tempfile.NamedTemporaryFile( delete = False ) as options_file: @@ -217,8 +218,20 @@ class YouCompleteMe( object ): return self._omnicomp + def FiletypeCompleterExistsForFiletype( self, filetype ): + try: + return self._available_completers[ filetype ] + except KeyError: + pass + + exists_completer = ( self.IsServerAlive() and + bool( SendCompleterAvailableRequest( filetype ) ) ) + self._available_completers[ filetype ] = exists_completer + return exists_completer + + def NativeFiletypeCompletionAvailable( self ): - return any( [ FiletypeCompleterExistsForFiletype( x ) for x in + return any( [ self.FiletypeCompleterExistsForFiletype( x ) for x in vimsupport.CurrentFiletypes() ] ) From fbdf7cc85ecd2731d295d7bab6b6f3fa3dee442d Mon Sep 17 00:00:00 2001 From: Andrea Cedraro Date: Mon, 15 Jun 2015 15:54:48 +0200 Subject: [PATCH 4/4] Reverse if logic in `UpdateDiagnosticInterface` --- python/ycm/youcompleteme.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/python/ycm/youcompleteme.py b/python/ycm/youcompleteme.py index 9d2340d0..d9147686 100644 --- a/python/ycm/youcompleteme.py +++ b/python/ycm/youcompleteme.py @@ -312,11 +312,10 @@ class YouCompleteMe( object ): def UpdateDiagnosticInterface( self ): - if ( not self.DiagnosticsForCurrentFileReady() or - not self.NativeFiletypeCompletionUsable() ): - return - self._diag_interface.UpdateWithNewDiagnostics( - self.GetDiagnosticsFromStoredRequest() ) + if ( self.DiagnosticsForCurrentFileReady() and + self.NativeFiletypeCompletionUsable() ): + self._diag_interface.UpdateWithNewDiagnostics( + self.GetDiagnosticsFromStoredRequest() ) def ShowDetailedDiagnostic( self ):