@theia/preferences 1.65.0-next.6 → 1.65.1

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 (160) hide show
  1. package/lib/browser/folder-preference-provider.d.ts +4 -2
  2. package/lib/browser/folder-preference-provider.d.ts.map +1 -1
  3. package/lib/browser/folder-preference-provider.js +9 -4
  4. package/lib/browser/folder-preference-provider.js.map +1 -1
  5. package/lib/browser/folders-preferences-provider.d.ts +2 -3
  6. package/lib/browser/folders-preferences-provider.d.ts.map +1 -1
  7. package/lib/browser/folders-preferences-provider.js +7 -8
  8. package/lib/browser/folders-preferences-provider.js.map +1 -1
  9. package/lib/browser/frontend-preference-storage.d.ts +20 -0
  10. package/lib/browser/frontend-preference-storage.d.ts.map +1 -0
  11. package/lib/browser/frontend-preference-storage.js +63 -0
  12. package/lib/browser/frontend-preference-storage.js.map +1 -0
  13. package/lib/browser/index.d.ts +0 -3
  14. package/lib/browser/index.d.ts.map +1 -1
  15. package/lib/browser/index.js +0 -3
  16. package/lib/browser/index.js.map +1 -1
  17. package/lib/browser/monaco-jsonc-editor.js +2 -2
  18. package/lib/browser/monaco-jsonc-editor.js.map +1 -1
  19. package/lib/browser/preference-bindings.d.ts +0 -1
  20. package/lib/browser/preference-bindings.d.ts.map +1 -1
  21. package/lib/browser/preference-bindings.js +13 -28
  22. package/lib/browser/preference-bindings.js.map +1 -1
  23. package/lib/browser/preference-frontend-contribution.d.ts +1 -1
  24. package/lib/browser/preference-frontend-contribution.d.ts.map +1 -1
  25. package/lib/browser/preference-frontend-contribution.js +3 -3
  26. package/lib/browser/preference-frontend-contribution.js.map +1 -1
  27. package/lib/browser/preference-frontend-module.d.ts.map +1 -1
  28. package/lib/browser/preference-frontend-module.js +4 -0
  29. package/lib/browser/preference-frontend-module.js.map +1 -1
  30. package/lib/browser/preference-transaction-manager.d.ts +4 -7
  31. package/lib/browser/preference-transaction-manager.d.ts.map +1 -1
  32. package/lib/browser/preference-transaction-manager.js +8 -11
  33. package/lib/browser/preference-transaction-manager.js.map +1 -1
  34. package/lib/browser/preference-tree-model.d.ts +4 -6
  35. package/lib/browser/preference-tree-model.d.ts.map +1 -1
  36. package/lib/browser/preference-tree-model.js +4 -4
  37. package/lib/browser/preference-tree-model.js.map +1 -1
  38. package/lib/browser/preferences-contribution.d.ts +2 -5
  39. package/lib/browser/preferences-contribution.d.ts.map +1 -1
  40. package/lib/browser/preferences-contribution.js +7 -17
  41. package/lib/browser/preferences-contribution.js.map +1 -1
  42. package/lib/browser/preferences-json-schema-contribution.d.ts +2 -6
  43. package/lib/browser/preferences-json-schema-contribution.d.ts.map +1 -1
  44. package/lib/browser/preferences-json-schema-contribution.js +30 -35
  45. package/lib/browser/preferences-json-schema-contribution.js.map +1 -1
  46. package/lib/browser/util/preference-scope-command-manager.d.ts.map +1 -1
  47. package/lib/browser/util/preference-scope-command-manager.js +1 -1
  48. package/lib/browser/util/preference-scope-command-manager.js.map +1 -1
  49. package/lib/browser/util/preference-tree-generator.d.ts +3 -4
  50. package/lib/browser/util/preference-tree-generator.d.ts.map +1 -1
  51. package/lib/browser/util/preference-tree-generator.js +10 -14
  52. package/lib/browser/util/preference-tree-generator.js.map +1 -1
  53. package/lib/browser/util/preference-types.d.ts +2 -2
  54. package/lib/browser/util/preference-types.d.ts.map +1 -1
  55. package/lib/browser/util/preference-types.js +4 -4
  56. package/lib/browser/util/preference-types.js.map +1 -1
  57. package/lib/browser/views/components/preference-node-renderer.d.ts +7 -2
  58. package/lib/browser/views/components/preference-node-renderer.d.ts.map +1 -1
  59. package/lib/browser/views/components/preference-node-renderer.js +19 -12
  60. package/lib/browser/views/components/preference-node-renderer.js.map +1 -1
  61. package/lib/browser/views/components/preference-select-input.d.ts.map +1 -1
  62. package/lib/browser/views/components/preference-select-input.js +6 -9
  63. package/lib/browser/views/components/preference-select-input.js.map +1 -1
  64. package/lib/browser/views/preference-editor-widget.d.ts +3 -2
  65. package/lib/browser/views/preference-editor-widget.d.ts.map +1 -1
  66. package/lib/browser/views/preference-editor-widget.js +3 -3
  67. package/lib/browser/views/preference-editor-widget.js.map +1 -1
  68. package/lib/browser/views/preference-scope-tabbar-widget.d.ts +2 -2
  69. package/lib/browser/views/preference-scope-tabbar-widget.d.ts.map +1 -1
  70. package/lib/browser/views/preference-scope-tabbar-widget.js +7 -7
  71. package/lib/browser/views/preference-scope-tabbar-widget.js.map +1 -1
  72. package/lib/browser/views/preference-widget.d.ts +2 -1
  73. package/lib/browser/views/preference-widget.d.ts.map +1 -1
  74. package/lib/browser/views/preference-widget.js.map +1 -1
  75. package/lib/browser/workspace-file-preference-provider.d.ts +2 -2
  76. package/lib/browser/workspace-file-preference-provider.d.ts.map +1 -1
  77. package/lib/browser/workspace-file-preference-provider.js +2 -2
  78. package/lib/browser/workspace-file-preference-provider.js.map +1 -1
  79. package/lib/browser/workspace-preference-provider.d.ts +13 -6
  80. package/lib/browser/workspace-preference-provider.d.ts.map +1 -1
  81. package/lib/browser/workspace-preference-provider.js +27 -17
  82. package/lib/browser/workspace-preference-provider.js.map +1 -1
  83. package/lib/common/abstract-resource-preference-provider.d.ts +69 -0
  84. package/lib/common/abstract-resource-preference-provider.d.ts.map +1 -0
  85. package/lib/{browser → common}/abstract-resource-preference-provider.js +36 -62
  86. package/lib/common/abstract-resource-preference-provider.js.map +1 -0
  87. package/lib/common/abstract-resource-preference-provider.spec.d.ts.map +1 -0
  88. package/lib/{browser → common}/abstract-resource-preference-provider.spec.js +17 -17
  89. package/lib/common/abstract-resource-preference-provider.spec.js.map +1 -0
  90. package/lib/common/jsonc-editor.d.ts +10 -0
  91. package/lib/common/jsonc-editor.d.ts.map +1 -0
  92. package/lib/common/jsonc-editor.js +68 -0
  93. package/lib/common/jsonc-editor.js.map +1 -0
  94. package/lib/{browser → common}/section-preference-provider.d.ts +1 -3
  95. package/lib/common/section-preference-provider.d.ts.map +1 -0
  96. package/lib/{browser → common}/section-preference-provider.js +3 -8
  97. package/lib/common/section-preference-provider.js.map +1 -0
  98. package/lib/{browser → common}/user-configs-preference-provider.d.ts +6 -5
  99. package/lib/common/user-configs-preference-provider.d.ts.map +1 -0
  100. package/lib/{browser → common}/user-configs-preference-provider.js +17 -13
  101. package/lib/common/user-configs-preference-provider.js.map +1 -0
  102. package/lib/{browser → common}/user-preference-provider.d.ts +1 -1
  103. package/lib/common/user-preference-provider.d.ts.map +1 -0
  104. package/lib/{browser → common}/user-preference-provider.js +2 -2
  105. package/lib/common/user-preference-provider.js.map +1 -0
  106. package/lib/node/backend-preference-storage.d.ts +34 -0
  107. package/lib/node/backend-preference-storage.d.ts.map +1 -0
  108. package/lib/node/backend-preference-storage.js +100 -0
  109. package/lib/node/backend-preference-storage.js.map +1 -0
  110. package/lib/node/preference-backend-module.d.ts.map +1 -1
  111. package/lib/node/preference-backend-module.js +9 -0
  112. package/lib/node/preference-backend-module.js.map +1 -1
  113. package/lib/node/preference-bindings.d.ts +3 -0
  114. package/lib/node/preference-bindings.d.ts.map +1 -0
  115. package/lib/node/preference-bindings.js +33 -0
  116. package/lib/node/preference-bindings.js.map +1 -0
  117. package/package.json +9 -9
  118. package/src/browser/folder-preference-provider.ts +5 -2
  119. package/src/browser/folders-preferences-provider.ts +4 -5
  120. package/src/browser/frontend-preference-storage.ts +72 -0
  121. package/src/browser/index.ts +0 -3
  122. package/src/browser/monaco-jsonc-editor.ts +2 -2
  123. package/src/browser/preference-bindings.ts +7 -26
  124. package/src/browser/preference-frontend-contribution.ts +1 -1
  125. package/src/browser/preference-frontend-module.ts +10 -0
  126. package/src/browser/preference-transaction-manager.ts +8 -13
  127. package/src/browser/preference-tree-model.ts +4 -7
  128. package/src/browser/preferences-contribution.ts +2 -9
  129. package/src/browser/preferences-json-schema-contribution.ts +20 -23
  130. package/src/browser/util/preference-scope-command-manager.ts +2 -2
  131. package/src/browser/util/preference-tree-generator.ts +8 -12
  132. package/src/browser/util/preference-types.ts +2 -5
  133. package/src/browser/views/components/preference-node-renderer.ts +15 -8
  134. package/src/browser/views/components/preference-select-input.ts +6 -9
  135. package/src/browser/views/preference-editor-widget.ts +2 -5
  136. package/src/browser/views/preference-scope-tabbar-widget.tsx +2 -2
  137. package/src/browser/views/preference-widget.tsx +2 -1
  138. package/src/browser/workspace-file-preference-provider.ts +2 -2
  139. package/src/browser/workspace-preference-provider.ts +37 -19
  140. package/src/{browser → common}/abstract-resource-preference-provider.spec.ts +19 -20
  141. package/src/{browser → common}/abstract-resource-preference-provider.ts +69 -57
  142. package/src/common/jsonc-editor.ts +65 -0
  143. package/src/{browser → common}/section-preference-provider.ts +1 -5
  144. package/src/{browser → common}/user-configs-preference-provider.ts +14 -10
  145. package/src/{browser → common}/user-preference-provider.ts +1 -1
  146. package/src/node/backend-preference-storage.ts +117 -0
  147. package/src/node/preference-backend-module.ts +16 -0
  148. package/src/node/preference-bindings.ts +31 -0
  149. package/lib/browser/abstract-resource-preference-provider.d.ts +0 -48
  150. package/lib/browser/abstract-resource-preference-provider.d.ts.map +0 -1
  151. package/lib/browser/abstract-resource-preference-provider.js.map +0 -1
  152. package/lib/browser/abstract-resource-preference-provider.spec.d.ts.map +0 -1
  153. package/lib/browser/abstract-resource-preference-provider.spec.js.map +0 -1
  154. package/lib/browser/section-preference-provider.d.ts.map +0 -1
  155. package/lib/browser/section-preference-provider.js.map +0 -1
  156. package/lib/browser/user-configs-preference-provider.d.ts.map +0 -1
  157. package/lib/browser/user-configs-preference-provider.js.map +0 -1
  158. package/lib/browser/user-preference-provider.d.ts.map +0 -1
  159. package/lib/browser/user-preference-provider.js.map +0 -1
  160. /package/lib/{browser → common}/abstract-resource-preference-provider.spec.d.ts +0 -0
