Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only parse the initial file the first time it's opened #1722

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions ycmd/completers/language_server/language_server_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,8 @@ def __init__( self, user_options, connection_type = 'stdio' ):
self._on_file_ready_to_parse_handlers = []
self.RegisterOnFileReadyToParse(
lambda self, request_data:
self._UpdateServerWithFileContents( request_data )
self._UpdateServerWithFileContents( request_data ),
True # once
)

self._signature_help_disabled = user_options[ 'disable_signature_help' ]
Expand Down Expand Up @@ -1898,20 +1899,30 @@ def OnFileReadyToParse( self, request_data ):
if not self.ServerIsHealthy():
return

def ClearOneshotHandlers():
self._on_file_ready_to_parse_handlers = [
( handler, once ) for handler, once
in self._on_file_ready_to_parse_handlers if not once
]

# If we haven't finished initializing yet, we need to queue up all functions
# registered on the FileReadyToParse event and in particular
# _UpdateServerWithFileContents in reverse order of registration. This
# ensures that the server is up to date as soon as we are able to send more
# messages. This is important because server start up can be quite slow and
# we must not block the user, while we must keep the server synchronized.
if not self._initialize_event.is_set():
for handler in reversed( self._on_file_ready_to_parse_handlers ):
for handler, _ in reversed( self._on_file_ready_to_parse_handlers ):
self._OnInitializeComplete( partial( handler,
request_data = request_data ) )
ClearOneshotHandlers()
return

for handler in reversed( self._on_file_ready_to_parse_handlers ):
for handler, _ in reversed( self._on_file_ready_to_parse_handlers ):
handler( self, request_data )
ClearOneshotHandlers()

self._UpdateServerWithFileContents( request_data )

# Return the latest diagnostics that we have received.
#
Expand Down Expand Up @@ -2480,8 +2491,8 @@ def _OnInitializeComplete( self, handler ):
self._on_initialize_complete_handlers.append( handler )


def RegisterOnFileReadyToParse( self, handler ):
self._on_file_ready_to_parse_handlers.append( handler )
def RegisterOnFileReadyToParse( self, handler, once=False ):
self._on_file_ready_to_parse_handlers.append( ( handler, once ) )


def GetHoverResponse( self, request_data ):
Expand Down
9 changes: 5 additions & 4 deletions ycmd/tests/rust/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ def tearDownModule():

def StartRustCompleterServerInDirectory( app, directory ):
app.post_json( '/event_notification',
BuildRequest(
filepath = os.path.join( directory, 'src', 'main.rs' ),
event_name = 'FileReadyToParse',
filetype = 'rust' ) )
BuildRequest( filepath = os.path.join( directory,
'src',
'main.rs' ),
event_name = 'FileReadyToParse',
filetype = 'rust' ) )
WaitUntilCompleterServerReady( app, 'rust' )


Expand Down
16 changes: 15 additions & 1 deletion ycmd/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# along with ycmd. If not, see <http://www.gnu.org/licenses/>.


from ycmd.utils import ReadFile
from hamcrest import ( assert_that,
contains_exactly,
contains_string,
Expand Down Expand Up @@ -76,9 +77,22 @@
} )


def GetTestFileContents( filename ):
try:
return ReadFile( filename )
except IOError:
return ''


def BuildRequest( **kwargs ):
filepath = kwargs[ 'filepath' ] if 'filepath' in kwargs else '/foo'
contents = kwargs[ 'contents' ] if 'contents' in kwargs else ''
contents = (
kwargs[ 'contents' ]
if 'contents' in kwargs
else GetTestFileContents( filepath )
if 'filepath' in kwargs
else ''
)
filetype = kwargs[ 'filetype' ] if 'filetype' in kwargs else 'foo'
filetypes = kwargs[ 'filetypes' ] if 'filetypes' in kwargs else [ filetype ]

Expand Down