Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/standalone/browser/standaloneCodeEditor.ts
3294 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as aria from '../../../base/browser/ui/aria/aria.js';
7
import { Disposable, IDisposable, toDisposable, DisposableStore } from '../../../base/common/lifecycle.js';
8
import { ICodeEditor, IDiffEditor, IDiffEditorConstructionOptions } from '../../browser/editorBrowser.js';
9
import { ICodeEditorService } from '../../browser/services/codeEditorService.js';
10
import { CodeEditorWidget } from '../../browser/widget/codeEditor/codeEditorWidget.js';
11
import { IDiffEditorOptions, IEditorOptions } from '../../common/config/editorOptions.js';
12
import { InternalEditorAction } from '../../common/editorAction.js';
13
import { IModelChangedEvent } from '../../common/editorCommon.js';
14
import { ITextModel } from '../../common/model.js';
15
import { StandaloneKeybindingService, updateConfigurationService } from './standaloneServices.js';
16
import { IStandaloneThemeService } from '../common/standaloneTheme.js';
17
import { IMenuItem, MenuId, MenuRegistry } from '../../../platform/actions/common/actions.js';
18
import { CommandsRegistry, ICommandHandler, ICommandService } from '../../../platform/commands/common/commands.js';
19
import { IConfigurationService } from '../../../platform/configuration/common/configuration.js';
20
import { ContextKeyExpr, ContextKeyValue, IContextKey, IContextKeyService } from '../../../platform/contextkey/common/contextkey.js';
21
import { IContextMenuService } from '../../../platform/contextview/browser/contextView.js';
22
import { IInstantiationService, ServicesAccessor } from '../../../platform/instantiation/common/instantiation.js';
23
import { IKeybindingService } from '../../../platform/keybinding/common/keybinding.js';
24
import { INotificationService } from '../../../platform/notification/common/notification.js';
25
import { IThemeService } from '../../../platform/theme/common/themeService.js';
26
import { IAccessibilityService } from '../../../platform/accessibility/common/accessibility.js';
27
import { StandaloneCodeEditorNLS } from '../../common/standaloneStrings.js';
28
import { IClipboardService } from '../../../platform/clipboard/common/clipboardService.js';
29
import { IEditorProgressService } from '../../../platform/progress/common/progress.js';
30
import { StandaloneThemeService } from './standaloneThemeService.js';
31
import { IModelService } from '../../common/services/model.js';
32
import { ILanguageSelection, ILanguageService } from '../../common/languages/language.js';
33
import { URI } from '../../../base/common/uri.js';
34
import { StandaloneCodeEditorService } from './standaloneCodeEditorService.js';
35
import { PLAINTEXT_LANGUAGE_ID } from '../../common/languages/modesRegistry.js';
36
import { ILanguageConfigurationService } from '../../common/languages/languageConfigurationRegistry.js';
37
import { IEditorConstructionOptions } from '../../browser/config/editorConfiguration.js';
38
import { ILanguageFeaturesService } from '../../common/services/languageFeatures.js';
39
import { DiffEditorWidget } from '../../browser/widget/diffEditor/diffEditorWidget.js';
40
import { IAccessibilitySignalService } from '../../../platform/accessibilitySignal/browser/accessibilitySignalService.js';
41
import { mainWindow } from '../../../base/browser/window.js';
42
import { setHoverDelegateFactory } from '../../../base/browser/ui/hover/hoverDelegateFactory.js';
43
import { IHoverService, WorkbenchHoverDelegate } from '../../../platform/hover/browser/hover.js';
44
import { setBaseLayerHoverDelegate } from '../../../base/browser/ui/hover/hoverDelegate2.js';
45
46
/**
47
* Description of an action contribution
48
*/
49
export interface IActionDescriptor {
50
/**
51
* An unique identifier of the contributed action.
52
*/
53
id: string;
54
/**
55
* A label of the action that will be presented to the user.
56
*/
57
label: string;
58
/**
59
* Precondition rule. The value should be a [context key expression](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts).
60
*/
61
precondition?: string;
62
/**
63
* An array of keybindings for the action.
64
*/
65
keybindings?: number[];
66
/**
67
* The keybinding rule (condition on top of precondition).
68
*/
69
keybindingContext?: string;
70
/**
71
* Control if the action should show up in the context menu and where.
72
* The context menu of the editor has these default:
73
* navigation - The navigation group comes first in all cases.
74
* 1_modification - This group comes next and contains commands that modify your code.
75
* 9_cutcopypaste - The last default group with the basic editing commands.
76
* You can also create your own group.
77
* Defaults to null (don't show in context menu).
78
*/
79
contextMenuGroupId?: string;
80
/**
81
* Control the order in the context menu group.
82
*/
83
contextMenuOrder?: number;
84
/**
85
* Method that will be executed when the action is triggered.
86
* @param editor The editor instance is passed in as a convenience
87
*/
88
run(editor: ICodeEditor, ...args: any[]): void | Promise<void>;
89
}
90
91
/**
92
* Options which apply for all editors.
93
*/
94
export interface IGlobalEditorOptions {
95
/**
96
* The number of spaces a tab is equal to.
97
* This setting is overridden based on the file contents when `detectIndentation` is on.
98
* Defaults to 4.
99
*/
100
tabSize?: number;
101
/**
102
* Insert spaces when pressing `Tab`.
103
* This setting is overridden based on the file contents when `detectIndentation` is on.
104
* Defaults to true.
105
*/
106
insertSpaces?: boolean;
107
/**
108
* Controls whether `tabSize` and `insertSpaces` will be automatically detected when a file is opened based on the file contents.
109
* Defaults to true.
110
*/
111
detectIndentation?: boolean;
112
/**
113
* Remove trailing auto inserted whitespace.
114
* Defaults to true.
115
*/
116
trimAutoWhitespace?: boolean;
117
/**
118
* Special handling for large files to disable certain memory intensive features.
119
* Defaults to true.
120
*/
121
largeFileOptimizations?: boolean;
122
/**
123
* Controls whether completions should be computed based on words in the document.
124
* Defaults to true.
125
*/
126
wordBasedSuggestions?: 'off' | 'currentDocument' | 'matchingDocuments' | 'allDocuments';
127
/**
128
* Controls whether word based completions should be included from opened documents of the same language or any language.
129
*/
130
wordBasedSuggestionsOnlySameLanguage?: boolean;
131
/**
132
* Controls whether the semanticHighlighting is shown for the languages that support it.
133
* true: semanticHighlighting is enabled for all themes
134
* false: semanticHighlighting is disabled for all themes
135
* 'configuredByTheme': semanticHighlighting is controlled by the current color theme's semanticHighlighting setting.
136
* Defaults to 'byTheme'.
137
*/
138
'semanticHighlighting.enabled'?: true | false | 'configuredByTheme';
139
/**
140
* Keep peek editors open even when double-clicking their content or when hitting `Escape`.
141
* Defaults to false.
142
*/
143
stablePeek?: boolean;
144
/**
145
* Lines above this length will not be tokenized for performance reasons.
146
* Defaults to 20000.
147
*/
148
maxTokenizationLineLength?: number;
149
/**
150
* Theme to be used for rendering.
151
* The current out-of-the-box available themes are: 'vs' (default), 'vs-dark', 'hc-black', 'hc-light'.
152
* You can create custom themes via `monaco.editor.defineTheme`.
153
* To switch a theme, use `monaco.editor.setTheme`.
154
* **NOTE**: The theme might be overwritten if the OS is in high contrast mode, unless `autoDetectHighContrast` is set to false.
155
*/
156
theme?: string;
157
/**
158
* If enabled, will automatically change to high contrast theme if the OS is using a high contrast theme.
159
* Defaults to true.
160
*/
161
autoDetectHighContrast?: boolean;
162
}
163
164
/**
165
* The options to create an editor.
166
*/
167
export interface IStandaloneEditorConstructionOptions extends IEditorConstructionOptions, IGlobalEditorOptions {
168
/**
169
* The initial model associated with this code editor.
170
*/
171
model?: ITextModel | null;
172
/**
173
* The initial value of the auto created model in the editor.
174
* To not automatically create a model, use `model: null`.
175
*/
176
value?: string;
177
/**
178
* The initial language of the auto created model in the editor.
179
* To not automatically create a model, use `model: null`.
180
*/
181
language?: string;
182
/**
183
* Initial theme to be used for rendering.
184
* The current out-of-the-box available themes are: 'vs' (default), 'vs-dark', 'hc-black', 'hc-light.
185
* You can create custom themes via `monaco.editor.defineTheme`.
186
* To switch a theme, use `monaco.editor.setTheme`.
187
* **NOTE**: The theme might be overwritten if the OS is in high contrast mode, unless `autoDetectHighContrast` is set to false.
188
*/
189
theme?: string;
190
/**
191
* If enabled, will automatically change to high contrast theme if the OS is using a high contrast theme.
192
* Defaults to true.
193
*/
194
autoDetectHighContrast?: boolean;
195
/**
196
* An URL to open when Ctrl+H (Windows and Linux) or Cmd+H (OSX) is pressed in
197
* the accessibility help dialog in the editor.
198
*
199
* Defaults to "https://go.microsoft.com/fwlink/?linkid=852450"
200
*/
201
accessibilityHelpUrl?: string;
202
/**
203
* Container element to use for ARIA messages.
204
* Defaults to document.body.
205
*/
206
ariaContainerElement?: HTMLElement;
207
}
208
209
/**
210
* The options to create a diff editor.
211
*/
212
export interface IStandaloneDiffEditorConstructionOptions extends IDiffEditorConstructionOptions {
213
/**
214
* Initial theme to be used for rendering.
215
* The current out-of-the-box available themes are: 'vs' (default), 'vs-dark', 'hc-black', 'hc-light.
216
* You can create custom themes via `monaco.editor.defineTheme`.
217
* To switch a theme, use `monaco.editor.setTheme`.
218
* **NOTE**: The theme might be overwritten if the OS is in high contrast mode, unless `autoDetectHighContrast` is set to false.
219
*/
220
theme?: string;
221
/**
222
* If enabled, will automatically change to high contrast theme if the OS is using a high contrast theme.
223
* Defaults to true.
224
*/
225
autoDetectHighContrast?: boolean;
226
}
227
228
export interface IStandaloneCodeEditor extends ICodeEditor {
229
updateOptions(newOptions: IEditorOptions & IGlobalEditorOptions): void;
230
addCommand(keybinding: number, handler: ICommandHandler, context?: string): string | null;
231
createContextKey<T extends ContextKeyValue = ContextKeyValue>(key: string, defaultValue: T): IContextKey<T>;
232
addAction(descriptor: IActionDescriptor): IDisposable;
233
}
234
235
export interface IStandaloneDiffEditor extends IDiffEditor {
236
addCommand(keybinding: number, handler: ICommandHandler, context?: string): string | null;
237
createContextKey<T extends ContextKeyValue = ContextKeyValue>(key: string, defaultValue: T): IContextKey<T>;
238
addAction(descriptor: IActionDescriptor): IDisposable;
239
240
getOriginalEditor(): IStandaloneCodeEditor;
241
getModifiedEditor(): IStandaloneCodeEditor;
242
}
243
244
let LAST_GENERATED_COMMAND_ID = 0;
245
246
let ariaDomNodeCreated = false;
247
/**
248
* Create ARIA dom node inside parent,
249
* or only for the first editor instantiation inside document.body.
250
* @param parent container element for ARIA dom node
251
*/
252
function createAriaDomNode(parent: HTMLElement | undefined) {
253
if (!parent) {
254
if (ariaDomNodeCreated) {
255
return;
256
}
257
ariaDomNodeCreated = true;
258
}
259
aria.setARIAContainer(parent || mainWindow.document.body);
260
}
261
262
/**
263
* A code editor to be used both by the standalone editor and the standalone diff editor.
264
*/
265
export class StandaloneCodeEditor extends CodeEditorWidget implements IStandaloneCodeEditor {
266
267
private readonly _standaloneKeybindingService: StandaloneKeybindingService | null;
268
269
constructor(
270
domElement: HTMLElement,
271
_options: Readonly<IStandaloneEditorConstructionOptions>,
272
@IInstantiationService instantiationService: IInstantiationService,
273
@ICodeEditorService codeEditorService: ICodeEditorService,
274
@ICommandService commandService: ICommandService,
275
@IContextKeyService contextKeyService: IContextKeyService,
276
@IHoverService hoverService: IHoverService,
277
@IKeybindingService keybindingService: IKeybindingService,
278
@IThemeService themeService: IThemeService,
279
@INotificationService notificationService: INotificationService,
280
@IAccessibilityService accessibilityService: IAccessibilityService,
281
@ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService,
282
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
283
) {
284
const options = { ..._options };
285
options.ariaLabel = options.ariaLabel || StandaloneCodeEditorNLS.editorViewAccessibleLabel;
286
super(domElement, options, {}, instantiationService, codeEditorService, commandService, contextKeyService, themeService, notificationService, accessibilityService, languageConfigurationService, languageFeaturesService);
287
288
if (keybindingService instanceof StandaloneKeybindingService) {
289
this._standaloneKeybindingService = keybindingService;
290
} else {
291
this._standaloneKeybindingService = null;
292
}
293
294
createAriaDomNode(options.ariaContainerElement);
295
296
setHoverDelegateFactory((placement, enableInstantHover) => instantiationService.createInstance(WorkbenchHoverDelegate, placement, { instantHover: enableInstantHover }, {}));
297
setBaseLayerHoverDelegate(hoverService);
298
}
299
300
public addCommand(keybinding: number, handler: ICommandHandler, context?: string): string | null {
301
if (!this._standaloneKeybindingService) {
302
console.warn('Cannot add command because the editor is configured with an unrecognized KeybindingService');
303
return null;
304
}
305
const commandId = 'DYNAMIC_' + (++LAST_GENERATED_COMMAND_ID);
306
const whenExpression = ContextKeyExpr.deserialize(context);
307
this._standaloneKeybindingService.addDynamicKeybinding(commandId, keybinding, handler, whenExpression);
308
return commandId;
309
}
310
311
public createContextKey<T extends ContextKeyValue = ContextKeyValue>(key: string, defaultValue: T): IContextKey<T> {
312
return this._contextKeyService.createKey(key, defaultValue);
313
}
314
315
public addAction(_descriptor: IActionDescriptor): IDisposable {
316
if ((typeof _descriptor.id !== 'string') || (typeof _descriptor.label !== 'string') || (typeof _descriptor.run !== 'function')) {
317
throw new Error('Invalid action descriptor, `id`, `label` and `run` are required properties!');
318
}
319
if (!this._standaloneKeybindingService) {
320
console.warn('Cannot add keybinding because the editor is configured with an unrecognized KeybindingService');
321
return Disposable.None;
322
}
323
324
// Read descriptor options
325
const id = _descriptor.id;
326
const label = _descriptor.label;
327
const precondition = ContextKeyExpr.and(
328
ContextKeyExpr.equals('editorId', this.getId()),
329
ContextKeyExpr.deserialize(_descriptor.precondition)
330
);
331
const keybindings = _descriptor.keybindings;
332
const keybindingsWhen = ContextKeyExpr.and(
333
precondition,
334
ContextKeyExpr.deserialize(_descriptor.keybindingContext)
335
);
336
const contextMenuGroupId = _descriptor.contextMenuGroupId || null;
337
const contextMenuOrder = _descriptor.contextMenuOrder || 0;
338
const run = (_accessor?: ServicesAccessor, ...args: any[]): Promise<void> => {
339
return Promise.resolve(_descriptor.run(this, ...args));
340
};
341
342
343
const toDispose = new DisposableStore();
344
345
// Generate a unique id to allow the same descriptor.id across multiple editor instances
346
const uniqueId = this.getId() + ':' + id;
347
348
// Register the command
349
toDispose.add(CommandsRegistry.registerCommand(uniqueId, run));
350
351
// Register the context menu item
352
if (contextMenuGroupId) {
353
const menuItem: IMenuItem = {
354
command: {
355
id: uniqueId,
356
title: label
357
},
358
when: precondition,
359
group: contextMenuGroupId,
360
order: contextMenuOrder
361
};
362
toDispose.add(MenuRegistry.appendMenuItem(MenuId.EditorContext, menuItem));
363
}
364
365
// Register the keybindings
366
if (Array.isArray(keybindings)) {
367
for (const kb of keybindings) {
368
toDispose.add(this._standaloneKeybindingService.addDynamicKeybinding(uniqueId, kb, run, keybindingsWhen));
369
}
370
}
371
372
// Finally, register an internal editor action
373
const internalAction = new InternalEditorAction(
374
uniqueId,
375
label,
376
label,
377
undefined,
378
precondition,
379
(...args: unknown[]) => Promise.resolve(_descriptor.run(this, ...args)),
380
this._contextKeyService
381
);
382
383
// Store it under the original id, such that trigger with the original id will work
384
this._actions.set(id, internalAction);
385
toDispose.add(toDisposable(() => {
386
this._actions.delete(id);
387
}));
388
389
return toDispose;
390
}
391
392
protected override _triggerCommand(handlerId: string, payload: any): void {
393
if (this._codeEditorService instanceof StandaloneCodeEditorService) {
394
// Help commands find this editor as the active editor
395
try {
396
this._codeEditorService.setActiveCodeEditor(this);
397
super._triggerCommand(handlerId, payload);
398
} finally {
399
this._codeEditorService.setActiveCodeEditor(null);
400
}
401
} else {
402
super._triggerCommand(handlerId, payload);
403
}
404
}
405
}
406
407
export class StandaloneEditor extends StandaloneCodeEditor implements IStandaloneCodeEditor {
408
409
private readonly _configurationService: IConfigurationService;
410
private readonly _standaloneThemeService: IStandaloneThemeService;
411
private _ownsModel: boolean;
412
413
constructor(
414
domElement: HTMLElement,
415
_options: Readonly<IStandaloneEditorConstructionOptions> | undefined,
416
@IInstantiationService instantiationService: IInstantiationService,
417
@ICodeEditorService codeEditorService: ICodeEditorService,
418
@ICommandService commandService: ICommandService,
419
@IContextKeyService contextKeyService: IContextKeyService,
420
@IHoverService hoverService: IHoverService,
421
@IKeybindingService keybindingService: IKeybindingService,
422
@IStandaloneThemeService themeService: IStandaloneThemeService,
423
@INotificationService notificationService: INotificationService,
424
@IConfigurationService configurationService: IConfigurationService,
425
@IAccessibilityService accessibilityService: IAccessibilityService,
426
@IModelService modelService: IModelService,
427
@ILanguageService languageService: ILanguageService,
428
@ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService,
429
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
430
) {
431
const options = { ..._options };
432
updateConfigurationService(configurationService, options, false);
433
const themeDomRegistration = (<StandaloneThemeService>themeService).registerEditorContainer(domElement);
434
if (typeof options.theme === 'string') {
435
themeService.setTheme(options.theme);
436
}
437
if (typeof options.autoDetectHighContrast !== 'undefined') {
438
themeService.setAutoDetectHighContrast(Boolean(options.autoDetectHighContrast));
439
}
440
const _model: ITextModel | null | undefined = options.model;
441
delete options.model;
442
super(domElement, options, instantiationService, codeEditorService, commandService, contextKeyService, hoverService, keybindingService, themeService, notificationService, accessibilityService, languageConfigurationService, languageFeaturesService);
443
444
this._configurationService = configurationService;
445
this._standaloneThemeService = themeService;
446
this._register(themeDomRegistration);
447
448
let model: ITextModel | null;
449
if (typeof _model === 'undefined') {
450
const languageId = languageService.getLanguageIdByMimeType(options.language) || options.language || PLAINTEXT_LANGUAGE_ID;
451
model = createTextModel(modelService, languageService, options.value || '', languageId, undefined);
452
this._ownsModel = true;
453
} else {
454
model = _model;
455
this._ownsModel = false;
456
}
457
458
this._attachModel(model);
459
if (model) {
460
const e: IModelChangedEvent = {
461
oldModelUrl: null,
462
newModelUrl: model.uri
463
};
464
this._onDidChangeModel.fire(e);
465
}
466
}
467
468
public override dispose(): void {
469
super.dispose();
470
}
471
472
public override updateOptions(newOptions: Readonly<IEditorOptions & IGlobalEditorOptions>): void {
473
updateConfigurationService(this._configurationService, newOptions, false);
474
if (typeof newOptions.theme === 'string') {
475
this._standaloneThemeService.setTheme(newOptions.theme);
476
}
477
if (typeof newOptions.autoDetectHighContrast !== 'undefined') {
478
this._standaloneThemeService.setAutoDetectHighContrast(Boolean(newOptions.autoDetectHighContrast));
479
}
480
super.updateOptions(newOptions);
481
}
482
483
protected override _postDetachModelCleanup(detachedModel: ITextModel): void {
484
super._postDetachModelCleanup(detachedModel);
485
if (detachedModel && this._ownsModel) {
486
detachedModel.dispose();
487
this._ownsModel = false;
488
}
489
}
490
}
491
492
export class StandaloneDiffEditor2 extends DiffEditorWidget implements IStandaloneDiffEditor {
493
494
private readonly _configurationService: IConfigurationService;
495
private readonly _standaloneThemeService: IStandaloneThemeService;
496
497
constructor(
498
domElement: HTMLElement,
499
_options: Readonly<IStandaloneDiffEditorConstructionOptions> | undefined,
500
@IInstantiationService instantiationService: IInstantiationService,
501
@IContextKeyService contextKeyService: IContextKeyService,
502
@ICodeEditorService codeEditorService: ICodeEditorService,
503
@IStandaloneThemeService themeService: IStandaloneThemeService,
504
@INotificationService notificationService: INotificationService,
505
@IConfigurationService configurationService: IConfigurationService,
506
@IContextMenuService contextMenuService: IContextMenuService,
507
@IEditorProgressService editorProgressService: IEditorProgressService,
508
@IClipboardService clipboardService: IClipboardService,
509
@IAccessibilitySignalService accessibilitySignalService: IAccessibilitySignalService,
510
) {
511
const options = { ..._options };
512
updateConfigurationService(configurationService, options, true);
513
const themeDomRegistration = (<StandaloneThemeService>themeService).registerEditorContainer(domElement);
514
if (typeof options.theme === 'string') {
515
themeService.setTheme(options.theme);
516
}
517
if (typeof options.autoDetectHighContrast !== 'undefined') {
518
themeService.setAutoDetectHighContrast(Boolean(options.autoDetectHighContrast));
519
}
520
521
super(
522
domElement,
523
options,
524
{},
525
contextKeyService,
526
instantiationService,
527
codeEditorService,
528
accessibilitySignalService,
529
editorProgressService,
530
);
531
532
this._configurationService = configurationService;
533
this._standaloneThemeService = themeService;
534
535
this._register(themeDomRegistration);
536
}
537
538
public override dispose(): void {
539
super.dispose();
540
}
541
542
public override updateOptions(newOptions: Readonly<IDiffEditorOptions & IGlobalEditorOptions>): void {
543
updateConfigurationService(this._configurationService, newOptions, true);
544
if (typeof newOptions.theme === 'string') {
545
this._standaloneThemeService.setTheme(newOptions.theme);
546
}
547
if (typeof newOptions.autoDetectHighContrast !== 'undefined') {
548
this._standaloneThemeService.setAutoDetectHighContrast(Boolean(newOptions.autoDetectHighContrast));
549
}
550
super.updateOptions(newOptions);
551
}
552
553
protected override _createInnerEditor(instantiationService: IInstantiationService, container: HTMLElement, options: Readonly<IEditorOptions>): CodeEditorWidget {
554
return instantiationService.createInstance(StandaloneCodeEditor, container, options);
555
}
556
557
public override getOriginalEditor(): IStandaloneCodeEditor {
558
return <StandaloneCodeEditor>super.getOriginalEditor();
559
}
560
561
public override getModifiedEditor(): IStandaloneCodeEditor {
562
return <StandaloneCodeEditor>super.getModifiedEditor();
563
}
564
565
public addCommand(keybinding: number, handler: ICommandHandler, context?: string): string | null {
566
return this.getModifiedEditor().addCommand(keybinding, handler, context);
567
}
568
569
public createContextKey<T extends ContextKeyValue = ContextKeyValue>(key: string, defaultValue: T): IContextKey<T> {
570
return this.getModifiedEditor().createContextKey(key, defaultValue);
571
}
572
573
public addAction(descriptor: IActionDescriptor): IDisposable {
574
return this.getModifiedEditor().addAction(descriptor);
575
}
576
}
577
578
/**
579
* @internal
580
*/
581
export function createTextModel(modelService: IModelService, languageService: ILanguageService, value: string, languageId: string | undefined, uri: URI | undefined): ITextModel {
582
value = value || '';
583
if (!languageId) {
584
const firstLF = value.indexOf('\n');
585
let firstLine = value;
586
if (firstLF !== -1) {
587
firstLine = value.substring(0, firstLF);
588
}
589
return doCreateModel(modelService, value, languageService.createByFilepathOrFirstLine(uri || null, firstLine), uri);
590
}
591
return doCreateModel(modelService, value, languageService.createById(languageId), uri);
592
}
593
594
/**
595
* @internal
596
*/
597
function doCreateModel(modelService: IModelService, value: string, languageSelection: ILanguageSelection, uri: URI | undefined): ITextModel {
598
return modelService.createModel(value, languageSelection, uri);
599
}
600
601