rc

.ycm_extra_conf.py

1
# This is largely taken from https://github.com/Valloric/ycmd/blob/master/cpp/ycm/.ycm_extra_conf.py
2
3
# NOTE: If the YCMD server "shuts down unexpectedly", it's possible that a new
4
# version of Python's been installed (for example: 3.7 -> 3.8), but the YCMD
5
# server is not updated then, so it expects 3.7, and can't find it. Check the
6
# logs, and if it complains about that, go to the ycmd folder, and run
7
# "python build.py --all".
8
9
import os
10
import ycm_core
11
12
# These are the compilation flags that will be used in case there's no
13
# compilation database set (by default, one is not set).
14
flags = [
15
'-Wall',
16
'-Wextra',
17
'-Werror',
18
'-Wc++98-compat',
19
'-Wno-long-long',
20
'-Wno-variadic-macros',
21
'-fexceptions',
22
'-DNDEBUG',
23
# I try to refrain from having to write C++, so c99 is good for me.
24
'-std=c',
25
'-x',
26
'c',
27
'-isystem',
28
'../BoostParts',
29
'-isystem',
30
# This path will only work on OS X, but extra paths that don't exist are not
31
# harmful
32
'/System/Library/Frameworks/Python.framework/Headers',
33
'-isystem',
34
'../llvm/include',
35
'-isystem',
36
'../llvm/tools/clang/include',
37
'-I',
38
'.',
39
'-I',
40
'./ClangCompleter',
41
'-isystem',
42
'./tests/gmock/gtest',
43
'-isystem',
44
'./tests/gmock/gtest/include',
45
'-isystem',
46
'./tests/gmock',
47
'-isystem',
48
'./tests/gmock/include',
49
]
50
51
compilation_database_folder = ''
52
53
if os.path.exists( compilation_database_folder ):
54
  database = ycm_core.CompilationDatabase( compilation_database_folder )
55
else:
56
  database = None
57
58
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
59
60
def DirectoryOfThisScript():
61
  return os.path.dirname( os.path.abspath( __file__ ) )
62
63
64
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
65
  if not working_directory:
66
    return list( flags )
67
  new_flags = []
68
  make_next_absolute = False
69
  path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
70
  for flag in flags:
71
    new_flag = flag
72
73
    if make_next_absolute:
74
      make_next_absolute = False
75
      if not flag.startswith( '/' ):
76
        new_flag = os.path.join( working_directory, flag )
77
78
    for path_flag in path_flags:
79
      if flag == path_flag:
80
        make_next_absolute = True
81
        break
82
83
      if flag.startswith( path_flag ):
84
        path = flag[ len( path_flag ): ]
85
        new_flag = path_flag + os.path.join( working_directory, path )
86
        break
87
88
    if new_flag:
89
      new_flags.append( new_flag )
90
  return new_flags
91
92
93
def IsHeaderFile( filename ):
94
  extension = os.path.splitext( filename )[ 1 ]
95
  return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
96
97
98
def GetCompilationInfoForFile( filename ):
99
  # The compilation_commands.json file generated by CMake does not have entries
100
  # for header files. So we do our best by asking the db for flags for a
101
  # corresponding source file, if any. If one exists, the flags for that file
102
  # should be good enough.
103
  if IsHeaderFile( filename ):
104
    basename = os.path.splitext( filename )[ 0 ]
105
    for extension in SOURCE_EXTENSIONS:
106
      replacement_file = basename + extension
107
      if os.path.exists( replacement_file ):
108
        compilation_info = database.GetCompilationInfoForFile(
109
          replacement_file )
110
        if compilation_info.compiler_flags_:
111
          return compilation_info
112
    return None
113
  return database.GetCompilationInfoForFile( filename )
114
115
116
def FlagsForFile( filename, **kwargs ):
117
  if database:
118
    # Bear in mind that compilation_info.compiler_flags_ does NOT return a
119
    # python list, but a "list-like" StringVec object
120
    compilation_info = GetCompilationInfoForFile( filename )
121
    if not compilation_info:
122
      return None
123
124
    final_flags = MakeRelativePathsInFlagsAbsolute(
125
      compilation_info.compiler_flags_,
126
      compilation_info.compiler_working_dir_ )
127
  else:
128
    relative_to = DirectoryOfThisScript()
129
    final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
130
131
  return {
132
    'flags': final_flags,
133
    'do_cache': True
134
  }
135