Better handling of unknown extra conf files
Previously, we'd implicitly turn off future notices about unknown extra conf files if we already raised one exception about it. This breaks when the user ends up not receiving the "unknown extra conf, load?" message. Now we only turn off the notice as a result of the user saying "don't load this" so that if the first request fails to reach them, they'll get a second (and third etc) request about it. Fixes #615
This commit is contained in:
parent
1edf22357f
commit
b1d71bbb91
@ -58,6 +58,8 @@ class EventNotification( BaseRequest ):
|
|||||||
except UnknownExtraConf as e:
|
except UnknownExtraConf as e:
|
||||||
if vimsupport.Confirm( str( e ) ):
|
if vimsupport.Confirm( str( e ) ):
|
||||||
_LoadExtraConfFile( e.extra_conf_file )
|
_LoadExtraConfFile( e.extra_conf_file )
|
||||||
|
else:
|
||||||
|
_IgnoreExtraConfFile( e.extra_conf_file )
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
vimsupport.PostVimMessage( str( e ) )
|
vimsupport.PostVimMessage( str( e ) )
|
||||||
|
|
||||||
@ -91,3 +93,7 @@ def SendEventNotificationAsync( event_name, extra_data = None ):
|
|||||||
def _LoadExtraConfFile( filepath ):
|
def _LoadExtraConfFile( filepath ):
|
||||||
BaseRequest.PostDataToHandler( { 'filepath': filepath },
|
BaseRequest.PostDataToHandler( { 'filepath': filepath },
|
||||||
'load_extra_conf_file' )
|
'load_extra_conf_file' )
|
||||||
|
|
||||||
|
def _IgnoreExtraConfFile( filepath ):
|
||||||
|
BaseRequest.PostDataToHandler( { 'filepath': filepath },
|
||||||
|
'ignore_extra_conf_file' )
|
||||||
|
@ -22,11 +22,7 @@ import os
|
|||||||
import inspect
|
import inspect
|
||||||
from ycm import extra_conf_store
|
from ycm import extra_conf_store
|
||||||
from ycm.utils import ToUtf8IfNeeded
|
from ycm.utils import ToUtf8IfNeeded
|
||||||
|
from ycm.server.responses import NoExtraConfDetected
|
||||||
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 )
|
|
||||||
|
|
||||||
INCLUDE_FLAGS = [ '-isystem', '-I', '-iquote', '--sysroot=', '-isysroot',
|
INCLUDE_FLAGS = [ '-isystem', '-I', '-iquote', '--sysroot=', '-isysroot',
|
||||||
'-include' ]
|
'-include' ]
|
||||||
@ -54,7 +50,7 @@ class Flags( object ):
|
|||||||
if not module:
|
if not module:
|
||||||
if not self.no_extra_conf_file_warning_posted:
|
if not self.no_extra_conf_file_warning_posted:
|
||||||
self.no_extra_conf_file_warning_posted = True
|
self.no_extra_conf_file_warning_posted = True
|
||||||
raise RuntimeError( NO_EXTRA_CONF_FILENAME_MESSAGE )
|
raise NoExtraConfDetected
|
||||||
return None
|
return None
|
||||||
|
|
||||||
results = _CallExtraConfFlagsForFile( module,
|
results = _CallExtraConfFlagsForFile( module,
|
||||||
|
@ -27,11 +27,9 @@ import sys
|
|||||||
import logging
|
import logging
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
from ycm import user_options_store
|
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
|
from fnmatch import fnmatch
|
||||||
|
|
||||||
# Constants
|
|
||||||
YCM_EXTRA_CONF_FILENAME = '.ycm_extra_conf.py'
|
|
||||||
|
|
||||||
# Singleton variables
|
# Singleton variables
|
||||||
_module_for_module_file = {}
|
_module_for_module_file = {}
|
||||||
@ -95,7 +93,7 @@ def _CallGlobalExtraConfMethod( function_name ):
|
|||||||
getattr( module, function_name )()
|
getattr( module, function_name )()
|
||||||
|
|
||||||
|
|
||||||
def _Disable( module_file ):
|
def Disable( module_file ):
|
||||||
"""Disables the loading of a module for the current session."""
|
"""Disables the loading of a module for the current session."""
|
||||||
with _module_for_module_file_lock:
|
with _module_for_module_file_lock:
|
||||||
_module_for_module_file[ module_file ] = None
|
_module_for_module_file[ module_file ] = None
|
||||||
@ -116,11 +114,6 @@ def _ShouldLoad( module_file ):
|
|||||||
if _MatchesGlobPattern( module_file, glob.lstrip('!') ):
|
if _MatchesGlobPattern( module_file, glob.lstrip('!') ):
|
||||||
return not is_blacklisted
|
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 )
|
raise UnknownExtraConf( module_file )
|
||||||
|
|
||||||
|
|
||||||
@ -139,7 +132,7 @@ def Load( module_file, force = False ):
|
|||||||
return _module_for_module_file[ module_file ]
|
return _module_for_module_file[ module_file ]
|
||||||
|
|
||||||
if not _ShouldLoad( module_file ):
|
if not _ShouldLoad( module_file ):
|
||||||
_Disable( module_file )
|
Disable( module_file )
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# This has to be here because a long time ago, the ycm_extra_conf.py files
|
# This has to be here because a long time ago, the ycm_extra_conf.py files
|
||||||
|
@ -146,6 +146,13 @@ def LoadExtraConfFile():
|
|||||||
extra_conf_store.Load( request_data[ 'filepath' ], force = True )
|
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' )
|
@app.post( '/debug_info' )
|
||||||
def DebugInfo():
|
def DebugInfo():
|
||||||
LOGGER.info( 'Received debug info request' )
|
LOGGER.info( 'Received debug info request' )
|
||||||
|
@ -19,9 +19,16 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
YCM_EXTRA_CONF_FILENAME = '.ycm_extra_conf.py'
|
||||||
|
|
||||||
CONFIRM_CONF_FILE_MESSAGE = ('Found {0}. Load? \n\n(Question can be turned '
|
CONFIRM_CONF_FILE_MESSAGE = ('Found {0}. Load? \n\n(Question can be turned '
|
||||||
'off with options, see YCM docs)')
|
'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 ):
|
class ServerError( Exception ):
|
||||||
def __init__( self, message ):
|
def __init__( self, message ):
|
||||||
super( ServerError, self ).__init__( message )
|
super( ServerError, self ).__init__( message )
|
||||||
@ -34,6 +41,11 @@ class UnknownExtraConf( ServerError ):
|
|||||||
self.extra_conf_file = extra_conf_file
|
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 ):
|
def BuildGoToResponse( filepath, line_num, column_num, description = None ):
|
||||||
response = {
|
response = {
|
||||||
|
@ -27,7 +27,8 @@ from webtest import TestApp, AppError
|
|||||||
from nose.tools import eq_, with_setup
|
from nose.tools import eq_, with_setup
|
||||||
from hamcrest import ( assert_that, has_item, has_items, has_entry,
|
from hamcrest import ( assert_that, has_item, has_items, has_entry,
|
||||||
contains_inanyorder, empty )
|
contains_inanyorder, empty )
|
||||||
from ..responses import BuildCompletionData, UnknownExtraConf
|
from ..responses import ( BuildCompletionData, UnknownExtraConf,
|
||||||
|
NoExtraConfDetected )
|
||||||
from .. import handlers
|
from .. import handlers
|
||||||
import bottle
|
import bottle
|
||||||
|
|
||||||
@ -239,6 +240,9 @@ def GetCompletions_ClangCompleter_UnknownExtraConfException_test():
|
|||||||
completion_data = BuildRequest( filepath = filepath,
|
completion_data = BuildRequest( filepath = filepath,
|
||||||
filetype = 'cpp',
|
filetype = 'cpp',
|
||||||
contents = open( filepath ).read(),
|
contents = open( filepath ).read(),
|
||||||
|
line_num = 10,
|
||||||
|
column_num = 6,
|
||||||
|
start_column = 6,
|
||||||
force_semantic = True )
|
force_semantic = True )
|
||||||
|
|
||||||
response = app.post_json( '/completions',
|
response = app.post_json( '/completions',
|
||||||
@ -250,6 +254,18 @@ def GetCompletions_ClangCompleter_UnknownExtraConfException_test():
|
|||||||
has_entry( 'exception',
|
has_entry( 'exception',
|
||||||
has_entry( 'TYPE', UnknownExtraConf.__name__ ) ) )
|
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 )
|
@with_setup( Setup )
|
||||||
def GetCompletions_ClangCompleter_WorksWhenExtraConfExplicitlyAllowed_test():
|
def GetCompletions_ClangCompleter_WorksWhenExtraConfExplicitlyAllowed_test():
|
||||||
|
Loading…
Reference in New Issue
Block a user