@@ -268,10 +268,29 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
268268 private _bufferedEvents : vscode . FileChangeEvent [ ] = [ ] ;
269269 private _fireSoonHandle ?: NodeJS . Timeout ;
270270
271+ /**
272+ * The stringified URIs of all `isfs` documents that may have had
273+ * their contents changed during the last time they were saved
274+ */
275+ private readonly _needsUpdate : Set < string > = new Set ( ) ;
276+
271277 public constructor ( ) {
272278 this . onDidChangeFile = this . _emitter . event ;
273279 }
274280
281+ /**
282+ * Check if this `isfs` document stringified URI was changed during
283+ * the last time it was saved. This is used to force VS Code to update
284+ * the editor tab containing the file.
285+ */
286+ public needsUpdate ( uriString : string ) : boolean {
287+ if ( this . _needsUpdate . has ( uriString ) ) {
288+ this . _needsUpdate . delete ( uriString ) ;
289+ return true ;
290+ }
291+ return false ;
292+ }
293+
275294 // Used by import and compile to make sure we notice its changes
276295 public fireFileChanged ( uri : vscode . Uri ) : void {
277296 this . _fireSoon ( { type : vscode . FileChangeType . Changed , uri } ) ;
@@ -476,6 +495,9 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
476495 overwrite : boolean ;
477496 }
478497 ) : void | Thenable < void > {
498+ const originalUriString = uri . toString ( ) ;
499+ const originalUri = vscode . Uri . parse ( originalUriString ) ;
500+ this . _needsUpdate . delete ( originalUriString ) ;
479501 uri = redirectDotvscodeRoot ( uri , new vscode . FileSystemError ( "Server does not have a /_vscode web application" ) ) ;
480502 if ( uri . path . startsWith ( "/." ) ) {
481503 throw new vscode . FileSystemError ( "dot-folders are not supported by server" ) ;
@@ -616,38 +638,17 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
616638 // is part of the "write" operation from VS Code's point of view. This is required
617639 // to prevent concurreny issues when VS Code refreshs its internal representaton of
618640 // the file system while documents are being compiled.
619- return this . compile ( uri , entry , update ) ;
641+ return this . compile ( originalUri , entry , update ) ;
620642 } else if ( update ) {
621643 // The file's contents may have changed as a result of the save,
622- // so make sure we notify VS Code and any watchers of the change
623- this . _notifyOfFileChange ( uri ) ;
644+ // so make sure VS Code updates the editor tab contents if needed
645+ this . _needsUpdate . add ( originalUriString ) ;
624646 } else if ( ! created ) {
625- this . _fireSoon ( { type : vscode . FileChangeType . Changed , uri } ) ;
647+ this . _fireSoon ( { type : vscode . FileChangeType . Changed , uri : originalUri } ) ;
626648 }
627649 } ) ;
628650 }
629651
630- /**
631- * Notify VS Code and any watchers that the contents of `uri` changed.
632- * Use this function instead of firing the file change event directly
633- * when we need to force the VS Code UI to show the change. For example,
634- * if the server changed the document during a save.
635- */
636- private _notifyOfFileChange ( uri : vscode . Uri ) : void {
637- // The file's contents may have changed as a result of the save,
638- // so make sure we notify VS Code and any watchers of the change
639- const uriString = uri . toString ( ) ;
640- if ( vscode . window . activeTextEditor ?. document . uri . toString ( ) == uriString ) {
641- setTimeout ( ( ) => {
642- const activeDoc = vscode . window . activeTextEditor ?. document ;
643- if ( activeDoc && ! activeDoc . isDirty && ! activeDoc . isClosed && activeDoc . uri . toString ( ) == uriString ) {
644- // Force VS Code to refresh the file's contents in the editor UI
645- vscode . commands . executeCommand ( "workbench.action.files.revert" ) ;
646- }
647- } , 75 ) ;
648- }
649- }
650-
651652 /** Process a Document object that was successfully deleted. */
652653 private async processDeletedDoc ( doc : Document , uri : vscode . Uri , csp : boolean , project : boolean ) : Promise < void > {
653654 const events : vscode . FileChangeEvent [ ] = [ ] ;
@@ -867,6 +868,9 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
867868 */
868869 public async compile ( uri : vscode . Uri , file ?: File , update ?: boolean ) : Promise < void > {
869870 if ( ! uri || uri . scheme != FILESYSTEM_SCHEMA ) return ;
871+ const originalUriString = uri . toString ( ) ;
872+ const originalUri = vscode . Uri . parse ( originalUriString ) ;
873+ this . _needsUpdate . delete ( originalUriString ) ;
870874 uri = redirectDotvscodeRoot ( uri , new vscode . FileSystemError ( "Server does not have a /_vscode web application" ) ) ;
871875 const compileList : string [ ] = [ ] ;
872876 try {
@@ -914,17 +918,36 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
914918 } )
915919 . catch ( ( ) => compileErrorMsg ( conf ) )
916920 ) ;
917- if ( update || ( file && filesToUpdate . includes ( file . fileName ) ) ) {
921+ if ( file && ( update || filesToUpdate . includes ( file . fileName ) ) ) {
918922 // This file was just written and the write may have changed its contents or the
919923 // compilation changed its contents. Therefore, we must force VS Code to update it.
920- this . _notifyOfFileChange ( uri ) ;
924+ this . _needsUpdate . add ( originalUriString ) ;
925+ }
926+ if ( filesToUpdate . length ) {
927+ // Force VS Code to refresh the active editor tab's contents if the file was changed
928+ // by compilation and is NOT the file that was saved if this is a post-save compilation
929+ const activeDoc = vscode . window . activeTextEditor ?. document ;
930+ if ( activeDoc && ! activeDoc . isDirty && ! activeDoc . isClosed ) {
931+ const activeDocUriString = activeDoc . uri . toString ( ) ;
932+ if (
933+ ! ( file && activeDocUriString == originalUriString ) &&
934+ filesToUpdate . some (
935+ ( f ) =>
936+ DocumentContentProvider . getUri ( f , undefined , undefined , undefined , originalUri ) ?. toString ( ) ==
937+ activeDocUriString
938+ )
939+ ) {
940+ // Force VS Code to refresh the contents in the active editor tab
941+ vscode . commands . executeCommand ( "workbench.action.files.revert" ) ;
942+ }
943+ }
921944 }
922945 // Fire file changed events for all files changed by compilation
923946 this . _fireSoon (
924947 ...filesToUpdate . map ( ( f ) => {
925948 return {
926949 type : vscode . FileChangeType . Changed ,
927- uri : DocumentContentProvider . getUri ( f , undefined , undefined , undefined , uri ) ,
950+ uri : DocumentContentProvider . getUri ( f , undefined , undefined , undefined , originalUri ) ,
928951 } ;
929952 } )
930953 ) ;
@@ -942,7 +965,7 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
942965 ) . map ( ( f : string ) => {
943966 return {
944967 type : vscode . FileChangeType . Changed ,
945- uri : DocumentContentProvider . getUri ( f , undefined , undefined , undefined , uri ) ,
968+ uri : DocumentContentProvider . getUri ( f , undefined , undefined , undefined , originalUri ) ,
946969 } ;
947970 } )
948971 ) ;
0 commit comments