From d88c95e3fe4b6627cb28acbf40a0c79bb46fb9fd Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Wed, 22 Oct 2025 21:48:22 +0200 Subject: [PATCH] Multiple slot selector working --- package.json | 3 ++- src/extension.ts | 56 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index ac911c5..06aff47 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ { "command": "modelsim.toggleWaveMode", "title": "Toggle Wave Debug Mode" } ], "keybindings": [ - { "command": "modelsim.addWaveUnderCursor", "key": "ctrl+w" }, + { "command": "modelsim.addWaveUnderCursor", "key": "ctrl+w", "args": { "mode": "auto" } }, + { "command": "modelsim.addWaveUnderCursor", "key": "ctrl+e", "args": { "mode": "set" } }, { "command": "modelsim.toggleWaveMode", "key": "ctrl+alt+m" }, { "command": "modelsim.zoomInWave", "key": "ctrl+alt+u" } ], diff --git a/src/extension.ts b/src/extension.ts index 84e48ff..44577c1 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -7,7 +7,7 @@ const lastHoverByDoc = new Map(); const HOVER_FRESH_MS = 2000; // Hold MANY instance paths per module name, e.g. queue_slot -> ["/test/...[0]", "/test/...[1]", ...] -let moduleTree: Record = {}; +let moduleTree: Record = {}; let waveMode = false; let statusItem: vscode.StatusBarItem; @@ -170,7 +170,7 @@ export function activate(context: vscode.ExtensionContext) { const cmd_2 = vscode.commands.registerCommand('modelsim.toggleWaveMode', async () => { toggleWaveMode(); }); - const cmd = vscode.commands.registerCommand('modelsim.addWaveUnderCursor', async () => { + const cmd = vscode.commands.registerCommand('modelsim.addWaveUnderCursor', async (args?: { mode?: string }) => { if (waveMode) { const editor = vscode.window.activeTextEditor; @@ -219,7 +219,7 @@ export function activate(context: vscode.ExtensionContext) { const modName = path.basename(editor.document.fileName, path.extname(editor.document.fileName)); let instancePaths = - moduleTree[modName] ?? moduleTree[modName.toLowerCase()]; + moduleTree[modName].module ?? moduleTree[modName.toLowerCase()].module; if (!instancePaths || instancePaths.length === 0) { console.log( `No instance paths found for module "${modName}". ` + @@ -228,15 +228,49 @@ export function activate(context: vscode.ExtensionContext) { return; } + + // Add the token for every instance of this module (dedupe paths just in case) instancePaths = Array.from(new Set(instancePaths)).map(p => p.replace(/\/+/g, '/')); - let ok = true; - for (const p of instancePaths) { - const cmd = `quietly add wave -noupdate ${p}/${tokenText}`.replace(/\/+/g, '/'); - const res = await sendAndAwait(sharedDir, cmd, timeoutMs); - ok = ok && !!res; + const mode = args?.mode ?? 'auto'; + + let instance_num = moduleTree[modName].last ?? moduleTree[modName.toLowerCase()].last; + if (instancePaths.length > 1 && mode === 'set') { + const input_num = await vscode.window.showInputBox({ + title: 'Enter a number', + prompt: 'This number will be used by the action.', + placeHolder: moduleTree[modName].last !== undefined ? `Press Enter to reuse ${moduleTree[modName].last}` : 'e.g. 42', + value: moduleTree[modName].last !== undefined ? String(moduleTree[modName].last) : '', + ignoreFocusOut: true, + validateInput: (value) => { + if (value.trim() === '') return null; // allow Enter to reuse last + const n = Number(value); + if (!Number.isInteger(n)) return 'Please enter an integer.'; + if (n < 0) return 'Please enter a non-negative integer.'; + // optionally cap it + if (n > 10000) return 'That’s too large (max 10000).'; + return null; + }, + }); + + if (input_num === undefined) { + // User hit Esc — do nothing + return; + } + + // Empty input means reuse last (if any) + instance_num = (input_num.trim() === '' || Number(input_num) >= moduleTree[modName].module.length) && moduleTree[modName].last !== undefined ? moduleTree[modName].last : Number(input_num); + + moduleTree[modName].last = instance_num; } + + let ok = true; + // for (const p of instancePaths) { + const cmd = `quietly add wave -noupdate \{${instancePaths[instance_num]}/${tokenText}\}`.replace(/\/+/g, '/'); + console.log(cmd); + const res = await sendAndAwait(sharedDir, cmd, timeoutMs); + ok = ok && !!res; ok = ok && !!(await sendAndAwait(sharedDir, 'update', timeoutMs)); if (ok) { @@ -355,7 +389,7 @@ async function requestModuleTree( sharedDir: string, topScope: string, timeoutMs: number -): Promise> { +): Promise> { const tree: Record = {}; const payload = `get_module_tree ${topScope}`; console.log("Requesting ModuleTree"); @@ -365,7 +399,7 @@ async function requestModuleTree( const text = (await res) ?? ""; console.log("Module Hierarchy: ", text) const rx = /\{([^}]+?)\s+\(([^)]+)\)\}/g; // { ()} - const moduleTree: Record = {}; + const moduleTree: Record = {}; let m: RegExpExecArray | null; while ((m = rx.exec(text))) { @@ -386,7 +420,7 @@ async function requestModuleTree( // .map(seg => (seg.startsWith("u_") ? seg : "u_" + seg)) // .join("/"); - (moduleTree[modType] ??= []).push(rawPath); + ((moduleTree[modType] ??= { module: [], last: 0 }).module).push(rawPath); } console.log(moduleTree);