@theia/monaco 1.73.0-next.9 → 1.73.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.
Files changed (43) hide show
  1. package/lib/browser/markdown-renderer/monaco-markdown-renderer.d.ts +2 -1
  2. package/lib/browser/markdown-renderer/monaco-markdown-renderer.d.ts.map +1 -1
  3. package/lib/browser/markdown-renderer/monaco-markdown-renderer.js +6 -1
  4. package/lib/browser/markdown-renderer/monaco-markdown-renderer.js.map +1 -1
  5. package/lib/browser/monaco-editor-provider.d.ts +2 -1
  6. package/lib/browser/monaco-editor-provider.d.ts.map +1 -1
  7. package/lib/browser/monaco-editor-provider.js +8 -3
  8. package/lib/browser/monaco-editor-provider.js.map +1 -1
  9. package/lib/browser/monaco-quick-input-service.d.ts.map +1 -1
  10. package/lib/browser/monaco-quick-input-service.js +27 -24
  11. package/lib/browser/monaco-quick-input-service.js.map +1 -1
  12. package/lib/browser/monaco-quick-input-service.spec.d.ts +2 -0
  13. package/lib/browser/monaco-quick-input-service.spec.d.ts.map +1 -0
  14. package/lib/browser/monaco-quick-input-service.spec.js +69 -0
  15. package/lib/browser/monaco-quick-input-service.spec.js.map +1 -0
  16. package/lib/browser/monaco-snippet-suggest-provider.d.ts +2 -0
  17. package/lib/browser/monaco-snippet-suggest-provider.d.ts.map +1 -1
  18. package/lib/browser/monaco-snippet-suggest-provider.js +7 -1
  19. package/lib/browser/monaco-snippet-suggest-provider.js.map +1 -1
  20. package/lib/browser/monaco-theming-service.d.ts +2 -0
  21. package/lib/browser/monaco-theming-service.d.ts.map +1 -1
  22. package/lib/browser/monaco-theming-service.js +8 -2
  23. package/lib/browser/monaco-theming-service.js.map +1 -1
  24. package/lib/browser/monaco-workspace.d.ts +6 -4
  25. package/lib/browser/monaco-workspace.d.ts.map +1 -1
  26. package/lib/browser/monaco-workspace.js +7 -1
  27. package/lib/browser/monaco-workspace.js.map +1 -1
  28. package/lib/browser/textmate/monaco-textmate-service.js +3 -2
  29. package/lib/browser/textmate/monaco-textmate-service.js.map +1 -1
  30. package/lib/browser/textmate/monaco-theme-registry.d.ts +2 -0
  31. package/lib/browser/textmate/monaco-theme-registry.d.ts.map +1 -1
  32. package/lib/browser/textmate/monaco-theme-registry.js +8 -2
  33. package/lib/browser/textmate/monaco-theme-registry.js.map +1 -1
  34. package/package.json +9 -9
  35. package/src/browser/markdown-renderer/monaco-markdown-renderer.ts +5 -3
  36. package/src/browser/monaco-editor-provider.ts +7 -4
  37. package/src/browser/monaco-quick-input-service.spec.ts +74 -0
  38. package/src/browser/monaco-quick-input-service.ts +28 -24
  39. package/src/browser/monaco-snippet-suggest-provider.ts +6 -2
  40. package/src/browser/monaco-theming-service.ts +6 -3
  41. package/src/browser/monaco-workspace.ts +6 -2
  42. package/src/browser/textmate/monaco-textmate-service.ts +3 -3
  43. package/src/browser/textmate/monaco-theme-registry.ts +7 -3
