Skip to content

Commit 95e23e3

Browse files
Untitled Notebooks and Automatic Notebooks (#2919)
1 parent f2a7a2d commit 95e23e3

File tree

4 files changed

+98
-10
lines changed

4 files changed

+98
-10
lines changed

package.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@
4545
"onCommand:PowerShell.UnregisterExternalExtension",
4646
"onCommand:PowerShell.GetPowerShellVersionDetails",
4747
"onView:PowerShellCommands",
48-
"onNotebookEditor:PowerShellNotebookMode"
48+
"onNotebook:PowerShellNotebookModeDefault",
49+
"onNotebookEditor:PowerShellNotebookModeDefault",
50+
"onNotebook:PowerShellNotebookModeOption",
51+
"onNotebookEditor:PowerShellNotebookModeOption"
4952
],
5053
"dependencies": {
5154
"node-fetch": "^2.6.1",
@@ -113,10 +116,21 @@
113116
},
114117
"notebookProvider": [
115118
{
116-
"viewType": "PowerShellNotebookMode",
119+
"viewType": "PowerShellNotebookModeDefault",
117120
"displayName": "Powershell Notebook",
118121
"selector": [
119122
{
123+
"filenamePattern": "*.Notebook.ps1"
124+
}
125+
],
126+
"priority": "default"
127+
},
128+
{
129+
"viewType": "PowerShellNotebookModeOption",
130+
"displayName": "Powershell Notebook",
131+
"selector": [
132+
{
133+
"excludeFileNamePattern": "*.Notebook.ps1",
120134
"filenamePattern": "*.ps1"
121135
}
122136
],

src/features/PowerShellNotebooks.ts

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,40 @@ export class PowerShellNotebooksFeature extends LanguageClientConsumer {
3434
}
3535

3636
public registerNotebookProviders() {
37+
const options = {
38+
transientOutputs: true,
39+
transientMetadata: {
40+
inputCollapsed: true,
41+
outputCollapsed: true,
42+
runState: true,
43+
runStartTime: true,
44+
executionOrder: true,
45+
lastRunDuration: true,
46+
statusMessage: true,
47+
},
48+
};
49+
50+
// Until vscode supports using the same view type with different priority,
51+
// we register 2 of the same viewTypes.
52+
// This one is used to open *.Notebook.ps1 files which automatically go straight to Notebook mode.
53+
this.disposables.push(vscode.notebook.registerNotebookKernelProvider({
54+
viewType: "PowerShellNotebookModeDefault"
55+
}, this.notebookKernel));
56+
57+
this.disposables.push(vscode.notebook.registerNotebookContentProvider(
58+
"PowerShellNotebookModeDefault",
59+
this.notebookContentProvider,
60+
options));
61+
62+
// This one is used to open *.ps1 files which will be opened in the default text editor first.
3763
this.disposables.push(vscode.notebook.registerNotebookKernelProvider({
38-
viewType: "PowerShellNotebookMode"
64+
viewType: "PowerShellNotebookModeOption"
3965
}, this.notebookKernel));
4066

4167
this.disposables.push(vscode.notebook.registerNotebookContentProvider(
42-
"PowerShellNotebookMode",
43-
this.notebookContentProvider));
68+
"PowerShellNotebookModeOption",
69+
this.notebookContentProvider,
70+
options));
4471
}
4572