@@ -17,20 +17,17 @@
17
17
  import { inject, injectable } from '@theia/core/shared/inversify';
18
18
  import URI from '@theia/core/lib/common/uri';
19
19
  import { JsonSchemaRegisterContext, JsonSchemaContribution, JsonSchemaDataStore } from '@theia/core/lib/browser/json-schema-store';
20
- import { PreferenceSchemaProvider } from '@theia/core/lib/browser/preferences/preference-contribution';
21
- import { PreferenceConfigurations } from '@theia/core/lib/browser/preferences/preference-configurations';
22
- import { PreferenceScope } from '@theia/core/lib/browser';
23
20
  import { WorkspaceService } from '@theia/workspace/lib/browser';
21
+ import { PreferenceSchemaService, PreferenceConfigurations, PreferenceScope } from '@theia/core';
22
+ import { UserStorageUri } from '@theia/userstorage/lib/browser';
24
23
 
25
24
  const PREFERENCE_URI_PREFIX = 'vscode://schemas/settings/';
26
- const USER_STORAGE_PREFIX = 'user-storage:/';
27
25
 
28
26
  @injectable()
29
27
  export class PreferencesJsonSchemaContribution implements JsonSchemaContribution {
30
- protected serializeSchema = (scope: PreferenceScope) => JSON.stringify(this.schemaProvider.getSchema(scope));
31
28
 
32
- @inject(PreferenceSchemaProvider)
33
- protected readonly schemaProvider: PreferenceSchemaProvider;
29
+ @inject(PreferenceSchemaService)
30
+ protected readonly schemaProvider: PreferenceSchemaService;
34
31
 
35
32
  @inject(PreferenceConfigurations)
36
33
  protected readonly preferenceConfigurations: PreferenceConfigurations;
@@ -47,39 +44,39 @@ export class PreferencesJsonSchemaContribution implements JsonSchemaContribution
47
44
  this.registerSchema(PreferenceScope.Workspace, context);
48
45
  this.registerSchema(PreferenceScope.Folder, context);
49
46
 
47
+ context.registerSchema({
48
+ fileMatch: `file://**/${this.preferenceConfigurations.getConfigName()}.json`,
49
+ url: this.getSchemaURIForScope(PreferenceScope.Folder).toString()
50
+ });
51
+
52
+ context.registerSchema({
53
+ fileMatch: UserStorageUri.resolve(this.preferenceConfigurations.getConfigName() + '.json').toString(),
54
+ url: this.getSchemaURIForScope(PreferenceScope.User).toString()
55
+ });
56
+
50
57
  this.workspaceService.updateSchema('settings', { $ref: this.getSchemaURIForScope(PreferenceScope.Workspace).toString() });
51
- this.schemaProvider.onDidPreferenceSchemaChanged(() => this.updateInMemoryResources());
58
+ this.schemaProvider.onDidChangeSchema(() => this.updateInMemoryResources());
52
59
  }
