Mercurial > vim-crosoft
comparison scripts/ycm_extra_conf.py @ 0:5d2c0db51914
Initial commit
| author | Ludovic Chabant <ludovic@chabant.com> |
|---|---|
| date | Tue, 17 Sep 2019 13:24:24 -0700 |
| parents | |
| children | f444739dd8af |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:5d2c0db51914 |
|---|---|
| 1 import argparse | |
| 2 import logging | |
| 3 import os.path | |
| 4 import sys | |
| 5 | |
| 6 | |
| 7 if True: # 'vim' in sys.modules: | |
| 8 sys.path.append(os.path.dirname(__file__)) | |
| 9 | |
| 10 | |
| 11 from logutil import setup_logging | |
| 12 from vsutil import SolutionCache | |
| 13 | |
| 14 | |
| 15 logger = logging.getLogger(__name__) | |
| 16 | |
| 17 | |
| 18 def _build_cflags(filename, solution, buildenv=None, slncache=None): | |
| 19 # Load the solution. | |
| 20 if not solution: | |
| 21 raise Exception( | |
| 22 "No solution path was provided in the client data!") | |
| 23 | |
| 24 cache, loaded = SolutionCache.load_or_rebuild(solution, slncache) | |
| 25 if not loaded: | |
| 26 cache.build_cache() | |
| 27 | |
| 28 # Find the current file in the solution. | |
| 29 filename_lower = filename.lower() | |
| 30 projpath = None | |
| 31 for pp, pi in cache.index.items(): | |
| 32 if filename_lower in pi: | |
| 33 projpath = pp | |
| 34 break | |
| 35 else: | |
| 36 raise Exception("File doesn't belong to the solution: %s" % filename) | |
| 37 | |
| 38 # Find the project that our file belongs to. | |
| 39 proj = cache.slnobj.find_project_by_path(projpath) | |
| 40 if not proj: | |
| 41 raise Exception("Can't find project in solution: %s" % projpath) | |
| 42 logger.debug("Found project %s: %s" % (proj.name, proj.abspath)) | |
| 43 | |
| 44 # Get the provided config/platform combo, which represent a solution | |
| 45 # configuration, and find the corresponding project configuration. | |
| 46 # For instance, a solution configuration of "Debug|Win64" could map | |
| 47 # to a "MyDebug|AnyCPU" configuration on a specific project. | |
| 48 sln_config_platform = '%s|%s' % (buildenv['Configuration'], | |
| 49 buildenv['Platform']) | |
| 50 proj_config_platform = cache.slnobj.find_project_configuration( | |
| 51 proj.guid, sln_config_platform) | |
| 52 if not proj_config_platform: | |
| 53 raise Exception("Can't find project configuration and platform for " | |
| 54 "solution configuration and platform: %s" % | |
| 55 sln_config_platform) | |
| 56 | |
| 57 # Make a build environment for the project, and figure out what | |
| 58 # kind of project it is. | |
| 59 proj_config, proj_platform = proj_config_platform.split('|') | |
| 60 | |
| 61 proj_buildenv = buildenv.copy() | |
| 62 proj_buildenv['Configuration'] = proj_config | |
| 63 proj_buildenv['Platform'] = proj_platform | |
| 64 | |
| 65 cfggroup = proj.propertygroup('Configuration', proj_buildenv) | |
| 66 cfgtype = cfggroup.get('ConfigurationType') | |
| 67 if not cfgtype: | |
| 68 raise Exception("Can't find configuration type. Did you specify a " | |
| 69 "configuration name and platform? Got: %s" % | |
| 70 proj_buildenv) | |
| 71 logger.debug("Found configuration type: %s" % cfgtype) | |
| 72 | |
| 73 # Let's prepare a list of standard stuff for C++. | |
| 74 preproc = [] | |
| 75 incpaths = [] | |
| 76 projdir = os.path.dirname(proj.abspath) | |
| 77 | |
| 78 if cfgtype == 'Makefile': | |
| 79 # It's a 'Makefile' project, which means we know as little about | |
| 80 # compiler flags as whatever information was given to VS. As | |
| 81 # such, if the solution setup doesn't give enough info, VS | |
| 82 # intellisense won't work, and neither will YouCompleteMe. | |
| 83 defaultpropgroup = proj.defaultpropertygroup(proj_buildenv) | |
| 84 | |
| 85 nmake_preproc = defaultpropgroup.get('NMakePreprocessorDefinitions') | |
| 86 preproc += nmake_preproc.strip(';').split(';') | |
| 87 | |
| 88 nmake_incpaths = defaultpropgroup.get('NMakeIncludeSearchPath') | |
| 89 incpaths += [os.path.abspath(os.path.join(projdir, p)) | |
| 90 for p in nmake_incpaths.strip(';').split(';')] | |
| 91 | |
| 92 else: | |
| 93 # We should definitely support standard VC++ projects here but | |
| 94 # I don't need it yet :) | |
| 95 raise Exception("Don't know how to handle configuration type: %s" % | |
| 96 cfgtype) | |
| 97 | |
| 98 # Build the clang/YCM flags with what we found. | |
| 99 flags = ['-x', 'c++'] # TODO: check language type from project file. | |
| 100 | |
| 101 for symbol in preproc: | |
| 102 flags.append('-D%s' % symbol) | |
| 103 for path in incpaths: | |
| 104 if path.startswith("C:\\Program Files"): | |
| 105 flags.append('-isystem') | |
| 106 else: | |
| 107 flags.append('-I') | |
| 108 flags.append(path) | |
| 109 | |
| 110 return {'flags': flags} | |
| 111 | |
| 112 | |
| 113 def _build_env_from_vim(client_data): | |
| 114 buildenv = {} | |
| 115 buildenv['Configuration'] = client_data.get('g:vimcrosoft_current_config', '') | |
| 116 buildenv['Platform'] = client_data.get('g:vimcrosoft_current_platform', '') | |
| 117 return buildenv | |
| 118 | |
| 119 | |
| 120 def Settings(**kwargs): | |
| 121 language = kwargs.get('language') | |
| 122 filename = kwargs.get('filename') | |
| 123 | |
| 124 client_data = kwargs.get('client_data', {}) | |
| 125 from_cli = kwargs.get('from_cli', False) | |
| 126 if from_cli: | |
| 127 solution = client_data.get('solution') | |
| 128 slncache = client_data.get('slncache') | |
| 129 buildenv = client_data.get('env', {}) | |
| 130 else: | |
| 131 solution = client_data.get('g:vimcrosoft_current_sln') | |
| 132 slncache = client_data.get('g:vimcrosoft_current_sln_cache') | |
| 133 buildenv = _build_env_from_vim(client_data) | |
| 134 | |
| 135 flags = None | |
| 136 | |
| 137 if language == 'cfamily': | |
| 138 try: | |
| 139 flags = _build_cflags(filename, solution, | |
| 140 buildenv=buildenv, slncache=slncache) | |
| 141 except Exception as exc: | |
| 142 if from_cli: | |
| 143 raise | |
| 144 flags = {'error': str(exc)} | |
| 145 else: | |
| 146 flags = {'error': f"Unknown language: {language}"} | |
| 147 | |
| 148 with open("D:\\P4\\DevEditor\\debug.txt", 'w') as fp: | |
| 149 fp.write("kwargs:") | |
| 150 fp.write(str(kwargs)) | |
| 151 fp.write("client_data:") | |
| 152 fp.write(str(list(kwargs['client_data'].items()))) | |
| 153 fp.write("flags:") | |
| 154 fp.write(str(flags)) | |
| 155 return flags | |
| 156 | |
| 157 | |
| 158 languages = { | |
| 159 'cfamily': ['h', 'c', 'hpp', 'cpp', 'inl'] | |
| 160 } | |
| 161 | |
| 162 | |
| 163 def _get_language(filename): | |
| 164 _, ext = os.path.splitext(filename) | |
| 165 ext = ext.lstrip('.') | |
| 166 for lang, exts in languages.items(): | |
| 167 if ext in exts: | |
| 168 return lang | |
| 169 return None | |
| 170 | |
| 171 | |
| 172 def main(): | |
| 173 parser = argparse.ArgumentParser() | |
| 174 parser.add_argument('solution', | |
| 175 help="The solution file") | |
| 176 parser.add_argument('filename', | |
| 177 help="The filename for which to get flags") | |
| 178 parser.add_argument('-p', '--property', | |
| 179 action="append", | |
| 180 help="Specifies a build property") | |
| 181 parser.add_argument('-c', '--cache', | |
| 182 help="The solution cache to use") | |
| 183 parser.add_argument('-v', '--verbose', | |
| 184 action='store_true', | |
| 185 help="Show debugging information") | |
| 186 args = parser.parse_args() | |
| 187 setup_logging(args.verbose) | |
| 188 | |
| 189 lang = _get_language(args.filename) | |
| 190 logger.debug(f"Got language {lang} for {args.filename}") | |
| 191 | |
| 192 build_env = {} | |
| 193 if args.property: | |
| 194 for p in args.property: | |
| 195 pname, pval = p.split('=', 1) | |
| 196 build_env[pname] = pval | |
| 197 logger.debug(f"Got build environment: {build_env}") | |
| 198 client_data = {'solution': args.solution, | |
| 199 'slncache': args.cache, | |
| 200 'env': build_env} | |
| 201 | |
| 202 params = {'from_cli': True, | |
| 203 'language': lang, | |
| 204 'filename': args.filename, | |
| 205 'client_data': client_data | |
| 206 } | |
| 207 flags = Settings(**params) | |
| 208 logger.info("Flags:") | |
| 209 import pprint | |
| 210 pp = pprint.PrettyPrinter(indent=2) | |
| 211 pp.pprint(flags) | |
| 212 | |
| 213 | |
| 214 if __name__ == '__main__': | |
| 215 main() |
