From 7e20d1e5a3231e9bc1d80f10dbef1d7a1ffe9cdc Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Mon, 4 Nov 2019 10:48:15 +0000 Subject: [PATCH] WIP: Ability to ignore extra conf files --- ycmd/completers/cpp/flags.py | 11 ++++- .../language_server_completer.py | 13 ++++-- ycmd/completers/python/python_completer.py | 21 +++++---- ycmd/extra_conf_support.py | 46 +++++++++++++++++++ 4 files changed, 77 insertions(+), 14 deletions(-) create mode 100644 ycmd/extra_conf_support.py diff --git a/ycmd/completers/cpp/flags.py b/ycmd/completers/cpp/flags.py index 581e38ca9b..a5834d738c 100644 --- a/ycmd/completers/cpp/flags.py +++ b/ycmd/completers/cpp/flags.py @@ -28,6 +28,7 @@ CLANG_RESOURCE_DIR ) from ycmd.responses import NoExtraConfDetected ycm_core = ImportCore() +from ycmd.extra_conf_support import IgnoreExtraConf # -include-pch and --sysroot= must be listed before -include and --sysroot # respectively because the latter is a prefix of the former (and the algorithm @@ -165,7 +166,10 @@ def _GetFlagsFromExtraConfOrDatabase( self, filename, client_data ): # Load the flags from the extra conf file if one is found and is not global. module = extra_conf_store.ModuleForSourceFile( filename ) if module and not extra_conf_store.IsGlobalExtraConfModule( module ): - return _CallExtraConfFlagsForFile( module, filename, client_data ) + try: + return _CallExtraConfFlagsForFile( module, filename, client_data ) + except IgnoreExtraConf: + pass # Load the flags from the compilation database if any. database = self.LoadCompilationDatabase( filename ) @@ -174,7 +178,10 @@ def _GetFlagsFromExtraConfOrDatabase( self, filename, client_data ): # Load the flags from the global extra conf if set. if module: - return _CallExtraConfFlagsForFile( module, filename, client_data ) + try: + return _CallExtraConfFlagsForFile( module, filename, client_data ) + except IgnoreExtraConf: + pass # No compilation database and no extra conf found. Warn the user if not # already warned. diff --git a/ycmd/completers/language_server/language_server_completer.py b/ycmd/completers/language_server/language_server_completer.py index 1e44d0b28d..740060a526 100644 --- a/ycmd/completers/language_server/language_server_completer.py +++ b/ycmd/completers/language_server/language_server_completer.py @@ -30,6 +30,7 @@ from ycmd.completers.completer import Completer, CompletionsCache from ycmd.completers.completer_utils import GetFileContents, GetFileLines from ycmd.utils import LOGGER +from ycmd.extra_conf_support import IgnoreExtraConf from ycmd.completers.language_server import language_server_protocol as lsp @@ -1416,10 +1417,14 @@ def DefaultSettings( self, request_data ): def GetSettings( self, module, request_data ): if hasattr( module, 'Settings' ): - settings = module.Settings( - language = self.Language(), - filename = request_data[ 'filepath' ], - client_data = request_data[ 'extra_conf_data' ] ) + try: + settings = module.Settings( + language = self.Language(), + filename = request_data[ 'filepath' ], + client_data = request_data[ 'extra_conf_data' ] ) + except IgnoreExtraConf: + settings = None + if settings is not None: return settings diff --git a/ycmd/completers/python/python_completer.py b/ycmd/completers/python/python_completer.py index 00c21a7b70..09e465c77d 100644 --- a/ycmd/completers/python/python_completer.py +++ b/ycmd/completers/python/python_completer.py @@ -16,6 +16,7 @@ # along with ycmd. If not, see . from ycmd import extra_conf_store, responses +from ycmd.extra_conf_support import IgnoreExtraConf from ycmd.completers.completer import Completer, SignatureHelpAvailalability from ycmd.utils import ( CodepointOffsetToByteOffset, ExpandVariablesInPath, @@ -71,14 +72,18 @@ def _SettingsForRequest( self, request_data ): def _GetSettings( self, module, filepath, client_data ): # We don't warn the user if no extra conf file is found. - if module: - if hasattr( module, 'Settings' ): - settings = module.Settings( language = 'python', - filename = filepath, - client_data = client_data ) - if settings is not None: - return settings - LOGGER.debug( 'No Settings function defined in %s', module.__file__ ) + try: + if module: + if hasattr( module, 'Settings' ): + settings = module.Settings( language = 'python', + filename = filepath, + client_data = client_data ) + if settings is not None: + return settings + LOGGER.debug( 'No Settings function defined in %s', module.__file__ ) + except IgnoreExtraConf: + pass + return { # NOTE: this option is only kept for backward compatibility. Setting the # Python interpreter path through the extra conf file is preferred. diff --git a/ycmd/extra_conf_support.py b/ycmd/extra_conf_support.py new file mode 100644 index 0000000000..ef47c8f961 --- /dev/null +++ b/ycmd/extra_conf_support.py @@ -0,0 +1,46 @@ +# Copyright (C) 2011-2019 ycmd contributors +# +# This file is part of ycmd. +# +# ycmd 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. +# +# ycmd 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 ycmd. If not, see . + +from __future__ import unicode_literals +from __future__ import print_function +from __future__ import division +from __future__ import absolute_import +# Not installing aliases from python-future; it's unreliable and slow. +from builtins import * # noqa + + +class IgnoreExtraConf( Exception ): + """Raise this exception from within a FlagsForFile or Settings function to + instruct ycmd to ignore this module for the current file. + + For example, if you wish to delegate to ycmd's built-in compilation database + support, you can write: + + from ycmd.extra_conf_support import IgnoreExtraConf + + def Settings( **kwargs ): + if kwargs[ 'language' ] == 'c-family': + # Use compilation database + raise IgnoreExtraConf() + + if kwargs[ 'language' ] == 'python': + ... + + This will then tell ycmd to use your compile_commands.json, or global extra + conf as if this local module doens't exist. + """ + pass