53
60
 
54
61
  protected registerSchema(scope: PreferenceScope, context: JsonSchemaRegisterContext): void {
55
62
  const scopeStr = PreferenceScope[scope].toLowerCase();
56
63
  const uri = new URI(PREFERENCE_URI_PREFIX + scopeStr);
57
64
 
58
- this.jsonSchemaData.setSchema(uri, this.serializeSchema(scope));
59
-
60
- context.registerSchema({
61
- fileMatch: this.getFileMatch(scopeStr),
62
- url: uri.toString()
63
- });
65
+ this.jsonSchemaData.setSchema(uri, (this.schemaProvider.getJSONSchema(scope)));
64
66
  }
65
67
 
66
68
  protected updateInMemoryResources(): void {
67
69
  this.jsonSchemaData.setSchema(this.getSchemaURIForScope(PreferenceScope.Default),
68
- this.serializeSchema(+PreferenceScope.Default));
70
+ (this.schemaProvider.getJSONSchema(PreferenceScope.Default)));
69
71
  this.jsonSchemaData.setSchema(this.getSchemaURIForScope(PreferenceScope.User),
70
- this.serializeSchema(+PreferenceScope.User));
72
+ this.schemaProvider.getJSONSchema(PreferenceScope.User));
71
73
  this.jsonSchemaData.setSchema(this.getSchemaURIForScope(PreferenceScope.Workspace),
72
- this.serializeSchema(+PreferenceScope.Workspace));
74
+ this.schemaProvider.getJSONSchema(PreferenceScope.Workspace));
73
75
  this.jsonSchemaData.setSchema(this.getSchemaURIForScope(PreferenceScope.Folder),
74
- this.serializeSchema(+PreferenceScope.Folder));
76
+ this.schemaProvider.getJSONSchema(PreferenceScope.Folder));
75
77
  }
76
78
 
77
79
  protected getSchemaURIForScope(scope: PreferenceScope): URI {
78
80
  return new URI(PREFERENCE_URI_PREFIX + PreferenceScope[scope].toLowerCase());
79
81
  }
80
-
81
- protected getFileMatch(scope: string): string[] {
82
- const baseName = this.preferenceConfigurations.getConfigName() + '.json';
83
- return [baseName, new URI(USER_STORAGE_PREFIX + scope).resolve(baseName).toString()];
84
- }
85
82
  }
@@ -15,9 +15,9 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { injectable, inject } from '@theia/core/shared/inversify';
18
- import { PreferenceScope, LabelProvider, codicon } from '@theia/core/lib/browser';
18
+ import { LabelProvider, codicon } from '@theia/core/lib/browser';
19
19
  import { FileStat } from '@theia/filesystem/lib/common/files';
20
- import { CommandRegistry, MenuModelRegistry, Command } from '@theia/core/lib/common';
20
+ import { CommandRegistry, MenuModelRegistry, Command, PreferenceScope } from '@theia/core/lib/common';
21
21
  import { Preference, PreferenceMenus } from './preference-types';
22
22
 
