X-Git-Url: https://git.rmz.io/dotfiles.git/blobdiff_plain/de55c1c46e484a81bed3730f7773d6745ef4405c..refs/heads/lazyvim:/vim/ycm_extra_conf.py diff --git a/vim/ycm_extra_conf.py b/vim/ycm_extra_conf.py index f02f017..f19fa08 100644 --- a/vim/ycm_extra_conf.py +++ b/vim/ycm_extra_conf.py @@ -1,17 +1,34 @@ # https://github.com/Valloric/ycmd/blob/master/cpp/ycm/.ycm_extra_conf.py # https://jonasdevlieghere.com/a-better-youcompleteme-config/ +# https://github.com/arximboldi/dotfiles/blob/master/emacs/.ycm_extra_conf.py import os import os.path +from glob import glob import logging import ycm_core +import difflib +# flags used when no compilation_db is found BASE_FLAGS = [ - '-Wall', '-std=c++1z', - '-xc++', - '-I/usr/lib/' - '-I/usr/include/' + '-x', 'c++', +] + +# flags are always added +EXTRA_FLAGS = [ + '-Wall', + '-Wextra', + '-Weverything', + '-Wno-c++98-compat', + '-Wno-c++98-compat-pedantic', + # '-Wshadow', + # '-Werror', + # '-Wc++98-compat', + # '-Wno-long-long', + # '-Wno-variadic-macros', + # '-fexceptions', + # '-DNDEBUG', ] SOURCE_EXTENSIONS = [ @@ -23,50 +40,66 @@ SOURCE_EXTENSIONS = [ '.mm' ] -HEADER_EXTENSIONS = [ - '.h', - '.hxx', - '.hpp', - '.hh' -] + +def generate_qt_flags(): + flags = ['-isystem', '/usr/include/qt/'] + for p in glob('/usr/include/qt/*/'): + flags += ['-isystem', p] + return flags + + +def similarity_ratio(s, t): + return difflib.SequenceMatcher(a=s.lower(), b=t.lower()).ratio() + def find_similar_file_in_database(dbpath, filename): import json - import Levenshtein logging.info("Trying to find some file close to: " + filename) - db = json.load(open(dbpath)) + db = json.load(open(dbpath+ "/compile_commands.json")) + best_filename = '' - best_distance = 1 << 31 + best_ratio = 0 for entry in db: - entry_filename = os.path.normpath( - os.path.join(entry["directory"], entry["file"])) - distance = Levenshtein.distance(str(filename), str(entry_filename)) - if distance < best_distance: - best_filename = entry_filename - best_distance = distance - return best_filename + entry_filename = os.path.normpath(os.path.join(entry["directory"], + entry["file"])) -def ok_compilation_info(info): - return bool(info.compiler_flags_) + if filename == entry_filename: + logging.info("Found exact match: " + entry_filename) + return entry_filename -def get_compilation_info_for_file(dbpath, database, filename): - info = database.GetCompilationInfoForFile(filename) - if ok_compilation_info(info): - logging.info("Flags for file where found in database: " + filename) - return info - else: - logging.info("Flags for file not found in database: " + filename) basename = os.path.splitext(filename)[0] for extension in SOURCE_EXTENSIONS: replacement_file = basename + extension - logging.info("Trying to replace extension with: " + extension) - info = database.GetCompilationInfoForFile(replacement_file) - if ok_compilation_info(info): - logging.info("Replacing header with: " + replacement_file) - return info - replacement_file = find_similar_file_in_database(dbpath, filename) - logging.info("Replacing header with: " + replacement_file) - return database.GetCompilationInfoForFile(replacement_file) + if entry_filename == replacement_file: + logging.info("Found match: " + replacement_file) + return entry_filename + + ratio = similarity_ratio(str(filename), str(entry_filename)) + if ratio > best_ratio: + best_filename = entry_filename + best_ratio = ratio + + logging.info("Found closest match: " + best_filename) + return best_filename + + +def find_nearest_compilation_database(root='.'): + dirs = glob(root + '/*/compile_commands.json', recursive=True) + + if len(dirs) == 1: + return dirs[0] + elif len(dirs) > 1: + logging.info("Multiple compilation databases found!") + logging.info(dirs) + dirs.sort(key=lambda x: os.stat(x).st_mtime, reverse=True) + logging.info("Selecting newest: %s" % (dirs[0])) + return dirs[0] + + parent = os.path.dirname(os.path.abspath(root)) + if parent == root: + raise RuntimeError("Could not find compile_commands.json") + return find_nearest_compilation_database(parent) + def find_nearest(path, target): candidates = [ @@ -83,39 +116,6 @@ def find_nearest(path, target): raise RuntimeError("Could not find " + target) return find_nearest(parent, target) -def make_relative_paths_in_flags_absolute(flags, working_directory): - if not working_directory: - return list(flags) - new_flags = [] - make_next_absolute = False - path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] - for flag in flags: - new_flag = flag - if make_next_absolute: - make_next_absolute = False - if not flag.startswith('/'): - new_flag = os.path.join(working_directory, flag) - for path_flag in path_flags: - if flag == path_flag: - make_next_absolute = True - break - if flag.startswith(path_flag): - path = flag[ len(path_flag): ] - new_flag = path_flag + os.path.join(working_directory, path) - break - if new_flag: - new_flags.append(new_flag) - return new_flags - -def flags_for_clang_complete(root): - try: - clang_complete_path = find_nearest(root, '.clang_complete') - clang_complete_flags = open(clang_complete_path, 'r').read().splitlines() - return clang_complete_flags - except Exception, err: - logging.info("Error while looking flags for .clang_complete in root: " + root) - logging.error(err) - return None def flags_for_include(root): try: @@ -126,49 +126,60 @@ def flags_for_include(root): real_path = os.path.join(dirroot, dir_path) flags = flags + ["-I" + real_path] return flags - except Exception, err: + except Exception as err: logging.info("Error while looking flags for includes in root: " + root) logging.error(err) return None -def flags_for_compilation_database(root, filename): + +def get_compilation_database(root): try: - compilation_db_path = find_nearest(root, 'compile_commands.json') + compilation_db_path = find_nearest_compilation_database(root) compilation_db_dir = os.path.dirname(compilation_db_path) logging.info("Set compilation database directory to " + compilation_db_dir) - compilation_db = ycm_core.CompilationDatabase(compilation_db_dir) - if not compilation_db: + db = ycm_core.CompilationDatabase(compilation_db_dir) + if db is None: logging.info("Compilation database file found but unable to load") return None - compilation_info = get_compilation_info_for_file( - compilation_db_path, compilation_db, filename) - if not compilation_info: - logging.info("No compilation info for " + filename + " in compilation database") - return None - return make_relative_paths_in_flags_absolute( - compilation_info.compiler_flags_, - compilation_info.compiler_working_dir_) - except Exception, err: - logging.info("Error while trying to get flags for " + filename + " in compilation database") + return db + except Exception as err: + logging.info("Error while trying to find compilation database: " + root) logging.error(err) return None -def flags_for_file(filename): - root = os.path.realpath(filename) - compilation_db_flags = flags_for_compilation_database(root, filename) - if compilation_db_flags: - final_flags = compilation_db_flags + +def Settings(**kwargs): + if kwargs['language'] != 'cfamily': + return {} + + print(kwargs) + client_data = kwargs['client_data'] + root = client_data.get('getcwd()', '.') + filename = kwargs['filename'] + + database = get_compilation_database(root) + if database: + filename = find_similar_file_in_database(database.database_directory, + filename) + compilation_info = database.GetCompilationInfoForFile(filename) + print(compilation_info) + if not compilation_info.compiler_flags_: + return {} #TODO use default flags + final_flags = list(compilation_info.compiler_flags_) + include_path_relative_to_dir = compilation_info.compiler_working_dir_ else: final_flags = BASE_FLAGS - clang_flags = flags_for_clang_complete(root) - if clang_flags: - final_flags = final_flags + clang_flags include_flags = flags_for_include(root) if include_flags: - final_flags = final_flags + include_flags + final_flags += include_flags + final_flags += generate_qt_flags() + final_flags += ['-I', root, + '-I', root + '/include'] + include_path_relative_to_dir = root + return { - 'flags': final_flags, + 'flags': final_flags + EXTRA_FLAGS, + 'include_paths_relative_to_dir': include_path_relative_to_dir, + 'override_filename': filename, 'do_cache': True } - -FlagsForFile = flags_for_file