]>
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/
33 def find_similar_file_in_database(dbpath
, filename
):
36 logging
.info("Trying to find some file close to: " + filename
)
37 db
= json
.load(open(dbpath
))
39 best_distance
= 1 << 31
41 entry_filename
= os
.path
.normpath(
42 os
.path
.join(entry
["directory"], entry
["file"]))
43 distance
= Levenshtein
.distance(str(filename
), str(entry_filename
))
44 if distance
< best_distance
:
45 best_filename
= entry_filename
46 best_distance
= distance
49 def ok_compilation_info(info
):
50 return bool(info
.compiler_flags_
)
52 def get_compilation_info_for_file(dbpath
, database
, filename
):
53 info
= database
.GetCompilationInfoForFile(filename
)
54 if ok_compilation_info(info
):
55 logging
.info("Flags for file where found in database: " + filename
)
58 logging
.info("Flags for file not found in database: " + filename
)
59 basename
= os
.path
.splitext(filename
)[0]
60 for extension
in SOURCE_EXTENSIONS
:
61 replacement_file
= basename
+ extension
62 logging
.info("Trying to replace extension with: " + extension
)
63 info
= database
.GetCompilationInfoForFile(replacement_file
)
64 if ok_compilation_info(info
):
65 logging
.info("Replacing header with: " + replacement_file
)
67 replacement_file
= find_similar_file_in_database(dbpath
, filename
)
68 logging
.info("Replacing header with: " + replacement_file
)
69 return database
.GetCompilationInfoForFile(replacement_file
)
71 def find_nearest(path
, target
):
73 os
.path
.join(path
, target
),
74 os
.path
.join(path
, 'build', target
),
75 os
.path
.join(path
, 'output', target
),
77 for candidate
in candidates
:
78 if os
.path
.isfile(candidate
) or os
.path
.isdir(candidate
):
79 logging
.info("Found nearest " + target
+ " at " + candidate
)
81 parent
= os
.path
.dirname(os
.path
.abspath(path
))
83 raise RuntimeError("Could not find " + target
)
84 return find_nearest(parent
, target
)
86 def make_relative_paths_in_flags_absolute(flags
, working_directory
):
87 if not working_directory
:
90 make_next_absolute
= False
91 path_flags
= [ '-isystem', '-I', '-iquote', '--sysroot=' ]
94 if make_next_absolute
:
95 make_next_absolute
= False
96 if not flag
.startswith('/'):
97 new_flag
= os
.path
.join(working_directory
, flag
)
98 for path_flag
in path_flags
:
100 make_next_absolute
= True
102 if flag
.startswith(path_flag
):
103 path
= flag
[ len(path_flag
): ]
104 new_flag
= path_flag
+ os
.path
.join(working_directory
, path
)
107 new_flags
.append(new_flag
)
110 def flags_for_clang_complete(root
):
112 clang_complete_path
= find_nearest(root
, '.clang_complete')
113 clang_complete_flags
= open(clang_complete_path
, 'r').read().splitlines()
114 return clang_complete_flags
115 except Exception, err
:
116 logging
.info("Error while looking flags for .clang_complete in root: " + root
)
120 def flags_for_include(root
):
122 include_path
= find_nearest(root
, 'include')
124 for dirroot
, dirnames
, filenames
in os
.walk(include_path
):
125 for dir_path
in dirnames
:
126 real_path
= os
.path
.join(dirroot
, dir_path
)
127 flags
= flags
+ ["-I" + real_path
]
129 except Exception, err
:
130 logging
.info("Error while looking flags for includes in root: " + root
)
134 def flags_for_compilation_database(root
, filename
):
136 compilation_db_path
= find_nearest(root
, 'compile_commands.json')
137 compilation_db_dir
= os
.path
.dirname(compilation_db_path
)
138 logging
.info("Set compilation database directory to " + compilation_db_dir
)
139 compilation_db
= ycm_core
.CompilationDatabase(compilation_db_dir
)
140 if not compilation_db
:
141 logging
.info("Compilation database file found but unable to load")
143 compilation_info
= get_compilation_info_for_file(
144 compilation_db_path
, compilation_db
, filename
)
145 if not compilation_info
:
146 logging
.info("No compilation info for " + filename
+ " in compilation database")
148 return make_relative_paths_in_flags_absolute(
149 compilation_info
.compiler_flags_
,
150 compilation_info
.compiler_working_dir_
)
151 except Exception, err
:
152 logging
.info("Error while trying to get flags for " + filename
+ " in compilation database")
156 def flags_for_file(filename
):
157 root
= os
.path
.realpath(filename
)
158 compilation_db_flags
= flags_for_compilation_database(root
, filename
)
159 if compilation_db_flags
:
160 final_flags
= compilation_db_flags
162 final_flags
= BASE_FLAGS
163 clang_flags
= flags_for_clang_complete(root
)
165 final_flags
= final_flags
+ clang_flags
166 include_flags
= flags_for_include(root
)
168 final_flags
= final_flags
+ include_flags
170 'flags': final_flags
,
174 FlagsForFile
= flags_for_file