23
23
  /**
@@ -15,9 +15,8 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
18
- import { CompositeTreeNode, PreferenceSchemaProvider, OVERRIDE_PROPERTY_PATTERN, PreferenceDataProperty } from '@theia/core/lib/browser';
19
- import { PreferenceConfigurations } from '@theia/core/lib/browser/preferences/preference-configurations';
20
- import { Emitter } from '@theia/core';
18
+ import { CompositeTreeNode } from '@theia/core/lib/browser';
19
+ import { Emitter, OVERRIDE_PROPERTY_PATTERN, PreferenceConfigurations, PreferenceDataProperty, PreferenceSchemaService } from '@theia/core';
21
20
  import debounce = require('@theia/core/shared/lodash.debounce');
22
21
  import { Preference } from './preference-types';
23
22
  import { COMMONLY_USED_SECTION_PREFIX, PreferenceLayoutProvider } from './preference-layout';
@@ -35,7 +34,7 @@ export interface CreatePreferencesGroupOptions {
35
34
  @injectable()
36
35
  export class PreferenceTreeGenerator {
37
36
 
38
- @inject(PreferenceSchemaProvider) protected readonly schemaProvider: PreferenceSchemaProvider;
37
+ @inject(PreferenceSchemaService) protected readonly schemaProvider: PreferenceSchemaService;
39
38
  @inject(PreferenceConfigurations) protected readonly preferenceConfigs: PreferenceConfigurations;
40
39
  @inject(PreferenceLayoutProvider) protected readonly layoutProvider: PreferenceLayoutProvider;
41
40
  @inject(PreferenceTreeLabelProvider) protected readonly labelProvider: PreferenceTreeLabelProvider;
@@ -57,15 +56,13 @@ export class PreferenceTreeGenerator {
57
56
  }
58
57
 
59
58
  protected async doInit(): Promise<void> {
60
- await this.schemaProvider.ready;
61
- this.schemaProvider.onDidPreferenceSchemaChanged(() => this.handleChangedSchema());
59
+ this.schemaProvider.onDidChangeSchema(() => this.handleChangedSchema());
62
60
  this.handleChangedSchema();
63
61
  }
64
62
 
65
63
  generateTree(): CompositeTreeNode {
66
64
  this._idCache.clear();
67
- const preferencesSchema = this.schemaProvider.getCombinedSchema();
68
- const propertyNames = Object.keys(preferencesSchema.properties);
65
+ const properties = this.schemaProvider.getSchemaProperties();
69
66
  const groups = new Map<string, Preference.CompositeTreeNode>();
70
67
  const root = this.createRootNode();
71
68
 
@@ -88,12 +85,11 @@ export class PreferenceTreeGenerator {
88
85
  });
89
86
  }
90
87
  for (const preference of commonlyUsedLayout.settings ?? []) {
91
- if (preference in preferencesSchema.properties) {
92
- this.createLeafNode(preference, commonlyUsed, preferencesSchema.properties[preference]);
88
+ if (properties.has(preference)) {
89
+ this.createLeafNode(preference, commonlyUsed, properties.get(preference)!);
93
90
  }
94
91
  }
95
- for (const propertyName of propertyNames) {
96
- const property = preferencesSchema.properties[propertyName];
92
+ for (const [propertyName, property] of properties.entries()) {
97
93
  if (!property.hidden && !property.deprecationMessage && !this.preferenceConfigs.isSectionName(propertyName) && !OVERRIDE_PROPERTY_PATTERN.test(propertyName)) {
98
94
  if (property.owner) {
99
95
  this.createPluginLeafNode(propertyName, property, root, groups);
@@ -15,15 +15,12 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import {
18
- PreferenceDataProperty,
19
- PreferenceScope,
20
18
  TreeNode as BaseTreeNode,
21
19
  CompositeTreeNode as BaseCompositeTreeNode,
22
20
  SelectableTreeNode,
23
- PreferenceInspection,
24
21
  CommonCommands,
25
- } from '@theia/core/lib/browser';
26
- import { Command, MenuPath } from '@theia/core';
22
+ } from '@theia/core/lib/browser';
23
+ import { Command, MenuPath, PreferenceDataProperty, PreferenceInspection, PreferenceScope } from '@theia/core';
27
24
  import { JSONValue } from '@theia/core/shared/@lumino/coreutils';
28
25
  import { JsonType } from '@theia/core/lib/common/json-schema';
29
26
 
@@ -16,13 +16,12 @@
16
16
 
17
17
  import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
18
18
  import {
19
- PreferenceService, ContextMenuRenderer, PreferenceInspection,
20
- PreferenceScope, PreferenceProvider, codicon, OpenerService, open, PreferenceDataProperty
19
+ ContextMenuRenderer, codicon, OpenerService, open
21
20
  } from '@theia/core/lib/browser';
22
21
  import { Preference, PreferenceMenus } from '../../util/preference-types';
23
22
  import { PreferenceTreeLabelProvider } from '../../util/preference-tree-label-provider';
24
23
  import { PreferencesScopeTabBar } from '../preference-scope-tabbar-widget';
25
- import { Disposable, nls } from '@theia/core/lib/common';
24
+ import { Disposable, nls, PreferenceDataProperty, PreferenceInspection, PreferenceScope, PreferenceService, PreferenceUtils } from '@theia/core/lib/common';
26
25
  import { JSONValue } from '@theia/core/shared/@lumino/coreutils';
27
26
  import debounce = require('@theia/core/shared/lodash.debounce');
28
27
  import { PreferenceTreeModel } from '../../preference-tree-model';
@@ -260,7 +259,7 @@ export abstract class PreferenceLeafNodeRenderer<ValueType extends JSONValue, In
260
259
  }
261
260
 
262
261
  protected handleCogAction({ currentTarget }: KeyboardEvent | MouseEvent): void {
263
- const value = Preference.getValueInScope(this.inspection, this.scopeTracker.currentScope.scope) ?? this.inspection?.defaultValue;
262
+ const value = Preference.getValueInScope(this.inspection, this.scopeTracker.currentScope.scope) ?? this.getDefaultValue();
264
263
  const target = currentTarget as HTMLElement | undefined;
265
264
  if (target && value !== undefined) {
266
265
  this.showCog();
@@ -295,7 +294,7 @@ export abstract class PreferenceLeafNodeRenderer<ValueType extends JSONValue, In
295
294
  const wasModified = this.isModifiedFromDefault;
296
295
  const { inspection } = this;
297
296
  const valueInCurrentScope = knownCurrentValue ?? Preference.getValueInScope(inspection, this.scopeTracker.currentScope.scope);
298
- this.isModifiedFromDefault = valueInCurrentScope !== undefined && !PreferenceProvider.deepEqual(valueInCurrentScope, inspection?.defaultValue);
297
+ this.isModifiedFromDefault = valueInCurrentScope !== undefined && !PreferenceUtils.deepEqual(valueInCurrentScope, this.getDefaultValue());
299
298
  if (wasModified !== this.isModifiedFromDefault) {
300
299
  this.gutter.classList.toggle('theia-mod-item-modified', this.isModifiedFromDefault);
301
300
  }
@@ -422,7 +421,7 @@ export abstract class PreferenceLeafNodeRenderer<ValueType extends JSONValue, In
422
421
  for (const otherScope of [PreferenceScope.User, PreferenceScope.Workspace]) {
423
422
  if (otherScope !== currentScopeInView) {
424
423
  const valueInOtherScope = Preference.getValueInScope(inspection, otherScope);
425
- if (valueInOtherScope !== undefined && !PreferenceProvider.deepEqual(valueInOtherScope, inspection.defaultValue)) {
424
+ if (valueInOtherScope !== undefined && !PreferenceUtils.deepEqual(valueInOtherScope, this.getDefaultValue())) {
426
425
  modifiedScopes.push(otherScope);
427
426
  }
428
427
  }
@@ -435,9 +434,9 @@ export abstract class PreferenceLeafNodeRenderer<ValueType extends JSONValue, In
435
434
  protected getValue(): ValueType | null {
436
435
  let currentValue = Preference.getValueInScope(this.inspection, this.scopeTracker.currentScope.scope);
437
436
  if (currentValue === undefined) {
438
- currentValue = this.inspection?.defaultValue;
437
+ currentValue = this.getDefaultValue();
439
438
  }
440
- return currentValue !== undefined ? currentValue : this.getFallbackValue();
439
+ return currentValue;
441
440
  }
442
441
 
443
442
  protected setPreferenceWithDebounce = debounce(this.setPreferenceImmediately.bind(this), 500, { leading: false, trailing: true });
@@ -461,6 +460,14 @@ export abstract class PreferenceLeafNodeRenderer<ValueType extends JSONValue, In
461
460
  this.updateHeadline();
462
461
  }
463
462
 
463
+ /**
464
+ * Returns the default value for this preference.
465
+ * @returns The default value from the inspection or the fallback value if no default is specified.
466
+ */
467
+ protected getDefaultValue(): ValueType {
468
+ return this.inspection?.defaultValue ?? this.getFallbackValue();
469
+ }
470
+
464
471
  /**
465
472
  * Should create an HTML element that the user can interact with to change the value of the preference.
466
473
  * @param container the parent element for the interactable. This method is responsible for adding the new element to its parent.
@@ -17,13 +17,13 @@
17
17
  import { PreferenceLeafNodeRenderer, PreferenceNodeRenderer } from './preference-node-renderer';
18
18
  import { injectable, interfaces } from '@theia/core/shared/inversify';
19
19
  import { JSONValue } from '@theia/core/shared/@lumino/coreutils';
20
- import { PreferenceProvider } from '@theia/core/lib/browser/preferences/preference-provider';
21
20
  import { SelectComponent, SelectOption } from '@theia/core/lib/browser/widgets/select-component';
22
21
  import { Preference } from '../../util/preference-types';
23
22
  import { PreferenceLeafNodeRendererContribution } from './preference-node-renderer-creator';
24
23
  import * as React from '@theia/core/shared/react';
25
24
  import { createRoot } from '@theia/core/shared/react-dom/client';
26
25
  import { escapeInvisibleChars } from '@theia/core/lib/common/strings';
26
+ import { PreferenceUtils } from '@theia/core';
27
27
 
28
28
  @injectable()
29
29
  export class PreferenceSelectInputRenderer extends PreferenceLeafNodeRenderer<JSONValue, HTMLDivElement> {
@@ -45,7 +45,7 @@ export class PreferenceSelectInputRenderer extends PreferenceLeafNodeRenderer<JS
45
45
  const value = values[i];
46
46
  const stringValue = `${value}`;
47
47
  const label = escapeInvisibleChars(preferenceData.enumItemLabels?.[i] ?? stringValue);
48
- const detail = PreferenceProvider.deepEqual(defaultValue, value) ? 'default' : undefined;
48
+ const detail = PreferenceUtils.deepEqual(defaultValue, value) ? 'default' : undefined;
49
49
  let enumDescription = preferenceData.enumDescriptions?.[i];
50
50
  let markdown = false;
51
51
  const markdownEnumDescription = preferenceData.markdownEnumDescriptions?.[i];
@@ -80,11 +80,8 @@ export class PreferenceSelectInputRenderer extends PreferenceLeafNodeRenderer<JS
80
80
  }
81
81
 
82
82
  protected getFallbackValue(): JSONValue {
83
- const { default: schemaDefault, defaultValue, enum: enumValues } = this.preferenceNode.preference.data;
84
- return schemaDefault !== undefined
85
- ? schemaDefault : defaultValue !== undefined
86
- ? defaultValue
87
- : enumValues![0];
83
+ const { default: schemaDefault, enum: enumValues } = this.preferenceNode.preference.data;
84
+ return schemaDefault !== undefined ? schemaDefault : enumValues![0];
88
85
  }
89
86
 
90
87
  protected doHandleValueChange(): void {
@@ -102,10 +99,10 @@ export class PreferenceSelectInputRenderer extends PreferenceLeafNodeRenderer<JS
102
99
  */
