4

recently I started working on c++ in linux(ubuntu), and I found a good vim plugin called "YouCompleteMe".

I installed it successfully with --clang-completer, and it does working, but not fully. It can recognize system c++ library but it cannot recognize other header files in my project directory, it only works for the currently open file. I think the problem is within my ".ycm_extra_conf.py", but I don't know how to change it properly.

Could anyone help?

This is my first post on stackoverflow, so if there is something wrong or you need more information, please leave your message. Thanks

Currently, my vim is like this: enter image description here

Here is my configuration file:

# Partially stolen from https://bitbucket.org/mblum/libgp/src/2537ea7329ef/.ycm_extra_conf.py
import os
import ycm_core
# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
        '-Wall',
        '-Wextra',
        '-Werror',
        '-Wno-long-long',
        '-Wno-variadic-macros',
        '-fexceptions',
        # THIS IS IMPORTANT! Without a "-std=<something>" flag, clang won't know which
        # language to use when compiling headers. So it will guess. Badly. So C++
        # headers will be compiled as C headers. You don't want that so ALWAYS specify
        # a "-std=<something>".
        # For a C project, you would set this to something like 'c99' instead of
        # 'c++11'.
        '-std=c++11',
        # ...and the same thing goes for the magic -x option which specifies the
        # language that the files to be compiled are written in. This is mostly
        # relevant for c++ headers.
        # For a C project, you would set this to 'c' instead of 'c++'.
        '-x', 'c++',
        # This path will only work on OS X, but extra paths that don't exist are not
        # harmful
        '-isystem', '/System/Library/Frameworks/Python.framework/Headers',
        '-isystem', '/usr/local/include',
        '-isystem', '/usr/bin/../lib/clang/3.4/include',
        '-isystem', '/usr/bin/../lib/gcc/i686-linux-gnu/4.8/include',
        '-isystem', '/usr/include/i386-linux-gnu',
        '-isystem', '/usr/include',
        '-I', 'include',
        '-I', 'src',
        '-I', '.',
        ]
# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ''

if compilation_database_folder:
    database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
    database = None

def DirectoryOfThisScript():
    return os.path.dirname( os.path.abspath( __file__ ) )

def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
    if not working_directory:
        return list( flags )
    new_flags = []
    make_next_absolute = False
    path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
    for flag in flags:
        new_flag = flag

        if make_next_absolute:
            make_next_absolute = False
            if not flag.startswith( '/' ):
                new_flag = os.path.join( working_directory, flag )

        for path_flag in path_flags:
            if flag == path_flag:
                make_next_absolute = True
                break

            if flag.startswith( path_flag ):
                path = flag[ len( path_flag ): ]
                new_flag = path_flag + os.path.join( working_directory, path )
                break

        if new_flag:
            new_flags.append( new_flag )
    return new_flags

def FlagsForFile( filename ):
    if database:
    # Bear in mind that compilation_info.compiler_flags_ does NOT return a
    # python list, but a "list-like" StringVec object
        compilation_info = database.GetCompilationInfoForFile( filename )
        final_flags = MakeRelativePathsInFlagsAbsolute(
        compilation_info.compiler_flags_,
        compilation_info.compiler_working_dir_ )
    else:
        # relative_to = DirectoryOfThisScript()
        relative_to = os.path.dirname(os.path.abspath(filename))
        final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
    return {
        'flags': final_flags,
        'do_cache': True
    }
gimbup
  • 184
  • 3
  • 18
  • This is really project specific that it is hard to answer this question. It also doesn't look like you actually changed the compile flags, so ycm can't find the headers since it doesn't have the right include directories. – FDinoff Oct 07 '15 at 18:04
  • Hi, do you mean I should specify the project path in the flags? right now, I only added system c++ library paths, should I add project path in this configuration file with "I" flag? – gimbup Oct 07 '15 at 19:03
  • Would probably be a good idea. – FDinoff Oct 07 '15 at 19:47
  • Thanks, it works! but I have a couple of directories in my project, (more than 20), and I have to indicate all of them in the configuration file, which is not so desirable.. but thank you again, at least it is working now :) – gimbup Oct 07 '15 at 21:01

0 Answers0