@@ -610,41 +610,17 @@ class TextBuffer {
610610 // can be used to prevent further calls to the callback.
611611 setFile ( file ) {
612612 if ( ! this . file && ! file ) return
613-
614- // We use this heuristic to try to help us skip potentially costly
615- // re-subscribes when nothing has meaningfully changed.
616- let isExistingFile = file && file . getPath ( ) === this . getPath ( )
617-
618- // But there are some exceptions we should consider.
619- //
620- // If the backing file is deleted, a subsequent call to `save` will
621- // re-create the file. In that scenario, even though the path matches the
622- // buffer's last path, we still need to resubscribe to file events.
623- let shouldResubscribeAfterDeletion = this . shouldResubscribeIfPathMatches &&
624- file ?. getPath ( ) === this . shouldResubscribeIfPathMatches
625-
626- // `file` is a duck-typed object, and just because two `file`s agree on
627- // their `getPath()` return value does not mean they are equivalent. Here
628- // we compare the old and new `file`s to see if they were instantiated from
629- // the same constructor; if not, we should re-subscribe.
630- let shouldResubscribeAfterNewImpl = ! this . file || ( file && this . file . constructor !== file . constructor )
613+ if ( file === this . file ) return
631614
632615 this . file = file
633- if ( this . file && ! isExistingFile ) {
634- this . file . setEncoding ?. ( this . getEncoding ( ) )
635- }
636-
637- if ( shouldResubscribeAfterDeletion || shouldResubscribeAfterNewImpl || ! isExistingFile ) {
616+ if ( this . file ) {
617+ if ( typeof this . file . setEncoding === 'function' ) {
618+ this . file . setEncoding ( this . getEncoding ( ) )
619+ }
638620 this . subscribeToFile ( )
639- this . shouldResubscribeIfPathMatches = undefined
640- }
641- if ( ! isExistingFile ) {
642- // The act of setting a new file (even calling this method with
643- // `undefined`) should clear this buffer's deleted state.
644- this . didHaveFileOnDisk = false
645- this . shouldResubscribeIfPathMatches = undefined
646- this . emitter . emit ( 'did-change-path' , this . getPath ( ) )
647621 }
622+
623+ this . emitter . emit ( 'did-change-path' , this . getPath ( ) )
648624 }
649625
650626 // Public: Sets the character set encoding for this buffer.
@@ -1972,8 +1948,16 @@ class TextBuffer {
19721948 //
19731949 // Returns a {Promise} that resolves when the save has completed.
19741950 saveAs ( filePath ) {
1975- if ( ! filePath ) throw new Error ( "Can't save buffer with no file path" )
1976- return this . saveTo ( new File ( filePath ) )
1951+ if ( ! filePath ) {
1952+ throw new Error ( "Can't save buffer with no file path" )
1953+ }
1954+ let file
1955+ if ( this . file ?. getPath ( ) === filePath ) {
1956+ file = this . file
1957+ } else {
1958+ file = new File ( filePath )
1959+ }
1960+ return this . saveTo ( file )
19771961 }
19781962
19791963 async saveTo ( file ) {
@@ -2375,16 +2359,6 @@ class TextBuffer {
23752359 const modified = this . buffer . isModified ( )
23762360 this . retainsUnmodifiedTraitAfterDeletion = ! modified
23772361 this . emitter . emit ( 'did-delete' )
2378- // We want to keep the `file` property around so that the user can save
2379- // this file again without having to pick a new path. But if that
2380- // happens, we'll need to resubscribe to file events, despite already
2381- // having subscribed the first time around.
2382- //
2383- // We can do this by calling `subscribeToFile` every time we call
2384- // `setFile`, but that will create a lot of churn. Instead, we should
2385- // keep track of this exact scenario and call `subscribeToFile` again
2386- // only when we need to.
2387- this . shouldResubscribeIfPathMatches = this . getPath ( )
23882362 if ( ! modified && this . shouldDestroyOnFileDelete ( ) ) {
23892363 return this . destroy ( )
23902364 } else {
0 commit comments