Skip to content

Commit ed35abb

Browse files
authored
fix copy output command without context (microsoft#203582)
* fix copy output without context * better title * clear output focus
1 parent 1b25a13 commit ed35abb

File tree

6 files changed

+157
-135
lines changed

6 files changed

+157
-135
lines changed

extensions/ipynb/package.json

Lines changed: 136 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,138 @@
11
{
2-
"name": "ipynb",
3-
"displayName": "%displayName%",
4-
"description": "%description%",
5-
"publisher": "vscode",
6-
"version": "1.0.0",
7-
"license": "MIT",
8-
"icon": "media/icon.png",
9-
"engines": {
10-
"vscode": "^1.57.0"
11-
},
12-
"enabledApiProposals": [
13-
"documentPaste",
14-
"diffContentOptions",
15-
"dropMetadata"
16-
],
17-
"activationEvents": [
18-
"onNotebook:jupyter-notebook",
19-
"onNotebookSerializer:interactive"
20-
],
21-
"extensionKind": [
22-
"workspace",
23-
"ui"
24-
],
25-
"main": "./out/ipynbMain.js",
26-
"browser": "./dist/browser/ipynbMain.js",
27-
"capabilities": {
28-
"virtualWorkspaces": true,
29-
"untrustedWorkspaces": {
30-
"supported": true
31-
}
32-
},
33-
"contributes": {
34-
"configuration": [
35-
{
36-
"properties": {
37-
"ipynb.pasteImagesAsAttachments.enabled": {
38-
"type": "boolean",
39-
"scope": "resource",
40-
"markdownDescription": "%ipynb.pasteImagesAsAttachments.enabled%",
41-
"default": true
42-
}
43-
}
44-
}
45-
],
46-
"commands": [
47-
{
48-
"command": "ipynb.newUntitledIpynb",
49-
"title": "%newUntitledIpynb.title%",
50-
"shortTitle": "%newUntitledIpynb.shortTitle%",
51-
"category": "Create"
52-
},
53-
{
54-
"command": "ipynb.openIpynbInNotebookEditor",
55-
"title": "%openIpynbInNotebookEditor.title%"
56-
},
57-
{
58-
"command": "ipynb.cleanInvalidImageAttachment",
59-
"title": "%cleanInvalidImageAttachment.title%"
60-
},
61-
{
62-
"command": "notebook.cellOutput.copy",
63-
"title": "%copyCellOutput.title%"
64-
}
65-
],
66-
"notebooks": [
67-
{
68-
"type": "jupyter-notebook",
69-
"displayName": "Jupyter Notebook",
70-
"selector": [
71-
{
72-
"filenamePattern": "*.ipynb"
73-
}
74-
],
75-
"priority": "default"
76-
}
77-
],
78-
"notebookRenderer": [
79-
{
80-
"id": "vscode.markdown-it-cell-attachment-renderer",
81-
"displayName": "%markdownAttachmentRenderer.displayName%",
82-
"entrypoint": {
83-
"extends": "vscode.markdown-it-renderer",
84-
"path": "./notebook-out/cellAttachmentRenderer.js"
85-
}
86-
}
87-
],
88-
"menus": {
89-
"file/newFile": [
90-
{
91-
"command": "ipynb.newUntitledIpynb",
92-
"group": "notebook"
93-
}
94-
],
95-
"commandPalette": [
96-
{
97-
"command": "ipynb.newUntitledIpynb"
98-
},
99-
{
100-
"command": "ipynb.openIpynbInNotebookEditor",
101-
"when": "false"
102-
},
103-
{
104-
"command": "ipynb.cleanInvalidImageAttachment",
105-
"when": "false"
106-
}
107-
],
108-
"webview/context": [
109-
{
110-
"command": "notebook.cellOutput.copy",
111-
"when": "webviewId == 'notebook.output' && webviewSection == 'image'"
112-
}
113-
]
114-
}
115-
},
116-
"scripts": {
117-
"compile": "npx gulp compile-extension:ipynb && npm run build-notebook",
118-
"watch": "npx gulp watch-extension:ipynb",
119-
"build-notebook": "node ./esbuild"
120-
},
121-
"dependencies": {
122-
"@enonic/fnv-plus": "^1.3.0",
123-
"detect-indent": "^6.0.0"
124-
},
125-
"devDependencies": {
126-
"@jupyterlab/nbformat": "^3.2.9",
127-
"@types/markdown-it": "12.2.3"
128-
},
129-
"repository": {
130-
"type": "git",
131-
"url": "https://github.com/microsoft/vscode.git"
132-
}
2+
"name": "ipynb",
3+
"displayName": "%displayName%",
4+
"description": "%description%",
5+
"publisher": "vscode",
6+
"version": "1.0.0",
7+
"license": "MIT",
8+
"icon": "media/icon.png",
9+
"engines": {
10+
"vscode": "^1.57.0"
11+
},
12+
"enabledApiProposals": [
13+
"documentPaste",
14+
"diffContentOptions",
15+
"dropMetadata"
16+
],
17+
"activationEvents": [
18+
"onNotebook:jupyter-notebook",
19+
"onNotebookSerializer:interactive"
20+
],
21+
"extensionKind": [
22+
"workspace",
23+
"ui"
24+
],
25+
"main": "./out/ipynbMain.js",
26+
"browser": "./dist/browser/ipynbMain.js",
27+
"capabilities": {
28+
"virtualWorkspaces": true,
29+
"untrustedWorkspaces": {
30+
"supported": true
31+
}
32+
},
33+
"contributes": {
34+
"configuration": [
35+
{
36+
"properties": {
37+
"ipynb.pasteImagesAsAttachments.enabled": {
38+
"type": "boolean",
39+
"scope": "resource",
40+
"markdownDescription": "%ipynb.pasteImagesAsAttachments.enabled%",
41+
"default": true
42+
}
43+
}
44+
}
45+
],
46+
"commands": [
47+
{
48+
"command": "ipynb.newUntitledIpynb",
49+
"title": "%newUntitledIpynb.title%",
50+
"shortTitle": "%newUntitledIpynb.shortTitle%",
51+
"category": "Create"
52+
},
53+
{
54+
"command": "ipynb.openIpynbInNotebookEditor",
55+
"title": "%openIpynbInNotebookEditor.title%"
56+
},
57+
{
58+
"command": "ipynb.cleanInvalidImageAttachment",
59+
"title": "%cleanInvalidImageAttachment.title%"
60+
},
61+
{
62+
"command": "notebook.cellOutput.copy",
63+
"title": "%copyCellOutput.title%",
64+
"category": "Notebook"
65+
}
66+
],
67+
"notebooks": [
68+
{
69+
"type": "jupyter-notebook",
70+
"displayName": "Jupyter Notebook",
71+
"selector": [
72+
{
73+
"filenamePattern": "*.ipynb"
74+
}
75+
],
76+
"priority": "default"
77+
}
78+
],
79+
"notebookRenderer": [
80+
{
81+
"id": "vscode.markdown-it-cell-attachment-renderer",
82+
"displayName": "%markdownAttachmentRenderer.displayName%",
83+
"entrypoint": {
84+
"extends": "vscode.markdown-it-renderer",
85+
"path": "./notebook-out/cellAttachmentRenderer.js"
86+
}
87+
}
88+
],
89+
"menus": {
90+
"file/newFile": [
91+
{
92+
"command": "ipynb.newUntitledIpynb",
93+
"group": "notebook"
94+
}
95+
],
96+
"commandPalette": [
97+
{
98+
"command": "ipynb.newUntitledIpynb"
99+
},
100+
{
101+
"command": "ipynb.openIpynbInNotebookEditor",
102+
"when": "false"
103+
},
104+
{
105+
"command": "ipynb.cleanInvalidImageAttachment",
106+
"when": "false"
107+
},
108+
{
109+
"command": "notebook.cellOutput.copy",
110+
"when": "notebookCellHasOutputs"
111+
}
112+
],
113+
"webview/context": [
114+
{
115+
"command": "notebook.cellOutput.copy",
116+
"when": "webviewId == 'notebook.output' && webviewSection == 'image'"
117+
}
118+
]
119+
}
120+
},
121+
"scripts": {
122+
"compile": "npx gulp compile-extension:ipynb && npm run build-notebook",
123+
"watch": "npx gulp watch-extension:ipynb",
124+
"build-notebook": "node ./esbuild"
125+
},
126+
"dependencies": {
127+
"@enonic/fnv-plus": "^1.3.0",
128+
"detect-indent": "^6.0.0"
129+
},
130+
"devDependencies": {
131+
"@jupyterlab/nbformat": "^3.2.9",
132+
"@types/markdown-it": "12.2.3"
133+
},
134+
"repository": {
135+
"type": "git",
136+
"url": "https://github.com/microsoft/vscode.git"
137+
}
133138
}

extensions/ipynb/package.nls.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"newUntitledIpynb.shortTitle": "Jupyter Notebook",
77
"openIpynbInNotebookEditor.title": "Open IPYNB File In Notebook Editor",
88
"cleanInvalidImageAttachment.title": "Clean Invalid Image Attachment Reference",
9-
"copyCellOutput.title": "Copy Output",
9+
"copyCellOutput.title": "Copy Cell Output",
1010
"markdownAttachmentRenderer.displayName": {
1111
"message": "Markdown-It ipynb Cell Attachment renderer",
1212
"comment": [

src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ registerAction2(class CopyCellOutputAction extends Action2 {
3333
});
3434
}
3535

36-
async run(accessor: ServicesAccessor, outputContext: INotebookOutputActionContext | { outputViewModel: ICellOutputViewModel }): Promise<void> {
36+
async run(accessor: ServicesAccessor, outputContext: INotebookOutputActionContext | { outputViewModel: ICellOutputViewModel } | undefined): Promise<void> {
3737
const editorService = accessor.get(IEditorService);
3838
const notebookEditor = getNotebookEditorFromEditorPane(editorService.activeEditorPane);
3939

@@ -42,7 +42,20 @@ registerAction2(class CopyCellOutputAction extends Action2 {
4242
}
4343

4444
let outputViewModel: ICellOutputViewModel | undefined;
45-
if ('outputId' in outputContext && typeof outputContext.outputId === 'string') {
45+
if (!outputContext) {
46+
const activeCell = notebookEditor.getActiveCell();
47+
if (!activeCell) {
48+
return;
49+
}
50+
51+
if (activeCell.focusedOutputId !== undefined) {
52+
outputViewModel = activeCell.outputsViewModels.find(output => {
53+
return output.model.outputId === activeCell.focusedOutputId;
54+
});
55+
} else {
56+
outputViewModel = activeCell.outputsViewModels.find(output => output.pickedMimeType?.isTrusted);
57+
}
58+
} else if ('outputId' in outputContext && typeof outputContext.outputId === 'string') {
4659
outputViewModel = getOutputViewModelFromId(outputContext.outputId, notebookEditor);
4760
} else {
4861
outputViewModel = outputContext.outputViewModel;

src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ export interface ICellViewModel extends IGenericCellViewModel {
256256
lineNumbers: 'on' | 'off' | 'inherit';
257257
chatHeight: number;
258258
focusMode: CellFocusMode;
259+
focusedOutputId?: string | undefined;
259260
outputIsHovered: boolean;
260261
getText(): string;
261262
getTextLength(): number;

src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2363,6 +2363,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
23632363
return;
23642364
}
23652365

2366+
cell.focusedOutputId = undefined;
2367+
23662368
if (focusItem === 'editor') {
23672369
this.focusElement(cell);
23682370
this._list.focusView();
@@ -2408,6 +2410,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
24082410

24092411
cell.updateEditState(CellEditState.Preview, 'focusNotebookCell');
24102412
cell.focusMode = CellFocusMode.Output;
2413+
cell.focusedOutputId = options?.outputId;
24112414
if (!options?.skipReveal) {
24122415
this.revealInCenterIfOutsideViewport(cell);
24132416
}

src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
667667
const latestCell = this.notebookEditor.getCellByInfo(resolvedResult.cellInfo);
668668
if (latestCell) {
669669
latestCell.outputIsFocused = true;
670-
this.notebookEditor.focusNotebookCell(latestCell, 'output', { skipReveal: true, outputWebviewFocused: true });
670+
this.notebookEditor.focusNotebookCell(latestCell, 'output', { outputId: resolvedResult.output.model.outputId, skipReveal: true, outputWebviewFocused: true });
671671
}
672672
}
673673
break;

0 commit comments

Comments
 (0)