]>
git.rmz.io Git - dotfiles.git/blob - vim/ycm_extra_conf.py
5d6e9f7d220561e7b81d50f31fcf12980254eb91
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
25 # '-Wno-variadic-macros',
47 def similarity_ratio(s
, t
):
48 return difflib
.SequenceMatcher(a
=s
.lower(), b
=t
.lower()).ratio()
51 def generate_qt_flags():
52 flags
= ['-isystem', '/usr/include/qt/']
53 for p
in glob('/usr/include/qt/*/'):
54 flags
+= ['-isystem', p
]
58 def find_similar_file_in_database(dbpath
, filename
):
60 logging
.info("Trying to find some file close to: " + filename
)
61 db
= json
.load(open(dbpath
))
65 entry_filename
= os
.path
.normpath(os
.path
.join(entry
["directory"],
67 ratio
= similarity_ratio(str(filename
), str(entry_filename
))
68 if ratio
> best_ratio
:
69 best_filename
= entry_filename
73 def ok_compilation_info(info
):
74 return bool(info
.compiler_flags_
)
76 def get_compilation_info_for_file(dbpath
, database
, filename
):
77 info
= database
.GetCompilationInfoForFile(filename
)
78 if ok_compilation_info(info
):
79 logging
.info("Flags for file where found in database: " + filename
)
82 logging
.info("Flags for file not found in database: " + filename
)
83 basename
= os
.path
.splitext(filename
)[0]
84 for extension
in SOURCE_EXTENSIONS
:
85 replacement_file
= basename
+ extension
86 logging
.info("Trying to replace extension with: " + extension
)
87 info
= database
.GetCompilationInfoForFile(replacement_file
)
88 if ok_compilation_info(info
):
89 logging
.info("Replacing header with: " + replacement_file
)
91 replacement_file
= find_similar_file_in_database(dbpath
, filename
)
92 logging
.info("Replacing header with: " + replacement_file
)
93 return database
.GetCompilationInfoForFile(replacement_file
)
96 def find_nearest_compilation_database(root
='.'):
97 dirs
= glob(root
+ '/*/compile_commands.json', recursive
=True)
102 logging
.info("Multiple compilation databases found!")
104 logging
.info("Selecting first: %s" % (dir))
107 parent
= os
.path
.dirname(os
.path
.abspath(root
))
109 raise RuntimeError("Could not find compile_commands.json")
110 return find_nearest_compilation_database(parent
)
113 def find_nearest(path
, target
):
115 os
.path
.join(path
, target
),
116 os
.path
.join(path
, 'build', target
),
117 os
.path
.join(path
, 'output', target
),
119 for candidate
in candidates
:
120 if os
.path
.isfile(candidate
) or os
.path
.isdir(candidate
):
121 logging
.info("Found nearest " + target
+ " at " + candidate
)
123 parent
= os
.path
.dirname(os
.path
.abspath(path
))
125 raise RuntimeError("Could not find " + target
)
126 return find_nearest(parent
, target
)
129 def make_relative_paths_in_flags_absolute(flags
, working_directory
):
130 if not working_directory
:
133 make_next_absolute
= False
134 path_flags
= [ '-isystem', '-I', '-iquote', '--sysroot=' ]
137 if make_next_absolute
:
138 make_next_absolute
= False
139 if not flag
.startswith('/'):
140 new_flag
= os
.path
.join(working_directory
, flag
)
141 for path_flag
in path_flags
:
142 if flag
== path_flag
:
143 make_next_absolute
= True
145 if flag
.startswith(path_flag
):
146 path
= flag
[ len(path_flag
): ]
147 new_flag
= path_flag
+ os
.path
.join(working_directory
, path
)
150 new_flags
.append(new_flag
)
154 def flags_for_include(root
):
156 include_path
= find_nearest(root
, 'include')
158 for dirroot
, dirnames
, filenames
in os
.walk(include_path
):
159 for dir_path
in dirnames
:
160 real_path
= os
.path
.join(dirroot
, dir_path
)
161 flags
= flags
+ ["-I" + real_path
]
163 except Exception as err
:
164 logging
.info("Error while looking flags for includes in root: " + root
)
169 def flags_for_compilation_database(root
, filename
):
171 compilation_db_path
= find_nearest_compilation_database(root
)
172 compilation_db_dir
= os
.path
.dirname(compilation_db_path
)
173 logging
.info("Set compilation database directory to " + compilation_db_dir
)
174 compilation_db
= ycm_core
.CompilationDatabase(compilation_db_dir
)
175 if not compilation_db
:
176 logging
.info("Compilation database file found but unable to load")
178 compilation_info
= get_compilation_info_for_file(
179 compilation_db_path
, compilation_db
, filename
)
180 if not compilation_info
:
181 logging
.info("No compilation info for " + filename
+ " in compilation database")
183 return make_relative_paths_in_flags_absolute(
184 compilation_info
.compiler_flags_
,
185 compilation_info
.compiler_working_dir_
)
186 except Exception as err
:
187 logging
.info("Error while trying to get flags for " + filename
+ " in compilation database")
192 def FlagsForFile(filename
, **kwargs
):
193 client_data
= kwargs
['client_data']
194 root
= client_data
['getcwd()']
196 compilation_db_flags
= flags_for_compilation_database(root
, filename
)
197 if compilation_db_flags
:
198 final_flags
= compilation_db_flags
200 final_flags
= BASE_FLAGS
201 include_flags
= flags_for_include(root
)
203 final_flags
= final_flags
+ include_flags
205 final_flags
+= generate_qt_flags()
208 '-I', root
+ '/include',
211 'flags': final_flags
+ EXTRA_FLAGS
,