From 03779f6f048f738a8c547ccc33f741cc41c39e62 Mon Sep 17 00:00:00 2001 From: Pho Hale Date: Fri, 6 Sep 2024 10:03:09 -0400 Subject: [PATCH] working multi-selection --- package.json | 20 ++++++++++++++++- src/cellTags.ts | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index fdfb689..0e13adb 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ ], "activationEvents": [ "onNotebook:jupyter-notebook", + "onNotebookEditor:editor.selection", + "onNotebookEditor:editor.onDidChangeActiveNotebookEditor", "onCommand:jupyter-cell-tags.removeTag", "onCommand:jupyter-cell-tags.addTag", "onCommand:jupyter-cell-tags.editTagsInJSON", @@ -42,8 +44,15 @@ { "command": "jupyter-cell-tags.addTag", "title": "Add Cell Tag", - "icon": "$(add)" + "icon": "$(add)", + "when": "jupyter-cell-tags.singleCellSelected" }, + { + "command": "jupyter-cell-tags.addTagsToSelectedCells", + "title": "🏷️➕🗂️ Add Tags to Selected Cells", + "icon": "$(add)", + "when": "jupyter-cell-tags.multipleCellsSelected" + }, { "command": "jupyter-cell-tags.editTagsInJSON", "title": "Edit Cell Tags (JSON)", @@ -58,8 +67,14 @@ "notebook/cell/title": [ { "command": "jupyter-cell-tags.addTag", + "when": "jupyter-cell-tags.singleCellSelected", "group": "jupytercelltags@1" }, + { + "command": "jupyter-cell-tags.addTagsToSelectedCells", + "when": "jupyter-cell-tags.multipleCellsSelected", + "group": "jupytercelltags@2" + }, { "command": "jupyter-cell-tags.editTagsInJSON", "group": "jupytercelltags@2" @@ -116,6 +131,9 @@ "lint": "eslint src --ext ts", "test": "node ./out/test/runTest.js" }, + "enabledApiProposals": [ + "notebookCellExecutionState" + ], "devDependencies": { "@types/vscode": "^1.72.0", "@types/glob": "^7.1.3", diff --git a/src/cellTags.ts b/src/cellTags.ts index 3b20bd1..e68590f 100644 --- a/src/cellTags.ts +++ b/src/cellTags.ts @@ -20,6 +20,12 @@ export async function addCellTag(cell: vscode.NotebookCell, tags: string[]) { await updateCellTags(cell, oldTags); } +export async function addTagsToMultipleCells(cells: vscode.NotebookCell[], tags: string[]) { + for (const cell of cells) { + await addCellTag(cell, tags); + } +} + export class CellTagStatusBarProvider implements vscode.NotebookCellStatusBarItemProvider { provideCellStatusBarItems( cell: vscode.NotebookCell, @@ -71,6 +77,20 @@ export function getActiveCell() { return editor.notebook.cellAt(editor.selections[0].start); } + +export function getActiveCells(): vscode.NotebookCell[] | undefined { + const editor = vscode.window.activeNotebookEditor; + if (!editor) { + return; + } + + let cells: vscode.NotebookCell[] = []; + for (const selection of editor.selections) { + cells = cells.concat(editor.notebook.getCells(selection)); + } + return cells.length > 0 ? cells : undefined; +} + export function reviveCell(args: vscode.NotebookCell | vscode.Uri | undefined): vscode.NotebookCell | undefined { if (!args) { return getActiveCell(); @@ -157,6 +177,46 @@ export function register(context: vscode.ExtensionContext) { ) ); + context.subscriptions.push(vscode.commands.registerCommand('jupyter-cell-tags.addTagsToSelectedCells', async () => { + const activeCells = getActiveCells(); + if (!activeCells) { + return; + } + const disposables: vscode.Disposable[] = []; + try { + const knownTags = activeCells.map(cell => cell.metadata.custom?.metadata?.tags ?? []).flat().sort(); + const knownTagsLowerCased = new Set(knownTags.map(tag => tag.toLowerCase())); + const knownTagQuickPickItems = Array.from(new Set(knownTags)).map(tag => ({ label: tag })); + const quickPick = vscode.window.createQuickPick(); + disposables.push(quickPick); + quickPick.placeholder = 'Type to select or create a cell tag'; + quickPick.items = knownTagQuickPickItems; + quickPick.show(); + quickPick.onDidChangeValue(e => { + e = e.trim().toLowerCase(); + if (!e || knownTagsLowerCased.has(e)) { + return; + } + quickPick.items = knownTagQuickPickItems.concat({ label: e }).sort(); + }, undefined, disposables); + const tag = await new Promise(resolve => { + quickPick.onDidHide(() => resolve(''), undefined, disposables); + quickPick.onDidAccept(() => { + if (quickPick.selectedItems.length) { + resolve(quickPick.selectedItems[0].label); + quickPick.hide(); + } + }, undefined, disposables); + }); + if (tag) { + await addTagsToMultipleCells(activeCells, [tag]); + } + } finally { + disposables.forEach(d => d.dispose()); + } + })); + + context.subscriptions.push( vscode.commands.registerCommand( 'jupyter-cell-tags.paramaterize',