From 7940496d0d44785bff26f47372bd8043ee3ceebb Mon Sep 17 00:00:00 2001 From: Radu Date: Tue, 27 Aug 2024 16:42:54 +0300 Subject: [PATCH 1/5] wip: first implementation --- .vscode/settings.json | 12 ++- package.json | 19 ++++- package.nls.es.json | 2 + package.nls.json | 2 + package.nls.pt.json | 2 + package.nls.ru.json | 2 + package.nls.zh-CN.json | 2 + .../tree/componentsTreeDataProvider.ts | 77 +++++++++++++++++++ src/extension.ts | 15 ++++ src/workspaceConfig.ts | 11 +++ 10 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index d9952f78f..b04ed7b41 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -34,5 +34,15 @@ } ], "typescript.updateImportsOnFileMove.enabled": "always", - "workbench.editor.enablePreview": true + "workbench.editor.enablePreview": true, + "idf.espIdfPathWin": "C:\\Users\\radur\\esp171\\v5.2.2\\esp-idf", + "idf.pythonBinPathWin": "C:\\Users\\radur\\esptools171\\python_env\\idf5.2_py3.11_env\\Scripts\\python.exe", + "idf.toolsPathWin": "C:\\Users\\radur\\esptools171", + "idf.customExtraPaths": "C:\\Users\\radur\\esptools171\\tools\\xtensa-esp-elf-gdb\\14.2_20240403\\xtensa-esp-elf-gdb\\bin;C:\\Users\\radur\\esptools171\\tools\\riscv32-esp-elf-gdb\\14.2_20240403\\riscv32-esp-elf-gdb\\bin;C:\\Users\\radur\\esptools171\\tools\\xtensa-esp-elf\\esp-13.2.0_20230928\\xtensa-esp-elf\\bin;C:\\Users\\radur\\esptools171\\tools\\riscv32-esp-elf\\esp-13.2.0_20230928\\riscv32-esp-elf\\bin;C:\\Users\\radur\\esptools171\\tools\\esp32ulp-elf\\2.35_20220830\\esp32ulp-elf\\bin;C:\\Users\\radur\\esptools171\\tools\\cmake\\3.24.0\\bin;C:\\Users\\radur\\esptools171\\tools\\openocd-esp32\\v0.12.0-esp32-20240318\\openocd-esp32\\bin;C:\\Users\\radur\\esptools171\\tools\\ninja\\1.11.1;C:\\Users\\radur\\esptools171\\tools\\idf-exe\\1.0.3;C:\\Users\\radur\\esptools171\\tools\\ccache\\4.8\\ccache-4.8-windows-x86_64;C:\\Users\\radur\\esptools171\\tools\\dfu-util\\0.11\\dfu-util-0.11-win64;C:\\Users\\radur\\esptools171\\tools\\esp-rom-elfs\\20230320", + "idf.customExtraVars": { + "OPENOCD_SCRIPTS": "C:\\Users\\radur\\esptools171\\tools\\openocd-esp32\\v0.12.0-esp32-20240318/openocd-esp32/share/openocd/scripts", + "IDF_CCACHE_ENABLE": "1", + "ESP_ROM_ELF_DIR": "C:\\Users\\radur\\esptools171\\tools\\esp-rom-elfs\\20230320/" + }, + "idf.gitPathWin": "C:\\Users\\radur\\esptools171\\tools\\idf-git\\2.39.2\\cmd\\git.exe" } diff --git a/package.json b/package.json index 6a6557dd9..940247ae2 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,7 @@ "onView:idfPartitionExplorer", "onView:espRainmaker", "onView:idfComponents", + "onView:projectSpecificComponents", "workspaceContains:**/project_description.json", "workspaceContains:**/sdkconfig", "workspaceContains:**/CMakeLists.txt" @@ -199,6 +200,10 @@ { "id": "idfComponents", "name": "%view.components.name%" + }, + { + "id": "projectSpecificComponents", + "name": "%view.idf.projectSpecificComponents%" } ] }, @@ -224,6 +229,11 @@ } ], "view/title": [ + { + "command": "espIdf.projectSpecificComponents.refresh", + "group": "navigation", + "when": "view == projectSpecificComponents" + }, { "command": "espIdf.searchError", "group": "navigation", @@ -978,7 +988,14 @@ "commands": [ { "command": "espIdf.searchError", - "title": "%espIdf.searchError.title%" + "title": "%espIdf.searchError.title%", + "category": "ESP-IDF" + }, + { + "command": "espIdf.projectSpecificComponents.refresh", + "title": "%espIdf.projectSpecificComponentsRefresh.title%", + "category": "ESP-IDF", + "icon": "$(refresh)" }, { "command": "espIdf.createFiles", diff --git a/package.nls.es.json b/package.nls.es.json index 3fd06b0ce..7c2aa15ee 100644 --- a/package.nls.es.json +++ b/package.nls.es.json @@ -94,6 +94,7 @@ "esp_idf.tmoScaleFactor.description": "Factor de escala para el tiempo de espera de gdb [predeterminado:1]", "esp_idf.verifyAppBinBeforeDebug.description": "Verificar binarios de la aplicación antes de depurar", "espIdf.searchError.title": "ESP-IDF: Sugerencia de error de búsqueda", + "espIdf.projectSpecificComponents.title": "Actualizar Componentes", "idf.flashType.description": "Método de flasheo del dispositivo, UART o JTag", "idf.wssPort.description": "Puerto del servidor de socket web para Core Dump o GDB Stub", "openocd.tcl.host.description": "Host para conexión tcl de Openocd", @@ -176,6 +177,7 @@ "view.idf.idfCommands": "Comandos", "view.idf.idfPartitionExplorer": "Explorador de Particiones del Dispositivo", "view.idf.idfSearchResults": "Resultados de búsqueda de documentación", + "view.idf.projectSpecificComponents": "Componentes Específicos del Proyecto", "viewContainer.title": "ESP-IDF: Explorador", "viewWelcome.idfPartitionExplorer": "Muestra la lista de particiones de su dispositivo con la opción de flashear binarios (.bin) en la partición seleccionada.\n\nSeleccione el puerto serial de su dispositivo y haga clic en Actualizar tabla de particiones.", "viewWelcome.idfSearchResults": "En cualquier editor de archivos abierto, seleccione un texto y haga clic con el botón derecho y seleccione ESP-IDF: Buscar en la documentación para obtener resultados coincidentes aquí.\n\nLos resultados se basan en su idioma actual de VS Code, versión de idf.espIdfPath (si no, la última) y idf.adapterTargetName.", diff --git a/package.nls.json b/package.nls.json index fd970c107..e1a78a68b 100644 --- a/package.nls.json +++ b/package.nls.json @@ -94,6 +94,7 @@ "esp_idf.tmoScaleFactor.description": "Scale factor for gdb timeout [default:1]", "esp_idf.verifyAppBinBeforeDebug.description": "Verify app binaries before debug", "espIdf.searchError.title": "ESP-IDF: Search Error Hint", + "espIdf.projectSpecificComponents.title": "Refresh Components", "idf.flashType.description": "Device flash method, UART or JTag", "idf.wssPort.description": "Web Socket Server Port for Core Dump or GDB Stub", "openocd.tcl.host.description": "Host for OpenOCD tcl connection", @@ -176,6 +177,7 @@ "view.idf.idfCommands": "Commands", "view.idf.idfPartitionExplorer": "Device Partition Explorer", "view.idf.idfSearchResults": "Documentation search results", + "view.idf.projectSpecificComponents": "Project-Specific Components", "viewContainer.title": "ESP-IDF: Explorer", "viewWelcome.idfPartitionExplorer": "Show the partition list from your device with the option to flash binaries (.bin) to the selected partition.\n\nSelect your device serial port and click Refresh Partition Table.", "viewWelcome.idfSearchResults": "On any opened file editor, select some text and right click and select ESP-IDF: Search in Documentation to get matching results here.\n\nResults are based on your current VS Code language, idf.espIdfPath version (latest otherwise) and idf.adapterTargetName.", diff --git a/package.nls.pt.json b/package.nls.pt.json index b2a29b9d3..5fe8a0846 100644 --- a/package.nls.pt.json +++ b/package.nls.pt.json @@ -87,6 +87,7 @@ "espIdf.unitTest.installPyTest.title": "Teste de unidade: instale os requisitos do ESP-IDF PyTest", "espIdf.webview.nvsPartitionEditor.title": "Abra o Editor de Partição NVS", "espIdf.welcome.title": "Bem-vindo", + "espIdf.projectSpecificComponents.title": "Atualizar Componentes", "esp_idf.appOffset.description": "Substituir o deslocamento do endereço inicial do programa de construção (ESP32_APP_FLASH_OFF)", "esp_idf.debuggers.text.description": "O comando para executar", "esp_idf.gdbinitFile.description": "caminho do arquivo gdbinit para adaptador de depuração ESP-IDF", @@ -174,6 +175,7 @@ "view.idf.idfCommands": "Comandos", "view.idf.idfPartitionExplorer": "Explorador de partição de dispositivo", "view.idf.idfSearchResults": "Resultados da pesquisa de documentação", + "view.idf.projectSpecificComponents": "Componentes Específicos do Projeto", "viewContainer.title": "ESP-IDF: Explorador", "viewWelcome.idfPartitionExplorer": "Mostre a lista de partições do seu dispositivo com a opção de atualizar binários (.bin) para a partição selecionada.\n\n", "viewWelcome.idfSearchResults": "Em qualquer editor de arquivo aberto, selecione algum texto e clique com o botão direito e selecione ESP-IDF: Pesquise na documentação para obter resultados correspondentes aqui.\n\n", diff --git a/package.nls.ru.json b/package.nls.ru.json index ac942a6c3..763375f02 100644 --- a/package.nls.ru.json +++ b/package.nls.ru.json @@ -87,6 +87,7 @@ "espIdf.unitTest.installPyTest.title": "Модульное тестирование: установите требования ESP-IDF PyTest.", "espIdf.webview.nvsPartitionEditor.title": "Откройте редактор разделов NVS.", "espIdf.welcome.title": "Добро пожаловать", + "espIdf.projectSpecificComponents.title": "Обновить Компоненты", "esp_idf.appOffset.description": "Переопределить смещение начального адреса программы сборки (ESP32_APP_FLASH_OFF)", "esp_idf.debuggers.text.description": "Команда для выполнения", "esp_idf.gdbinitFile.description": "Путь к файлу gdbinit для адаптера отладки ESP-IDF", @@ -176,6 +177,7 @@ "view.idf.idfCommands": "Команды", "view.idf.idfPartitionExplorer": "Обозреватель разделов устройства", "view.idf.idfSearchResults": "Результаты поиска документации", + "view.idf.projectSpecificComponents": "Специфические Компоненты Проекта", "viewContainer.title": "ESP-IDF: Проводник", "viewWelcome.idfPartitionExplorer": "Покажите список разделов вашего устройства с возможностью записать двоичные файлы (.bin) в выбранный раздел.\n\n", "viewWelcome.idfSearchResults": "В любом открытом редакторе файлов выделите текст, щелкните правой кнопкой мыши и выберите ESP-IDF: поиск в документации, чтобы получить соответствующие результаты здесь.\n\n", diff --git a/package.nls.zh-CN.json b/package.nls.zh-CN.json index 9e895f576..15af5883f 100644 --- a/package.nls.zh-CN.json +++ b/package.nls.zh-CN.json @@ -87,6 +87,7 @@ "espIdf.unitTest.installPyTest.title": "单元测试:安装 ESP-IDF PyTest 要求", "espIdf.webview.nvsPartitionEditor.title": "打开 NVS 分区编辑器", "espIdf.welcome.title": "欢迎", + "espIdf.projectSpecificComponents.title": "刷新组件", "esp_idf.appOffset.description": "覆盖构建程序起始地址偏移 (ESP32_APP_FLASH_OFF)", "esp_idf.debuggers.text.description": "要执行的命令", "esp_idf.gdbinitFile.description": "用于 ESP-IDF 调试适配器的 gdbinit 文件路径", @@ -176,6 +177,7 @@ "view.idf.idfCommands": "命令", "view.idf.idfPartitionExplorer": "设备分区资源管理器", "view.idf.idfSearchResults": "文档搜索结果", + "view.idf.projectSpecificComponents": "项目特定组件", "viewContainer.title": "ESP-IDF:资源管理器", "viewWelcome.idfPartitionExplorer": "显示您的设备的分区列表,选择要将二进制文件 (.bin) 烧录到的分区。\n\n选择您的设备串行端口,然后单击刷新分区表。", "viewWelcome.idfSearchResults": "在任何已打开的文件编辑器中,选择一些文本,右键单击并选择 ESP-IDF:在文档中搜索以在此处获取匹配的结果。\n\n结果基于您当前的 VS Code 语言、idf.espIdfPath 版本 (否则为最新版本) 和 idf.adapterTargetName。", diff --git a/src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts b/src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts new file mode 100644 index 000000000..4789c6ff8 --- /dev/null +++ b/src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts @@ -0,0 +1,77 @@ +import * as vscode from "vscode"; +import * as fs from 'fs'; +import * as path from 'path'; +import * as yaml from 'js-yaml'; + +class Component extends vscode.TreeItem { + constructor( + public readonly label: string, + public readonly collapsibleState: vscode.TreeItemCollapsibleState, + public readonly description?: string + ) { + super(label, collapsibleState); + this.tooltip = `${this.label}${this.description ? ` - ${this.description}` : ''}`; + } +} + +export class ComponentsTreeDataProvider implements vscode.TreeDataProvider { + private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); + readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; + private workspaceFolder: vscode.Uri; + + constructor(workspaceFolder: vscode.Uri | undefined) { + this.workspaceFolder = workspaceFolder; + } + + refresh(workspaceFolder: vscode.Uri): void { + this.workspaceFolder = workspaceFolder; + this._onDidChangeTreeData.fire(); + } + + getTreeItem(element: Component): vscode.TreeItem { + return element; + } + + getChildren(element?: Component): Thenable { + if (!this.workspaceFolder) { + vscode.window.showInformationMessage('No workspace folder is open'); + return Promise.resolve([]); + } + + const idfComponentPath = vscode.Uri.joinPath(this.workspaceFolder, 'main', 'idf_component.yml'); + + return vscode.workspace.fs.stat(idfComponentPath).then( + () => { + if (!element) { + return this.getDependencies(idfComponentPath); + } + return Promise.resolve([]); + }, + () => { + return Promise.resolve([new Component( + 'idf_component.yml not found', + vscode.TreeItemCollapsibleState.None, + 'Create this file to define your component dependencies' + )]); + } + ); + } + + private async getDependencies(fileUri: vscode.Uri): Promise { + try { + const fileContents = await vscode.workspace.fs.readFile(fileUri); + const data = yaml.load(fileContents.toString()) as any; + + if (data && data.dependencies) { + return Object.entries(data.dependencies).map(([dep, version]) => + new Component(`${dep}`, vscode.TreeItemCollapsibleState.None, `${version}`) + ); + } else { + return [new Component('No dependencies found', vscode.TreeItemCollapsibleState.None)]; + } + } catch (err) { + vscode.window.showErrorMessage(`Error reading idf_component.yml: ${err}`); + return [new Component('Error reading file', vscode.TreeItemCollapsibleState.None)]; + } + } +} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 10241e3fb..93ff2b183 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -37,6 +37,7 @@ import { TraceType, } from "./espIdf/tracing/tree/appTraceArchiveTreeDataProvider"; import { AppTraceTreeDataProvider } from "./espIdf/tracing/tree/appTraceTreeDataProvider"; +import { ComponentsTreeDataProvider } from "./espIdf/projectSpecificComponents/tree/componentsTreeDataProvider" import { ExamplesPlanel } from "./examples/ExamplesPanel"; import * as idfConf from "./idfConfiguration"; import { Logger } from "./logger/logger"; @@ -48,6 +49,7 @@ import { getProjectName, initSelectedWorkspace, updateIdfComponentsTree, + updateProjectSpecificComponentsTree, } from "./workspaceConfig"; import { SystemViewResultParser } from "./espIdf/tracing/system-view"; import { Telemetry } from "./telemetry"; @@ -179,6 +181,9 @@ let appTraceArchiveTreeDataProvider: AppTraceArchiveTreeDataProvider; let appTraceManager: AppTraceManager; let gdbHeapTraceManager: GdbHeapTraceManager; +// Specific Project Components +let componentsTreeDataProvider: ComponentsTreeDataProvider; + // Partition table let partitionTableTreeDataProvider: PartitionTreeDataProvider; @@ -301,6 +306,12 @@ export async function activate(context: vscode.ExtensionContext) { e.element.expanded = false; }); + // Specific Project Components tree view + const refreshCommand = vscode.commands.registerCommand('espIdf.projectSpecificComponents.refresh', () => { + componentsTreeDataProvider.refresh(workspaceRoot); + }); + context.subscriptions.push(refreshCommand); + // register openOCD status bar item registerOpenOCDStatusBarItem(context); @@ -904,6 +915,7 @@ export async function activate(context: vscode.ExtensionContext) { "$(plug) " + idfConf.readParameter("idf.port", workspaceRoot); } updateIdfComponentsTree(workspaceRoot); + updateProjectSpecificComponentsTree(workspaceRoot); const workspaceFolderInfo = { clickCommand: "espIdf.pickAWorkspaceFolder", currentWorkSpace: option.name, @@ -3687,7 +3699,10 @@ function registerQemuStatusBarItem(context: vscode.ExtensionContext) { } function registerTreeProvidersForIDFExplorer(context: vscode.ExtensionContext) { + componentsTreeDataProvider = new ComponentsTreeDataProvider(workspaceRoot); + appTraceTreeDataProvider = new AppTraceTreeDataProvider(); + appTraceArchiveTreeDataProvider = new AppTraceArchiveTreeDataProvider(); espIdfDocsResultTreeDataProvider = new DocSearchResultTreeDataProvider(); diff --git a/src/workspaceConfig.ts b/src/workspaceConfig.ts index 1e7a3777b..c04d0adc6 100644 --- a/src/workspaceConfig.ts +++ b/src/workspaceConfig.ts @@ -17,6 +17,7 @@ import { pathExists } from "fs-extra"; import * as path from "path"; import * as vscode from "vscode"; import { IdfTreeDataProvider } from "./idfComponentsDataProvider"; +import { ComponentsTreeDataProvider } from "../src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider" import { writeParameter } from "./idfConfiguration"; import { Logger } from "./logger/logger"; import * as utils from "./utils"; @@ -25,6 +26,7 @@ import { getSDKConfigFilePath } from "./utils"; export function initSelectedWorkspace(status?: vscode.StatusBarItem) { const workspaceRoot = vscode.workspace.workspaceFolders[0].uri; updateIdfComponentsTree(workspaceRoot); + updateProjectSpecificComponentsTree(workspaceRoot); const workspaceFolderInfo = { clickCommand: "espIdf.pickAWorkspaceFolder", currentWorkSpace: vscode.workspace.workspaceFolders[0].name, @@ -104,3 +106,12 @@ export async function getIdfTargetFromSdkconfig( statusItem.text = "$(chip) " + idfTarget; } } + +let projectSpecificComponentsProvider: ComponentsTreeDataProvider; +export function updateProjectSpecificComponentsTree(workspaceFolder: vscode.Uri) { + if (typeof projectSpecificComponentsProvider === "undefined") { + projectSpecificComponentsProvider = new ComponentsTreeDataProvider(workspaceFolder); + vscode.window.registerTreeDataProvider("projectSpecificComponents", projectSpecificComponentsProvider); + } + projectSpecificComponentsProvider.refresh(workspaceFolder); +} \ No newline at end of file From e5b3d6115b153c8b07d66d9c2ce388396f1d72a6 Mon Sep 17 00:00:00 2001 From: Radu Date: Tue, 27 Aug 2024 16:49:50 +0300 Subject: [PATCH 2/5] wip: add file watcher --- .../tree/componentsTreeDataProvider.ts | 23 ++++++++++++------- src/extension.ts | 2 +- src/workspaceConfig.ts | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts b/src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts index 4789c6ff8..d18f5c981 100644 --- a/src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts +++ b/src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts @@ -1,6 +1,4 @@ import * as vscode from "vscode"; -import * as fs from 'fs'; -import * as path from 'path'; import * as yaml from 'js-yaml'; class Component extends vscode.TreeItem { @@ -17,15 +15,24 @@ class Component extends vscode.TreeItem { export class ComponentsTreeDataProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; - private workspaceFolder: vscode.Uri; + private workspaceFolder?: vscode.Uri; constructor(workspaceFolder: vscode.Uri | undefined) { this.workspaceFolder = workspaceFolder; + + // Watch the idf_component.yml file for changes + if (workspaceFolder) { + const idfComponentPath = vscode.Uri.joinPath(this.workspaceFolder, 'main', 'idf_component.yml'); + const watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(idfComponentPath, '*')); + + watcher.onDidChange(() => this.refresh()); + watcher.onDidCreate(() => this.refresh()); + watcher.onDidDelete(() => this.refresh()); + } } - refresh(workspaceFolder: vscode.Uri): void { - this.workspaceFolder = workspaceFolder; - this._onDidChangeTreeData.fire(); + refresh(): void { + this._onDidChangeTreeData.fire(); // Trigger UI update for the tree } getTreeItem(element: Component): vscode.TreeItem { @@ -70,8 +77,8 @@ export class ComponentsTreeDataProvider implements vscode.TreeDataProvider { - componentsTreeDataProvider.refresh(workspaceRoot); + componentsTreeDataProvider.refresh(); }); context.subscriptions.push(refreshCommand); diff --git a/src/workspaceConfig.ts b/src/workspaceConfig.ts index c04d0adc6..e9c730978 100644 --- a/src/workspaceConfig.ts +++ b/src/workspaceConfig.ts @@ -113,5 +113,5 @@ export function updateProjectSpecificComponentsTree(workspaceFolder: vscode.Uri) projectSpecificComponentsProvider = new ComponentsTreeDataProvider(workspaceFolder); vscode.window.registerTreeDataProvider("projectSpecificComponents", projectSpecificComponentsProvider); } - projectSpecificComponentsProvider.refresh(workspaceFolder); + projectSpecificComponentsProvider.refresh(); } \ No newline at end of file From 4d9620cf04d2f19155bb6a437d759a85c356b727 Mon Sep 17 00:00:00 2001 From: Radu Date: Wed, 28 Aug 2024 16:25:18 +0300 Subject: [PATCH 3/5] wip: modify names --- package.json | 14 +- package.nls.es.json | 6 +- package.nls.json | 6 +- package.nls.pt.json | 6 +- package.nls.ru.json | 6 +- package.nls.zh-CN.json | 6 +- .../tree/componentsTreeDataProvider.ts | 120 ++++++++++++++++++ .../tree/componentsTreeDataProvider.ts | 84 ------------ src/extension.ts | 8 +- src/workspaceConfig.ts | 16 +-- 10 files changed, 154 insertions(+), 118 deletions(-) create mode 100644 src/espIdf/espRegistryComponents/tree/componentsTreeDataProvider.ts delete mode 100644 src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts diff --git a/package.json b/package.json index 940247ae2..aed49813c 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "onView:idfPartitionExplorer", "onView:espRainmaker", "onView:idfComponents", - "onView:projectSpecificComponents", + "onView:espRegistryComponents", "workspaceContains:**/project_description.json", "workspaceContains:**/sdkconfig", "workspaceContains:**/CMakeLists.txt" @@ -202,8 +202,8 @@ "name": "%view.components.name%" }, { - "id": "projectSpecificComponents", - "name": "%view.idf.projectSpecificComponents%" + "id": "espRegistryComponents", + "name": "%view.idf.espRegistryComponents%" } ] }, @@ -230,9 +230,9 @@ ], "view/title": [ { - "command": "espIdf.projectSpecificComponents.refresh", + "command": "espIdf.espRegistryComponents.refresh", "group": "navigation", - "when": "view == projectSpecificComponents" + "when": "view == espRegistryComponents" }, { "command": "espIdf.searchError", @@ -992,8 +992,8 @@ "category": "ESP-IDF" }, { - "command": "espIdf.projectSpecificComponents.refresh", - "title": "%espIdf.projectSpecificComponentsRefresh.title%", + "command": "espIdf.espRegistryComponents.refresh", + "title": "%espIdf.espRegistryComponentsRefresh.title%", "category": "ESP-IDF", "icon": "$(refresh)" }, diff --git a/package.nls.es.json b/package.nls.es.json index 7c2aa15ee..8763cb9d8 100644 --- a/package.nls.es.json +++ b/package.nls.es.json @@ -94,7 +94,7 @@ "esp_idf.tmoScaleFactor.description": "Factor de escala para el tiempo de espera de gdb [predeterminado:1]", "esp_idf.verifyAppBinBeforeDebug.description": "Verificar binarios de la aplicación antes de depurar", "espIdf.searchError.title": "ESP-IDF: Sugerencia de error de búsqueda", - "espIdf.projectSpecificComponents.title": "Actualizar Componentes", + "espIdf.espRegistryComponents.title": "Actualizar Componentes", "idf.flashType.description": "Método de flasheo del dispositivo, UART o JTag", "idf.wssPort.description": "Puerto del servidor de socket web para Core Dump o GDB Stub", "openocd.tcl.host.description": "Host para conexión tcl de Openocd", @@ -168,7 +168,7 @@ "trace.stop_tmo.description": "stop_tmo se establecerá para el rastreo de la aplicación", "trace.trace_size.description": "trace_size se establecerá para el rastreo de la aplicación", "trace.wait4halt.description": "wait4halt se establecerá para el rastreo de la aplicación", - "view.components.name": "Componentes del proyecto", + "view.components.name": "Navegación de Componentes", "view.debug.peripheral": "Visor periférico ESP-IDF", "view.idf.espEFuseExplorer": "Explorador de eFuse", "view.idf.espRainmaker": "RainMaker", @@ -177,7 +177,7 @@ "view.idf.idfCommands": "Comandos", "view.idf.idfPartitionExplorer": "Explorador de Particiones del Dispositivo", "view.idf.idfSearchResults": "Resultados de búsqueda de documentación", - "view.idf.projectSpecificComponents": "Componentes Específicos del Proyecto", + "view.idf.espRegistryComponents": "Componentes del Registro ESP", "viewContainer.title": "ESP-IDF: Explorador", "viewWelcome.idfPartitionExplorer": "Muestra la lista de particiones de su dispositivo con la opción de flashear binarios (.bin) en la partición seleccionada.\n\nSeleccione el puerto serial de su dispositivo y haga clic en Actualizar tabla de particiones.", "viewWelcome.idfSearchResults": "En cualquier editor de archivos abierto, seleccione un texto y haga clic con el botón derecho y seleccione ESP-IDF: Buscar en la documentación para obtener resultados coincidentes aquí.\n\nLos resultados se basan en su idioma actual de VS Code, versión de idf.espIdfPath (si no, la última) y idf.adapterTargetName.", diff --git a/package.nls.json b/package.nls.json index e1a78a68b..414d24fd8 100644 --- a/package.nls.json +++ b/package.nls.json @@ -94,7 +94,7 @@ "esp_idf.tmoScaleFactor.description": "Scale factor for gdb timeout [default:1]", "esp_idf.verifyAppBinBeforeDebug.description": "Verify app binaries before debug", "espIdf.searchError.title": "ESP-IDF: Search Error Hint", - "espIdf.projectSpecificComponents.title": "Refresh Components", + "espIdf.espRegistryComponentsRefresh.title": "Refresh Components", "idf.flashType.description": "Device flash method, UART or JTag", "idf.wssPort.description": "Web Socket Server Port for Core Dump or GDB Stub", "openocd.tcl.host.description": "Host for OpenOCD tcl connection", @@ -168,7 +168,7 @@ "trace.stop_tmo.description": "stop_tmo will be set for the apptrace", "trace.trace_size.description": "trace_size will set for the apptrace", "trace.wait4halt.description": "wait4halt will be set for the apptrace", - "view.components.name": "Project Components", + "view.components.name": "Components Navigation", "view.debug.peripheral": "ESP-IDF: Peripheral Viewer", "view.idf.espEFuseExplorer": "eFuseExplorer", "view.idf.espRainmaker": "RainMaker", @@ -177,7 +177,7 @@ "view.idf.idfCommands": "Commands", "view.idf.idfPartitionExplorer": "Device Partition Explorer", "view.idf.idfSearchResults": "Documentation search results", - "view.idf.projectSpecificComponents": "Project-Specific Components", + "view.idf.espRegistryComponents": "ESP Registry Components", "viewContainer.title": "ESP-IDF: Explorer", "viewWelcome.idfPartitionExplorer": "Show the partition list from your device with the option to flash binaries (.bin) to the selected partition.\n\nSelect your device serial port and click Refresh Partition Table.", "viewWelcome.idfSearchResults": "On any opened file editor, select some text and right click and select ESP-IDF: Search in Documentation to get matching results here.\n\nResults are based on your current VS Code language, idf.espIdfPath version (latest otherwise) and idf.adapterTargetName.", diff --git a/package.nls.pt.json b/package.nls.pt.json index 5fe8a0846..e30859178 100644 --- a/package.nls.pt.json +++ b/package.nls.pt.json @@ -87,7 +87,7 @@ "espIdf.unitTest.installPyTest.title": "Teste de unidade: instale os requisitos do ESP-IDF PyTest", "espIdf.webview.nvsPartitionEditor.title": "Abra o Editor de Partição NVS", "espIdf.welcome.title": "Bem-vindo", - "espIdf.projectSpecificComponents.title": "Atualizar Componentes", + "espIdf.espRegistryComponents.title": "Atualizar Componentes", "esp_idf.appOffset.description": "Substituir o deslocamento do endereço inicial do programa de construção (ESP32_APP_FLASH_OFF)", "esp_idf.debuggers.text.description": "O comando para executar", "esp_idf.gdbinitFile.description": "caminho do arquivo gdbinit para adaptador de depuração ESP-IDF", @@ -166,7 +166,7 @@ "trace.stop_tmo.description": "stop_tmo será definido para o apptrace", "trace.trace_size.description": "trace_size será definido para o apptrace", "trace.wait4halt.description": "wait4halt será definido para o apptrace", - "view.components.name": "Componentes do Projeto", + "view.components.name": "Navegação de Componentes", "view.debug.peripheral": "ESP-IDF: visualizador periférico", "view.idf.espEFuseExplorer": "eFuseExplorer", "view.idf.espRainmaker": "Criador de Chuva", @@ -175,7 +175,7 @@ "view.idf.idfCommands": "Comandos", "view.idf.idfPartitionExplorer": "Explorador de partição de dispositivo", "view.idf.idfSearchResults": "Resultados da pesquisa de documentação", - "view.idf.projectSpecificComponents": "Componentes Específicos do Projeto", + "view.idf.espRegistryComponents": "Componentes do Registro ESP", "viewContainer.title": "ESP-IDF: Explorador", "viewWelcome.idfPartitionExplorer": "Mostre a lista de partições do seu dispositivo com a opção de atualizar binários (.bin) para a partição selecionada.\n\n", "viewWelcome.idfSearchResults": "Em qualquer editor de arquivo aberto, selecione algum texto e clique com o botão direito e selecione ESP-IDF: Pesquise na documentação para obter resultados correspondentes aqui.\n\n", diff --git a/package.nls.ru.json b/package.nls.ru.json index 763375f02..7bd7bdabc 100644 --- a/package.nls.ru.json +++ b/package.nls.ru.json @@ -87,7 +87,7 @@ "espIdf.unitTest.installPyTest.title": "Модульное тестирование: установите требования ESP-IDF PyTest.", "espIdf.webview.nvsPartitionEditor.title": "Откройте редактор разделов NVS.", "espIdf.welcome.title": "Добро пожаловать", - "espIdf.projectSpecificComponents.title": "Обновить Компоненты", + "espIdf.espRegistryComponents.title": "Обновить Компоненты", "esp_idf.appOffset.description": "Переопределить смещение начального адреса программы сборки (ESP32_APP_FLASH_OFF)", "esp_idf.debuggers.text.description": "Команда для выполнения", "esp_idf.gdbinitFile.description": "Путь к файлу gdbinit для адаптера отладки ESP-IDF", @@ -168,7 +168,7 @@ "trace.stop_tmo.description": "stop_tmo будет установлен для apptrace", "trace.trace_size.description": "Trace_size будет установлен для трассировки приложения.", "trace.wait4halt.description": "wait4halt будет установлен для apptrace", - "view.components.name": "Компоненты проекта", + "view.components.name": "Навигация по компонентам", "view.debug.peripheral": "ESP-IDF: Периферийное средство просмотра", "view.idf.espEFuseExplorer": "eFuseExplorer", "view.idf.espRainmaker": "RainMaker", @@ -177,7 +177,7 @@ "view.idf.idfCommands": "Команды", "view.idf.idfPartitionExplorer": "Обозреватель разделов устройства", "view.idf.idfSearchResults": "Результаты поиска документации", - "view.idf.projectSpecificComponents": "Специфические Компоненты Проекта", + "view.idf.espRegistryComponents": "Компоненты реестра ESP", "viewContainer.title": "ESP-IDF: Проводник", "viewWelcome.idfPartitionExplorer": "Покажите список разделов вашего устройства с возможностью записать двоичные файлы (.bin) в выбранный раздел.\n\n", "viewWelcome.idfSearchResults": "В любом открытом редакторе файлов выделите текст, щелкните правой кнопкой мыши и выберите ESP-IDF: поиск в документации, чтобы получить соответствующие результаты здесь.\n\n", diff --git a/package.nls.zh-CN.json b/package.nls.zh-CN.json index 15af5883f..b771dabdc 100644 --- a/package.nls.zh-CN.json +++ b/package.nls.zh-CN.json @@ -87,7 +87,7 @@ "espIdf.unitTest.installPyTest.title": "单元测试:安装 ESP-IDF PyTest 要求", "espIdf.webview.nvsPartitionEditor.title": "打开 NVS 分区编辑器", "espIdf.welcome.title": "欢迎", - "espIdf.projectSpecificComponents.title": "刷新组件", + "espIdf.espRegistryComponents.title": "刷新组件", "esp_idf.appOffset.description": "覆盖构建程序起始地址偏移 (ESP32_APP_FLASH_OFF)", "esp_idf.debuggers.text.description": "要执行的命令", "esp_idf.gdbinitFile.description": "用于 ESP-IDF 调试适配器的 gdbinit 文件路径", @@ -168,7 +168,7 @@ "trace.stop_tmo.description": "将为 apptrace 设置 stop_tmo", "trace.trace_size.description": "将为 apptrace 设置 trace_size", "trace.wait4halt.description": "将为 apptrace 设置 wait4halt", - "view.components.name": "项目组件", + "view.components.name": "组件导航", "view.debug.peripheral": "ESP-IDF:外围设备查看器", "view.idf.espEFuseExplorer": "eFuseExplorer", "view.idf.espRainmaker": "RainMaker", @@ -177,7 +177,7 @@ "view.idf.idfCommands": "命令", "view.idf.idfPartitionExplorer": "设备分区资源管理器", "view.idf.idfSearchResults": "文档搜索结果", - "view.idf.projectSpecificComponents": "项目特定组件", + "view.idf.espRegistryComponents": "ESP 注册表组件", "viewContainer.title": "ESP-IDF:资源管理器", "viewWelcome.idfPartitionExplorer": "显示您的设备的分区列表,选择要将二进制文件 (.bin) 烧录到的分区。\n\n选择您的设备串行端口,然后单击刷新分区表。", "viewWelcome.idfSearchResults": "在任何已打开的文件编辑器中,选择一些文本,右键单击并选择 ESP-IDF:在文档中搜索以在此处获取匹配的结果。\n\n结果基于您当前的 VS Code 语言、idf.espIdfPath 版本 (否则为最新版本) 和 idf.adapterTargetName。", diff --git a/src/espIdf/espRegistryComponents/tree/componentsTreeDataProvider.ts b/src/espIdf/espRegistryComponents/tree/componentsTreeDataProvider.ts new file mode 100644 index 000000000..9dfb4c9d3 --- /dev/null +++ b/src/espIdf/espRegistryComponents/tree/componentsTreeDataProvider.ts @@ -0,0 +1,120 @@ +import * as vscode from "vscode"; +import * as yaml from "js-yaml"; + +class Component extends vscode.TreeItem { + constructor( + public readonly label: string, + public readonly collapsibleState: vscode.TreeItemCollapsibleState, + public readonly description?: string + ) { + super(label, collapsibleState); + this.tooltip = `${this.label}${ + this.description ? ` - ${this.description}` : "" + }`; + } +} + +export class ComponentsTreeDataProvider + implements vscode.TreeDataProvider { + private _onDidChangeTreeData: vscode.EventEmitter< + Component | undefined | null | void + > = new vscode.EventEmitter(); + readonly onDidChangeTreeData: vscode.Event< + Component | undefined | null | void + > = this._onDidChangeTreeData.event; + private workspaceFolder?: vscode.Uri; + + constructor(workspaceFolder: vscode.Uri | undefined) { + this.workspaceFolder = workspaceFolder; + + // Watch the idf_component.yml file for changes + if (workspaceFolder) { + const idfComponentPath = vscode.Uri.joinPath( + this.workspaceFolder, + "main", + "idf_component.yml" + ); + const watcher = vscode.workspace.createFileSystemWatcher( + new vscode.RelativePattern(idfComponentPath, "*") + ); + + watcher.onDidChange(() => this.refresh()); + watcher.onDidCreate(() => this.refresh()); + watcher.onDidDelete(() => this.refresh()); + } + } + + refresh(): void { + this._onDidChangeTreeData.fire(); // Trigger UI update for the tree + } + + getTreeItem(element: Component): vscode.TreeItem { + return element; + } + + getChildren(element?: Component): Thenable { + if (!this.workspaceFolder) { + vscode.window.showInformationMessage("No workspace folder is open"); + return Promise.resolve([]); + } + + const idfComponentPath = vscode.Uri.joinPath( + this.workspaceFolder, + "main", + "idf_component.yml" + ); + + return vscode.workspace.fs.stat(idfComponentPath).then( + () => { + if (!element) { + return this.getDependencies(idfComponentPath); + } + return Promise.resolve([]); + }, + () => { + return Promise.resolve([ + new Component( + "idf_component.yml not found", + vscode.TreeItemCollapsibleState.None, + "Create this file to define your component dependencies" + ), + ]); + } + ); + } + + private async getDependencies(fileUri: vscode.Uri): Promise { + try { + const fileContents = await vscode.workspace.fs.readFile(fileUri); + const data = yaml.load(fileContents.toString()) as any; + + if (data && data.dependencies) { + return Object.entries(data.dependencies).map( + ([dep, version]) => + new Component( + `${dep}`, + vscode.TreeItemCollapsibleState.None, + `${version}` + ) + ); + } else { + return [ + new Component( + "No dependencies found", + vscode.TreeItemCollapsibleState.None + ), + ]; + } + } catch (err) { + vscode.window.showErrorMessage( + `Error reading idf_component.yml: ${(err as Error).message}` + ); + return [ + new Component( + "Error reading file", + vscode.TreeItemCollapsibleState.None + ), + ]; + } + } +} diff --git a/src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts b/src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts deleted file mode 100644 index d18f5c981..000000000 --- a/src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider.ts +++ /dev/null @@ -1,84 +0,0 @@ -import * as vscode from "vscode"; -import * as yaml from 'js-yaml'; - -class Component extends vscode.TreeItem { - constructor( - public readonly label: string, - public readonly collapsibleState: vscode.TreeItemCollapsibleState, - public readonly description?: string - ) { - super(label, collapsibleState); - this.tooltip = `${this.label}${this.description ? ` - ${this.description}` : ''}`; - } -} - -export class ComponentsTreeDataProvider implements vscode.TreeDataProvider { - private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); - readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; - private workspaceFolder?: vscode.Uri; - - constructor(workspaceFolder: vscode.Uri | undefined) { - this.workspaceFolder = workspaceFolder; - - // Watch the idf_component.yml file for changes - if (workspaceFolder) { - const idfComponentPath = vscode.Uri.joinPath(this.workspaceFolder, 'main', 'idf_component.yml'); - const watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(idfComponentPath, '*')); - - watcher.onDidChange(() => this.refresh()); - watcher.onDidCreate(() => this.refresh()); - watcher.onDidDelete(() => this.refresh()); - } - } - - refresh(): void { - this._onDidChangeTreeData.fire(); // Trigger UI update for the tree - } - - getTreeItem(element: Component): vscode.TreeItem { - return element; - } - - getChildren(element?: Component): Thenable { - if (!this.workspaceFolder) { - vscode.window.showInformationMessage('No workspace folder is open'); - return Promise.resolve([]); - } - - const idfComponentPath = vscode.Uri.joinPath(this.workspaceFolder, 'main', 'idf_component.yml'); - - return vscode.workspace.fs.stat(idfComponentPath).then( - () => { - if (!element) { - return this.getDependencies(idfComponentPath); - } - return Promise.resolve([]); - }, - () => { - return Promise.resolve([new Component( - 'idf_component.yml not found', - vscode.TreeItemCollapsibleState.None, - 'Create this file to define your component dependencies' - )]); - } - ); - } - - private async getDependencies(fileUri: vscode.Uri): Promise { - try { - const fileContents = await vscode.workspace.fs.readFile(fileUri); - const data = yaml.load(fileContents.toString()) as any; - - if (data && data.dependencies) { - return Object.entries(data.dependencies).map(([dep, version]) => - new Component(`${dep}`, vscode.TreeItemCollapsibleState.None, `${version}`) - ); - } else { - return [new Component('No dependencies found', vscode.TreeItemCollapsibleState.None)]; - } - } catch (err) { - vscode.window.showErrorMessage(`Error reading idf_component.yml: ${(err as Error).message}`); - return [new Component('Error reading file', vscode.TreeItemCollapsibleState.None)]; - } - } -} diff --git a/src/extension.ts b/src/extension.ts index 44350918d..3cbaac424 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -37,7 +37,7 @@ import { TraceType, } from "./espIdf/tracing/tree/appTraceArchiveTreeDataProvider"; import { AppTraceTreeDataProvider } from "./espIdf/tracing/tree/appTraceTreeDataProvider"; -import { ComponentsTreeDataProvider } from "./espIdf/projectSpecificComponents/tree/componentsTreeDataProvider" +import { ComponentsTreeDataProvider } from "./espIdf/espRegistryComponents/tree/componentsTreeDataProvider" import { ExamplesPlanel } from "./examples/ExamplesPanel"; import * as idfConf from "./idfConfiguration"; import { Logger } from "./logger/logger"; @@ -49,7 +49,7 @@ import { getProjectName, initSelectedWorkspace, updateIdfComponentsTree, - updateProjectSpecificComponentsTree, + updateEspRegistryComponentsTree, } from "./workspaceConfig"; import { SystemViewResultParser } from "./espIdf/tracing/system-view"; import { Telemetry } from "./telemetry"; @@ -307,7 +307,7 @@ export async function activate(context: vscode.ExtensionContext) { }); // Specific Project Components tree view - const refreshCommand = vscode.commands.registerCommand('espIdf.projectSpecificComponents.refresh', () => { + const refreshCommand = vscode.commands.registerCommand('espIdf.espRegistryComponents.refresh', () => { componentsTreeDataProvider.refresh(); }); context.subscriptions.push(refreshCommand); @@ -915,7 +915,7 @@ export async function activate(context: vscode.ExtensionContext) { "$(plug) " + idfConf.readParameter("idf.port", workspaceRoot); } updateIdfComponentsTree(workspaceRoot); - updateProjectSpecificComponentsTree(workspaceRoot); + updateEspRegistryComponentsTree(workspaceRoot); const workspaceFolderInfo = { clickCommand: "espIdf.pickAWorkspaceFolder", currentWorkSpace: option.name, diff --git a/src/workspaceConfig.ts b/src/workspaceConfig.ts index e9c730978..a50bf7964 100644 --- a/src/workspaceConfig.ts +++ b/src/workspaceConfig.ts @@ -17,7 +17,7 @@ import { pathExists } from "fs-extra"; import * as path from "path"; import * as vscode from "vscode"; import { IdfTreeDataProvider } from "./idfComponentsDataProvider"; -import { ComponentsTreeDataProvider } from "../src/espIdf/projectSpecificComponents/tree/componentsTreeDataProvider" +import { ComponentsTreeDataProvider } from "../src/espIdf/espRegistryComponents/tree/componentsTreeDataProvider" import { writeParameter } from "./idfConfiguration"; import { Logger } from "./logger/logger"; import * as utils from "./utils"; @@ -26,7 +26,7 @@ import { getSDKConfigFilePath } from "./utils"; export function initSelectedWorkspace(status?: vscode.StatusBarItem) { const workspaceRoot = vscode.workspace.workspaceFolders[0].uri; updateIdfComponentsTree(workspaceRoot); - updateProjectSpecificComponentsTree(workspaceRoot); + updateEspRegistryComponentsTree(workspaceRoot); const workspaceFolderInfo = { clickCommand: "espIdf.pickAWorkspaceFolder", currentWorkSpace: vscode.workspace.workspaceFolders[0].name, @@ -107,11 +107,11 @@ export async function getIdfTargetFromSdkconfig( } } -let projectSpecificComponentsProvider: ComponentsTreeDataProvider; -export function updateProjectSpecificComponentsTree(workspaceFolder: vscode.Uri) { - if (typeof projectSpecificComponentsProvider === "undefined") { - projectSpecificComponentsProvider = new ComponentsTreeDataProvider(workspaceFolder); - vscode.window.registerTreeDataProvider("projectSpecificComponents", projectSpecificComponentsProvider); +let espRegistryComponentsProvider: ComponentsTreeDataProvider; +export function updateEspRegistryComponentsTree(workspaceFolder: vscode.Uri) { + if (typeof espRegistryComponentsProvider === "undefined") { + espRegistryComponentsProvider = new ComponentsTreeDataProvider(workspaceFolder); + vscode.window.registerTreeDataProvider("espRegistryComponents", espRegistryComponentsProvider); } - projectSpecificComponentsProvider.refresh(); + espRegistryComponentsProvider.refresh(); } \ No newline at end of file From 102593d2e019d20b837402a9f538bb6f30ca1360 Mon Sep 17 00:00:00 2001 From: Radu Date: Wed, 28 Aug 2024 18:21:06 +0300 Subject: [PATCH 4/5] Update names --- src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extension.ts b/src/extension.ts index 3cbaac424..c46efbc67 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -306,7 +306,7 @@ export async function activate(context: vscode.ExtensionContext) { e.element.expanded = false; }); - // Specific Project Components tree view + // ESP Registry Components tree view const refreshCommand = vscode.commands.registerCommand('espIdf.espRegistryComponents.refresh', () => { componentsTreeDataProvider.refresh(); }); From f207bc05462094b7c59a442517a73b1388986520 Mon Sep 17 00:00:00 2001 From: Radu Date: Tue, 17 Sep 2024 13:13:16 +0300 Subject: [PATCH 5/5] wip: Add remove component feature --- package.json | 10 +++ .../tree/componentsTreeDataProvider.ts | 65 ++++++++++++++++++- src/extension.ts | 27 ++++++-- 3 files changed, 96 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index aed49813c..454746516 100644 --- a/package.json +++ b/package.json @@ -280,6 +280,11 @@ } ], "view/item/context": [ + { + "command": "espIdf.deleteComponent", + "when": "view == espRegistryComponents", + "group": "inline" + }, { "command": "esp.rainmaker.backend.logout", "when": "view == espRainmaker && viewItem == account", @@ -997,6 +1002,11 @@ "category": "ESP-IDF", "icon": "$(refresh)" }, + { + "command": "espIdf.deleteComponent", + "title": "Delete Component", + "icon": "$(trash)" + }, { "command": "espIdf.createFiles", "title": "%espIdf.createFiles.title%", diff --git a/src/espIdf/espRegistryComponents/tree/componentsTreeDataProvider.ts b/src/espIdf/espRegistryComponents/tree/componentsTreeDataProvider.ts index 9dfb4c9d3..4a966276b 100644 --- a/src/espIdf/espRegistryComponents/tree/componentsTreeDataProvider.ts +++ b/src/espIdf/espRegistryComponents/tree/componentsTreeDataProvider.ts @@ -1,7 +1,9 @@ import * as vscode from "vscode"; import * as yaml from "js-yaml"; +import * as path from "path"; +import * as fs from "fs-extra"; -class Component extends vscode.TreeItem { +export class Component extends vscode.TreeItem { constructor( public readonly label: string, public readonly collapsibleState: vscode.TreeItemCollapsibleState, @@ -11,6 +13,7 @@ class Component extends vscode.TreeItem { this.tooltip = `${this.label}${ this.description ? ` - ${this.description}` : "" }`; + this.contextValue = "component"; // This will be used to show the delete command in context menu } } @@ -117,4 +120,64 @@ export class ComponentsTreeDataProvider ]; } } + + async deleteComponentFromYml( + componentName: string, + workspaceFolder: vscode.Uri + ): Promise { + const idfComponentPath = vscode.Uri.joinPath( + this.workspaceFolder || workspaceFolder, + "main", + "idf_component.yml" + ); + + try { + // Delete from idf_component.yml + const fileContents = await vscode.workspace.fs.readFile(idfComponentPath); + const data = yaml.load(fileContents.toString()) as any; + + if (data && data.dependencies && data.dependencies[componentName]) { + delete data.dependencies[componentName]; + const newContents = yaml.dump(data); + await vscode.workspace.fs.writeFile( + idfComponentPath, + Buffer.from(newContents) + ); + + // Delete the component folder + const managedComponentsPath = path.join( + workspaceFolder.fsPath, + "managed_components" + ); + const componentFolderName = componentName.replace("/", "__"); + const componentFolderPath = path.join( + managedComponentsPath, + componentFolderName + ); + + if (await fs.pathExists(componentFolderPath)) { + await fs.remove(componentFolderPath); + vscode.window.showInformationMessage( + `Deleted component "${componentName}" from path ${componentFolderPath}` + ); + } else { + vscode.window.showWarningMessage( + `Component folder not found: ${componentFolderPath}` + ); + } + + this.refresh(); + } else { + vscode.window.showWarningMessage( + `Component ${componentName} not found in idf_component.yml` + ); + } + } catch (err) { + vscode.window.showErrorMessage( + `Error updating idf_component.yml or deleting component folder: ${ + (err as Error).message + }` + ); + } + } } diff --git a/src/extension.ts b/src/extension.ts index c46efbc67..d0e682119 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -37,7 +37,10 @@ import { TraceType, } from "./espIdf/tracing/tree/appTraceArchiveTreeDataProvider"; import { AppTraceTreeDataProvider } from "./espIdf/tracing/tree/appTraceTreeDataProvider"; -import { ComponentsTreeDataProvider } from "./espIdf/espRegistryComponents/tree/componentsTreeDataProvider" +import { + ComponentsTreeDataProvider, + Component, +} from "./espIdf/espRegistryComponents/tree/componentsTreeDataProvider"; import { ExamplesPlanel } from "./examples/ExamplesPanel"; import * as idfConf from "./idfConfiguration"; import { Logger } from "./logger/logger"; @@ -306,11 +309,25 @@ export async function activate(context: vscode.ExtensionContext) { e.element.expanded = false; }); - // ESP Registry Components tree view - const refreshCommand = vscode.commands.registerCommand('espIdf.espRegistryComponents.refresh', () => { + // ESP Registry Components tree view actions + const refreshCommand = vscode.commands.registerCommand( + "espIdf.espRegistryComponents.refresh", + () => { componentsTreeDataProvider.refresh(); - }); - context.subscriptions.push(refreshCommand); + } + ); + context.subscriptions.push(refreshCommand); + + const deleteComponentCommand = vscode.commands.registerCommand( + "espIdf.deleteComponent", + (component: Component) => { + componentsTreeDataProvider.deleteComponentFromYml( + component.label, + workspaceRoot + ); + } + ); + context.subscriptions.push(deleteComponentCommand); // register openOCD status bar item registerOpenOCDStatusBarItem(context);