@@ -8,35 +8,71 @@ import { EvaluateRequestType } from "./Console";
8
8
import { LanguageClientConsumer } from "../languageClientConsumer" ;
9
9
import Settings = require( "../settings" ) ;
10
10
import { ILogger } from "../logging" ;
11
+ import { LanguageClient } from "vscode-languageclient" ;
11
12
12
- export class PowerShellNotebooksFeature extends LanguageClientConsumer implements vscode . NotebookContentProvider , vscode . NotebookKernel {
13
+ export class PowerShellNotebooksFeature extends LanguageClientConsumer {
13
14
14
- private readonly showNotebookModeCommand : vscode . Disposable ;
15
- private readonly hideNotebookModeCommand : vscode . Disposable ;
15
+ private readonly disposables : vscode . Disposable [ ] ;
16
+ private readonly notebookContentProvider : vscode . NotebookContentProvider ;
17
+ private readonly notebookKernel : PowerShellNotebookKernel ;
16
18
17
- private _onDidChangeNotebook = new vscode . EventEmitter < vscode . NotebookDocumentEditEvent > ( ) ;
18
- public onDidChangeNotebook : vscode . Event < vscode . NotebookDocumentEditEvent > = this . _onDidChangeNotebook . event ;
19
- public kernel ?: vscode . NotebookKernel ;
19
+ public constructor ( logger : ILogger , skipRegisteringCommands ?: boolean ) {
20
+ super ( ) ;
21
+ this . disposables = [ ] ;
22
+ if ( ! skipRegisteringCommands ) {
23
+ this . disposables . push ( vscode . commands . registerCommand (
24
+ "PowerShell.EnableNotebookMode" ,
25
+ PowerShellNotebooksFeature . EnableNotebookMode ) ) ;
20
26
21
- public label : string = "PowerShell" ;
22
- public preloads ?: vscode . Uri [ ] ;
27
+ this . disposables . push ( vscode . commands . registerCommand (
28
+ "PowerShell.DisableNotebookMode" ,
29
+ PowerShellNotebooksFeature . DisableNotebookMode ) ) ;
30
+ }
23
31
24
- public constructor ( private logger : ILogger , skipRegisteringCommands ?: boolean ) {
25
- super ( ) ;
26
- // VS Code Notebook API uses this property for handling cell execution.
27
- this . kernel = this ;
32
+ this . notebookContentProvider = new PowerShellNotebookContentProvider ( logger ) ;
33
+ this . notebookKernel = new PowerShellNotebookKernel ( ) ;
34
+ }
28
35
29
- if ( ! skipRegisteringCommands ) {
30
- this . showNotebookModeCommand = vscode . commands . registerCommand (
31
- "PowerShell.ShowNotebookMode" ,
32
- PowerShellNotebooksFeature . showNotebookMode ) ;
36
+ public registerNotebookProviders ( ) {
37
+ this . disposables . push ( vscode . notebook . registerNotebookKernelProvider ( {
38
+ viewType : "PowerShellNotebookMode"
39
+ } , this . notebookKernel ) ) ;
40
+
41
+ this . disposables . push ( vscode . notebook . registerNotebookContentProvider (
42
+ "PowerShellNotebookMode" ,
43
+ this . notebookContentProvider ) ) ;
44
+ }
33
45
34
- this . hideNotebookModeCommand = vscode . commands . registerCommand (
35
- "PowerShell.HideNotebookMode" ,
36
- PowerShellNotebooksFeature . hideNotebookMode ) ;
46
+ public dispose ( ) {
47
+ for ( const disposable of this . disposables ) {
48
+ disposable . dispose ( ) ;
37
49
}
38
50
}
39
51
52
+ public setLanguageClient ( languageClient : LanguageClient ) {
53
+ this . notebookKernel . setLanguageClient ( languageClient ) ;
54
+ }
55
+
56
+ private static async EnableNotebookMode ( ) {
57
+ const uri = vscode . window . activeTextEditor . document . uri ;
58
+ await vscode . commands . executeCommand ( "workbench.action.closeActiveEditor" ) ;
59
+ await vscode . commands . executeCommand ( "vscode.openWith" , uri , "PowerShellNotebookMode" ) ;
60
+ }
61
+
62
+ private static async DisableNotebookMode ( ) {
63
+ const uri = vscode . notebook . activeNotebookEditor . document . uri ;
64
+ await vscode . commands . executeCommand ( "workbench.action.closeActiveEditor" ) ;
65
+ await vscode . commands . executeCommand ( "vscode.openWith" , uri , "default" ) ;
66
+ }
67
+ }
68
+
69
+ class PowerShellNotebookContentProvider implements vscode . NotebookContentProvider {
70
+ private _onDidChangeNotebook = new vscode . EventEmitter < vscode . NotebookDocumentEditEvent > ( ) ;
71
+ public onDidChangeNotebook : vscode . Event < vscode . NotebookDocumentEditEvent > = this . _onDidChangeNotebook . event ;
72
+
73
+ public constructor ( private logger : ILogger ) {
74
+ }
75
+
40
76
public async openNotebook ( uri : vscode . Uri , context : vscode . NotebookDocumentOpenContext ) : Promise < vscode . NotebookData > {
41
77
// load from backup if needed.
42
78
const actualUri = context . backupId ? vscode . Uri . parse ( context . backupId ) : uri ;
@@ -186,11 +222,6 @@ export class PowerShellNotebooksFeature extends LanguageClientConsumer implement
186
222
} ;
187
223
}
188
224
189
- public dispose ( ) {
190
- this . showNotebookModeCommand . dispose ( ) ;
191
- this . hideNotebookModeCommand . dispose ( ) ;
192
- }
193
-
194
225
private async _save ( document : vscode . NotebookDocument , targetResource : vscode . Uri , _token : vscode . CancellationToken ) : Promise < void > {
195
226
this . logger . writeDiagnostic ( `Saving Notebook: ${ targetResource . toString ( ) } ` ) ;
196
227
@@ -215,35 +246,64 @@ export class PowerShellNotebooksFeature extends LanguageClientConsumer implement
215
246
216
247
await vscode . workspace . fs . writeFile ( targetResource , new TextEncoder ( ) . encode ( retArr . join ( "\n" ) ) ) ;
217
248
}
249
+ }
218
250
219
- private static async showNotebookMode ( ) {
220
- const uri = vscode . window . activeTextEditor . document . uri ;
221
- await vscode . commands . executeCommand ( "workbench.action.closeActiveEditor" ) ;
222
- await vscode . commands . executeCommand ( "vscode.openWith" , uri , "PowerShellNotebookMode" ) ;
251
+ class PowerShellNotebookKernel implements vscode . NotebookKernel , vscode . NotebookKernelProvider {
252
+ private static informationMessage = "PowerShell extension has not finished starting up yet. Please try again in a few moments." ;
253
+
254
+ public id ?: string ;
255
+ public label : string = "PowerShell" ;
256
+ public description ?: string = "The PowerShell Notebook Mode kernel that runs commands in the PowerShell Integrated Console." ;
257
+ public isPreferred ?: boolean ;
258
+ public preloads ?: vscode . Uri [ ] ;
259
+
260
+ private _languageClient : LanguageClient ;
261
+ private get languageClient ( ) : LanguageClient {
262
+ if ( ! this . _languageClient ) {
263
+ vscode . window . showInformationMessage (
264
+ PowerShellNotebookKernel . informationMessage ) ;
265
+ }
266
+ return this . _languageClient ;
223
267
}
224
268
225
- private static async hideNotebookMode ( ) {
226
- const uri = vscode . notebook . activeNotebookEditor . document . uri ;
227
- await vscode . commands . executeCommand ( "workbench.action.closeActiveEditor" ) ;
228
- await vscode . commands . executeCommand ( "vscode.openWith" , uri , "default" ) ;
269
+ private set languageClient ( value : LanguageClient ) {
270
+ this . _languageClient = value ;
229
271
}
230
272
231
- /*
232
- `vscode.NotebookKernel` implementations
233
- */
234
- public async executeAllCells ( document : vscode . NotebookDocument , token : vscode . CancellationToken ) : Promise < void > {
273
+ public async executeAllCells ( document : vscode . NotebookDocument ) : Promise < void > {
235
274
for ( const cell of document . cells ) {
236
- await this . executeCell ( document , cell , token ) ;
275
+ if ( cell . cellKind === vscode . CellKind . Code ) {
276
+ await this . executeCell ( document , cell ) ;
277
+ }
237
278
}
238
279
}
239
280
240
- public async executeCell ( document : vscode . NotebookDocument , cell : vscode . NotebookCell | undefined , token : vscode . CancellationToken ) : Promise < void > {
241
- if ( token . isCancellationRequested ) {
242
- return ;
243
- }
244
-
281
+ public async executeCell ( document : vscode . NotebookDocument , cell : vscode . NotebookCell | undefined ) : Promise < void > {
245
282
await this . languageClient . sendRequest ( EvaluateRequestType , {
246
283
expression : cell . document . getText ( ) ,
247
284
} ) ;
248
285
}
286
+
287
+ // Since executing a cell is a "fire and forget", there's no time for the user to cancel
288
+ // any of the executing cells. We can bring this in after PSES has a better API for executing code.
289
+ public cancelCellExecution ( document : vscode . NotebookDocument , cell : vscode . NotebookCell ) : void {
290
+ return ;
291
+ }
292
+
293
+ // Since executing a cell is a "fire and forget", there's no time for the user to cancel
294
+ // any of the executing cells. We can bring this in after PSES has a better API for executing code.
295
+ public cancelAllCellsExecution ( document : vscode . NotebookDocument ) : void {
296
+ return ;
297
+ }
298
+
299
+ public setLanguageClient ( languageClient : LanguageClient ) {
300
+ this . languageClient = languageClient ;
301
+ }
302
+
303
+ /*
304
+ vscode.NotebookKernelProvider implementation
305
+ */
306
+ public provideKernels ( document : vscode . NotebookDocument , token : vscode . CancellationToken ) : vscode . ProviderResult < vscode . NotebookKernel [ ] > {
307
+ return [ this ] ;
308
+ }
249
309
}
0 commit comments