@@ -68,9 +68,11 @@ export const GetEditorContextRequestType =
6868export interface IGetEditorContextRequestArguments {
6969}
7070
71+ // NOTE: The server at least now expects this response, but it's not used in any
72+ // way. In the future we could actually communicate an error to the user.
7173enum EditorOperationResponse {
72- Unsupported = 0 ,
7374 Completed ,
75+ Failed
7476}
7577
7678export const InsertTextRequestType =
@@ -148,6 +150,7 @@ interface IInvokeRegisteredEditorCommandParameter {
148150export class ExtensionCommandsFeature extends LanguageClientConsumer {
149151 private commands : vscode . Disposable [ ] ;
150152 private handlers : vscode . Disposable [ ] = [ ] ;
153+ private statusBarMessages : vscode . Disposable [ ] = [ ] ;
151154 private extensionCommands : IExtensionCommand [ ] = [ ] ;
152155
153156 constructor ( private logger : ILogger ) {
@@ -216,9 +219,7 @@ export class ExtensionCommandsFeature extends LanguageClientConsumer {
216219
217220 this . languageClient . onRequest (
218221 NewFileRequestType ,
219- // NOTE: The VS Code API does not support naming a file as it's
220- // opened, only when it's saved. Hence the argument is not used.
221- ( _filePath ) => this . newFile ( ) ) ,
222+ ( _content ) => this . newFile ( _content ) ) ,
222223
223224 this . languageClient . onRequest (
224225 OpenFileRequestType ,
@@ -267,6 +268,9 @@ export class ExtensionCommandsFeature extends LanguageClientConsumer {
267268 for ( const handler of this . handlers ) {
268269 handler . dispose ( ) ;
269270 }
271+ for ( const statusBarMessage of this . statusBarMessages ) {
272+ statusBarMessage . dispose ( ) ;
273+ }
270274 }
271275
272276 private addExtensionCommand ( command : IExtensionCommandAddedNotificationBody ) : void {
@@ -355,27 +359,35 @@ export class ExtensionCommandsFeature extends LanguageClientConsumer {
355359 } ;
356360 }
357361
358- private async newFile ( ) : Promise < EditorOperationResponse > {
359- const doc = await vscode . workspace . openTextDocument ( { content : "" } ) ;
362+ private async newFile ( content : string ) : Promise < EditorOperationResponse > {
363+ const doc = await vscode . workspace . openTextDocument (
364+ { language : "powershell" , content : content } ) ;
360365 await vscode . window . showTextDocument ( doc ) ;
361366 return EditorOperationResponse . Completed ;
362367 }
363368
364369 private async openFile ( openFileDetails : IOpenFileDetails ) : Promise < EditorOperationResponse > {
365370 const filePath = await this . resolveFilePathWithCwd ( openFileDetails . filePath ) ;
366- const doc = await vscode . workspace . openTextDocument ( filePath ) ;
367- await vscode . window . showTextDocument ( doc , { preview : openFileDetails . preview } ) ;
371+ try {
372+ const doc = await vscode . workspace . openTextDocument ( filePath ) ;
373+ await vscode . window . showTextDocument ( doc , { preview : openFileDetails . preview } ) ;
374+ } catch {
375+ void this . logger . writeAndShowWarning ( `File to open not found: ${ filePath } ` ) ;
376+ return EditorOperationResponse . Failed ;
377+ }
368378 return EditorOperationResponse . Completed ;
369379 }
370380
371381 private async closeFile ( filePath : string ) : Promise < EditorOperationResponse > {
372382 filePath = await this . resolveFilePathWithCwd ( filePath ) ;
373- const doc = vscode . workspace . textDocuments . find ( ( x ) => x . fileName === filePath ) ;
383+ const doc = vscode . workspace . textDocuments . find ( ( x ) => x . uri . fsPath === filePath ) ;
374384 if ( doc != undefined && ! doc . isClosed ) {
375385 await vscode . window . showTextDocument ( doc ) ;
376386 await vscode . commands . executeCommand ( "workbench.action.closeActiveEditor" ) ;
387+ return EditorOperationResponse . Completed ;
377388 }
378- return EditorOperationResponse . Completed ;
389+ void this . logger . writeAndShowWarning ( `File to close not found or already closed: ${ filePath } ` ) ;
390+ return EditorOperationResponse . Failed ;
379391 }
380392
381393 /**
@@ -388,17 +400,17 @@ export class ExtensionCommandsFeature extends LanguageClientConsumer {
388400 if ( saveFileDetails . filePath . startsWith ( "untitled" ) || saveFileDetails . filePath . startsWith ( "file" ) ) {
389401 currentFileUri = vscode . Uri . parse ( saveFileDetails . filePath ) ;
390402 } else {
391- currentFileUri = vscode . Uri . file ( saveFileDetails . filePath ) ;
403+ const filePath = await this . resolveFilePathWithCwd ( saveFileDetails . filePath ) ;
404+ currentFileUri = vscode . Uri . file ( filePath ) ;
392405 }
393406
394- // If the file to save can't be found, just complete the request
395- const doc = vscode . workspace . textDocuments . find ( ( x ) => x . uri === currentFileUri ) ;
407+ const doc = vscode . workspace . textDocuments . find ( ( x ) => x . uri . fsPath === currentFileUri . fsPath ) ;
396408 if ( doc === undefined ) {
397- void this . logger . writeAndShowError ( `File to save not found: ${ currentFileUri . fsPath } ` ) ;
398- return EditorOperationResponse . Completed ;
409+ void this . logger . writeAndShowWarning ( `File to save not found: ${ currentFileUri . fsPath } ` ) ;
410+ return EditorOperationResponse . Failed ;
399411 }
400412
401- let newFilePath = saveFileDetails . newPath ;
413+ let newFilePath = saveFileDetails . newPath ?? undefined ; // Otherwise it's null.
402414 if ( currentFileUri . scheme === "file" ) {
403415 // If no newFile is given, just save the current file
404416 if ( newFilePath === undefined ) {
@@ -416,31 +428,29 @@ export class ExtensionCommandsFeature extends LanguageClientConsumer {
416428 } else if ( currentFileUri . scheme === "untitled" ) {
417429 // We need a new name to save an untitled file
418430 if ( newFilePath === undefined ) {
419- void this . logger . writeAndShowError ( "Cannot save untitled file! Try SaveAs(\"path/to/file.ps1\") instead." ) ;
420- return EditorOperationResponse . Completed ;
431+ void this . logger . writeAndShowWarning ( "Cannot save untitled file! Try SaveAs(\"path/to/file.ps1\") instead." ) ;
432+ return EditorOperationResponse . Failed ;
421433 }
422434
423435 newFilePath = await this . resolveFilePathWithCwd ( newFilePath ) ;
424436 } else {
425437 // Other URI schemes are not supported
426438 const msg = JSON . stringify ( saveFileDetails , undefined , 2 ) ;
427- void this . logger . writeAndShowError (
439+ void this . logger . writeAndShowWarning (
428440 `<${ ExtensionCommandsFeature . name } >: Saving a document with scheme '${ currentFileUri . scheme } ' ` +
429441 `is currently unsupported. Message: '${ msg } '` ) ;
430- return EditorOperationResponse . Completed ;
442+ return EditorOperationResponse . Failed ;
431443 }
432444
433- await this . saveFileAs ( doc , newFilePath ) ;
434- return EditorOperationResponse . Completed ;
435-
445+ return await this . saveFileAs ( doc , newFilePath ) ;
436446 }
437447
438448 /**
439449 * Take a document available to vscode at the given URI and save it to the given absolute path
440450 * @param documentUri the URI of the vscode document to save
441451 * @param filePath the absolute path to save the document contents to
442452 */
443- private async saveFileAs ( doc : vscode . TextDocument , filePath : string ) : Promise < void > {
453+ private async saveFileAs ( doc : vscode . TextDocument , filePath : string ) : Promise < EditorOperationResponse > {
444454 // Write the old document's contents to the new document path
445455 const newFileUri = vscode . Uri . file ( filePath ) ;
446456 try {
@@ -450,12 +460,13 @@ export class ExtensionCommandsFeature extends LanguageClientConsumer {
450460 } catch ( err ) {
451461 void this . logger . writeAndShowWarning ( `<${ ExtensionCommandsFeature . name } >: ` +
452462 `Unable to save file to path '${ filePath } ': ${ err } ` ) ;
453- return ;
463+ return EditorOperationResponse . Failed ;
454464 }
455465
456466 // Finally open the new document
457467 const newFile = await vscode . workspace . openTextDocument ( newFileUri ) ;
458468 await vscode . window . showTextDocument ( newFile , { preview : true } ) ;
469+ return EditorOperationResponse . Completed ;
459470 }
460471
461472 // Resolve file path against user's CWD setting
@@ -474,9 +485,9 @@ export class ExtensionCommandsFeature extends LanguageClientConsumer {
474485 asCodePosition ( details . selectionRange . start ) ! ,
475486 asCodePosition ( details . selectionRange . end ) ! ) ,
476487 ] ;
488+ return EditorOperationResponse . Completed ;
477489 }
478-
479- return EditorOperationResponse . Completed ;
490+ return EditorOperationResponse . Failed ;
480491 }
481492
482493 private showInformationMessage ( message : string ) : EditorOperationResponse {
@@ -496,11 +507,12 @@ export class ExtensionCommandsFeature extends LanguageClientConsumer {
496507
497508 private setStatusBarMessage ( messageDetails : IStatusBarMessageDetails ) : EditorOperationResponse {
498509 if ( messageDetails . timeout ) {
499- vscode . window . setStatusBarMessage ( messageDetails . message , messageDetails . timeout ) ;
510+ this . statusBarMessages . push (
511+ vscode . window . setStatusBarMessage ( messageDetails . message , messageDetails . timeout ) ) ;
500512 } else {
501- vscode . window . setStatusBarMessage ( messageDetails . message ) ;
513+ this . statusBarMessages . push (
514+ vscode . window . setStatusBarMessage ( messageDetails . message ) ) ;
502515 }
503-
504516 return EditorOperationResponse . Completed ;
505517 }
506518}
0 commit comments