From 2796de88f5d81abc4630291c4acd5b485b376c8b Mon Sep 17 00:00:00 2001 From: Kirigaya <1193466151@qq.com> Date: Mon, 6 Jan 2025 16:14:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=A2=9E=E5=8A=A0/=E5=88=A0?= =?UTF-8?q?=E9=99=A4=20device=20=E7=9A=84=E6=9B=B4=E6=96=B0=20&=20?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=A4=8D=E5=86=99=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 ++- l10n/bundle.l10n.de.json | 8 +++++- l10n/bundle.l10n.en.json | 8 +++++- l10n/bundle.l10n.ja.json | 8 +++++- l10n/bundle.l10n.zh-cn.json | 8 +++++- l10n/bundle.l10n.zh-tw.json | 8 +++++- package.json | 50 +++++++++++++++++----------------- project/property-schema.json | 5 ++-- src/extension.ts | 7 ++++- src/function/lsp-client/cdn.ts | 4 +-- src/global/opeParam.ts | 5 ++++ src/global/util.ts | 13 ++++++++- src/hdlFs/file.ts | 15 +++++++--- src/manager/PL/index.ts | 37 +++++++++++++++++++------ src/manager/PL/xilinx.ts | 8 ++++++ src/manager/prj.ts | 39 ++++++++++++++++++-------- 16 files changed, 167 insertions(+), 60 deletions(-) diff --git a/.gitignore b/.gitignore index 9d9e4d9..3e061ea 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,6 @@ resources/dide-viewer/view/* resources/dide-lsp/server/* resources/dide-lsp/static/* resources/dide-netlist/static/* -resources/dide-netlist/view/* \ No newline at end of file +resources/dide-netlist/view/* +scripts/update-icon.py +scripts/vscode-package.py \ No newline at end of file diff --git a/l10n/bundle.l10n.de.json b/l10n/bundle.l10n.de.json index ffcb9fe..a53a58d 100644 --- a/l10n/bundle.l10n.de.json +++ b/l10n/bundle.l10n.de.json @@ -111,5 +111,11 @@ "toolbar.save-as-pdf": "Aktuelle Ansicht als PDF speichern", "pdf-file": "PDF-Datei", "export-pdf": "PDF wird exportiert", - "info.process-killed": "Prozess {0} wurde zerstört" + "info.process-killed": "Prozess {0} wurde zerstört", + "info.addDevice.placeholder": "Bitte geben Sie den Namen des Geräts ein", + "warning.addDevice.name-taken": "Der Name des Geräts {0} ist bereits vergeben", + "info.addDevice.add-success": "Gerät {0} wurde erfolgreich hinzugefügt", + "info.delDevice.placeholder": "Wählen Sie das zu löschende Gerät aus", + "info.delDevice.del-success": "Gerät {0} wurde erfolgreich gelöscht", + "info.progress.launch-lsp": "Starten Sie den Digital LSP-Sprachserver" } \ No newline at end of file diff --git a/l10n/bundle.l10n.en.json b/l10n/bundle.l10n.en.json index 6d8f114..60fdbf4 100644 --- a/l10n/bundle.l10n.en.json +++ b/l10n/bundle.l10n.en.json @@ -111,5 +111,11 @@ "toolbar.save-as-pdf": "Save current view as PDF", "pdf-file": "PDF file", "export-pdf": "Exporting PDF", - "info.process-killed": "Process {0} has been destroyed" + "info.process-killed": "Process {0} has been destroyed", + "info.addDevice.placeholder": "Please enter the name of the device", + "warning.addDevice.name-taken": "The name of device {0} is already taken", + "info.addDevice.add-success": "Device {0} has been successfully added", + "info.delDevice.placeholder": "Select the device to delete", + "info.delDevice.del-success": "Device {0} has been successfully deleted", + "info.progress.launch-lsp": "Start the Digital LSP language server" } \ No newline at end of file diff --git a/l10n/bundle.l10n.ja.json b/l10n/bundle.l10n.ja.json index 2f12f40..0143285 100644 --- a/l10n/bundle.l10n.ja.json +++ b/l10n/bundle.l10n.ja.json @@ -111,5 +111,11 @@ "toolbar.save-as-pdf": "現在のビューをPDFとして保存", "pdf-file": "PDFファイル", "export-pdf": "PDFをエクスポート中", - "info.process-killed": "プロセス {0} は破棄されました" + "info.process-killed": "プロセス {0} は破棄されました", + "info.addDevice.placeholder": "デバイスの名前を入力してください", + "warning.addDevice.name-taken": "デバイス {0} の名前は既に使用されています", + "info.addDevice.add-success": "デバイス {0} が正常に追加されました", + "info.delDevice.placeholder": "削除するデバイスを選択してください", + "info.delDevice.del-success": "デバイス {0} は正常に削除されました", + "info.progress.launch-lsp": "Digital LSP 言語サーバーを起動する" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-cn.json b/l10n/bundle.l10n.zh-cn.json index f28c4d0..a9bd5f7 100644 --- a/l10n/bundle.l10n.zh-cn.json +++ b/l10n/bundle.l10n.zh-cn.json @@ -111,5 +111,11 @@ "toolbar.save-as-pdf": "将当前视图保存为 pdf", "pdf-file": "pdf 文件", "export-pdf": "正在导出 pdf", - "info.process-killed": "进程 {0} 已经被销毁" + "info.process-killed": "进程 {0} 已经被销毁", + "info.addDevice.placeholder": "请输入 device 的名字", + "warning.addDevice.name-taken": "device {0} 的名字已经被占用", + "info.addDevice.add-success": "device {0} 已被成功添加", + "info.delDevice.placeholder": "选择需要删除的 device", + "info.delDevice.del-success": "device {0} 已被成功删除", + "info.progress.launch-lsp": "启动 Digital LSP 语言服务器" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-tw.json b/l10n/bundle.l10n.zh-tw.json index 7c3ba19..da35311 100644 --- a/l10n/bundle.l10n.zh-tw.json +++ b/l10n/bundle.l10n.zh-tw.json @@ -111,5 +111,11 @@ "toolbar.save-as-pdf": "將目前視圖儲存為PDF", "pdf-file": "PDF檔案", "export-pdf": "正在匯出PDF", - "info.process-killed": "進程 {0} 已經被銷毀" + "info.process-killed": "進程 {0} 已經被銷毀", + "info.addDevice.placeholder": "請輸入設備的名稱", + "warning.addDevice.name-taken": "設備 {0} 的名字已經被佔用", + "info.addDevice.add-success": "設備 {0} 已成功添加", + "info.delDevice.placeholder": "選擇需要刪除的設備", + "info.delDevice.del-success": "設備 {0} 已被成功刪除", + "info.progress.launch-lsp": "啟動 Digital LSP 語言伺服器" } \ No newline at end of file diff --git a/package.json b/package.json index 830ea60..cef8361 100644 --- a/package.json +++ b/package.json @@ -420,130 +420,130 @@ }, { "command": "digital-ide.treeView.arch.expand", - "category": "tool", + "category": "Digital-IDE", "icon": "$(expand-all)", "title": "%digital-ide.treeView.arch.expand.title%" }, { "command": "digital-ide.treeView.arch.collapse", - "category": "tool", + "category": "Digital-IDE", "icon": "$(collapse-all)", "title": "%digital-ide.treeView.arch.collapse.title%" }, { "command": "digital-ide.treeView.arch.refresh", - "category": "tool", + "category": "Digital-IDE", "icon": "$(refresh)", "title": "%digital-ide.treeView.arch.refresh.title%" }, { "command": "digital-ide.treeView.arch.openFile", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.treeView.arch.openFile.title%" }, { "command": "digital-ide.soft.launch", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.soft.launch.title%" }, { "command": "digital-ide.soft.build", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.soft.build.title%" }, { "command": "digital-ide.soft.download", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.soft.download.title%" }, { "command": "digital-ide.hard.launch", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.launch.title%" }, { "command": "digital-ide.hard.simulate", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.simulate.title%" }, { "command": "digital-ide.hard.simulate.cli", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.simulate.cli.title%" }, { "command": "digital-ide.hard.simulate.gui", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.simulate.gui.title%" }, { "command": "digital-ide.hard.refresh", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.refresh.title%" }, { "command": "digital-ide.hard.build", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.build.title%" }, { "command": "digital-ide.hard.build.synth", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.build.synth.title%" }, { "command": "digital-ide.hard.build.impl", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.build.impl.title%" }, { "command": "digital-ide.hard.build.bitstream", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.build.bitstream.title%" }, { "command": "digital-ide.hard.program", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.program.title%" }, { "command": "digital-ide.hard.gui", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.gui.title%" }, { "command": "digital-ide.hard.exit", - "category": "tool", + "category": "Digital-IDE", "title": "%digital-ide.hard.exit.title%" }, { "command": "digital-ide.pl.setSrcTop", - "category": "pl", + "category": "Digital-IDE", "title": "%digital-ide.pl.setSrcTop.title%" }, { "command": "digital-ide.pl.setSimTop", - "category": "pl", + "category": "Digital-IDE", "title": "%digital-ide.pl.setSimTop.title%" }, { "command": "digital-ide.pl.addDevice", - "category": "pl", + "category": "Digital-IDE", "title": "%digital-ide.pl.addDevice.title%" }, { "command": "digital-ide.pl.delDevice", - "category": "pl", + "category": "Digital-IDE", "title": "%digital-ide.pl.delDevice.title%" }, { "command": "digital-ide.pl.addFile", - "category": "pl", + "category": "Digital-IDE", "title": "%digital-ide.pl.addFile.title%" }, { "command": "digital-ide.pl.delFile", - "category": "pl", + "category": "Digital-IDE", "title": "%digital-ide.pl.delFile.title%" }, { diff --git a/project/property-schema.json b/project/property-schema.json index 34c1ebf..2a329ee 100644 --- a/project/property-schema.json +++ b/project/property-schema.json @@ -8,7 +8,7 @@ "description": "The tool chain you need", "enum": [ "xilinx", - "efinity" + "efinity" ] }, "prjName": { @@ -198,7 +198,8 @@ "xc7a35tftg256-1", "xc7a35tcsg324-1", "xc7z035ffg676-2", - "xc7z020clg484-1" + "xc7z020clg484-1", + "hello-world" ] } }, diff --git a/src/extension.ts b/src/extension.ts index 32c5a9b..213e9f6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -32,6 +32,11 @@ async function registerCommand(context: vscode.ExtensionContext, packageJson: an manager.prjManage.transformXilinxToStandard(context); }) ); + context.subscriptions.push( + vscode.commands.registerCommand('digital-ide.property-json.overwrite', () => { + manager.prjManage.overwritePropertyJson() + }) + ) } function readPackageJson(context: vscode.ExtensionContext): any | undefined { @@ -79,7 +84,7 @@ async function launch(context: vscode.ExtensionContext) { await vscode.window.withProgress({ location: vscode.ProgressLocation.Window, - title: "启动 Digital LSP 语言服务器" + title: t('info.progress.launch-lsp') }, async () => { await lspClient.activate(context, packageJson); }); diff --git a/src/function/lsp-client/cdn.ts b/src/function/lsp-client/cdn.ts index 0daffdd..a5bfe15 100644 --- a/src/function/lsp-client/cdn.ts +++ b/src/function/lsp-client/cdn.ts @@ -46,8 +46,8 @@ function measureRequestTimecost(url: string, timeout: number = 5): Promise[] = []; for (const link of links) { diff --git a/src/global/opeParam.ts b/src/global/opeParam.ts index 49040b0..5d4d204 100644 --- a/src/global/opeParam.ts +++ b/src/global/opeParam.ts @@ -3,6 +3,7 @@ import * as fs from 'fs'; import { Arch, PrjInfo, RawPrjInfo, resolve } from './prjInfo'; import { hdlPath } from '../hdlFs'; +import { getUserHomeDir } from './util'; type AbsPath = string; type RelPath = string; @@ -94,6 +95,10 @@ class OpeParam { return this._propertySchemaPath; } + public get dideHome() : AbsPath { + return hdlPath.join(getUserHomeDir(), '.digital-ide'); + } + /** * path of property-init.json */ diff --git a/src/global/util.ts b/src/global/util.ts index 0f5c03c..619d964 100644 --- a/src/global/util.ts +++ b/src/global/util.ts @@ -5,6 +5,7 @@ import * as childProcess from 'child_process'; import { AbsPath, MainOutput } from "."; import { t } from '../i18n'; +import { hdlPath } from '../hdlFs'; export class PathSet { files: Set = new Set(); @@ -251,4 +252,14 @@ export function killProcess(pid: number): Promise { resolve(); }); }); -} \ No newline at end of file +} + +/** + * 获取当前用户的主目录 + * @returns 用户主目录的绝对路径 + */ +export function getUserHomeDir(): AbsPath { + // 优先使用环境变量,如果不存在则使用 os.homedir() + const path = process.env.HOME || process.env.USERPROFILE || os.homedir(); + return hdlPath.toSlash(path); +} diff --git a/src/hdlFs/file.ts b/src/hdlFs/file.ts index 37caa4a..aa2afd5 100644 --- a/src/hdlFs/file.ts +++ b/src/hdlFs/file.ts @@ -183,6 +183,17 @@ export function readJSON(path: AbsPath): any { return {}; } +export function checkJson(path: AbsPath): any { + try { + const context = fs.readFileSync(path, 'utf-8'); + const obj = JSON.parse(context) + const toolChain = obj.properties.toolChain; + return true; + } catch (error) { + return false; + } +} + export function writeJSON(path: AbsPath, obj: object): boolean { try { const jsonString = JSON.stringify(obj, null, '\t'); @@ -239,10 +250,6 @@ export function copyFile(src: AbsPath, dest: AbsPath, cover: boolean = true): bo return false; } - if (!cover) { - cover = true; - } - try { const parent = fspath.dirname(dest); fs.mkdirSync(parent, {recursive: true}); diff --git a/src/manager/PL/index.ts b/src/manager/PL/index.ts index d6feece..69d636e 100644 --- a/src/manager/PL/index.ts +++ b/src/manager/PL/index.ts @@ -3,8 +3,7 @@ * Hardware Programming */ import * as vscode from 'vscode'; -import { exec } from 'child_process'; -import { platform } from 'os'; +import * as fs from 'fs'; import { PLContext, XilinxOperation } from './xilinx'; import { BaseManage } from '../common'; @@ -157,32 +156,53 @@ class PlManage extends BaseManage { this.context.ope.delFiles(files, this.context); } + /** + * @description 添加自定义 device 字符串 + * @returns + */ async addDevice() { const propertySchema = opeParam.propertySchemaPath; let propertyParam = hdlFile.readJSON(propertySchema) as PropertySchema; const device = await vscode.window.showInputBox({ password: false, ignoreFocusOut: true, - placeHolder: 'Please input the name of device' + placeHolder: t('info.addDevice.placeholder') }); if (!device) { return; } + // 同步到缓存中 + const dideHome = opeParam.dideHome; + const cachePPy = hdlPath.join(dideHome, 'property-schema.json'); + if (!propertyParam.properties.device.enum.includes(device)) { propertyParam.properties.device.enum.push(device); hdlFile.writeJSON(propertySchema, propertyParam); - vscode.window.showInformationMessage(`Add the ${device} successfully!!!`); + hdlFile.writeJSON(cachePPy, propertyParam); + vscode.window.showInformationMessage(t('info.addDevice.add-success', device)); } else { - vscode.window.showWarningMessage("The device already exists."); + vscode.window.showWarningMessage(t('warning.addDevice.name-taken', device)); } } + /** + * @description 删除用户创建的 device + * @returns + */ async delDevice() { const propertySchema = opeParam.propertySchemaPath; - let propertyParam = hdlFile.readJSON(propertySchema) as PropertySchema; - const device = await vscode.window.showQuickPick(propertyParam.properties.device.enum); + const propertyParam = hdlFile.readJSON(propertySchema) as PropertySchema; + const cachePPy = hdlPath.join(opeParam.dideHome, 'property-schema.json'); + + const device = await vscode.window.showQuickPick( + propertyParam.properties.device.enum.filter(device => device !== 'none'), + { + placeHolder: t('info.delDevice.placeholder'), + ignoreFocusOut: true + } + ); if (!device) { return; } @@ -190,7 +210,8 @@ class PlManage extends BaseManage { const index = propertyParam.properties.device.enum.indexOf(device); propertyParam.properties.device.enum.splice(index, 1); hdlFile.writeJSON(propertySchema, propertyParam); - vscode.window.showInformationMessage(`Delete the ${device} successfully!!!`); + hdlFile.writeJSON(cachePPy, propertyParam); + vscode.window.showInformationMessage(t('info.delDevice.del-success', device)); } } diff --git a/src/manager/PL/xilinx.ts b/src/manager/PL/xilinx.ts index a826ed7..0b792b9 100644 --- a/src/manager/PL/xilinx.ts +++ b/src/manager/PL/xilinx.ts @@ -457,6 +457,14 @@ class XilinxOperation { for (const pid of srcscannerPids) { await killProcess(pid); } + + // 删除所有 vivado_pid21812.str + for (const file of fs.readdirSync(opeParam.workspacePath)) { + if (file.startsWith('vivado_pid') && file.endsWith('.str')) { + const file_path = hdlPath.join(opeParam.workspacePath, file); + hdlFile.rmSync(file_path); + } + } } public async exit(context: PLContext) { diff --git a/src/manager/prj.ts b/src/manager/prj.ts index d0af706..52aefa7 100644 --- a/src/manager/prj.ts +++ b/src/manager/prj.ts @@ -3,7 +3,7 @@ import * as vscode from 'vscode'; import * as fs from 'fs'; import * as fspath from 'path'; -import { AbsPath, IProgress, LspClient, MainOutput, opeParam, ReportType } from '../global'; +import { AbsPath, IProgress, MainOutput, opeParam, ReportType } from '../global'; import { PathSet } from '../global/util'; import { RawPrjInfo } from '../global/prjInfo'; import { hdlDir, hdlFile, hdlPath } from '../hdlFs'; @@ -14,9 +14,7 @@ import { hdlIgnore } from './ignore'; import { hdlMonitor } from '../monitor'; import { t } from '../i18n'; import { PpyAction } from '../monitor/propery'; -import { refreshArchTree } from '../function/treeView'; -import * as lspClient from '../function/lsp-client'; -import { refreshWorkspaceDiagonastics } from '../function/lsp/linter/manager'; +import { checkJson, readJSON } from '../hdlFs/file'; interface RefreshPrjConfig { @@ -36,7 +34,11 @@ class PrjManage { vscode.window.showWarningMessage('property file already exists !!!'); return; } - const template = hdlFile.readJSON(opeParam.propertyInitPath) as RawPrjInfo; + + const cachePPy = hdlPath.join(opeParam.dideHome, 'property-init.json'); + const propertyInitPath = fs.existsSync(cachePPy) ? cachePPy: opeParam.propertyInitPath; + + const template = hdlFile.readJSON(propertyInitPath) as RawPrjInfo; hdlFile.writeJSON(opeParam.propertyJsonPath, template); // 当创建 property.json 时,monitor 似乎无法获取到 ppy 的 add 事件 @@ -45,13 +47,22 @@ class PrjManage { await ppyAction.add(opeParam.propertyJsonPath, hdlMonitor); } - // overwrite content in current property.json to property-init.json + /** + * @description 用户自定义 property-init.json + */ public async overwritePropertyJson() { + const dideHome = opeParam.dideHome; + hdlDir.mkdir(dideHome); + const cachePPy = hdlPath.join(dideHome, 'property-init.json'); + if (!fs.existsSync(cachePPy)) { + hdlFile.copyFile(opeParam.propertyInitPath, cachePPy); + } + const options = { preview: false, viewColumn: vscode.ViewColumn.Active }; - const uri = vscode.Uri.file(opeParam.propertyInitPath); + const uri = vscode.Uri.file(cachePPy); await vscode.window.showTextDocument(uri, options); } @@ -83,12 +94,8 @@ class PrjManage { propertySchemaPath, propertyInitPath); - // set path for merge in prjInfo opeParam.prjInfo.initContextPath(extensionPath, workspacePath); - const refreshPrjConfig: RefreshPrjConfig = {mkdir: true}; - - // merge prjInfo from propertyJsonPath if exist if (fs.existsSync(propertyJsonPath)) { const rawPrjInfo = hdlFile.readJSON(propertyJsonPath) as RawPrjInfo; opeParam.mergePrjInfo(rawPrjInfo); @@ -96,6 +103,15 @@ class PrjManage { refreshPrjConfig.mkdir = false; } + // 创建用户目录 + hdlDir.mkdir(opeParam.dideHome); + // 同步部分文件 + const cachePPySchema = hdlPath.join(opeParam.dideHome, 'property-schema.json'); + const propertySchema = opeParam.propertySchemaPath; + if (fs.existsSync(cachePPySchema) && checkJson(cachePPySchema)) { + hdlFile.copyFile(cachePPySchema, propertySchema); + } + return refreshPrjConfig; } @@ -527,6 +543,7 @@ class PrjManage { // hdlMonitor.start(); // }); } + } const prjManage = new PrjManage();