@@ -0,0 +1,74 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
18
+ let disableJSDOM = enableJSDOM();
19
+
20
+ // @lumino/dragdrop (pulled in transitively) extends the DragEvent DOM global at
21
+ // module load, which JSDOM does not provide; stub it so the import succeeds.
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ if (!(global as any).DragEvent) {
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ (global as any).DragEvent = class DragEvent extends (global as any).Event { };
26
+ }
27
+
28
+ import { expect } from 'chai';
29
+ import { getColorRegistry } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/colorRegistry';
30
+ import { MonacoQuickInputImplementation } from './monaco-quick-input-service';
31
+
32
+ disableJSDOM();
33
+
34
+ /**
35
+ * The quick input styles mirror VS Code's, referencing theme colors by id. Each
36
+ * id is turned into a `var(--theia-<id>)` CSS custom property; a mis-cased or
37
+ * misspelled id yields an undefined variable, silently breaking the styling
38
+ * (e.g. the Command Palette hover highlight). This test guards against such
39
+ * typos by checking every referenced color id against the registered colors.
40
+ */
41
+ describe('MonacoQuickInputImplementation styles', () => {
42
+
43
+ before(() => disableJSDOM = enableJSDOM());
44
+ after(() => disableJSDOM());
45
+
46
+ it('should only reference registered color ids', () => {
47
+ const registeredIds = new Set(getColorRegistry().getColors().map(color => color.id));
48
+
49
+ // Mirror ColorRegistry.toCssVariableName without the full DI graph.
50
+ const colorRegistry = { toCssVariableName: (id: string) => `--theia-${id.replace(/\./g, '-')}` };
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ const instance: any = Object.create(MonacoQuickInputImplementation.prototype);
53
+ instance.colorRegistry = colorRegistry;
54
+ const styles = instance.computeStyles();
55
+
56
+ const referencedIds = new Set<string>();
57
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
+ const collect = (value: any): void => {
59
+ if (typeof value === 'string') {
60
+ const match = /^var\(--theia-(.+)\)$/.exec(value);
61
+ if (match) {
62
+ // No registered color id contains a dash, so dashes were dots.
63
+ referencedIds.add(match[1].replace(/-/g, '.'));
64
+ }
65
+ } else if (value && typeof value === 'object') {
66
+ Object.values(value).forEach(collect);
67
+ }
68
+ };
69
+ collect(styles);
70
+
71
+ const unregistered = [...referencedIds].filter(id => !registeredIds.has(id)).sort();
72
+ expect(unregistered, `Unregistered color ids referenced by computeStyles: ${unregistered.join(', ')}`).to.be.empty;
73
+ });
74
+ });
@@ -306,8 +306,8 @@ export class MonacoQuickInputImplementation implements IQuickInputService {
306
306
  inputActiveOptionBackground: this.asCssVariable('inputOption.activeBackground')
307
307
  },
308
308
  pickerGroup: {
309
- pickerGroupBorder: this.asCssVariable('pickerGroup.Border'),
310
- pickerGroupForeground: this.asCssVariable('pickerGroupForeground')
309
+ pickerGroupBorder: this.asCssVariable('pickerGroup.border'),
310
+ pickerGroupForeground: this.asCssVariable('pickerGroup.foreground')
311
311
  },