103
100
  protected getDataValue(): number {
104
101
  const currentValue = this.getValue();
105
- let selected = this.enumValues.findIndex(value => PreferenceProvider.deepEqual(value, currentValue));
102
+ let selected = this.enumValues.findIndex(value => PreferenceUtils.deepEqual(value, currentValue));
106
103
  if (selected === -1) {
107
104
  const fallback = this.getFallbackValue();
108
- selected = this.enumValues.findIndex(value => PreferenceProvider.deepEqual(value, fallback));
105
+ selected = this.enumValues.findIndex(value => PreferenceUtils.deepEqual(value, fallback));
109
106
  }
110
107
  return Math.max(selected, 0);
111
108
  }
@@ -19,16 +19,13 @@ import { postConstruct, injectable, inject } from '@theia/core/shared/inversify'
19
19
  import throttle = require('@theia/core/shared/lodash.throttle');
20
20
  import * as deepEqual from 'fast-deep-equal';
21
21
  import {
22
- PreferenceService,
23
22
  CompositeTreeNode,
24
23
  SelectableTreeNode,
25
24
  StatefulWidget,
26
25
  TopDownTreeIterator,
27
- PreferenceChanges,
28
26
  ExpandableTreeNode,
29
- PreferenceSchemaProvider,
30
27
  } from '@theia/core/lib/browser';
