From 00db8fd8b18c0157bacae17a062f360795b8907c Mon Sep 17 00:00:00 2001 From: Strahinja Val Markovic Date: Sat, 19 Jan 2013 18:53:30 -0800 Subject: [PATCH] compilation_database.json now fully supported --- cpp/ycm/.ycm_clang_options.py | 32 +++++++++++++++++++- python/completers/cpp/clang_helpers.py | 41 ++++++++++++++++++++++++++ python/completers/cpp/flags.py | 8 +++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 python/completers/cpp/clang_helpers.py diff --git a/cpp/ycm/.ycm_clang_options.py b/cpp/ycm/.ycm_clang_options.py index 290e6dca..b72f3058 100644 --- a/cpp/ycm/.ycm_clang_options.py +++ b/cpp/ycm/.ycm_clang_options.py @@ -1,5 +1,14 @@ import os +import ycm_core +from clang_helpers import PrepareClangFlags +# Set this to the absolute path to the folder containing the +# compilation_database.json file to use that instead of 'flags'. See here for +# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html +compilation_database_folder = '' + +# These are the compilation flags that will be used in case there's no +# compilation database set. flags = [ '-Wall', '-Wextra', @@ -41,6 +50,12 @@ flags = [ './tests/gmock/include' ] +if compilation_database_folder: + database = ycm_core.CompilationDatabase( compilation_database_folder ) +else: + database = None + + def DirectoryOfThisScript(): return os.path.dirname( os.path.abspath( __file__ ) ) @@ -54,7 +69,22 @@ def MakeAbsoluteIfRelativePath( path ): def FlagsForFile( filename ): + if database: + # Bear in mind that database.FlagsForFile does NOT return a python list, but + # a "list-like" StringVec object + final_flags = PrepareClangFlags( database.FlagsForFile( filename ) ) + + # NOTE: This is just for YouCompleteMe; it's highly likely that your project + # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR + # ycm_clang_options IF YOU'RE NOT 100% YOU NEED IT. + try: + final_flags.remove( '-stdlib=libc++' ) + except ValueError: + pass + else: + final_flags = [ MakeAbsoluteIfRelativePath( x ) for x in flags ] + return { - 'flags': [ MakeAbsoluteIfRelativePath( x ) for x in flags ], + 'flags': final_flags, 'do_cache': True } diff --git a/python/completers/cpp/clang_helpers.py b/python/completers/cpp/clang_helpers.py new file mode 100644 index 00000000..2b598f0f --- /dev/null +++ b/python/completers/cpp/clang_helpers.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# +# Copyright (C) 2011, 2012 Strahinja Val Markovic +# +# 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 . + + +# Given an interable object that produces strings (flags for Clang), removes the +# '-c' and '-o' options that Clang does not like to see when it's producing +# completions for a file. +def PrepareClangFlags( flags ): + new_flags = [] + skip = True + for flag in flags: + if skip: + skip = False + continue + + if flag == '-c': + skip = True; + continue + + if flag == '-o': + skip = True; + continue + + new_flags.append( flag ) + return new_flags diff --git a/python/completers/cpp/flags.py b/python/completers/cpp/flags.py index 3aa1b4b5..6004e113 100644 --- a/python/completers/cpp/flags.py +++ b/python/completers/cpp/flags.py @@ -22,6 +22,7 @@ import os import ycm_core import random import string +import sys CLANG_OPTIONS_FILENAME = '.ycm_clang_options.py' @@ -63,7 +64,10 @@ class Flags( object ): flags_module = self.flags_module_for_flags_module_file[ flags_module_file ] except KeyError: + sys.path.append( _DirectoryOfThisScript() ) flags_module = imp.load_source( _RandomName(), flags_module_file ) + del sys.path[ -1 ] + self.flags_module_for_flags_module_file[ flags_module_file ] = flags_module @@ -125,3 +129,7 @@ def _SpecialClangIncludes(): libclang_dir = os.path.dirname( ycm_core.__file__ ) path_to_includes = os.path.join( libclang_dir, 'clang_includes' ) return [ '-I', path_to_includes ] + + +def _DirectoryOfThisScript(): + return os.path.dirname( os.path.abspath( __file__ ) )