Fix #209158. Add Copy Output and Open Output in Text Editor to Scrollable text output context menu. (#216920)

* Fix #209158. Add Copy Output and Open Output in Text Editor to Scrollable text output context menu.

* Context menu should be triggered on container

* fix naming
This commit is contained in:
Peng Lyu 2024-06-24 10:31:17 -07:00 committed by GitHub
parent 36a5701192
commit 1b883b238e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 72 additions and 1 deletions

View File

@ -62,6 +62,11 @@
"command": "notebook.cellOutput.copy",
"title": "%copyCellOutput.title%",
"category": "Notebook"
},
{
"command": "notebook.cellOutput.openInTextEditor",
"title": "%openCellOutput.title%",
"category": "Notebook"
}
],
"notebooks": [
@ -108,12 +113,24 @@
{
"command": "notebook.cellOutput.copy",
"when": "notebookCellHasOutputs"
},
{
"command": "notebook.cellOutput.openInTextEditor",
"when": "false"
}
],
"webview/context": [
{
"command": "notebook.cellOutput.copy",
"when": "webviewId == 'notebook.output' && webviewSection == 'image'"
},
{
"command": "notebook.cellOutput.copy",
"when": "webviewId == 'notebook.output' && webviewSection == 'text'"
},
{
"command": "notebook.cellOutput.openInTextEditor",
"when": "webviewId == 'notebook.output' && webviewSection == 'text'"
}
]
}

View File

@ -7,6 +7,7 @@
"openIpynbInNotebookEditor.title": "Open IPYNB File In Notebook Editor",
"cleanInvalidImageAttachment.title": "Clean Invalid Image Attachment Reference",
"copyCellOutput.title": "Copy Cell Output",
"openCellOutput.title": "Open Cell Output in Text Editor",
"markdownAttachmentRenderer.displayName": {
"message": "Markdown-It ipynb Cell Attachment renderer",
"comment": [

View File

@ -71,6 +71,11 @@ function generateNestedViewAllElement(outputId: string) {
function truncatedArrayOfString(id: string, buffer: string[], linesLimit: number, linkOptions: LinkOptions) {
const container = document.createElement('div');
container.setAttribute('data-vscode-context', JSON.stringify({
webviewSection: 'text',
outputId: id,
'preventDefaultContextMenuItems': true
}));
const lineCount = buffer.length;
if (lineCount <= linesLimit) {
@ -95,6 +100,11 @@ function truncatedArrayOfString(id: string, buffer: string[], linesLimit: number
function scrollableArrayOfString(id: string, buffer: string[], linkOptions: LinkOptions) {
const element = document.createElement('div');
element.setAttribute('data-vscode-context', JSON.stringify({
webviewSection: 'text',
outputId: id,
'preventDefaultContextMenuItems': true
}));
if (buffer.length > softScrollableLineLimit) {
element.appendChild(generateNestedViewAllElement(id));
}

View File

@ -7,6 +7,7 @@ import { ServicesAccessor } from 'vs/editor/browser/editorExtensions';
import { localize } from 'vs/nls';
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { INotebookOutputActionContext, NOTEBOOK_ACTIONS_CATEGORY } from 'vs/workbench/contrib/notebook/browser/controller/coreActions';
import { NOTEBOOK_CELL_HAS_OUTPUTS } from 'vs/workbench/contrib/notebook/common/notebookContextKeys';
import * as icons from 'vs/workbench/contrib/notebook/browser/notebookIcons';
@ -14,7 +15,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { copyCellOutput } from 'vs/workbench/contrib/notebook/browser/contrib/clipboard/cellOutputClipboard';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ICellOutputViewModel, ICellViewModel, INotebookEditor, getNotebookEditorFromEditorPane } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellKind, CellUri } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
export const COPY_OUTPUT_COMMAND_ID = 'notebook.cellOutput.copy';
@ -104,3 +105,45 @@ function getOutputViewModelFromId(outputId: string, notebookEditor: INotebookEdi
return undefined;
}
export const OPEN_OUTPUT_COMMAND_ID = 'notebook.cellOutput.openInTextEditor';
registerAction2(class OpenCellOutputInEditorAction extends Action2 {
constructor() {
super({
id: OPEN_OUTPUT_COMMAND_ID,
title: localize('notebookActions.openOutputInEditor', "Open Cell Output in Text Editor"),
f1: false,
category: NOTEBOOK_ACTIONS_CATEGORY,
icon: icons.copyIcon,
});
}
private getNoteboookEditor(editorService: IEditorService, outputContext: INotebookOutputActionContext | { outputViewModel: ICellOutputViewModel } | undefined): INotebookEditor | undefined {
if (outputContext && 'notebookEditor' in outputContext) {
return outputContext.notebookEditor;
}
return getNotebookEditorFromEditorPane(editorService.activeEditorPane);
}
async run(accessor: ServicesAccessor, outputContext: INotebookOutputActionContext | { outputViewModel: ICellOutputViewModel } | undefined): Promise<void> {
const notebookEditor = this.getNoteboookEditor(accessor.get(IEditorService), outputContext);
if (!notebookEditor) {
return;
}
let outputViewModel: ICellOutputViewModel | undefined;
if (outputContext && 'outputId' in outputContext && typeof outputContext.outputId === 'string') {
outputViewModel = getOutputViewModelFromId(outputContext.outputId, notebookEditor);
} else if (outputContext && 'outputViewModel' in outputContext) {
outputViewModel = outputContext.outputViewModel;
}
const openerService = accessor.get(IOpenerService);
if (outputViewModel?.model.outputId && notebookEditor.textModel?.uri) {
openerService.open(CellUri.generateCellOutputUri(notebookEditor.textModel.uri, outputViewModel.model.outputId));
}
}
});