@@ -8,35 +8,71 @@ import { EvaluateRequestType } from "./Console";
88import { LanguageClientConsumer } from "../languageClientConsumer" ;
99import Settings = require( "../settings" ) ;
1010import { ILogger } from "../logging" ;
11+ import { LanguageClient } from "vscode-languageclient" ;
1112
12- export class PowerShellNotebooksFeature extends LanguageClientConsumer implements vscode . NotebookContentProvider , vscode . NotebookKernel {
13+ export class PowerShellNotebooksFeature extends LanguageClientConsumer {
1314
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 ;
1618
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 ) ) ;
2026
21- public label : string = "PowerShell" ;
22- public preloads ?: vscode . Uri [ ] ;
27+ this . disposables . push ( vscode . commands . registerCommand (
28+ "PowerShell.DisableNotebookMode" ,
29+ PowerShellNotebooksFeature . DisableNotebookMode ) ) ;
30+ }
2331
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+ }
2835
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+ }
3345
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 ( ) ;
3749 }
3850 }
3951
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+
4076 public async openNotebook ( uri : vscode . Uri , context : vscode . NotebookDocumentOpenContext ) : Promise < vscode . NotebookData > {
4177 // load from backup if needed.
4278 const actualUri = context . backupId ? vscode . Uri . parse ( context . backupId ) : uri ;
@@ -186,11 +222,6 @@ export class PowerShellNotebooksFeature extends LanguageClientConsumer implement
186222 } ;
187223 }
188224
189- public dispose ( ) {
190- this . showNotebookModeCommand . dispose ( ) ;
191- this . hideNotebookModeCommand . dispose ( ) ;
192- }
193-
194225 private async _save ( document : vscode . NotebookDocument , targetResource : vscode . Uri , _token : vscode . CancellationToken ) : Promise < void > {
195226 this . logger . writeDiagnostic ( `Saving Notebook: ${ targetResource . toString ( ) } ` ) ;
196227
@@ -215,35 +246,64 @@ export class PowerShellNotebooksFeature extends LanguageClientConsumer implement
215246
216247 await vscode . workspace . fs . writeFile ( targetResource , new TextEncoder ( ) . encode ( retArr . join ( "\n" ) ) ) ;
217248 }
249+ }
218250
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 ;
223267 }
224268
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 ;
229271 }
230272
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 > {
235274 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+ }
237278 }
238279 }
239280
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 > {
245282 await this . languageClient . sendRequest ( EvaluateRequestType , {
246283 expression : cell . document . getText ( ) ,
247284 } ) ;
248285 }
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+ }
249309}
0 commit comments