]> git.rmz.io Git - dotfiles.git/blob - ycm_extra_conf.py
mutt: don't ask to delete, don't mark old
[dotfiles.git] / ycm_extra_conf.py
1 # This file is NOT licensed under the GPLv3, which is the license for the rest
2 # of YouCompleteMe.
3 #
4 # Here's the license text for this file:
5 #
6 # This is free and unencumbered software released into the public domain.
7 #
8 # Anyone is free to copy, modify, publish, use, compile, sell, or
9 # distribute this software, either in source code form or as a compiled
10 # binary, for any purpose, commercial or non-commercial, and by any
11 # means.
12 #
13 # In jurisdictions that recognize copyright laws, the author or authors
14 # of this software dedicate any and all copyright interest in the
15 # software to the public domain. We make this dedication for the benefit
16 # of the public at large and to the detriment of our heirs and
17 # successors. We intend this dedication to be an overt act of
18 # relinquishment in perpetuity of all present and future rights to this
19 # software under copyright law.
20 #
21 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 # IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25 # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26 # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 # OTHER DEALINGS IN THE SOFTWARE.
28 #
29 # For more information, please refer to <http://unlicense.org/>
30
31 import os
32 import shlex
33 import subprocess
34 import ycm_core
35
36 # These are the compilation flags that will be used in case there's no
37 # compilation database set (by default, one is not set).
38 # CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
39 flags = [
40 '-Wall',
41 '-Wextra',
42 '-Wshadow',
43 #'-Werror',
44 #'-Wc++98-compat',
45 '-Wno-long-long',
46 '-Wno-variadic-macros',
47 '-fexceptions',
48 '-DNDEBUG',
49 # THIS IS IMPORTANT! Without a "-std=<something>" flag, clang won't know which
50 # language to use when compiling headers. So it will guess. Badly. So C++
51 # headers will be compiled as C headers. You don't want that so ALWAYS specify
52 # a "-std=<something>".
53 # For a C project, you would set this to something like 'c99' instead of
54 # 'c++11'.
55 '-std=c++11',
56 # ...and the same thing goes for the magic -x option which specifies the
57 # language that the files to be compiled are written in. This is mostly
58 # relevant for c++ headers.
59 # For a C project, you would set this to 'c' instead of 'c++'.
60 '-x', 'c++',
61 '-isystem', '/usr/include',
62 ]
63
64 # This function makes it easy to pull in additional flags from pkg-config
65 def rospack():
66 cmd = ['rospack', 'cflags-only-I']
67 print subprocess.Popen('pwd')
68 out = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE).stdout
69 line = out.readline()[:-1].split(" ")
70 includes = []
71 for include in line:
72 includes += ['-I', include]
73 return filter(lambda a: a != ' ', line)
74
75 flags += rospack()
76
77 # Set this to the absolute path to the folder (NOT the file!) containing the
78 # compile_commands.json file to use that instead of 'flags'. See here for
79 # more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
80 #
81 # Most projects will NOT need to set this to anything; you can just change the
82 # 'flags' list of compilation flags. Notice that YCM itself uses that approach.
83 compilation_database_folder = ''
84
85 if os.path.exists( compilation_database_folder ):
86 database = ycm_core.CompilationDatabase( compilation_database_folder )
87 else:
88 database = None
89
90 SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
91
92 def DirectoryOfThisScript():
93 return os.path.dirname( os.path.abspath( __file__ ) )
94
95
96 def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
97 if not working_directory:
98 return list( flags )
99 new_flags = []
100 make_next_absolute = False
101 path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
102 for flag in flags:
103 new_flag = flag
104
105 if make_next_absolute:
106 make_next_absolute = False
107 if not flag.startswith( '/' ):
108 new_flag = os.path.join( working_directory, flag )
109
110 for path_flag in path_flags:
111 if flag == path_flag:
112 make_next_absolute = True
113 break
114
115 if flag.startswith( path_flag ):
116 path = flag[ len( path_flag ): ]
117 new_flag = path_flag + os.path.join( working_directory, path )
118 break
119
120 if new_flag:
121 new_flags.append( new_flag )
122 return new_flags
123
124
125 def IsHeaderFile( filename ):
126 extension = os.path.splitext( filename )[ 1 ]
127 return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
128
129
130 def GetCompilationInfoForFile( filename ):
131 # The compilation_commands.json file generated by CMake does not have entries
132 # for header files. So we do our best by asking the db for flags for a
133 # corresponding source file, if any. If one exists, the flags for that file
134 # should be good enough.
135 if IsHeaderFile( filename ):
136 basename = os.path.splitext( filename )[ 0 ]
137 for extension in SOURCE_EXTENSIONS:
138 replacement_file = basename + extension
139 if os.path.exists( replacement_file ):
140 compilation_info = database.GetCompilationInfoForFile(
141 replacement_file )
142 if compilation_info.compiler_flags_:
143 return compilation_info
144 return None
145 return database.GetCompilationInfoForFile( filename )
146
147
148 def FlagsForFile( filename, **kwargs ):
149 if database:
150 # Bear in mind that compilation_info.compiler_flags_ does NOT return a
151 # python list, but a "list-like" StringVec object
152 compilation_info = GetCompilationInfoForFile( filename )
153 if not compilation_info:
154 return None
155
156 final_flags = MakeRelativePathsInFlagsAbsolute(
157 compilation_info.compiler_flags_,
158 compilation_info.compiler_working_dir_ )
159
160 # NOTE: This is just for YouCompleteMe; it's highly likely that your project
161 # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR
162 # ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT.
163 try:
164 final_flags.remove( '-stdlib=libc++' )
165 except ValueError:
166 pass
167 else:
168 relative_to = DirectoryOfThisScript()
169 final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
170
171 return {
172 'flags': final_flags,
173 'do_cache': True
174 }