4673
public dispose() {
@@ -55,8 +82,17 @@ export class PowerShellNotebooksFeature extends LanguageClientConsumer {
5582

5683
private static async EnableNotebookMode() {
5784
const uri = vscode.window.activeTextEditor.document.uri;
58-
await vscode.commands.executeCommand("workbench.action.closeActiveEditor");
59-
await vscode.commands.executeCommand("vscode.openWith", uri, "PowerShellNotebookMode");
85+
86+
// If the file is an untitled file, then we can't close it.
87+
if (!vscode.window.activeTextEditor.document.isUntitled) {
88+
await vscode.commands.executeCommand("workbench.action.closeActiveEditor");
89+
}
90+
91+
if (uri.fsPath?.endsWith(".Notebook.ps1")) {
92+
await vscode.commands.executeCommand("vscode.openWith", uri, "PowerShellNotebookModeDefault");
93+
} else {
94+
await vscode.commands.executeCommand("vscode.openWith", uri, "PowerShellNotebookModeOption");
95+
}
6096
}
6197

6298
private static async DisableNotebookMode() {
@@ -95,8 +131,12 @@ class PowerShellNotebookContentProvider implements vscode.NotebookContentProvide
95131
// load from backup if needed.
96132
const actualUri = context.backupId ? vscode.Uri.parse(context.backupId) : uri;
97133
this.logger.writeDiagnostic(`Opening Notebook: ${uri.toString()}`);
134+
const isUntitled = uri.scheme !== "file";
98135

99-
const data = (await vscode.workspace.fs.readFile(actualUri)).toString();
136+
// If we have an untitled file, get the contents from vscode instead of the file system.
137+
const data: string = isUntitled
138+
? (await vscode.workspace.openTextDocument(actualUri)).getText()
139+
: (await vscode.workspace.fs.readFile(actualUri)).toString();
100140

101141
let lines: string[];
102142
// store the line ending in the metadata of the document
@@ -117,6 +157,7 @@ class PowerShellNotebookContentProvider implements vscode.NotebookContentProvide
117157
metadata: {
118158
custom: {
119159
lineEnding,
160+
isUntitled,
120161
}
121162
}
122163
};
@@ -374,6 +415,11 @@ class PowerShellNotebookKernel implements vscode.NotebookKernel, vscode.Notebook
374415
await this.languageClient.sendRequest(EvaluateRequestType, {
375416
expression: cell.document.getText(),
376417
});
418+
419+
// Show the integrated console if it isn't already visible and
420+
// scroll terminal to bottom so new output is visible
421+
await vscode.commands.executeCommand("PowerShell.ShowSessionConsole", true);
422+
await vscode.commands.executeCommand("workbench.action.terminal.scrollToBottom");
377423
}
378424

379425
// Since executing a cell is a "fire and forget", there's no time for the user to cancel

test/features/PowerShellNotebooks.test.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ const notebookSimpleLineComments = vscode.Uri.file(
3434
path.join(...notebookDir,"simpleLineComments.ps1"));
3535
const notebookSimpleMixedComments = vscode.Uri.file(
3636
path.join(...notebookDir,"simpleMixedComments.ps1"));
37+
const notebookSimpleDotNotebook = vscode.Uri.file(
38+
path.join(...notebookDir,"simple.Notebook.ps1"));
3739

3840
const notebookTestData = new Map<vscode.Uri, vscode.NotebookCellData[]>();
3941

@@ -343,7 +345,7 @@ suite("PowerShellNotebooks tests", () => {
343345
}
344346

345347
// Open an existing notebook ps1.
346-
await vscode.commands.executeCommand("vscode.openWith", notebookSimpleMixedComments, "PowerShellNotebookMode");
348+
await vscode.commands.executeCommand("vscode.openWith", notebookSimpleMixedComments, "PowerShellNotebookModeOption");
347349

348350
// Allow some time to pass to render the Notebook
349351
await utils.sleep(5000);
@@ -369,7 +371,7 @@ suite("PowerShellNotebooks tests", () => {
369371
}
370372

371373
// Open an existing notebook ps1.
372-
await vscode.commands.executeCommand("vscode.openWith", notebookBlockCommentsWithTextOnSameLine, "PowerShellNotebookMode");
374+
await vscode.commands.executeCommand("vscode.openWith", notebookBlockCommentsWithTextOnSameLine, "PowerShellNotebookModeOption");
373375

374376
// Allow some time to pass to render the Notebook
375377
await utils.sleep(5000);
@@ -385,4 +387,28 @@ suite("PowerShellNotebooks tests", () => {
385387
// Verify that saving does not mutate result.
386388
assert.strictEqual(contentOfBackingFileBefore, contentOfBackingFileAfter);
387389
}).timeout(20000);
390+
391+
test("Can open an untitled Notebook", async () => {
392+
const doc = await vscode.workspace.openTextDocument({
393+
language: "powershell",
394+
content: `# asdf
395+
gci`,
396+
});
397+
398+
const notebookData = await notebookContentProvider.openNotebook(doc.uri, {});
399+
assert.strictEqual(notebookData.cells.length, 2);
400+
assert.strictEqual(notebookData.cells[0].cellKind, vscode.CellKind.Markdown);
401+
assert.strictEqual(notebookData.cells[0].source, "asdf");
402+
assert.strictEqual(notebookData.cells[1].cellKind, vscode.CellKind.Code);
403+
assert.strictEqual(notebookData.cells[1].source, "gci");
404+
}).timeout(20000);
405+
406+
test(".Notebook.ps1 files are opened automatically", async () => {
407+
await vscode.commands.executeCommand("vscode.open", notebookSimpleDotNotebook);
408+
assert.strictEqual(vscode.notebook.activeNotebookEditor.document.cells.length, 2);
409+
assert.strictEqual(vscode.notebook.activeNotebookEditor.document.cells[0].cellKind, vscode.CellKind.Markdown);
410+
assert.strictEqual(vscode.notebook.activeNotebookEditor.document.cells[0].document.getText(), "asdf");
411+
assert.strictEqual(vscode.notebook.activeNotebookEditor.document.cells[1].cellKind, vscode.CellKind.Code);
412+
assert.strictEqual(vscode.notebook.activeNotebookEditor.document.cells[1].document.getText(), "gci\n");
413+
}).timeout(20000);
388414
});
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# asdf
2+
gci

0 commit comments

Comments
 (0)