diff --git a/package.json b/package.json index e68b9e237348..09d8c0370ddd 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "onCommand:python.viewTestOutput", "onCommand:python.viewOutput", "onCommand:python.datascience.viewJupyterOutput", + "onCOmmand:python.datascience.export", "onCommand:python.datascience.exportAsPythonScript", "onCommand:python.datascience.exportToHTML", "onCommand:python.datascience.exportToPDF", @@ -361,6 +362,15 @@ "title": "%python.command.python.datascience.viewJupyterOutput.title%", "category": "Python" }, + { + "command": "python.datascience.export", + "title": "%DataScience.notebookExportAs%", + "category": "Python", + "icon": { + "light": "resources/light/export_to_python.svg", + "dark": "resources/dark/export_to_python.svg" + } + }, { "command": "python.datascience.exportAsPythonScript", "title": "%python.command.python.datascience.exportAsPythonScript.title%", @@ -849,6 +859,12 @@ "title": "%python.command.python.datascience.restartkernel.title%", "group": "navigation", "when": "notebookEditorFocused" + }, + { + "command": "python.datascience.export", + "title": "%DataScience.notebookExportAs%", + "group": "navigation", + "when": "notebookEditorFocused" } ], "explorer/context": [ @@ -1236,6 +1252,12 @@ "title": "%DataScience.gatherQuality%", "category": "Python", "when": "false" + }, + { + "command": "python.datascience.export", + "title": "%DataScience.notebookExportAs%", + "category": "Python", + "when": "false" } ], "view/title": [ diff --git a/resources/dark/export_to_python.svg b/resources/dark/export_to_python.svg new file mode 100644 index 000000000000..a68ca2942cb7 --- /dev/null +++ b/resources/dark/export_to_python.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/light/export_to_python.svg b/resources/light/export_to_python.svg new file mode 100644 index 000000000000..873383aaeb21 --- /dev/null +++ b/resources/light/export_to_python.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/client/common/application/commands.ts b/src/client/common/application/commands.ts index 6dd8052485ac..17c73a6e3a43 100644 --- a/src/client/common/application/commands.ts +++ b/src/client/common/application/commands.ts @@ -175,7 +175,7 @@ export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgu [DSCommands.ExportAsPythonScript]: [INotebookModel]; [DSCommands.ExportToHTML]: [INotebookModel, string | undefined]; [DSCommands.ExportToPDF]: [INotebookModel, string | undefined]; - [DSCommands.Export]: [INotebookModel, string | undefined]; + [DSCommands.Export]: [Uri | INotebookModel, string | undefined]; [DSCommands.SwitchJupyterKernel]: [INotebook | undefined, 'raw' | 'jupyter']; [DSCommands.SelectJupyterCommandLine]: [undefined | Uri]; [DSCommands.SaveNotebookNonCustomEditor]: [Uri]; diff --git a/src/client/datascience/commands/exportCommands.ts b/src/client/datascience/commands/exportCommands.ts index d609860657c4..e936e60d3ec3 100644 --- a/src/client/datascience/commands/exportCommands.ts +++ b/src/client/datascience/commands/exportCommands.ts @@ -4,12 +4,14 @@ 'use strict'; import { inject, injectable } from 'inversify'; -import { QuickPickItem, QuickPickOptions } from 'vscode'; +import { QuickPickItem, QuickPickOptions, Uri } from 'vscode'; import { getLocString } from '../../../datascience-ui/react-common/locReactSide'; import { ICommandNameArgumentTypeMapping } from '../../common/application/commands'; import { IApplicationShell, ICommandManager } from '../../common/application/types'; +import { IFileSystem } from '../../common/platform/types'; import { IDisposable } from '../../common/types'; import { DataScience } from '../../common/utils/localize'; +import { isUri } from '../../common/utils/misc'; import { sendTelemetryEvent } from '../../telemetry'; import { Commands, Telemetry } from '../constants'; import { ExportManager } from '../export/exportManager'; @@ -27,7 +29,8 @@ export class ExportCommands implements IDisposable { @inject(ICommandManager) private readonly commandManager: ICommandManager, @inject(IExportManager) private exportManager: ExportManager, @inject(IApplicationShell) private readonly applicationShell: IApplicationShell, - @inject(INotebookEditorProvider) private readonly notebookProvider: INotebookEditorProvider + @inject(INotebookEditorProvider) private readonly notebookProvider: INotebookEditorProvider, + @inject(IFileSystem) private readonly fs: IFileSystem ) {} public register() { this.registerCommand(Commands.ExportAsPythonScript, (model) => this.export(model, ExportFormat.python)); @@ -55,9 +58,22 @@ export class ExportCommands implements IDisposable { this.disposables.push(disposable); } - private async export(model: INotebookModel, exportMethod?: ExportFormat, defaultFileName?: string) { + private async export(modelOrUri: Uri | INotebookModel, exportMethod?: ExportFormat, defaultFileName?: string) { + defaultFileName = typeof defaultFileName === 'string' ? defaultFileName : undefined; + let model: INotebookModel | undefined; + if (modelOrUri && isUri(modelOrUri)) { + const uri = modelOrUri; + const editor = this.notebookProvider.editors.find((item) => + this.fs.arePathsSame(item.file.fsPath, uri.fsPath) + ); + if (editor && editor.model) { + model = editor.model; + } + } else { + model = modelOrUri; + } if (!model) { - // if no model was passed then this was called from the command pallete, + // if no model was passed then this was called from the command palette, // so we need to get the active editor const activeEditor = this.notebookProvider.activeEditor; if (!activeEditor || !activeEditor.model) {