monaco-languageclient 9.7.1 → 10.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/lib/{commonTypes.d.ts → common/commonTypes.d.ts} +2 -2
- package/lib/common/commonTypes.d.ts.map +1 -0
- package/lib/common/commonTypes.js +6 -0
- package/lib/common/commonTypes.js.map +1 -0
- package/lib/common/index.d.ts +4 -0
- package/lib/common/index.d.ts.map +1 -0
- package/lib/{tools → common}/index.js +1 -0
- package/lib/common/index.js.map +1 -0
- package/lib/common/logging.d.ts.map +1 -0
- package/lib/common/logging.js.map +1 -0
- package/lib/common/utils.d.ts +5 -0
- package/lib/common/utils.d.ts.map +1 -0
- package/lib/{tools → common}/utils.js +14 -0
- package/lib/common/utils.js.map +1 -0
- package/lib/editorApp/config.d.ts +55 -0
- package/lib/editorApp/config.d.ts.map +1 -0
- package/lib/editorApp/config.js +13 -0
- package/lib/editorApp/config.js.map +1 -0
- package/lib/editorApp/editorApp.d.ts +66 -0
- package/lib/editorApp/editorApp.d.ts.map +1 -0
- package/lib/editorApp/editorApp.js +404 -0
- package/lib/editorApp/editorApp.js.map +1 -0
- package/lib/editorApp/index.d.ts +3 -0
- package/lib/editorApp/index.d.ts.map +1 -0
- package/lib/editorApp/index.js +7 -0
- package/lib/editorApp/index.js.map +1 -0
- package/lib/fs/definitions.d.ts +1 -1
- package/lib/fs/definitions.d.ts.map +1 -1
- package/lib/fs/endpoints/defaultEndpoint.d.ts +1 -1
- package/lib/fs/endpoints/defaultEndpoint.d.ts.map +1 -1
- package/lib/index.d.ts +15 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +18 -2
- package/lib/index.js.map +1 -1
- package/lib/vscode/apiWrapper.d.ts +59 -0
- package/lib/vscode/apiWrapper.d.ts.map +1 -0
- package/lib/vscode/apiWrapper.js +290 -0
- package/lib/vscode/apiWrapper.js.map +1 -0
- package/lib/vscode/config.d.ts +46 -0
- package/lib/vscode/config.d.ts.map +1 -0
- package/lib/vscode/config.js +7 -0
- package/lib/vscode/config.js.map +1 -0
- package/lib/vscode/index.d.ts +4 -2
- package/lib/vscode/index.d.ts.map +1 -1
- package/lib/vscode/index.js +4 -2
- package/lib/vscode/index.js.map +1 -1
- package/lib/vscode/locales.d.ts +5 -0
- package/lib/vscode/locales.d.ts.map +1 -0
- package/lib/vscode/locales.js +124 -0
- package/lib/vscode/locales.js.map +1 -0
- package/lib/vscode/utils.d.ts +13 -0
- package/lib/vscode/utils.d.ts.map +1 -0
- package/lib/vscode/utils.js +56 -0
- package/lib/vscode/utils.js.map +1 -0
- package/lib/vscode/viewsService.d.ts +4 -0
- package/lib/vscode/viewsService.d.ts.map +1 -0
- package/lib/vscode/viewsService.js +67 -0
- package/lib/vscode/viewsService.js.map +1 -0
- package/lib/{vscode → worker}/fakeWorker.d.ts.map +1 -1
- package/lib/{vscode → worker}/fakeWorker.js.map +1 -1
- package/lib/worker/index.d.ts +4 -0
- package/lib/worker/index.d.ts.map +1 -0
- package/lib/worker/index.js +8 -0
- package/lib/worker/index.js.map +1 -0
- package/lib/{workerFactory.d.ts → worker/workerFactory.d.ts} +1 -1
- package/lib/worker/workerFactory.d.ts.map +1 -0
- package/lib/{workerFactory.js → worker/workerFactory.js} +1 -1
- package/lib/worker/workerFactory.js.map +1 -0
- package/lib/worker/workerLoaders.d.ts +5 -0
- package/lib/worker/workerLoaders.d.ts.map +1 -0
- package/lib/worker/workerLoaders.js +26 -0
- package/lib/worker/workerLoaders.js.map +1 -0
- package/lib/wrapper/index.d.ts +4 -0
- package/lib/wrapper/index.d.ts.map +1 -0
- package/lib/wrapper/index.js +8 -0
- package/lib/wrapper/index.js.map +1 -0
- package/lib/wrapper/lcconfig.d.ts +24 -0
- package/lib/wrapper/lcconfig.d.ts.map +1 -0
- package/lib/wrapper/lcconfig.js +6 -0
- package/lib/wrapper/lcconfig.js.map +1 -0
- package/lib/wrapper/lcmanager.d.ts +18 -0
- package/lib/wrapper/lcmanager.d.ts.map +1 -0
- package/lib/wrapper/lcmanager.js +75 -0
- package/lib/wrapper/lcmanager.js.map +1 -0
- package/lib/wrapper/lcwrapper.d.ts +37 -0
- package/lib/wrapper/lcwrapper.d.ts.map +1 -0
- package/lib/wrapper/lcwrapper.js +247 -0
- package/lib/wrapper/lcwrapper.js.map +1 -0
- package/package.json +70 -28
- package/src/{commonTypes.ts → common/commonTypes.ts} +2 -2
- package/src/{tools → common}/index.ts +1 -0
- package/src/{tools → common}/utils.ts +16 -1
- package/src/editorApp/config.ts +67 -0
- package/src/editorApp/editorApp.ts +458 -0
- package/{lib/commonTypes.js → src/editorApp/index.ts} +3 -2
- package/src/fs/definitions.ts +1 -1
- package/src/fs/endpoints/defaultEndpoint.ts +1 -1
- package/src/index.ts +29 -2
- package/src/vscode/apiWrapper.ts +333 -0
- package/src/vscode/config.ts +55 -0
- package/src/vscode/index.ts +4 -2
- package/src/vscode/locales.ts +128 -0
- package/src/vscode/utils.ts +67 -0
- package/src/vscode/viewsService.ts +73 -0
- package/src/worker/index.ts +8 -0
- package/src/{workerFactory.ts → worker/workerFactory.ts} +2 -2
- package/src/worker/workerLoaders.ts +36 -0
- package/src/wrapper/index.ts +8 -0
- package/src/wrapper/lcconfig.ts +32 -0
- package/src/wrapper/lcmanager.ts +89 -0
- package/src/wrapper/lcwrapper.ts +280 -0
- package/lib/client.d.ts +0 -13
- package/lib/client.d.ts.map +0 -1
- package/lib/client.js +0 -16
- package/lib/client.js.map +0 -1
- package/lib/commonTypes.d.ts.map +0 -1
- package/lib/commonTypes.js.map +0 -1
- package/lib/tools/index.d.ts +0 -3
- package/lib/tools/index.d.ts.map +0 -1
- package/lib/tools/index.js.map +0 -1
- package/lib/tools/logging.d.ts.map +0 -1
- package/lib/tools/logging.js.map +0 -1
- package/lib/tools/utils.d.ts +0 -3
- package/lib/tools/utils.d.ts.map +0 -1
- package/lib/tools/utils.js.map +0 -1
- package/lib/vscode/services.d.ts +0 -64
- package/lib/vscode/services.d.ts.map +0 -1
- package/lib/vscode/services.js +0 -192
- package/lib/vscode/services.js.map +0 -1
- package/lib/workerFactory.d.ts.map +0 -1
- package/lib/workerFactory.js.map +0 -1
- package/src/client.ts +0 -26
- package/src/vscode/services.ts +0 -249
- /package/lib/{tools → common}/logging.d.ts +0 -0
- /package/lib/{tools → common}/logging.js +0 -0
- /package/lib/{vscode → worker}/fakeWorker.d.ts +0 -0
- /package/lib/{vscode → worker}/fakeWorker.js +0 -0
- /package/src/{tools → common}/logging.ts +0 -0
- /package/src/{vscode → worker}/fakeWorker.ts +0 -0
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
/* --------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) 2024 TypeFox and others.
|
|
3
|
+
* Licensed under the MIT License. See LICENSE in the package root for license information.
|
|
4
|
+
* ------------------------------------------------------------------------------------------ */
|
|
5
|
+
|
|
6
|
+
import { ConfigurationTarget, IConfigurationService, LogLevel, StandaloneServices } from '@codingame/monaco-vscode-api';
|
|
7
|
+
import { createModelReference, type ITextFileEditorModel } from '@codingame/monaco-vscode-api/monaco';
|
|
8
|
+
import * as monaco from '@codingame/monaco-vscode-editor-api';
|
|
9
|
+
import type { IReference } from '@codingame/monaco-vscode-editor-service-override';
|
|
10
|
+
import { ConsoleLogger, type Logger } from 'monaco-languageclient/common';
|
|
11
|
+
import { getEnhancedMonacoEnvironment, type OverallConfigType } from 'monaco-languageclient/vscodeApiWrapper';
|
|
12
|
+
import * as vscode from 'vscode';
|
|
13
|
+
import { ModelRefs, type CallbackDisposeable, type CodeContent, type CodeResources, type DisposableModelRefs, type EditorAppConfig, type TextContents, type TextModels } from './config.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* This is the base class for both Monaco Ediotor Apps:
|
|
17
|
+
* - EditorAppClassic
|
|
18
|
+
* - EditorAppExtended
|
|
19
|
+
*
|
|
20
|
+
* It provides the generic functionality for both implementations.
|
|
21
|
+
*/
|
|
22
|
+
export class EditorApp {
|
|
23
|
+
|
|
24
|
+
private $type: OverallConfigType;
|
|
25
|
+
private id: string;
|
|
26
|
+
private config: EditorAppConfig;
|
|
27
|
+
|
|
28
|
+
protected logger: Logger = new ConsoleLogger();
|
|
29
|
+
|
|
30
|
+
private editor: monaco.editor.IStandaloneCodeEditor | undefined;
|
|
31
|
+
private diffEditor: monaco.editor.IStandaloneDiffEditor | undefined;
|
|
32
|
+
|
|
33
|
+
private modelRefs: ModelRefs = new ModelRefs();
|
|
34
|
+
|
|
35
|
+
private onTextChanged?: (textChanges: TextContents) => void;
|
|
36
|
+
private textChangedDiposeables: CallbackDisposeable = {};
|
|
37
|
+
private modelDisposables: DisposableModelRefs = {};
|
|
38
|
+
|
|
39
|
+
private modelRefDisposeTimeout = -1;
|
|
40
|
+
|
|
41
|
+
private startingAwait?: Promise<void>;
|
|
42
|
+
private startingResolve: (value: void | PromiseLike<void>) => void;
|
|
43
|
+
|
|
44
|
+
private disposingAwait?: Promise<void>;
|
|
45
|
+
private disposingResolve: (value: void | PromiseLike<void>) => void;
|
|
46
|
+
|
|
47
|
+
constructor(userAppConfig?: EditorAppConfig) {
|
|
48
|
+
this.$type = userAppConfig?.$type ?? 'extended';
|
|
49
|
+
this.id = userAppConfig?.id ?? Math.floor(Math.random() * 1000001).toString();
|
|
50
|
+
if ((userAppConfig?.useDiffEditor ?? false) && !userAppConfig?.codeResources?.original) {
|
|
51
|
+
throw new Error(`Use diff editor was used without a valid config. code: ${userAppConfig?.codeResources?.modified} codeOriginal: ${userAppConfig?.codeResources?.original}`);
|
|
52
|
+
}
|
|
53
|
+
this.config = {
|
|
54
|
+
codeResources: userAppConfig?.codeResources ?? undefined,
|
|
55
|
+
useDiffEditor: userAppConfig?.useDiffEditor ?? false,
|
|
56
|
+
readOnly: userAppConfig?.readOnly ?? false,
|
|
57
|
+
domReadOnly: userAppConfig?.domReadOnly ?? false,
|
|
58
|
+
overrideAutomaticLayout: userAppConfig?.overrideAutomaticLayout ?? true
|
|
59
|
+
};
|
|
60
|
+
this.config.editorOptions = {
|
|
61
|
+
...userAppConfig?.editorOptions,
|
|
62
|
+
automaticLayout: userAppConfig?.overrideAutomaticLayout ?? true
|
|
63
|
+
};
|
|
64
|
+
this.config.diffEditorOptions = {
|
|
65
|
+
...userAppConfig?.diffEditorOptions,
|
|
66
|
+
automaticLayout: userAppConfig?.overrideAutomaticLayout ?? true
|
|
67
|
+
};
|
|
68
|
+
this.config.languageDef = userAppConfig?.languageDef;
|
|
69
|
+
|
|
70
|
+
this.logger.setLevel(this.config.logLevel ?? LogLevel.Off);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
isDiffEditor() {
|
|
74
|
+
return this.config.useDiffEditor === true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
getConfig(): EditorAppConfig {
|
|
78
|
+
return this.config;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
getEditor(): monaco.editor.IStandaloneCodeEditor | undefined {
|
|
82
|
+
return this.editor;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
getDiffEditor(): monaco.editor.IStandaloneDiffEditor | undefined {
|
|
86
|
+
return this.diffEditor;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
getTextModels(): TextModels {
|
|
90
|
+
return {
|
|
91
|
+
modified: this.modelRefs.modified?.object.textEditorModel ?? undefined,
|
|
92
|
+
original: this.modelRefs.original?.object.textEditorModel ?? undefined
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getLogger() {
|
|
97
|
+
return this.logger;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
registerOnTextChangedCallback(onTextChanged?: (textChanges: TextContents) => void) {
|
|
101
|
+
this.onTextChanged = onTextChanged;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public setModelRefDisposeTimeout(modelRefDisposeTimeout: number) {
|
|
105
|
+
this.modelRefDisposeTimeout = modelRefDisposeTimeout;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private markStarting() {
|
|
109
|
+
this.startingAwait = new Promise<void>((resolve) => {
|
|
110
|
+
this.startingResolve = resolve;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private markStarted() {
|
|
115
|
+
this.startingResolve();
|
|
116
|
+
this.startingAwait = undefined;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
isStarting() {
|
|
120
|
+
return this.startingAwait !== undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
getStartingAwait() {
|
|
124
|
+
return this.startingAwait;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
isStarted() {
|
|
128
|
+
return this.editor !== undefined || this.diffEditor !== undefined;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Starts the single editor application.
|
|
133
|
+
*/
|
|
134
|
+
async start(htmlContainer: HTMLElement) {
|
|
135
|
+
if (this.isStarting()) {
|
|
136
|
+
await this.getStartingAwait();
|
|
137
|
+
}
|
|
138
|
+
this.markStarting();
|
|
139
|
+
|
|
140
|
+
if (!this.isDisposed()) {
|
|
141
|
+
throw new Error('You called start without properly disposing the EditorApp.');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const languageDef = this.config.languageDef;
|
|
145
|
+
if (languageDef) {
|
|
146
|
+
if (this.$type === 'extended') {
|
|
147
|
+
throw new Error('Language definition is not supported for extended editor apps where textmate is used.');
|
|
148
|
+
}
|
|
149
|
+
// register own language first
|
|
150
|
+
monaco.languages.register(languageDef.languageExtensionConfig);
|
|
151
|
+
|
|
152
|
+
const languageRegistered = monaco.languages.getLanguages().filter(x => x.id === languageDef.languageExtensionConfig.id);
|
|
153
|
+
if (languageRegistered.length === 0) {
|
|
154
|
+
// this is only meaningful for languages supported by monaco out of the box
|
|
155
|
+
monaco.languages.register({
|
|
156
|
+
id: languageDef.languageExtensionConfig.id
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// apply monarch definitions
|
|
161
|
+
if (languageDef.monarchLanguage) {
|
|
162
|
+
monaco.languages.setMonarchTokensProvider(languageDef.languageExtensionConfig.id, languageDef.monarchLanguage);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (languageDef.theme) {
|
|
166
|
+
monaco.editor.defineTheme(languageDef.theme.name, languageDef.theme.data);
|
|
167
|
+
monaco.editor.setTheme(languageDef.theme.name);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (this.config.editorOptions?.['semanticHighlighting.enabled'] !== undefined) {
|
|
172
|
+
StandaloneServices.get(IConfigurationService).updateValue('editor.semanticHighlighting.enabled',
|
|
173
|
+
this.config.editorOptions['semanticHighlighting.enabled'], ConfigurationTarget.USER);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ensure proper default resources are initialized, uris have to be unique
|
|
177
|
+
const modified = {
|
|
178
|
+
text: this.config.codeResources?.modified?.text ?? '',
|
|
179
|
+
uri: this.config.codeResources?.modified?.uri ?? `default-uri-modified-${this.id}`,
|
|
180
|
+
enforceLanguageId: this.config.codeResources?.modified?.enforceLanguageId ?? undefined
|
|
181
|
+
};
|
|
182
|
+
this.modelRefs.modified = await this.buildModelReference(modified, this.logger);
|
|
183
|
+
|
|
184
|
+
if (this.isDiffEditor()) {
|
|
185
|
+
const original = {
|
|
186
|
+
text: this.config.codeResources?.original?.text ?? '',
|
|
187
|
+
uri: this.config.codeResources?.original?.uri ?? `default-uri-original-${this.id}`,
|
|
188
|
+
enforceLanguageId: this.config.codeResources?.original?.enforceLanguageId ?? undefined
|
|
189
|
+
};
|
|
190
|
+
this.modelRefs.original = await this.buildModelReference(original, this.logger);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
const envEnhanced = getEnhancedMonacoEnvironment();
|
|
195
|
+
const viewServiceType = envEnhanced.viewServiceType;
|
|
196
|
+
if (viewServiceType === 'EditorService' || viewServiceType === undefined) {
|
|
197
|
+
this.logger.info(`Starting monaco-editor (${this.id})`);
|
|
198
|
+
await this.createEditors(htmlContainer!);
|
|
199
|
+
} else {
|
|
200
|
+
this.logger.info('No EditorService configured. monaco-editor will not be started.');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
this.logger.info('EditorApp start completed successfully.');
|
|
204
|
+
// eslint-disable-next-line no-useless-catch
|
|
205
|
+
} catch (e) {
|
|
206
|
+
throw e;
|
|
207
|
+
} finally {
|
|
208
|
+
// in case of rejection, mark as started, otherwise the promise will never resolve
|
|
209
|
+
this.markStarted();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async createEditors(htmlContainer: HTMLElement): Promise<void> {
|
|
214
|
+
if (this.isDiffEditor()) {
|
|
215
|
+
this.diffEditor = monaco.editor.createDiffEditor(htmlContainer, this.config.diffEditorOptions);
|
|
216
|
+
const modified = this.modelRefs.modified?.object.textEditorModel ?? undefined;
|
|
217
|
+
const original = this.modelRefs.original?.object.textEditorModel ?? undefined;
|
|
218
|
+
if (modified !== undefined && original !== undefined) {
|
|
219
|
+
const model = {
|
|
220
|
+
modified,
|
|
221
|
+
original
|
|
222
|
+
};
|
|
223
|
+
this.diffEditor.setModel(model);
|
|
224
|
+
this.announceModelUpdate(model);
|
|
225
|
+
}
|
|
226
|
+
} else {
|
|
227
|
+
const model = {
|
|
228
|
+
modified: this.modelRefs.modified?.object.textEditorModel
|
|
229
|
+
};
|
|
230
|
+
this.editor = monaco.editor.create(htmlContainer, {
|
|
231
|
+
...this.config.editorOptions,
|
|
232
|
+
model: model.modified
|
|
233
|
+
});
|
|
234
|
+
this.announceModelUpdate(model);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
updateCode(code: { modified?: string, original?: string }) {
|
|
239
|
+
if (this.isDiffEditor()) {
|
|
240
|
+
if (code.modified !== undefined) {
|
|
241
|
+
this.diffEditor?.getModifiedEditor().setValue(code.modified);
|
|
242
|
+
}
|
|
243
|
+
if (code.original !== undefined) {
|
|
244
|
+
this.diffEditor?.getOriginalEditor().setValue(code.original);
|
|
245
|
+
}
|
|
246
|
+
} else {
|
|
247
|
+
if (code.modified !== undefined) {
|
|
248
|
+
this.editor?.setValue(code.modified);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async updateCodeResources(codeResources?: CodeResources): Promise<void> {
|
|
255
|
+
let updateModified = false;
|
|
256
|
+
let updateOriginal = false;
|
|
257
|
+
|
|
258
|
+
if (codeResources?.modified !== undefined && codeResources.modified.uri !== this.modelRefs.modified?.object.resource.path) {
|
|
259
|
+
this.modelDisposables.modified = this.modelRefs.modified;
|
|
260
|
+
this.modelRefs.modified = await this.buildModelReference(codeResources.modified, this.logger);
|
|
261
|
+
updateModified = true;
|
|
262
|
+
}
|
|
263
|
+
if (codeResources?.original !== undefined && codeResources.original.uri !== this.modelRefs.original?.object.resource.path) {
|
|
264
|
+
this.modelDisposables.original = this.modelRefs.original;
|
|
265
|
+
this.modelRefs.original = await this.buildModelReference(codeResources.original, this.logger);
|
|
266
|
+
updateOriginal = true;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (this.isDiffEditor()) {
|
|
270
|
+
if (updateModified && updateOriginal) {
|
|
271
|
+
const modified = this.modelRefs.modified?.object.textEditorModel ?? undefined;
|
|
272
|
+
const original = this.modelRefs.original?.object.textEditorModel ?? undefined;
|
|
273
|
+
if (modified !== undefined && original !== undefined) {
|
|
274
|
+
const model = {
|
|
275
|
+
modified,
|
|
276
|
+
original
|
|
277
|
+
};
|
|
278
|
+
this.diffEditor?.setModel(model);
|
|
279
|
+
this.announceModelUpdate(model);
|
|
280
|
+
}
|
|
281
|
+
} else {
|
|
282
|
+
this.logger.info('Diff Editor: Code resources were not updated. They are ether unchanged or undefined.');
|
|
283
|
+
}
|
|
284
|
+
} else {
|
|
285
|
+
if (updateModified) {
|
|
286
|
+
const model = {
|
|
287
|
+
modified: this.modelRefs.modified?.object.textEditorModel
|
|
288
|
+
};
|
|
289
|
+
if (model.modified !== undefined && model.modified !== null) {
|
|
290
|
+
this.editor?.setModel(model.modified);
|
|
291
|
+
this.announceModelUpdate(model);
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
294
|
+
this.logger.info('Editor: Code resources were not updated. They are either unchanged or undefined.');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
await this.disposeModelRefs();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async buildModelReference(codeContent: CodeContent, logger?: Logger): Promise<IReference<ITextFileEditorModel>> {
|
|
302
|
+
const code = codeContent.text;
|
|
303
|
+
const modelRef = await createModelReference(vscode.Uri.parse(codeContent.uri), code);
|
|
304
|
+
|
|
305
|
+
// update the text if different
|
|
306
|
+
if (modelRef.object.textEditorModel?.getValue() !== code) {
|
|
307
|
+
modelRef.object.textEditorModel?.setValue(code);
|
|
308
|
+
}
|
|
309
|
+
const enforceLanguageId = codeContent.enforceLanguageId;
|
|
310
|
+
if (enforceLanguageId !== undefined) {
|
|
311
|
+
modelRef.object.setLanguageId(enforceLanguageId);
|
|
312
|
+
logger?.info(`Main languageId is enforced: ${enforceLanguageId}`);
|
|
313
|
+
}
|
|
314
|
+
return modelRef;
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
private announceModelUpdate(textModels: TextModels) {
|
|
318
|
+
if (this.onTextChanged !== undefined) {
|
|
319
|
+
let changed = false;
|
|
320
|
+
if (textModels.modified !== undefined && textModels.modified !== null) {
|
|
321
|
+
const old = this.textChangedDiposeables.modified;
|
|
322
|
+
this.textChangedDiposeables.modified = textModels.modified.onDidChangeContent(() => {
|
|
323
|
+
didModelContentChange(textModels, this.onTextChanged);
|
|
324
|
+
});
|
|
325
|
+
old?.dispose();
|
|
326
|
+
changed = true;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (textModels.original !== undefined && textModels.original !== null) {
|
|
330
|
+
const old = this.textChangedDiposeables.original;
|
|
331
|
+
this.textChangedDiposeables.original = textModels.original.onDidChangeContent(() => {
|
|
332
|
+
didModelContentChange(textModels, this.onTextChanged);
|
|
333
|
+
});
|
|
334
|
+
old?.dispose();
|
|
335
|
+
changed = true;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (changed) {
|
|
339
|
+
// do it initially
|
|
340
|
+
didModelContentChange(textModels, this.onTextChanged);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async dispose() {
|
|
346
|
+
if (this.isDisposing()) {
|
|
347
|
+
await this.getDisposingAwait();
|
|
348
|
+
}
|
|
349
|
+
this.markDisposing();
|
|
350
|
+
|
|
351
|
+
if (this.editor) {
|
|
352
|
+
this.editor.dispose();
|
|
353
|
+
this.editor = undefined;
|
|
354
|
+
}
|
|
355
|
+
if (this.diffEditor) {
|
|
356
|
+
this.diffEditor.dispose();
|
|
357
|
+
this.diffEditor = undefined;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
this.textChangedDiposeables.modified?.dispose();
|
|
361
|
+
this.textChangedDiposeables.original?.dispose();
|
|
362
|
+
this.textChangedDiposeables.modified = undefined;
|
|
363
|
+
this.textChangedDiposeables.original = undefined;
|
|
364
|
+
|
|
365
|
+
await this.disposeModelRefs();
|
|
366
|
+
|
|
367
|
+
this.markDisposed();
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
isDisposed(): boolean {
|
|
371
|
+
return this.editor === undefined && this.diffEditor === undefined &&
|
|
372
|
+
// this.textChangedDiposeables.modified === undefined && this.textChangedDiposeables.original === undefined &&
|
|
373
|
+
this.modelDisposables.original === undefined && this.modelDisposables.modified === undefined;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
private markDisposing() {
|
|
377
|
+
this.disposingAwait = new Promise<void>((resolve) => {
|
|
378
|
+
this.disposingResolve = resolve;
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
private markDisposed() {
|
|
383
|
+
this.disposingResolve();
|
|
384
|
+
this.disposingAwait = undefined;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
isDisposing() {
|
|
388
|
+
return this.disposingAwait !== undefined;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
getDisposingAwait() {
|
|
392
|
+
return this.disposingAwait;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
async disposeModelRefs() {
|
|
396
|
+
const diposeRefs = () => {
|
|
397
|
+
if (this.logger.getLevel() === LogLevel.Debug) {
|
|
398
|
+
const models = monaco.editor.getModels();
|
|
399
|
+
this.logger.debug('Current model URIs:');
|
|
400
|
+
models.forEach((model, _index) => {
|
|
401
|
+
this.logger.debug(`${model.uri.toString()}`);
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (this.modelDisposables.modified !== undefined && !(this.modelDisposables.modified.object.isDisposed() === true)) {
|
|
406
|
+
this.modelDisposables.modified.dispose();
|
|
407
|
+
this.modelDisposables.modified = undefined;
|
|
408
|
+
}
|
|
409
|
+
if (this.modelDisposables.original !== undefined && !(this.modelDisposables.original.object.isDisposed() === true)) {
|
|
410
|
+
this.modelDisposables.original.dispose();
|
|
411
|
+
this.modelDisposables.original = undefined;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
if (this.logger.getLevel() === LogLevel.Debug) {
|
|
415
|
+
if (this.modelDisposables.modified === undefined && this.modelDisposables.original === undefined) {
|
|
416
|
+
this.logger.debug('All model references are disposed.');
|
|
417
|
+
} else {
|
|
418
|
+
this.logger.debug('Model references are still available.');
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
if (this.modelRefDisposeTimeout > 0) {
|
|
424
|
+
this.logger.debug('Using async dispose of model references');
|
|
425
|
+
await new Promise<void>(resolve => setTimeout(() => {
|
|
426
|
+
diposeRefs();
|
|
427
|
+
resolve();
|
|
428
|
+
}, this.modelRefDisposeTimeout));
|
|
429
|
+
} else {
|
|
430
|
+
diposeRefs();
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
updateLayout() {
|
|
435
|
+
if (this.isDiffEditor()) {
|
|
436
|
+
this.diffEditor?.layout();
|
|
437
|
+
} else {
|
|
438
|
+
this.editor?.layout();
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
reportStatus() {
|
|
443
|
+
const status: string[] = [];
|
|
444
|
+
status.push('EditorApp status:');
|
|
445
|
+
status.push(`Editor: ${this.editor?.getId()}`);
|
|
446
|
+
status.push(`DiffEditor: ${this.diffEditor?.getId()}`);
|
|
447
|
+
return status;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export const didModelContentChange = (textModels: TextModels, onTextChanged?: (textChanges: TextContents) => void) => {
|
|
452
|
+
const modified = textModels.modified?.getValue() ?? '';
|
|
453
|
+
const original = textModels.original?.getValue() ?? '';
|
|
454
|
+
onTextChanged?.({
|
|
455
|
+
modified,
|
|
456
|
+
original
|
|
457
|
+
});
|
|
458
|
+
};
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
* Copyright (c) 2024 TypeFox and others.
|
|
3
3
|
* Licensed under the MIT License. See LICENSE in the package root for license information.
|
|
4
4
|
* ------------------------------------------------------------------------------------------ */
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
|
|
6
|
+
export * from './config.js';
|
|
7
|
+
export * from './editorApp.js';
|
package/src/fs/definitions.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License. See LICENSE in the package root for license information.
|
|
4
4
|
* ------------------------------------------------------------------------------------------ */
|
|
5
5
|
|
|
6
|
-
import type { Logger } from 'monaco-languageclient/
|
|
6
|
+
import type { Logger } from 'monaco-languageclient/common';
|
|
7
7
|
|
|
8
8
|
export interface FileReadRequest {
|
|
9
9
|
resourceUri: string
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License. See LICENSE in the package root for license information.
|
|
4
4
|
* ------------------------------------------------------------------------------------------ */
|
|
5
5
|
|
|
6
|
-
import type { Logger } from 'monaco-languageclient/
|
|
6
|
+
import type { Logger } from 'monaco-languageclient/common';
|
|
7
7
|
import type { DirectoryListingRequest, DirectoryListingRequestResult, FileReadRequest, FileReadRequestResult, FileSystemEndpoint, FileUpdate, FileUpdateResult, StatsRequest, StatsRequestResult } from '../definitions.js';
|
|
8
8
|
import { EndpointType } from '../definitions.js';
|
|
9
9
|
|
package/src/index.ts
CHANGED
|
@@ -3,5 +3,32 @@
|
|
|
3
3
|
* Licensed under the MIT License. See LICENSE in the package root for license information.
|
|
4
4
|
* ------------------------------------------------------------------------------------------ */
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { BaseLanguageClient, MessageTransports, ProposedFeatures, type LanguageClientOptions } from 'vscode-languageclient/browser.js';
|
|
7
|
+
|
|
8
|
+
export type MonacoLanguageClientOptions = {
|
|
9
|
+
name: string;
|
|
10
|
+
id?: string;
|
|
11
|
+
clientOptions: LanguageClientOptions;
|
|
12
|
+
messageTransports: MessageTransports;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class MonacoLanguageClient extends BaseLanguageClient {
|
|
16
|
+
protected readonly messageTransports: MessageTransports;
|
|
17
|
+
|
|
18
|
+
constructor({ id, name, clientOptions, messageTransports }: MonacoLanguageClientOptions) {
|
|
19
|
+
super(id ?? name.toLowerCase(), name, clientOptions);
|
|
20
|
+
this.messageTransports = messageTransports;
|
|
21
|
+
ProposedFeatures.createAll(this);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
protected override createMessageTransports(_encoding: string): Promise<MessageTransports> {
|
|
25
|
+
return Promise.resolve(this.messageTransports);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class MonacoLanguageClientWithProposedFeatures extends MonacoLanguageClient {
|
|
30
|
+
constructor({ id, name, clientOptions, messageTransports }: MonacoLanguageClientOptions) {
|
|
31
|
+
super({ id, name, clientOptions, messageTransports });
|
|
32
|
+
ProposedFeatures.createAll(this);
|
|
33
|
+
}
|
|
34
|
+
}
|