Skip to content

Commit d8c4517

Browse files
committed
fix: Always destroy the ref when the model is disposed
1 parent c0f548c commit d8c4517

1 file changed

Lines changed: 21 additions & 5 deletions

File tree

src/service-override/modelEditor.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { ScrollType } from 'vs/editor/common/editorCommon'
1717
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'
1818
import { ITextModel } from 'vs/editor/common/model'
1919
import { IReference } from 'vs/base/common/lifecycle'
20+
import { URI } from 'vs/base/common/uri'
2021
import { IModelService } from '../services'
2122
import { unsupported } from '../tools'
2223

@@ -101,10 +102,6 @@ class EditorService implements IEditorService {
101102
// The model doesn't exist, resolve it
102103
const modelRef = await this.textModelService.createModelReference(resource)
103104
model = modelRef.object.textEditorModel
104-
// Dispose the ref when the model is disposed or we'll get a disposed model next time
105-
model.onWillDispose(() => {
106-
modelRef.dispose()
107-
})
108105
} else {
109106
// If the model was already existing, try to find an associated editor
110107
const codeEditors = StandaloneServices.get(ICodeEditorService).listCodeEditors()
@@ -142,9 +139,28 @@ class EditorService implements IEditorService {
142139
revertAll = unsupported
143140
}
144141

142+
/**
143+
* Vscode manage models by using the EditorInput class
144+
* The EditorInput class keeps a reference to the model, preventing it from being destroyed
145+
* With monaco, we don't have this class, but the only way to retrieve a model is to use the createModelReference method which returns a ref
146+
* We don't want the user to manipulate ref, so we just provide the model to them.
147+
* The user may want to dispose the model when there is no more usage of it, but doing so doesn't dispose the ref
148+
* This class just force dispose the refs when the model is disposed
149+
*/
150+
class CustomTextModelResolverService extends TextModelResolverService {
151+
override async createModelReference (resource: URI) {
152+
const ref = await super.createModelReference(resource)
153+
// Dispose the ref when the model is disposed or we'll get a disposed model next time
154+
ref.object.textEditorModel.onWillDispose(() => {
155+
ref.dispose()
156+
})
157+
return ref
158+
}
159+
}
160+
145161
export default function getServiceOverride (openEditor: OpenEditor): IEditorOverrideServices {
146162
return {
147-
[ITextModelService.toString()]: new SyncDescriptor(TextModelResolverService),
163+
[ITextModelService.toString()]: new SyncDescriptor(CustomTextModelResolverService),
148164
[ICodeEditorService.toString()]: new SyncDescriptor(CodeEditorService),
149165
[IEditorService.toString()]: new SyncDescriptor(EditorService, [openEditor])
150166
}

0 commit comments

Comments
 (0)