31
- import { unreachable } from '@theia/core/lib/common';
28
+ import { PreferenceChanges, PreferenceSchemaService, PreferenceService, unreachable } from '@theia/core/lib/common';
32
29
  import { BaseWidget, DEFAULT_SCROLL_OPTIONS } from '@theia/core/lib/browser/widgets/widget';
33
30
  import { PreferenceTreeModel, PreferenceFilterChangeEvent, PreferenceFilterChangeSource } from '../preference-tree-model';
34
31
  import { PreferenceNodeRendererFactory, GeneralPreferenceNodeRenderer } from './components/preference-node-renderer';
@@ -68,7 +65,7 @@ export class PreferencesEditorWidget extends BaseWidget implements StatefulWidge
68
65
  @inject(PreferenceTreeModel) protected readonly model: PreferenceTreeModel;
69
66
  @inject(PreferenceNodeRendererFactory) protected readonly rendererFactory: PreferenceNodeRendererFactory;
70
67
  @inject(PreferenceNodeRendererCreatorRegistry) protected readonly rendererRegistry: PreferenceNodeRendererCreatorRegistry;
71
- @inject(PreferenceSchemaProvider) protected readonly schemaProvider: PreferenceSchemaProvider;
68
+ @inject(PreferenceSchemaService) protected readonly schemaProvider: PreferenceSchemaService;
72
69
  @inject(PreferencesScopeTabBar) protected readonly tabbar: PreferencesScopeTabBar;
73
70
 
74
71
  @postConstruct()
@@ -16,13 +16,13 @@
16
16
 
17
17
  import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
18
18
  import { TabBar, Widget, Title } from '@theia/core/shared/@lumino/widgets';
19
- import { PreferenceScope, Message, ContextMenuRenderer, LabelProvider, StatefulWidget, codicon } from '@theia/core/lib/browser';
19
+ import { Message, ContextMenuRenderer, LabelProvider, StatefulWidget, codicon } from '@theia/core/lib/browser';
20
20
  import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
21
21
  import URI from '@theia/core/lib/common/uri';
22
22
  import { FileStat } from '@theia/filesystem/lib/common/files';
23
23
  import { PreferenceScopeCommandManager } from '../util/preference-scope-command-manager';
24
24
  import { Preference, PreferenceMenus } from '../util/preference-types';
25
- import { CommandRegistry, DisposableCollection, Emitter, MenuModelRegistry } from '@theia/core/lib/common';
25
+ import { CommandRegistry, DisposableCollection, Emitter, MenuModelRegistry, PreferenceScope } from '@theia/core/lib/common';
26
26
  import { nls } from '@theia/core/lib/common/nls';
27
27
 
28
28
  const USER_TAB_LABEL = nls.localizeByDefault('User');
@@ -15,7 +15,7 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { postConstruct, injectable, inject } from '@theia/core/shared/inversify';
18
- import { Panel, Widget, Message, StatefulWidget, PreferenceScope, codicon } from '@theia/core/lib/browser';
18
+ import { Panel, Widget, Message, StatefulWidget, codicon } from '@theia/core/lib/browser';
19
19
  import { PreferencesEditorState, PreferencesEditorWidget } from './preference-editor-widget';
20
20
  import { PreferencesTreeWidget } from './preference-tree-widget';
21
21
  import { PreferencesSearchbarState, PreferencesSearchbarWidget } from './preference-searchbar-widget';
@@ -23,6 +23,7 @@ import { PreferencesScopeTabBar, PreferencesScopeTabBarState } from './preferenc
23
23
  import { Preference } from '../util/preference-types';
24
24
  import URI from '@theia/core/lib/common/uri';
25
25
  import { nls } from '@theia/core/lib/common/nls';
26
+ import { PreferenceScope } from '@theia/core';
26
27
 
