]>
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
16 '-isystem', '/usr/include',
17 '-isystem', '/usr/local/include',
27 # '-Wno-variadic-macros',
49 def similarity_ratio(s
, t
):
50 return difflib
.SequenceMatcher(a
=s
.lower(), b
=t
.lower()).ratio()
53 def generate_qt_flags():
54 flags
= ['-isystem', '/usr/include/qt/']
55 for p
in glob('/usr/include/qt/*/'):
56 flags
+= ['-isystem', p
]
60 def find_similar_file_in_database(dbpath
, filename
):
62 logging
.info("Trying to find some file close to: " + filename
)
63 db
= json
.load(open(dbpath
))
67 entry_filename
= os
.path
.normpath(os
.path
.join(entry
["directory"],
69 ratio
= similarity_ratio(str(filename
), str(entry_filename
))
70 if ratio
> best_ratio
:
71 best_filename
= entry_filename
75 def ok_compilation_info(info
):
76 return bool(info
.compiler_flags_
)
78 def get_compilation_info_for_file(dbpath
, database
, filename
):
79 info
= database
.GetCompilationInfoForFile(filename
)
80 if ok_compilation_info(info
):
81 logging
.info("Flags for file where found in database: " + filename
)
84 logging
.info("Flags for file not found in database: " + filename
)
85 basename
= os
.path
.splitext(filename
)[0]
86 for extension
in SOURCE_EXTENSIONS
:
87 replacement_file
= basename
+ extension
88 logging
.info("Trying to replace extension with: " + extension
)
89 info
= database
.GetCompilationInfoForFile(replacement_file
)
90 if ok_compilation_info(info
):
91 logging
.info("Replacing header with: " + replacement_file
)
93 replacement_file
= find_similar_file_in_database(dbpath
, filename
)
94 logging
.info("Replacing header with: " + replacement_file
)
95 return database
.GetCompilationInfoForFile(replacement_file
)
98 def find_nearest_compilation_database(root
='.'):
99 dirs
= glob(root
+ '/*/compile_commands.json', recursive
=True)
104 logging
.info("Multiple compilation databases found!")
106 logging
.info("Selecting first: %s" % (dir))
109 parent
= os
.path
.dirname(os
.path
.abspath(root
))
111 raise RuntimeError("Could not find compile_commands.json")
112 return find_nearest_compilation_database(parent
)
115 def find_nearest(path
, target
):
117 os
.path
.join(path
, target
),
118 os
.path
.join(path
, 'build', target
),
119 os
.path
.join(path
, 'output', target
),
121 for candidate
in candidates
:
122 if os
.path
.isfile(candidate
) or os
.path
.isdir(candidate
):
123 logging
.info("Found nearest " + target
+ " at " + candidate
)
125 parent
= os
.path
.dirname(os
.path
.abspath(path
))
127 raise RuntimeError("Could not find " + target
)
128 return find_nearest(parent
, target
)
131 def make_relative_paths_in_flags_absolute(flags
, working_directory
):
132 if not working_directory
:
135 make_next_absolute
= False
136 path_flags
= [ '-isystem', '-I', '-iquote', '--sysroot=' ]
139 if make_next_absolute
:
140 make_next_absolute
= False
141 if not flag
.startswith('/'):
142 new_flag
= os
.path
.join(working_directory
, flag
)
143 for path_flag
in path_flags
:
144 if flag
== path_flag
:
145 make_next_absolute
= True
147 if flag
.startswith(path_flag
):
148 path
= flag
[ len(path_flag
): ]
149 new_flag
= path_flag
+ os
.path
.join(working_directory
, path
)
152 new_flags
.append(new_flag
)
156 def flags_for_include(root
):
158 include_path
= find_nearest(root
, 'include')
160 for dirroot
, dirnames
, filenames
in os
.walk(include_path
):
161 for dir_path
in dirnames
:
162 real_path
= os
.path
.join(dirroot
, dir_path
)
163 flags
= flags
+ ["-I" + real_path
]
165 except Exception as err
:
166 logging
.info("Error while looking flags for includes in root: " + root
)
171 def flags_for_compilation_database(root
, filename
):
173 compilation_db_path
= find_nearest_compilation_database(root
)
174 compilation_db_dir
= os
.path
.dirname(compilation_db_path
)
175 logging
.info("Set compilation database directory to " + compilation_db_dir
)
176 compilation_db
= ycm_core
.CompilationDatabase(compilation_db_dir
)
177 if not compilation_db
:
178 logging
.info("Compilation database file found but unable to load")
180 compilation_info
= get_compilation_info_for_file(
181 compilation_db_path
, compilation_db
, filename
)
182 if not compilation_info
:
183 logging
.info("No compilation info for " + filename
+ " in compilation database")
185 return make_relative_paths_in_flags_absolute(
186 compilation_info
.compiler_flags_
,
187 compilation_info
.compiler_working_dir_
)
188 except Exception as err
:
189 logging
.info("Error while trying to get flags for " + filename
+ " in compilation database")
194 def FlagsForFile(filename
, **kwargs
):
195 client_data
= kwargs
['client_data']
196 root
= client_data
['getcwd()']
198 compilation_db_flags
= flags_for_compilation_database(root
, filename
)
199 if compilation_db_flags
:
200 final_flags
= compilation_db_flags
202 final_flags
= BASE_FLAGS
203 include_flags
= flags_for_include(root
)
205 final_flags
= final_flags
+ include_flags
207 final_flags
+= generate_qt_flags()
210 '-I', root
+ '/include',
213 'flags': final_flags
+ EXTRA_FLAGS
,