]>
git.rmz.io Git - dotfiles.git/blob - vim/ycm_extra_conf.py
1 # https://github.com/Valloric/ycmd/blob/master/cpp/ycm/.ycm_extra_conf.py
2 # https://jonasdevlieghere.com/a-better-youcompleteme-config/
3 # https://github.com/arximboldi/dotfiles/blob/master/emacs/.ycm_extra_conf.py
12 # flags used when no compilation_db is found
18 # flags are always added
24 '-Wno-c++98-compat-pedantic',
29 # '-Wno-variadic-macros',
51 def similarity_ratio(s
, t
):
52 return difflib
.SequenceMatcher(a
=s
.lower(), b
=t
.lower()).ratio()
55 def generate_qt_flags():
56 flags
= ['-isystem', '/usr/include/qt/']
57 for p
in glob('/usr/include/qt/*/'):
58 flags
+= ['-isystem', p
]
62 def find_similar_file_in_database(dbpath
, filename
):
64 logging
.info("Trying to find some file close to: " + filename
)
65 db
= json
.load(open(dbpath
))
69 entry_filename
= os
.path
.normpath(os
.path
.join(entry
["directory"],
71 ratio
= similarity_ratio(str(filename
), str(entry_filename
))
72 if ratio
> best_ratio
:
73 best_filename
= entry_filename
77 def ok_compilation_info(info
):
78 return bool(info
.compiler_flags_
)
80 def get_compilation_info_for_file(dbpath
, database
, filename
):
81 info
= database
.GetCompilationInfoForFile(filename
)
82 if ok_compilation_info(info
):
83 logging
.info("Flags for file where found in database: " + filename
)
86 logging
.info("Flags for file not found in database: " + filename
)
87 basename
= os
.path
.splitext(filename
)[0]
88 for extension
in SOURCE_EXTENSIONS
:
89 replacement_file
= basename
+ extension
90 logging
.info("Trying to replace extension with: " + extension
)
91 info
= database
.GetCompilationInfoForFile(replacement_file
)
92 if ok_compilation_info(info
):
93 logging
.info("Replacing header with: " + replacement_file
)
95 replacement_file
= find_similar_file_in_database(dbpath
, filename
)
96 logging
.info("Replacing header with: " + replacement_file
)
97 return database
.GetCompilationInfoForFile(replacement_file
)
100 def find_nearest_compilation_database(root
='.'):
101 dirs
= glob(root
+ '/*/compile_commands.json', recursive
=True)
106 logging
.info("Multiple compilation databases found!")
108 logging
.info("Selecting first: %s" % (dir))
111 parent
= os
.path
.dirname(os
.path
.abspath(root
))
113 raise RuntimeError("Could not find compile_commands.json")
114 return find_nearest_compilation_database(parent
)
117 def find_nearest(path
, target
):
119 os
.path
.join(path
, target
),
120 os
.path
.join(path
, 'build', target
),
121 os
.path
.join(path
, 'output', target
),
123 for candidate
in candidates
:
124 if os
.path
.isfile(candidate
) or os
.path
.isdir(candidate
):
125 logging
.info("Found nearest " + target
+ " at " + candidate
)
127 parent
= os
.path
.dirname(os
.path
.abspath(path
))
129 raise RuntimeError("Could not find " + target
)
130 return find_nearest(parent
, target
)
133 def make_relative_paths_in_flags_absolute(flags
, working_directory
):
134 if not working_directory
:
137 make_next_absolute
= False
138 path_flags
= [ '-isystem', '-I', '-iquote', '--sysroot=' ]
141 if make_next_absolute
:
142 make_next_absolute
= False
143 if not flag
.startswith('/'):
144 new_flag
= os
.path
.join(working_directory
, flag
)
145 for path_flag
in path_flags
:
146 if flag
== path_flag
:
147 make_next_absolute
= True
149 if flag
.startswith(path_flag
):
150 path
= flag
[ len(path_flag
): ]
151 new_flag
= path_flag
+ os
.path
.join(working_directory
, path
)
154 new_flags
.append(new_flag
)
158 def flags_for_include(root
):
160 include_path
= find_nearest(root
, 'include')
162 for dirroot
, dirnames
, filenames
in os
.walk(include_path
):
163 for dir_path
in dirnames
:
164 real_path
= os
.path
.join(dirroot
, dir_path
)
165 flags
= flags
+ ["-I" + real_path
]
167 except Exception as err
:
168 logging
.info("Error while looking flags for includes in root: " + root
)
173 def flags_for_compilation_database(root
, filename
):
175 compilation_db_path
= find_nearest_compilation_database(root
)
176 compilation_db_dir
= os
.path
.dirname(compilation_db_path
)
177 logging
.info("Set compilation database directory to " + compilation_db_dir
)
178 compilation_db
= ycm_core
.CompilationDatabase(compilation_db_dir
)
179 if not compilation_db
:
180 logging
.info("Compilation database file found but unable to load")
182 compilation_info
= get_compilation_info_for_file(
183 compilation_db_path
, compilation_db
, filename
)
184 if not compilation_info
:
185 logging
.info("No compilation info for " + filename
+ " in compilation database")
187 return make_relative_paths_in_flags_absolute(
188 compilation_info
.compiler_flags_
,
189 compilation_info
.compiler_working_dir_
)
190 except Exception as err
:
191 logging
.info("Error while trying to get flags for " + filename
+ " in compilation database")
196 def FlagsForFile(filename
, **kwargs
):
197 client_data
= kwargs
['client_data']
198 root
= client_data
['getcwd()']
200 compilation_db_flags
= flags_for_compilation_database(root
, filename
)
201 if compilation_db_flags
:
202 final_flags
= compilation_db_flags
204 final_flags
= BASE_FLAGS
205 include_flags
= flags_for_include(root
)
207 final_flags
= final_flags
+ include_flags
209 final_flags
+= generate_qt_flags()
212 '-I', root
+ '/include',
215 'flags': final_flags
+ EXTRA_FLAGS
,