diff --git a/python/ycm/client/event_notification.py b/python/ycm/client/event_notification.py index 9652413f..9300e174 100644 --- a/python/ycm/client/event_notification.py +++ b/python/ycm/client/event_notification.py @@ -58,6 +58,8 @@ class EventNotification( BaseRequest ): except UnknownExtraConf as e: if vimsupport.Confirm( str( e ) ): _LoadExtraConfFile( e.extra_conf_file ) + else: + _IgnoreExtraConfFile( e.extra_conf_file ) except Exception as e: vimsupport.PostVimMessage( str( e ) ) @@ -91,3 +93,7 @@ def SendEventNotificationAsync( event_name, extra_data = None ): def _LoadExtraConfFile( filepath ): BaseRequest.PostDataToHandler( { 'filepath': filepath }, 'load_extra_conf_file' ) + +def _IgnoreExtraConfFile( filepath ): + BaseRequest.PostDataToHandler( { 'filepath': filepath }, + 'ignore_extra_conf_file' ) diff --git a/python/ycm/completers/cpp/flags.py b/python/ycm/completers/cpp/flags.py index cbf72fa6..6c2fee1c 100644 --- a/python/ycm/completers/cpp/flags.py +++ b/python/ycm/completers/cpp/flags.py @@ -22,11 +22,7 @@ import os import inspect from ycm import extra_conf_store from ycm.utils import ToUtf8IfNeeded - -NO_EXTRA_CONF_FILENAME_MESSAGE = ( 'No {0} file detected, so no compile flags ' - 'are available. Thus no semantic support for C/C++/ObjC/ObjC++. Go READ THE ' - 'DOCS *NOW*, DON\'T file a bug report.' ).format( - extra_conf_store.YCM_EXTRA_CONF_FILENAME ) +from ycm.server.responses import NoExtraConfDetected INCLUDE_FLAGS = [ '-isystem', '-I', '-iquote', '--sysroot=', '-isysroot', '-include' ] @@ -54,7 +50,7 @@ class Flags( object ): if not module: if not self.no_extra_conf_file_warning_posted: self.no_extra_conf_file_warning_posted = True - raise RuntimeError( NO_EXTRA_CONF_FILENAME_MESSAGE ) + raise NoExtraConfDetected return None results = _CallExtraConfFlagsForFile( module, diff --git a/python/ycm/extra_conf_store.py b/python/ycm/extra_conf_store.py index d49576c4..6267a0db 100644 --- a/python/ycm/extra_conf_store.py +++ b/python/ycm/extra_conf_store.py @@ -27,11 +27,9 @@ import sys import logging from threading import Lock from ycm import user_options_store -from ycm.server.responses import UnknownExtraConf +from ycm.server.responses import UnknownExtraConf, YCM_EXTRA_CONF_FILENAME from fnmatch import fnmatch -# Constants -YCM_EXTRA_CONF_FILENAME = '.ycm_extra_conf.py' # Singleton variables _module_for_module_file = {} @@ -95,7 +93,7 @@ def _CallGlobalExtraConfMethod( function_name ): getattr( module, function_name )() -def _Disable( module_file ): +def Disable( module_file ): """Disables the loading of a module for the current session.""" with _module_for_module_file_lock: _module_for_module_file[ module_file ] = None @@ -116,11 +114,6 @@ def _ShouldLoad( module_file ): if _MatchesGlobPattern( module_file, glob.lstrip('!') ): return not is_blacklisted - # We disable the file if it's unknown so that we don't ask the user about it - # repeatedly. Raising UnknownExtraConf should result in the client sending - # another request to load the module file if the user explicitly chooses to do - # that. - _Disable( module_file ) raise UnknownExtraConf( module_file ) @@ -139,7 +132,7 @@ def Load( module_file, force = False ): return _module_for_module_file[ module_file ] if not _ShouldLoad( module_file ): - _Disable( module_file ) + Disable( module_file ) return None # This has to be here because a long time ago, the ycm_extra_conf.py files diff --git a/python/ycm/server/handlers.py b/python/ycm/server/handlers.py index eae41ab6..0319bde9 100644 --- a/python/ycm/server/handlers.py +++ b/python/ycm/server/handlers.py @@ -146,6 +146,13 @@ def LoadExtraConfFile(): extra_conf_store.Load( request_data[ 'filepath' ], force = True ) +@app.post( '/ignore_extra_conf_file' ) +def IgnoreExtraConfFile(): + LOGGER.info( 'Received extra conf ignore request' ) + request_data = request.json + extra_conf_store.Disable( request_data[ 'filepath' ] ) + + @app.post( '/debug_info' ) def DebugInfo(): LOGGER.info( 'Received debug info request' ) diff --git a/python/ycm/server/responses.py b/python/ycm/server/responses.py index f0ca6364..a44adfe7 100644 --- a/python/ycm/server/responses.py +++ b/python/ycm/server/responses.py @@ -19,9 +19,16 @@ import os +YCM_EXTRA_CONF_FILENAME = '.ycm_extra_conf.py' + CONFIRM_CONF_FILE_MESSAGE = ('Found {0}. Load? \n\n(Question can be turned ' 'off with options, see YCM docs)') +NO_EXTRA_CONF_FILENAME_MESSAGE = ( 'No {0} file detected, so no compile flags ' + 'are available. Thus no semantic support for C/C++/ObjC/ObjC++. Go READ THE ' + 'DOCS *NOW*, DON\'T file a bug report.' ).format( YCM_EXTRA_CONF_FILENAME ) + + class ServerError( Exception ): def __init__( self, message ): super( ServerError, self ).__init__( message ) @@ -34,6 +41,11 @@ class UnknownExtraConf( ServerError ): self.extra_conf_file = extra_conf_file +class NoExtraConfDetected( ServerError ): + def __init__( self ): + super( NoExtraConfDetected, self ).__init__( + NO_EXTRA_CONF_FILENAME_MESSAGE ) + def BuildGoToResponse( filepath, line_num, column_num, description = None ): response = { diff --git a/python/ycm/server/tests/get_completions_test.py b/python/ycm/server/tests/get_completions_test.py index 6386cb0e..7762f414 100644 --- a/python/ycm/server/tests/get_completions_test.py +++ b/python/ycm/server/tests/get_completions_test.py @@ -27,7 +27,8 @@ from webtest import TestApp, AppError from nose.tools import eq_, with_setup from hamcrest import ( assert_that, has_item, has_items, has_entry, contains_inanyorder, empty ) -from ..responses import BuildCompletionData, UnknownExtraConf +from ..responses import ( BuildCompletionData, UnknownExtraConf, + NoExtraConfDetected ) from .. import handlers import bottle @@ -239,6 +240,9 @@ def GetCompletions_ClangCompleter_UnknownExtraConfException_test(): completion_data = BuildRequest( filepath = filepath, filetype = 'cpp', contents = open( filepath ).read(), + line_num = 10, + column_num = 6, + start_column = 6, force_semantic = True ) response = app.post_json( '/completions', @@ -250,6 +254,18 @@ def GetCompletions_ClangCompleter_UnknownExtraConfException_test(): has_entry( 'exception', has_entry( 'TYPE', UnknownExtraConf.__name__ ) ) ) + app.post_json( '/ignore_extra_conf_file', + { 'filepath': PathToTestFile( '.ycm_extra_conf.py' ) } ) + + response = app.post_json( '/completions', + completion_data, + expect_errors = True ) + + eq_( response.status_code, httplib.INTERNAL_SERVER_ERROR ) + assert_that( response.json, + has_entry( 'exception', + has_entry( 'TYPE', NoExtraConfDetected.__name__ ) ) ) + @with_setup( Setup ) def GetCompletions_ClangCompleter_WorksWhenExtraConfExplicitlyAllowed_test():