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) {