312
312
  widget: {
313
313
  quickInputBackground: this.asCssVariable('quickInput.background'),
@@ -321,38 +321,38 @@ export class MonacoQuickInputImplementation implements IQuickInputService {
321
321
  listInactiveFocusForeground: this.asCssVariable('quickInputList.focusForeground'),
322
322
  listInactiveSelectionIconForeground: this.asCssVariable('quickInputList.focusIconForeground'),
323
323
  listInactiveFocusBackground: this.asCssVariable('quickInputList.focusBackground'),
324
- listFocusOutline: this.asCssVariable('activeContrastBorder'),
325
- listInactiveFocusOutline: this.asCssVariable('activeContrastBorder'),
324
+ listFocusOutline: this.asCssVariable('contrastActiveBorder'),
325
+ listInactiveFocusOutline: this.asCssVariable('contrastActiveBorder'),
326
326
 
327
327
  listFocusBackground: this.asCssVariable('list.focusBackground'),
328
328
  listFocusForeground: this.asCssVariable('list.focusForeground'),
329
329
  listActiveSelectionBackground: this.asCssVariable('list.activeSelectionBackground'),
330
- listActiveSelectionForeground: this.asCssVariable('list.ActiveSelectionForeground'),
331
- listActiveSelectionIconForeground: this.asCssVariable('list.ActiveSelectionIconForeground'),
332
- listFocusAndSelectionOutline: this.asCssVariable('list.FocusAndSelectionOutline'),
333
- listFocusAndSelectionBackground: this.asCssVariable('list.ActiveSelectionBackground'),
334
- listFocusAndSelectionForeground: this.asCssVariable('list.ActiveSelectionForeground'),
335
- listInactiveSelectionBackground: this.asCssVariable('list.InactiveSelectionBackground'),
336
- listInactiveSelectionForeground: this.asCssVariable('list.InactiveSelectionForeground'),
337
- listHoverBackground: this.asCssVariable('list.HoverBackground'),
338
- listHoverForeground: this.asCssVariable('list.HoverForeground'),
339
- listDropOverBackground: this.asCssVariable('list.DropOverBackground'),
340
- listDropBetweenBackground: this.asCssVariable('list.DropBetweenBackground'),
341
- listSelectionOutline: this.asCssVariable('activeContrastBorder'),
342
- listHoverOutline: this.asCssVariable('activeContrastBorder'),
330
+ listActiveSelectionForeground: this.asCssVariable('list.activeSelectionForeground'),
331
+ listActiveSelectionIconForeground: this.asCssVariable('list.activeSelectionIconForeground'),
332
+ listFocusAndSelectionOutline: this.asCssVariable('list.focusAndSelectionOutline'),
333
+ listFocusAndSelectionBackground: this.asCssVariable('list.activeSelectionBackground'),
334
+ listFocusAndSelectionForeground: this.asCssVariable('list.activeSelectionForeground'),
335
+ listInactiveSelectionBackground: this.asCssVariable('list.inactiveSelectionBackground'),
336
+ listInactiveSelectionForeground: this.asCssVariable('list.inactiveSelectionForeground'),
337
+ listHoverBackground: this.asCssVariable('list.hoverBackground'),
338
+ listHoverForeground: this.asCssVariable('list.hoverForeground'),
339
+ listDropOverBackground: this.asCssVariable('list.dropBackground'),
340
+ listDropBetweenBackground: this.asCssVariable('list.dropBetweenBackground'),
341
+ listSelectionOutline: this.asCssVariable('contrastActiveBorder'),
342
+ listHoverOutline: this.asCssVariable('contrastActiveBorder'),
343
343
  treeIndentGuidesStroke: this.asCssVariable('tree.indentGuidesStroke'),
344
344
  treeInactiveIndentGuidesStroke: this.asCssVariable('tree.inactiveIndentGuidesStroke'),
345
- treeStickyScrollBackground: this.asCssVariable('tree.StickyScrollBackground'),
346
- treeStickyScrollBorder: this.asCssVariable('tree.tickyScrollBorde'),
347
- treeStickyScrollShadow: this.asCssVariable('tree.StickyScrollShadow'),
345
+ treeStickyScrollBackground: undefined,
346
+ treeStickyScrollBorder: undefined,
347
+ treeStickyScrollShadow: this.asCssVariable('scrollbar.shadow'),
348
348
  tableColumnsBorder: this.asCssVariable('tree.tableColumnsBorder'),
349
349
  tableOddRowsBackgroundColor: this.asCssVariable('tree.tableOddRowsBackground'),
350
350
 
351
351
  },
352
352
  inputBox: {
353
- inputForeground: this.asCssVariable('inputForeground'),
354
- inputBackground: this.asCssVariable('inputBackground'),
355
- inputBorder: this.asCssVariable('inputBorder'),
353
+ inputForeground: this.asCssVariable('input.foreground'),
354
+ inputBackground: this.asCssVariable('input.background'),
355
+ inputBorder: this.asCssVariable('input.border'),
356
356
  inputValidationInfoBackground: this.asCssVariable('inputValidation.infoBackground'),
357
357
  inputValidationInfoForeground: this.asCssVariable('inputValidation.infoForeground'),
358
358
  inputValidationInfoBorder: this.asCssVariable('inputValidation.infoBorder'),
@@ -373,7 +373,7 @@ export class MonacoQuickInputImplementation implements IQuickInputService {
373
373
  buttonBackground: this.asCssVariable('button.background'),
374
374
  buttonHoverBackground: this.asCssVariable('button.hoverBackground'),
375
375
  buttonBorder: this.asCssVariable('contrastBorder'),
376
- buttonSeparator: this.asCssVariable('button.Separator'),
376
+ buttonSeparator: this.asCssVariable('button.separator'),
377
377
  buttonSecondaryForeground: this.asCssVariable('button.secondaryForeground'),
378
378
  buttonSecondaryBackground: this.asCssVariable('button.secondaryBackground'),
379
379
  buttonSecondaryHoverBackground: this.asCssVariable('button.secondaryHoverBackground'),
@@ -480,6 +480,10 @@ export class MonacoQuickInputService implements QuickInputService {
480
480
  wrapped.activeItems = [options.activeItem];
481
481
  }
482
482
 
483
+ if (options.value) {
484
+ wrapped.value = options.value;
485
+ }
486
+
483
487
  wrapped.onDidChangeValue((filter: string) => {
484
488
  if (options.onDidChangeValue) {
485
489
  options.onDidChangeValue(wrapped, filter);
@@ -19,7 +19,7 @@
19
19
  *--------------------------------------------------------------------------------------------*/
20
20
 
21
21
  import * as jsoncparser from 'jsonc-parser';
22
- import { injectable, inject } from '@theia/core/shared/inversify';
22
+ import { injectable, inject, named } from '@theia/core/shared/inversify';
23
23
  import URI from '@theia/core/lib/common/uri';
24
24
  import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
25
25
  import { FileService } from '@theia/filesystem/lib/browser/file-service';
@@ -27,6 +27,7 @@ import { FileOperationError } from '@theia/filesystem/lib/common/files';
27
27
  import * as monaco from '@theia/monaco-editor-core';
28
28
  import { SnippetParser } from '@theia/monaco-editor-core/esm/vs/editor/contrib/snippet/browser/snippetParser';
29
29
  import { isObject } from '@theia/core/lib/common';
30
+ import { ILogger } from '@theia/core';
30
31
 
31
32
  @injectable()
32
33
  export class MonacoSnippetSuggestProvider implements monaco.languages.CompletionItemProvider {
@@ -36,6 +37,9 @@ export class MonacoSnippetSuggestProvider implements monaco.languages.Completion
36
37
  @inject(FileService)
37
38
  protected readonly fileService: FileService;
38
39
 
40
+ @inject(ILogger) @named('monaco:MonacoSnippetSuggestProvider')
41
+ protected readonly logger: ILogger;
42
+
39
43
  protected readonly snippets = new Map<string, Snippet[]>();
40
44
  protected readonly pendingSnippets = new Map<string, Promise<void>[]>();
41
45
 
@@ -150,7 +154,7 @@ export class MonacoSnippetSuggestProvider implements monaco.languages.Completion
150
154
  toDispose.push(this.fromJSON(snippets, options));
151
155
  } catch (e) {
152
156
  if (!(e instanceof FileOperationError)) {
153
- console.error(e);
157
+ this.logger.error(e);
154
158
  }
155
159
  }
156
160
  }
@@ -16,7 +16,7 @@
16
16
 
17
17
  /* eslint-disable @typescript-eslint/no-explicit-any */
18
18
 
19
- import { injectable, inject } from '@theia/core/shared/inversify';
19
+ import { injectable, inject, named } from '@theia/core/shared/inversify';
20
20
  import * as jsoncparser from 'jsonc-parser';
21
21
  import * as plistparser from 'fast-plist';
22
22
  import URI from '@theia/core/lib/common/uri';
@@ -25,6 +25,7 @@ import { MonacoThemeRegistry } from './textmate/monaco-theme-registry';
25
25
  import { getThemes, putTheme, MonacoThemeState, stateToTheme, ThemeServiceWithDB } from './monaco-indexed-db';
26
26
  import { FileService } from '@theia/filesystem/lib/browser/file-service';
27
27
  import * as monaco from '@theia/monaco-editor-core';
28
+ import { ILogger } from '@theia/core';
28
29
 
29
30
  export interface MonacoTheme {
30
31
  id?: string;
@@ -61,6 +62,8 @@ export class MonacoThemingService {
61
62
  @inject(FileService) protected readonly fileService: FileService;
62
63
  @inject(MonacoThemeRegistry) protected readonly monacoThemeRegistry: MonacoThemeRegistry;
63
64
  @inject(ThemeServiceWithDB) protected readonly themeService: ThemeServiceWithDB;
65
+ @inject(ILogger) @named('monaco:MonacoThemingService')
66
+ protected readonly logger: ILogger;
64
67
 
65
68
  /** Register themes whose configuration needs to be loaded */
66
69
  register(theme: MonacoTheme, pending: { [uri: string]: Promise<any> } = {}): Disposable {
@@ -83,7 +86,7 @@ export class MonacoThemingService {
83
86
  const { id, description, uiTheme } = theme;
84
87
  toDispose.push(this.registerParsedTheme({ id, label, description, uiTheme: uiTheme, json, includes }));
85
88
  } catch (e) {
86
- console.error('Failed to load theme from ' + theme.uri, e);
89
+ this.logger.error('Failed to load theme from ' + theme.uri, e);
87
90
  }
88
91
  }
89
92
 
@@ -180,7 +183,7 @@ export class MonacoThemingService {
180
183
  this.doRegisterParsedTheme(state);
181
184
  }
182
185
  } catch (e) {
183
- console.error('Failed to restore monaco themes', e);
186
+ this.logger.error('Failed to restore monaco themes', e);
184
187
  }
185
188
  }
186
189
 
@@ -17,9 +17,10 @@
17
17
  /* eslint-disable no-null/no-null */
18
18
 
19
19
  import { URI as Uri } from '@theia/core/shared/vscode-uri';
20
- import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
20
+ import { injectable, inject, postConstruct, named } from '@theia/core/shared/inversify';
21
21
  import URI from '@theia/core/lib/common/uri';
22
22
  import { Emitter } from '@theia/core/lib/common/event';
23
+ import { ILogger } from '@theia/core';
23
24
  import { FileSystemPreferences } from '@theia/filesystem/lib/common';
24
25
  import { EditorManager } from '@theia/editor/lib/browser';
25
26
  import { MonacoTextModelService } from './monaco-text-model-service';
@@ -126,6 +127,9 @@ export class MonacoWorkspace {
126
127
  @inject(SaveableService)
127
128
  protected readonly saveService: SaveableService;
128
129
 
130
+ @inject(ILogger) @named('monaco:MonacoWorkspace')
131
+ protected readonly logger: ILogger;
132
+
129
133
  @postConstruct()
130
134
  protected init(): void {
131
135
  this.resolveReady();
@@ -265,7 +269,7 @@ export class MonacoWorkspace {
265
269
  const ariaSummary = this.getAriaSummary(totalEdits, totalFiles);
266
270
  return { ariaSummary, isApplied: true };
267
271
  } catch (e) {
268
- console.error('Failed to apply Resource edits:', e);
272
+ this.logger.error('Failed to apply Resource edits:', e);
269
273
  return {
270
274
  ariaSummary: `Error applying Resource edits: ${e.toString()}`,
271
275
  isApplied: false
@@ -50,7 +50,7 @@ export class MonacoTextmateService implements FrontendApplicationContribution {
50
50
  @inject(TextmateRegistry)
51
51
  protected readonly textmateRegistry: TextmateRegistry;
52
52
 
53
- @inject(ILogger)
53
+ @inject(ILogger) @named('monaco:MonacoTextmateService')
54
54
  protected readonly logger: ILogger;
55
55
 
56
56
  @inject(OnigasmProvider)
@@ -70,7 +70,7 @@ export class MonacoTextmateService implements FrontendApplicationContribution {
70
70
 
71
71
  initialize(): void {
72
72
  if (!isBasicWasmSupported) {
73
- console.log('Textmate support deactivated because WebAssembly is not detected.');
73
+ this.logger.info('Textmate support deactivated because WebAssembly is not detected.');
74
74
  return;
75
75
  }
76
76
 
@@ -78,7 +78,7 @@ export class MonacoTextmateService implements FrontendApplicationContribution {
78
78
  try {
79
79
  grammarProvider.registerTextmateLanguage(this.textmateRegistry);
80
80
  } catch (err) {
81
- console.error(err);
81
+ this.logger.error(err);
82
82
  }
83
83
  }
84
84
 
@@ -17,7 +17,7 @@
17
17
 
18
18
  /* eslint-disable @typescript-eslint/no-explicit-any */
19
19
 
20
- import { inject, injectable } from '@theia/core/shared/inversify';
20
+ import { inject, injectable, named } from '@theia/core/shared/inversify';
21
21
  import { IRawTheme } from 'vscode-textmate';
22
22
  import * as monaco from '@theia/monaco-editor-core';
23
23
  import { IStandaloneThemeService } from '@theia/monaco-editor-core/esm/vs/editor/standalone/common/standaloneTheme';
@@ -25,12 +25,16 @@ import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/stan
25
25
  import { StandaloneThemeService } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneThemeService';
26
26
  import { Color } from '@theia/monaco-editor-core/esm/vs/base/common/color';
27
27
  import { MixStandaloneTheme, TextmateRegistryFactory, ThemeMix } from './monaco-theme-types';
28
+ import { ILogger } from '@theia/core';
28
29
 
29
30
  @injectable()
30
31
  export class MonacoThemeRegistry {
31
32
 
32
33
  @inject(TextmateRegistryFactory) protected readonly registryFactory: TextmateRegistryFactory;
33
34
 
35
+ @inject(ILogger) @named('monaco:MonacoThemeRegistry')
36
+ protected readonly logger: ILogger;
37
+
34
38
  initializeDefaultThemes(): void {
35
39
  this.register(require('../../../data/monaco-themes/vscode/dark_theia.json'), {
36
40
  './dark_vs.json': require('../../../data/monaco-themes/vscode/dark_vs.json'),
@@ -87,7 +91,7 @@ export class MonacoThemeRegistry {
87
91
  };
88
92
  if (typeof json.include !== 'undefined') {
89
93
  if (!includes || !includes[json.include]) {
90
- console.error(`Couldn't resolve includes theme ${json.include}.`);
94
+ this.logger.error(`Couldn't resolve includes theme ${json.include}.`);
91
95
  } else {
92
96
  const parentTheme = this.register(includes[json.include], includes);
93
97
  Object.assign(result.colors, parentTheme.colors);
@@ -161,7 +165,7 @@ export class MonacoThemeRegistry {
161
165
  const normalized = String(color).replace(/^\#/, '').slice(0, 6);
162
166
  if (normalized.length < 6 || !(normalized).match(/^[0-9A-Fa-f]{6}$/)) {
163
167
  // ignoring not normalized colors to avoid breaking token color indexes between monaco and vscode-textmate
164
- console.error(`Color '${normalized}' is NOT normalized, it must have 6 positions.`);
168
+ this.logger.error(`Color '${normalized}' is NOT normalized, it must have 6 positions.`);
165
169
  return undefined;
166
170
  }
167
171
  return '#' + normalized;