27
28
  interface PreferencesWidgetState {
28
29
  scopeTabBarState: PreferencesScopeTabBarState,
@@ -16,9 +16,9 @@
16
16
 
17
17
  import { inject, injectable } from '@theia/core/shared/inversify';
18
18
  import URI from '@theia/core/lib/common/uri';
19
- import { PreferenceScope } from '@theia/core/lib/browser/preferences';
19
+ import { PreferenceScope } from '@theia/core/lib/common/preferences';
20
20
  import { WorkspaceService, WorkspaceData } from '@theia/workspace/lib/browser/workspace-service';
21
- import { AbstractResourcePreferenceProvider } from './abstract-resource-preference-provider';
21
+ import { AbstractResourcePreferenceProvider } from '../common/abstract-resource-preference-provider';
22
22
 
23
23
  @injectable()
24
24
  export class WorkspaceFilePreferenceProviderOptions {
@@ -16,15 +16,17 @@
16
16
 
17
17
  /* eslint-disable @typescript-eslint/no-explicit-any */
18
18
 
19
- import { inject, injectable, postConstruct, named } from '@theia/core/shared/inversify';
19
+ import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
20
20
  import URI from '@theia/core/lib/common/uri';
21
21
  import { DisposableCollection } from '@theia/core/lib/common/disposable';
22
- import { PreferenceScope, PreferenceProvider } from '@theia/core/lib/browser/preferences';
23
22
  import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
24
23
  import { WorkspaceFilePreferenceProviderFactory, WorkspaceFilePreferenceProvider } from './workspace-file-preference-provider';
24
+ import { Deferred } from '@theia/core/lib/common/promise-util';
25
+ import { Emitter, Event, PreferenceProvider, PreferenceProviderDataChanges, PreferenceProviderProvider, PreferenceScope } from '@theia/core';
26
+ import { JSONObject } from '@theia/core/shared/@lumino/coreutils';
25
27
 
26
28
  @injectable()
27
- export class WorkspacePreferenceProvider extends PreferenceProvider {
29
+ export class WorkspacePreferenceProvider implements PreferenceProvider {
28
30
 
29
31
  @inject(WorkspaceService)
30
32
  protected readonly workspaceService: WorkspaceService;
@@ -32,11 +34,19 @@ export class WorkspacePreferenceProvider extends PreferenceProvider {
32
34
  @inject(WorkspaceFilePreferenceProviderFactory)
33
35
  protected readonly workspaceFileProviderFactory: WorkspaceFilePreferenceProviderFactory;
34
36
 
35
- @inject(PreferenceProvider) @named(PreferenceScope.Folder)
36
- protected readonly folderPreferenceProvider: PreferenceProvider;
37
+ @inject(PreferenceProviderProvider)
38
+ protected readonly preferenceProviderProvider: PreferenceProviderProvider;
39
+
40
+ protected readonly onDidPreferencesChangedEmitter = new Emitter<PreferenceProviderDataChanges>();
41
+ readonly onDidPreferencesChanged: Event<PreferenceProviderDataChanges> = this.onDidPreferencesChangedEmitter.event;
37
42
 
38
43
  protected readonly toDisposeOnEnsureDelegateUpToDate = new DisposableCollection();
39
44
 
45
+ protected _ready = new Deferred<void>();
46
+ readonly ready = this._ready.promise;
47
+
48
+ protected readonly disposables = new DisposableCollection();
49
+
40
50
  @postConstruct()
41
51
  protected init(): void {
42
52
  this.workspaceService.ready.then(() => {
@@ -46,15 +56,23 @@ export class WorkspacePreferenceProvider extends PreferenceProvider {
46
56
  this._ready.resolve();
47
57
  }
48
58
  });
49
- this.workspaceService.onWorkspaceLocationChanged(() => this.ensureDelegateUpToDate());
50
- this.workspaceService.onWorkspaceChanged(() => this.ensureDelegateUpToDate());
59
+ this.disposables.push(this.workspaceService.onWorkspaceLocationChanged(() => this.ensureDelegateUpToDate()));
60
+ this.disposables.push(this.workspaceService.onWorkspaceChanged(() => this.ensureDelegateUpToDate()));
61
+ }
62
+
63
+ dispose(): void {
64
+ this.disposables.dispose();
65
+ }
66
+
67
+ canHandleScope(scope: PreferenceScope): boolean {
68
+ return true;
51
69
  }
52
70
 
53
- override getConfigUri(resourceUri: string | undefined = this.ensureResourceUri(), sectionName?: string): URI | undefined {
54
- return this.delegate?.getConfigUri(resourceUri, sectionName);
71
+ getConfigUri(resourceUri: string | undefined = this.ensureResourceUri(), sectionName?: string): URI | undefined {
72
+ return this.delegate?.getConfigUri && this.delegate?.getConfigUri(resourceUri, sectionName);
55
73
  }
56
74
 
57
- override getContainingConfigUri(resourceUri: string | undefined = this.ensureResourceUri(), sectionName?: string): URI | undefined {
75
+ getContainingConfigUri(resourceUri: string | undefined = this.ensureResourceUri(), sectionName?: string): URI | undefined {
58
76
  return this.delegate?.getContainingConfigUri?.(resourceUri, sectionName);
59
77
  }
60
78
 
@@ -67,7 +85,7 @@ export class WorkspacePreferenceProvider extends PreferenceProvider {
67
85
  const delegate = this.createDelegate();
68
86
  if (this._delegate !== delegate) {
69
87
  this.toDisposeOnEnsureDelegateUpToDate.dispose();
70
- this.toDispose.push(this.toDisposeOnEnsureDelegateUpToDate);
88
+ this.disposables.push(this.toDisposeOnEnsureDelegateUpToDate);
71
89
 
72
90
  this._delegate = delegate;
73
91
 
@@ -91,7 +109,7 @@ export class WorkspacePreferenceProvider extends PreferenceProvider {
91
109
  return undefined;
92
110
  }
93
111
  if (!this.workspaceService.isMultiRootWorkspaceOpened) {
94
- return this.folderPreferenceProvider;
112
+ return this.preferenceProviderProvider(PreferenceScope.Folder);
95
113
  }
96
114
  if (this._delegate instanceof WorkspaceFilePreferenceProvider && this._delegate.getConfigUri().isEqual(workspace.resource)) {
97
115
  return this._delegate;
@@ -101,21 +119,16 @@ export class WorkspacePreferenceProvider extends PreferenceProvider {
101
119
  });
102
120
  }
103
121
 
104
- override get<T>(preferenceName: string, resourceUri: string | undefined = this.ensureResourceUri()): T | undefined {
122
+ get<T>(preferenceName: string, resourceUri: string | undefined = this.ensureResourceUri()): T | undefined {
105
123
  const delegate = this.delegate;
106
124
  return delegate ? delegate.get<T>(preferenceName, resourceUri) : undefined;
107
125
  }
108
126
 
109
- override resolve<T>(preferenceName: string, resourceUri: string | undefined = this.ensureResourceUri()): { value?: T, configUri?: URI } {
127
+ resolve<T>(preferenceName: string, resourceUri: string | undefined = this.ensureResourceUri()): { value?: T, configUri?: URI } {
110
128
  const delegate = this.delegate;
111
129
  return delegate ? delegate.resolve<T>(preferenceName, resourceUri) : {};
112
130
  }
113
131
 
114
- getPreferences(resourceUri: string | undefined = this.ensureResourceUri()): { [p: string]: any } {
115
- const delegate = this.delegate;
116
- return delegate ? delegate.getPreferences(resourceUri) : {};
117
- }
118
-
119
132
  async setPreference(preferenceName: string, value: any, resourceUri: string | undefined = this.ensureResourceUri()): Promise<boolean> {
120
133
  const delegate = this.delegate;
121
134
  if (delegate) {
@@ -124,6 +137,11 @@ export class WorkspacePreferenceProvider extends PreferenceProvider {
124
137
  return false;
125
138
  }
126
139
 
140
+ getPreferences(resourceUri: string | undefined = this.ensureResourceUri()): JSONObject {
141
+ const delegate = this.delegate;
142
+ return delegate ? delegate.getPreferences(resourceUri) : {};
143
+ }
144
+
127
145
  protected ensureResourceUri(): string | undefined {
128
146
  if (this.workspaceService.workspace && !this.workspaceService.isMultiRootWorkspaceOpened) {
129
147
  return this.workspaceService.workspace.resource.toString();
@@ -24,32 +24,31 @@ FrontendApplicationConfigProvider.set({});
24
24
 
25
25
  import { expect } from 'chai';
26
26
  import { Container } from '@theia/core/shared/inversify';
27
- import { AbstractResourcePreferenceProvider } from './abstract-resource-preference-provider';
28
- import { FileService } from '@theia/filesystem/lib/browser/file-service';
27
+ import { AbstractResourcePreferenceProvider, FileContentStatus, PreferenceStorage, PreferenceStorageFactory } from './abstract-resource-preference-provider';
29
28
  import { bindPreferenceService } from '@theia/core/lib/browser/frontend-application-bindings';
30
29
  import { bindMockPreferenceProviders } from '@theia/core/lib/browser/preferences/test';
31
30
  import { Deferred } from '@theia/core/lib/common/promise-util';
32
- import { Disposable, MessageService } from '@theia/core/lib/common';
31
+ import { Listener, MessageService, PreferenceSchemaService } from '@theia/core/lib/common';
33
32
  import { MonacoWorkspace } from '@theia/monaco/lib/browser/monaco-workspace';
34
- import { PreferenceSchemaProvider } from '@theia/core/lib/browser';
35
33
  import { EditorManager } from '@theia/editor/lib/browser';
36
- import { PreferenceTransactionFactory } from './preference-transaction-manager';
34
+ import { PreferenceTransactionFactory } from '../browser/preference-transaction-manager';
35
+ import { JSONValue } from '@theia/core/shared/@lumino/coreutils';
37
36
 
38
37
  disableJSDOM();
39
38
 
40
- class MockFileService {
39
+ class MockPreferenceStorage implements PreferenceStorage {
40
+ onDidChangeFileContent: Listener.Registration<FileContentStatus, Promise<boolean>> = Listener.None as unknown as Listener.Registration<FileContentStatus, Promise<boolean>>;
41
+ writeValue(key: string, path: string[], value: JSONValue): Promise<boolean> {
42
+ throw new Error('Method not implemented.');
43
+ }
44
+ dispose(): void { }
41
45
  releaseContent = new Deferred();
42
- async read(): Promise<{ value: string }> {
46
+ async read(): Promise<string> {
43
47
  await this.releaseContent.promise;
44
- return { value: JSON.stringify({ 'editor.fontSize': 20 }) };
48
+ return JSON.stringify({ 'editor.fontSize': 20 });
45
49
  }
46
- watch = RETURN_DISPOSABLE;
47
- onDidFilesChange = RETURN_DISPOSABLE;
48
50
  }
49
-
50
- const RETURN_DISPOSABLE = () => Disposable.NULL;
51
-
52
- const mockSchemaProvider = { getCombinedSchema: () => ({ properties: {} }) };
51
+ const mockSchemaProvider = { getSchemaProperty: () => undefined };
53
52
 
54
53
  class LessAbstractPreferenceProvider extends AbstractResourcePreferenceProvider {
55
54
  getUri(): any { }
@@ -58,15 +57,15 @@ class LessAbstractPreferenceProvider extends AbstractResourcePreferenceProvider
58
57
 
59
58
  describe('AbstractResourcePreferenceProvider', () => {
60
59
  let provider: AbstractResourcePreferenceProvider;
61
- let fileService: MockFileService;
60
+ let preferenceStorage: MockPreferenceStorage;
62
61
 
63
62
  beforeEach(() => {
64
- fileService = new MockFileService();
63
+ preferenceStorage = new MockPreferenceStorage();
65
64
  const testContainer = new Container();
66
65
  bindPreferenceService(testContainer.bind.bind(testContainer));
67
66
  bindMockPreferenceProviders(testContainer.bind.bind(testContainer), testContainer.unbind.bind(testContainer));
68
- testContainer.rebind(<any>PreferenceSchemaProvider).toConstantValue(mockSchemaProvider);
69
- testContainer.bind(<any>FileService).toConstantValue(fileService);
67
+ testContainer.rebind(<any>PreferenceSchemaService).toConstantValue(mockSchemaProvider);
68
+ testContainer.bind(<any>PreferenceStorageFactory).toFactory(() => () => preferenceStorage);
70
69
  testContainer.bind(<any>MessageService).toConstantValue(undefined);
71
70
  testContainer.bind(<any>MonacoWorkspace).toConstantValue(undefined);
72
71
  testContainer.bind(<any>EditorManager).toConstantValue(undefined);
@@ -81,14 +80,14 @@ describe('AbstractResourcePreferenceProvider', () => {
81
80
  expect(provider.get('editor.fontSize')).to.be.undefined;
82
81
 
83
82
  resolveWhenFinished.resolve();
84
- fileService.releaseContent.resolve(); // Allow the initialization to run
83
+ preferenceStorage.releaseContent.resolve(); // Allow the initialization to run
85
84
 
86
85
  // This promise would reject if the provider had declared itself ready before we resolve `resolveWhenFinished`
87
86
  await Promise.race([resolveWhenFinished.promise, errorIfReadyFirst]);
88
87
  });
89
88
 
90
89
  it('should report values in file when `ready` resolves.', async () => {
91
- fileService.releaseContent.resolve();
90
+ preferenceStorage.releaseContent.resolve();
92
91
  await provider.ready;
93
92
  expect(provider.get('editor.fontSize')).to.equal(20); // The value provided by the mock FileService implementation.
94
93
  });