Mercurial > vim-crosoft
diff scripts/find_companion.py @ 10:f444739dd8af
Improvements to YCM dynamic flags.
- Fallback to a "companion" item (e.g. header/source) or a nearby item
when no flags are found for an item.
- Finding a "companion" is also exposed as a standalone script.
- Ability to pass extra clang flags, including some from a special
file found in the .vimcrosoft directory.
- Add support for PCH and other forced-include files.
- Add options for short/long args, or forcing forward slashes.
- Debugging/troubleshooting options, including dumping a batch file and
response file to run clang directly, and the ability to auto-load a
solution's last known environment when running in command line.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Thu, 24 Sep 2020 23:02:16 -0700 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/find_companion.py Thu Sep 24 23:02:16 2020 -0700 @@ -0,0 +1,88 @@ +import argparse +import logging +import os.path +import sys + + +if True: # 'vim' in sys.modules: + sys.path.append(os.path.dirname(__file__)) + + +from logutil import setup_logging +from vshelpers import load_vimcrosoft_auto_env, find_vimcrosoft_slncache, find_item_project +from vsutil import SolutionCache, ITEM_TYPE_CPP_SRC, ITEM_TYPE_CPP_HDR + + +logger = logging.getLogger(__name__) + + +def _find_companion_item(solution, item_path, companion_name=None, companion_type=None, slncache=None): + # Try to guess the default companion file if needed. + if companion_name == None or companion_type == None: + primary_name, primary_ext = os.path.splitext(item_path) + primary_name = os.path.basename(primary_name) + if primary_ext == '.cpp': + companion_name = primary_name + '.h' + companion_type = ITEM_TYPE_CPP_HDR + elif primary_ext == '.h': + companion_name = primary_name + '.cpp' + companion_type = ITEM_TYPE_CPP_SRC + else: + raise Exception("Can't guess the companion file for: %s" % item_path) + + # Find the primary file in the solution. + cache, proj = find_item_project(item_path, solution, slncache) + logger.debug("Found project %s: %s" % (proj.name, proj.abspath)) + + # Look for the companion file in that project: + candidates = [] + dfgroup = proj.defaultitemgroup() + for cur_item in dfgroup.get_items_of_type(companion_type): + cur_item_name = os.path.basename(cur_item.include) + if cur_item_name == companion_name: + cur_item_path = proj.get_abs_item_include(cur_item) + candidates.append((cur_item, _get_companion_score(cur_item_path, item_path))) + candidates = sorted(candidates, key=lambda i: i[1], reverse=True) + logger.debug("Found candidates: %s" % [(c[0].include, c[1]) for c in candidates]) + if candidates: + return proj.get_abs_item_include(candidates[0][0]) + return None + + +def _get_companion_score(item_path, ref_path): + for i, c in enumerate(zip(item_path, ref_path)): + if c[0] != c[1]: + return i + return min(len(item_path, ref_path)) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('solution', + help="The solution file") + parser.add_argument('filename', + help="The filename for which to get the companion") + parser.add_argument('--no-auto-env', + action='store_true', + help="Don't read configuration information from Vimcrosoft cache") + parser.add_argument('-c', '--cache', + help="The solution cache to use") + parser.add_argument('-v', '--verbose', + action='store_true', + help="Show debugging information") + args = parser.parse_args() + setup_logging(args.verbose) + + build_env = {} + slncache = args.cache + if not args.no_auto_env: + load_vimcrosoft_auto_env(args.solution, build_env) + if not slncache: + slncache = find_vimcrosoft_slncache(args.solution) + + companion = _find_companion_item(args.solution, args.filename, + slncache=slncache) + print(companion) + +if __name__ == '__main__': + main()