Keil,懂得都懂,代码补全就没有。
原理很简单,配置好.vscode文件夹下的两个json就行。
但我懒,一个工程配一遍烦死了。
正好学习一下python的用法。
单程序文件,放到目标文件夹下执行即可。
# coding=utf-8
"""
Keil工程文件夹适配VSCode
Author: DT9025A
"""
import xml.dom.minidom as xml
import re as regex
import os.path as path
import os
class Target:
target_name = ''
toolset_name = ''
target_device = ''
target_vendor = ''
target_cpu = ''
create_batch_file = '0'
def __init__(self, xml_result_elements):
Target.target_name = xml_result_elements.getElementsByTagName('TargetName')[0].firstChild.data
Target.toolset_name = xml_result_elements.getElementsByTagName('ToolsetName')[0].firstChild.data
xml_result_elements = xml_result_elements.getElementsByTagName('TargetOption')[0]. \
getElementsByTagName('TargetCommonOption')[0]
Target.target_device = xml_result_elements.getElementsByTagName('Device')[0].firstChild.data
Target.target_vendor = xml_result_elements.getElementsByTagName('Vendor')[0].firstChild.data
Target.target_cpu = xml_result_elements.getElementsByTagName('Cpu')[0].firstChild.data
Target.create_batch_file = xml_result_elements.getElementsByTagName('CreateBatchFile')[0].firstChild.data
def read_uvproj(file_path):
file_result = None
file_found = False
file_list = os.listdir(file_path)
for filename in file_list:
match_result = regex.match(".*?uvproj$", filename)
if match_result is not None:
file_result = match_result.string
file_found = True
break
if file_found is True:
file_result = path.join(file_path, file_result)
xml_result_tree = xml.parse(file_result)
xml_result_elements = xml_result_tree.getElementsByTagName('Project')
if xml_result_elements.length != 0:
xml_result_elements = xml_result_elements[0].getElementsByTagName('Targets')
if xml_result_elements.length > 0:
if xml_result_elements.length != 1:
print(f'文件 {file_result} 中有多个Target, 转换第一个')
result = Target(xml_result_elements[0])
print("------\n将要进行转换的Target:\nTarget Name : %s\nToolset Name : %s\nTarget Device : %s\n"
"Target Vendor : %s\nTarget CPU : %s\nCreate Batch File : %s\n------" %
(result.target_name, result.toolset_name, result.target_device,
result.target_vendor, result.target_cpu, result.create_batch_file))
if result.create_batch_file != '1':
print("未在Output勾选Create Batch File, 点击调试编译功能将不可用.\n"
"若想要在VSCode进行编译, 请勾选上述选项后在Keil中执行一次Build")
return result
else:
print(f'文件 {file_result} 中没有Target')
else:
print(f'文件 {file_result} 不是有效的uvproj文件')
else:
print(f'目录 {file_path} 下没有uvproj文件')
if __name__ == '__main__':
work_path = os.path.abspath(os.curdir)
vscode_conf_path = path.join(work_path, '.vscode')
print("读取目录 %s 下的uvproj文件..." % work_path)
target = read_uvproj(work_path)
if target is None:
exit(0)
if path.exists(vscode_conf_path):
user_choice = input("该目录下已经有VSCode配置文件夹, 是否继续? [y/N] ")
if regex.fullmatch("[Nn]", user_choice) or len(user_choice) == 0:
print("取消配置")
exit(0)
else:
print("创建文件夹 .vscode")
os.makedirs(vscode_conf_path)
keil_dir = input("输入Keil INC路径 (例如C:/Keil4/C51/INC) ")
if keil_dir.index('\\') != -1:
keil_dir = keil_dir.replace('\\', '/')
if keil_dir[-1] == '/':
keil_dir = keil_dir[0:-1]
file = open(path.join(vscode_conf_path, "c_cpp_properties.json"), "w", encoding='utf-8')
file.write("""{
"configurations": [
{
"name": "Keil",
"includePath": [
"${workspaceFolder}/**",
"%s/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"__CC_ARM",
"sbit=unsigned char",
"sfr=unsigned char",
"pin=unsigned char",
"sfr16=unsigned char",
"bit=unsigned char",
"idata=/**/",
"bdata=/**/",
"data=/**/",
"xdata=/**/",
"code=/**/",
"at=/**/",
"interrupt=/**/"
],
"cStandard": "c99"
}
],
"version": 4
}""" % keil_dir)
file.close()
print("写入文件 c_cpp_properties.json")
file = open(path.join(vscode_conf_path, "launch.json"), "w", encoding='utf-8')
file.write("""{
"version": "0.2.0",
"configurations": [
{
"name": "编译",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceFolder}/%s.BAT",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false
}
]
}""" % target.target_name)
file.close()
print("写入文件 launch.json")
input("完成")