@codingame/monaco-vscode-api 1.76.9 → 1.78.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -49
- package/dist/Bibtex.tmLanguage.js +2 -0
- package/dist/Handlebars.tmLanguage.js +2 -0
- package/dist/JSON.tmLanguage.js +2 -0
- package/dist/JSONC.tmLanguage.js +2 -0
- package/dist/JavaScript.tmLanguage.js +2 -0
- package/dist/JavaScriptReact.tmLanguage.js +2 -0
- package/dist/LaTeX.tmLanguage.js +2 -0
- package/dist/MagicPython.tmLanguage.js +2 -0
- package/dist/MagicRegExp.tmLanguage.js +2 -0
- package/dist/Red-color-theme.js +2 -0
- package/dist/Regular Expressions (JavaScript).js +2 -0
- package/dist/TeX.tmLanguage.js +2 -0
- package/dist/TypeScript.tmLanguage.js +2 -0
- package/dist/TypeScriptReact.tmLanguage.js +2 -0
- package/dist/_.contribution.js +1 -1
- package/dist/abyss-color-theme.js +2 -0
- package/dist/api.js +1 -3
- package/dist/api2.js +421 -18091
- package/dist/asp-vb-net.tmlanguage.js +2 -0
- package/dist/assets/diffLineDeleted.mp3 +0 -0
- package/dist/assets/diffLineInserted.mp3 +0 -0
- package/dist/assets/diffLineModified.mp3 +0 -0
- package/dist/audioCue.js +108 -478
- package/dist/bat.js +9 -0
- package/dist/batchfile.js +2 -0
- package/dist/batchfile.tmLanguage.js +2 -0
- package/dist/button.js +35 -8
- package/dist/c.js +2 -0
- package/dist/c.tmLanguage.js +2 -0
- package/dist/clojure.js +8 -0
- package/dist/clojure.tmLanguage.js +2 -0
- package/dist/coffeescript.js +9 -0
- package/dist/coffeescript.tmLanguage.js +2 -0
- package/dist/coffeescript2.js +2 -0
- package/dist/configuration.d.ts +269 -4
- package/dist/configuration.js +4326 -328
- package/dist/configuration2.js +14 -324
- package/dist/cpp-grammar-bailout.tmLanguage.js +2 -0
- package/dist/cpp.embedded.macro.tmLanguage.js +2 -0
- package/dist/cpp.js +16 -0
- package/dist/cpp.tmLanguage.js +2 -0
- package/dist/cpp2.js +2 -0
- package/dist/csharp.js +9 -0
- package/dist/csharp.tmLanguage.js +2 -0
- package/dist/csharp2.js +2 -0
- package/dist/cshtml.tmLanguage.js +2 -0
- package/dist/css.js +8 -0
- package/dist/css.tmLanguage.js +2 -0
- package/dist/cuda-cpp.tmLanguage.js +2 -0
- package/dist/dark_plus.js +2 -0
- package/dist/dark_plus_experimental.js +2 -0
- package/dist/dark_vs.js +2 -0
- package/dist/dart.js +8 -0
- package/dist/dart.tmLanguage.js +2 -0
- package/dist/debug.js +12115 -12209
- package/dist/default-extensions/bat.js +12 -0
- package/dist/default-extensions/clojure.js +11 -0
- package/dist/default-extensions/coffeescript.js +12 -0
- package/dist/default-extensions/cpp.js +19 -0
- package/dist/default-extensions/csharp.js +12 -0
- package/dist/default-extensions/css.js +11 -0
- package/dist/default-extensions/dart.js +11 -0
- package/dist/default-extensions/diff.js +11 -0
- package/dist/default-extensions/docker.js +11 -0
- package/dist/default-extensions/fsharp.js +12 -0
- package/dist/default-extensions/go.js +11 -0
- package/dist/default-extensions/groovy.js +12 -0
- package/dist/default-extensions/handlebars.js +11 -0
- package/dist/default-extensions/hlsl.js +11 -0
- package/dist/default-extensions/html.js +13 -0
- package/dist/default-extensions/ini.js +13 -0
- package/dist/default-extensions/java.js +12 -0
- package/dist/default-extensions/javascript.js +17 -0
- package/dist/default-extensions/json.js +13 -0
- package/dist/default-extensions/julia.js +11 -0
- package/dist/default-extensions/latex.js +14 -0
- package/dist/default-extensions/less.js +11 -0
- package/dist/default-extensions/log.js +10 -0
- package/dist/default-extensions/lua.js +11 -0
- package/dist/default-extensions/make.js +11 -0
- package/dist/default-extensions/markdown-basics.js +12 -0
- package/dist/default-extensions/objective-c.js +13 -0
- package/dist/default-extensions/perl.js +13 -0
- package/dist/default-extensions/php.js +13 -0
- package/dist/default-extensions/powershell.js +11 -0
- package/dist/default-extensions/pug.js +11 -0
- package/dist/default-extensions/python.js +12 -0
- package/dist/default-extensions/r.js +11 -0
- package/dist/default-extensions/razor.js +11 -0
- package/dist/default-extensions/ruby.js +11 -0
- package/dist/default-extensions/rust.js +11 -0
- package/dist/default-extensions/scss.js +12 -0
- package/dist/default-extensions/shaderlab.js +11 -0
- package/dist/default-extensions/shellscript.js +11 -0
- package/dist/default-extensions/sql.js +11 -0
- package/dist/default-extensions/swift.js +12 -0
- package/dist/default-extensions/theme-abyss.js +10 -0
- package/dist/default-extensions/theme-defaults.js +18 -0
- package/dist/default-extensions/theme-kimbie-dark.js +10 -0
- package/dist/default-extensions/theme-monokai-dimmed.js +10 -0
- package/dist/default-extensions/theme-monokai.js +10 -0
- package/dist/default-extensions/theme-quietlight.js +10 -0
- package/dist/default-extensions/theme-red.js +10 -0
- package/dist/default-extensions/theme-seti.js +10 -0
- package/dist/default-extensions/theme-solarized-dark.js +10 -0
- package/dist/default-extensions/theme-solarized-light.js +10 -0
- package/dist/default-extensions/theme-tomorrow-night-blue.js +10 -0
- package/dist/default-extensions/typescript-basics.js +17 -0
- package/dist/default-extensions/vb.js +12 -0
- package/dist/default-extensions/xml.js +13 -0
- package/dist/default-extensions/yaml.js +13 -0
- package/dist/dialogs.js +12 -216
- package/dist/diff.js +8 -0
- package/dist/diff.tmLanguage.js +2 -0
- package/dist/dimmed-monokai-color-theme.js +2 -0
- package/dist/docker.js +8 -0
- package/dist/docker.tmLanguage.js +2 -0
- package/dist/dom.js +101 -0
- package/dist/extensionManagement.js +4 -0
- package/dist/extensions.d.ts +368 -23
- package/dist/extensions.js +4 -85
- package/dist/extensionsRegistry.js +63 -64
- package/dist/files.d.ts +845 -0
- package/dist/files.js +1805 -1151
- package/dist/files2.js +32 -0
- package/dist/fsharp.js +9 -0
- package/dist/fsharp.tmLanguage.js +2 -0
- package/dist/fsharp2.js +2 -0
- package/dist/go.js +8 -0
- package/dist/go.tmLanguage.js +2 -0
- package/dist/groovy.js +9 -0
- package/dist/groovy.tmLanguage.js +2 -0
- package/dist/groovy2.js +2 -0
- package/dist/handlebars.js +8 -0
- package/dist/hc_black.js +2 -0
- package/dist/hc_light.js +2 -0
- package/dist/hlsl.js +8 -0
- package/dist/hlsl.tmLanguage.js +2 -0
- package/dist/html-derivative.tmLanguage.js +2 -0
- package/dist/html.js +10 -0
- package/dist/html.tmLanguage.js +2 -0
- package/dist/html.tmLanguage2.js +2 -0
- package/dist/html2.js +2 -0
- package/dist/ini.js +10 -0
- package/dist/ini.language-configuration.js +2 -0
- package/dist/ini.tmLanguage.js +2 -0
- package/dist/injection.js +1 -1
- package/dist/java.js +9 -0
- package/dist/java.tmLanguage.js +2 -0
- package/dist/java2.js +2 -0
- package/dist/javascript-language-configuration.js +2 -0
- package/dist/javascript.js +14 -0
- package/dist/javascript2.js +2 -0
- package/dist/jsdoc.js.injection.tmLanguage.js +2 -0
- package/dist/jsdoc.ts.injection.tmLanguage.js +2 -0
- package/dist/json.js +10 -0
- package/dist/jsonErrorMessages.js +1 -1
- package/dist/julia.js +8 -0
- package/dist/julia.tmLanguage.js +2 -0
- package/dist/keybindings.d.ts +1 -10
- package/dist/keybindings.js +291 -353
- package/dist/kimbie-dark-color-theme.js +2 -0
- package/dist/language-configuration.js +2 -0
- package/dist/language-configuration10.js +2 -0
- package/dist/language-configuration11.js +2 -0
- package/dist/language-configuration12.js +2 -0
- package/dist/language-configuration13.js +2 -0
- package/dist/language-configuration14.js +2 -0
- package/dist/language-configuration15.js +2 -0
- package/dist/language-configuration16.js +2 -0
- package/dist/language-configuration17.js +2 -0
- package/dist/language-configuration18.js +2 -0
- package/dist/language-configuration19.js +2 -0
- package/dist/language-configuration2.js +2 -0
- package/dist/language-configuration20.js +2 -0
- package/dist/language-configuration21.js +2 -0
- package/dist/language-configuration22.js +2 -0
- package/dist/language-configuration23.js +2 -0
- package/dist/language-configuration24.js +2 -0
- package/dist/language-configuration25.js +2 -0
- package/dist/language-configuration26.js +2 -0
- package/dist/language-configuration27.js +2 -0
- package/dist/language-configuration28.js +2 -0
- package/dist/language-configuration29.js +2 -0
- package/dist/language-configuration3.js +2 -0
- package/dist/language-configuration30.js +2 -0
- package/dist/language-configuration31.js +2 -0
- package/dist/language-configuration32.js +2 -0
- package/dist/language-configuration33.js +2 -0
- package/dist/language-configuration34.js +2 -0
- package/dist/language-configuration35.js +2 -0
- package/dist/language-configuration36.js +2 -0
- package/dist/language-configuration37.js +2 -0
- package/dist/language-configuration38.js +2 -0
- package/dist/language-configuration39.js +2 -0
- package/dist/language-configuration4.js +2 -0
- package/dist/language-configuration5.js +2 -0
- package/dist/language-configuration6.js +2 -0
- package/dist/language-configuration7.js +2 -0
- package/dist/language-configuration8.js +2 -0
- package/dist/language-configuration9.js +2 -0
- package/dist/languageService.js +5 -6
- package/dist/languages.d.ts +66 -1
- package/dist/languages.js +924 -5
- package/dist/latex.js +11 -0
- package/dist/layout.contribution.darwin.js +1 -1
- package/dist/layout.contribution.linux.js +1 -1
- package/dist/layout.contribution.win.js +1 -1
- package/dist/layout.js +4 -10
- package/dist/layoutService.js +10 -2
- package/dist/less.js +8 -0
- package/dist/less.tmLanguage.js +2 -0
- package/dist/light_plus.js +2 -0
- package/dist/light_plus_experimental.js +2 -0
- package/dist/light_vs.js +2 -0
- package/dist/log.js +7 -0
- package/dist/log.tmLanguage.js +2 -0
- package/dist/lua.js +8 -0
- package/dist/lua.tmLanguage.js +2 -0
- package/dist/make.js +8 -0
- package/dist/make.tmLanguage.js +2 -0
- package/dist/markdown-basics.js +9 -0
- package/dist/markdown-latex-combined.tmLanguage.js +2 -0
- package/dist/markdown.js +2 -0
- package/dist/markdown.tmLanguage.js +2 -0
- package/dist/memento.js +91 -0
- package/dist/modelEditor.d.ts +1480 -138
- package/dist/modelEditor.js +8700 -326
- package/dist/monaco.d.ts +987 -15
- package/dist/monaco.js +40 -10
- package/dist/monokai-color-theme.js +2 -0
- package/dist/notifications.js +86 -64
- package/dist/objective-c.js +10 -0
- package/dist/objective-c.tmLanguage.js +2 -0
- package/dist/objective-c__.tmLanguage.js +2 -0
- package/dist/perl.js +10 -0
- package/dist/perl.language-configuration.js +2 -0
- package/dist/perl.tmLanguage.js +2 -0
- package/dist/perl6.language-configuration.js +2 -0
- package/dist/perl6.tmLanguage.js +2 -0
- package/dist/php.js +10 -0
- package/dist/php.tmLanguage.js +2 -0
- package/dist/php2.js +2 -0
- package/dist/platform.js +105 -0
- package/dist/platform.tmLanguage.js +2 -0
- package/dist/polyfill.js +51923 -11069
- package/dist/powershell.js +8 -0
- package/dist/powershell.tmLanguage.js +2 -0
- package/dist/preferences.js +2532 -0
- package/dist/properties.language-configuration.js +2 -0
- package/dist/pug.js +8 -0
- package/dist/pug.tmLanguage.js +2 -0
- package/dist/python.js +9 -0
- package/dist/quietlight-color-theme.js +2 -0
- package/dist/r.js +8 -0
- package/dist/r.tmLanguage.js +2 -0
- package/dist/razor.js +8 -0
- package/dist/rollup-vsix-plugin.d.ts +8 -0
- package/dist/rollup-vsix-plugin.js +104 -0
- package/dist/ruby.js +8 -0
- package/dist/ruby.tmLanguage.js +2 -0
- package/dist/rust.js +8 -0
- package/dist/rust.tmLanguage.js +2 -0
- package/dist/sassdoc.tmLanguage.js +2 -0
- package/dist/scss.js +9 -0
- package/dist/scss.tmLanguage.js +2 -0
- package/dist/services.d.ts +12988 -12840
- package/dist/services.js +1 -1
- package/dist/shaderlab.js +8 -0
- package/dist/shaderlab.tmLanguage.js +2 -0
- package/dist/shell-unix-bash.tmLanguage.js +2 -0
- package/dist/shellscript.js +8 -0
- package/dist/snippets.js +6 -11
- package/dist/snippetsService.js +7 -10
- package/dist/solarized-dark-color-theme.js +2 -0
- package/dist/solarized-light-color-theme.js +2 -0
- package/dist/sql.js +8 -0
- package/dist/sql.tmLanguage.js +2 -0
- package/dist/swift.js +9 -0
- package/dist/swift.tmLanguage.js +2 -0
- package/dist/swift2.js +2 -0
- package/dist/tags-language-configuration.js +2 -0
- package/dist/textmate.d.ts +0 -264
- package/dist/textmate.js +402 -66
- package/dist/theme-abyss.js +7 -0
- package/dist/theme-defaults.js +15 -0
- package/dist/theme-kimbie-dark.js +7 -0
- package/dist/theme-monokai-dimmed.js +7 -0
- package/dist/theme-monokai.js +7 -0
- package/dist/theme-quietlight.js +7 -0
- package/dist/theme-red.js +7 -0
- package/dist/theme-seti.js +7 -0
- package/dist/theme-solarized-dark.js +7 -0
- package/dist/theme-solarized-light.js +7 -0
- package/dist/theme-tomorrow-night-blue.js +7 -0
- package/dist/theme.js +6 -11
- package/dist/{contextkeys.js → theme2.js} +165 -143
- package/dist/tokenClassificationRegistry.js +46 -2
- package/dist/tomorrow-night-blue-color-theme.js +2 -0
- package/dist/typescript-basics.js +14 -0
- package/dist/typescript.js +2 -0
- package/dist/unboundCommands.js +41 -0
- package/dist/utils.js +345 -0
- package/dist/vb.js +9 -0
- package/dist/vb2.js +2 -0
- package/dist/vs-seti-icon-theme.js +2 -0
- package/dist/vs_minimal-icon-theme.js +2 -0
- package/dist/xml.js +10 -0
- package/dist/xml.language-configuration.js +2 -0
- package/dist/xml.tmLanguage.js +2 -0
- package/dist/xsl.language-configuration.js +2 -0
- package/dist/xsl.tmLanguage.js +2 -0
- package/dist/yaml.js +10 -0
- package/dist/yaml.tmLanguage.js +2 -0
- package/package.json +50 -33
- package/dist/async.js +0 -301
- package/dist/cancellation.js +0 -3
- package/dist/configurationRegistry.js +0 -441
- package/dist/extensionResourceLoader.js +0 -96
- package/dist/labels.js +0 -14
- package/dist/languageConfiguration.js +0 -919
- package/dist/missing-services.js +0 -5554
- package/dist/resources.js +0 -197
- package/dist/services2.js +0 -3467
- package/dist/textFileEditorModel.js +0 -2985
- package/dist/tokenClassification.d.ts +0 -7
- package/dist/tokenClassification.js +0 -277
- package/dist/variableResolver.js +0 -1711
- package/dist/workbenchThemeService.js +0 -46
- package/dist/workspaceContext.js +0 -50
- /package/dist/{languageConfiguration.d.ts → preferences.d.ts} +0 -0
|
@@ -0,0 +1,2532 @@
|
|
|
1
|
+
import { __decorate, EditorInput, __param, IPreferencesService, EditorModel, IExtensionService, Emitter, FOLDER_SETTINGS_PATH, validateSettingsEditorOptions, SIDE_GROUP, DEFAULT_EDITOR_ASSOCIATION, USE_SPLIT_JSON_SETTING, DEFAULT_SETTINGS_EDITOR_SETTING, TextResourceEditorInput, SideBySideEditorInput, parse$1, getErrorMessage, IEditorService, IEditorGroupsService, ITextFileService, IUserDataProfileService, IUserDataProfilesService, IJSONEditingService, IRemoteAgentService, ITextEditorService, ExtensionIdentifierMap, isEmptyObject, visit, isStringArray, SettingMatchType, Selection$2, Range$2, flatten } from './polyfill.js';
|
|
2
|
+
import { getAllUnboundCommands } from './unboundCommands.js';
|
|
3
|
+
import { Language } from './platform.js';
|
|
4
|
+
import { or, matchesPrefix, matchesWords, matchesContiguousSubString, matchesCamelCase } from 'monaco-editor/esm/vs/base/common/filters.js';
|
|
5
|
+
import { UILabelProvider, AriaLabelProvider, UserSettingsLabelProvider } from 'monaco-editor/esm/vs/base/common/keybindingLabels.js';
|
|
6
|
+
import { isString, isObject, isUndefinedOrNull, withNullAsUndefined } from 'monaco-editor/esm/vs/base/common/types.js';
|
|
7
|
+
import { ExtensionIdentifier } from 'monaco-editor/esm/vs/platform/extensions/common/extensions.js';
|
|
8
|
+
import { coalesce, distinct, tail } from 'monaco-editor/esm/vs/base/common/arrays.js';
|
|
9
|
+
import { ResolvedKeybindingItem } from 'monaco-editor/esm/vs/platform/keybinding/common/resolvedKeybindingItem.js';
|
|
10
|
+
import { MenuRegistry } from 'monaco-editor/esm/vs/platform/actions/common/actions.js';
|
|
11
|
+
import { localize } from 'monaco-editor/esm/vs/nls.js';
|
|
12
|
+
import { IKeybindingService } from 'monaco-editor/esm/vs/platform/keybinding/common/keybinding.js';
|
|
13
|
+
import { compareIgnoreCase, equalsIgnoreCase } from 'monaco-editor/esm/vs/base/common/strings.js';
|
|
14
|
+
import { OS } from 'monaco-editor/esm/vs/base/common/platform.js';
|
|
15
|
+
import { IInstantiationService } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation.js';
|
|
16
|
+
import { URI } from 'monaco-editor/esm/vs/base/common/uri.js';
|
|
17
|
+
import { Schemas } from 'monaco-editor/esm/vs/base/common/network.js';
|
|
18
|
+
import { FOLDER_SCOPES, WORKSPACE_SCOPES } from './configuration2.js';
|
|
19
|
+
import { Color } from 'monaco-editor/esm/vs/base/common/color.js';
|
|
20
|
+
import { Registry } from 'monaco-editor/esm/vs/platform/registry/common/platform.js';
|
|
21
|
+
import { Extensions, OVERRIDE_PROPERTY_REGEX, getDefaultValue } from 'monaco-editor/esm/vs/platform/configuration/common/configurationRegistry.js';
|
|
22
|
+
import { IConfigurationService } from 'monaco-editor/esm/vs/platform/configuration/common/configuration.js';
|
|
23
|
+
import { Disposable } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
|
|
24
|
+
import { getCodeEditor } from 'monaco-editor/esm/vs/editor/browser/editorBrowser.js';
|
|
25
|
+
import { SuggestController } from 'monaco-editor/esm/vs/editor/contrib/suggest/browser/suggestController.js';
|
|
26
|
+
import { CoreEditingCommands } from 'monaco-editor/esm/vs/editor/browser/coreCommands.js';
|
|
27
|
+
import { INotificationService } from 'monaco-editor/esm/vs/platform/notification/common/notification.js';
|
|
28
|
+
import { IWorkspaceContextService } from 'monaco-editor/esm/vs/platform/workspace/common/workspace.js';
|
|
29
|
+
import { ITextModelService } from 'monaco-editor/esm/vs/editor/common/services/resolverService.js';
|
|
30
|
+
import { IModelService } from 'monaco-editor/esm/vs/editor/common/services/model.js';
|
|
31
|
+
import { ILanguageService } from 'monaco-editor/esm/vs/editor/common/languages/language.js';
|
|
32
|
+
import { ILabelService } from 'monaco-editor/esm/vs/platform/label/common/label.js';
|
|
33
|
+
import { SyncDescriptor } from 'monaco-editor/esm/vs/platform/instantiation/common/descriptors.js';
|
|
34
|
+
const KEYBINDING_ENTRY_TEMPLATE_ID = 'keybinding.entry.template';
|
|
35
|
+
const SOURCE_SYSTEM = ( (localize('default', "System")));
|
|
36
|
+
const SOURCE_EXTENSION = ( (localize('extension', "Extension")));
|
|
37
|
+
const SOURCE_USER = ( (localize('user', "User")));
|
|
38
|
+
const wordFilter = or(matchesPrefix, matchesWords, matchesContiguousSubString);
|
|
39
|
+
const SOURCE_REGEX = /@source:\s*(user|default|system|extension)/i;
|
|
40
|
+
const EXTENSION_REGEX = /@ext:\s*((".+")|([^\s]+))/i;
|
|
41
|
+
let KeybindingsEditorModel = class KeybindingsEditorModel extends EditorModel {
|
|
42
|
+
constructor(os, keybindingsService, extensionService) {
|
|
43
|
+
super();
|
|
44
|
+
this.keybindingsService = keybindingsService;
|
|
45
|
+
this.extensionService = extensionService;
|
|
46
|
+
this._keybindingItems = [];
|
|
47
|
+
this._keybindingItemsSortedByPrecedence = [];
|
|
48
|
+
this.modifierLabels = {
|
|
49
|
+
ui: UILabelProvider.modifierLabels[os],
|
|
50
|
+
aria: AriaLabelProvider.modifierLabels[os],
|
|
51
|
+
user: UserSettingsLabelProvider.modifierLabels[os]
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
fetch(searchValue, sortByPrecedence = false) {
|
|
55
|
+
let keybindingItems = sortByPrecedence ? this._keybindingItemsSortedByPrecedence : this._keybindingItems;
|
|
56
|
+
const commandIdMatches = /@command:\s*(.+)/i.exec(searchValue);
|
|
57
|
+
if (commandIdMatches && commandIdMatches[1]) {
|
|
58
|
+
return (
|
|
59
|
+
(keybindingItems.filter(k => k.command === commandIdMatches[1])
|
|
60
|
+
.map(
|
|
61
|
+
keybindingItem => ({ id: KeybindingsEditorModel.getId(keybindingItem), keybindingItem, templateId: KEYBINDING_ENTRY_TEMPLATE_ID })
|
|
62
|
+
))
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (SOURCE_REGEX.test(searchValue)) {
|
|
66
|
+
keybindingItems = this.filterBySource(keybindingItems, searchValue);
|
|
67
|
+
searchValue = searchValue.replace(SOURCE_REGEX, '');
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const extensionMatches = EXTENSION_REGEX.exec(searchValue);
|
|
71
|
+
if (extensionMatches && (extensionMatches[2] || extensionMatches[3])) {
|
|
72
|
+
const extensionId = extensionMatches[2] ? extensionMatches[2].substring(1, extensionMatches[2].length - 1) : extensionMatches[3];
|
|
73
|
+
keybindingItems = this.filterByExtension(keybindingItems, extensionId);
|
|
74
|
+
searchValue = searchValue.replace(EXTENSION_REGEX, '');
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const keybindingMatches = /@keybinding:\s*((\".+\")|(\S+))/i.exec(searchValue);
|
|
78
|
+
if (keybindingMatches && (keybindingMatches[2] || keybindingMatches[3])) {
|
|
79
|
+
searchValue = keybindingMatches[2] || `"${keybindingMatches[3]}"`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
searchValue = searchValue.trim();
|
|
84
|
+
if (!searchValue) {
|
|
85
|
+
return (
|
|
86
|
+
(keybindingItems.map(
|
|
87
|
+
keybindingItem => ({ id: KeybindingsEditorModel.getId(keybindingItem), keybindingItem, templateId: KEYBINDING_ENTRY_TEMPLATE_ID })
|
|
88
|
+
))
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
return this.filterByText(keybindingItems, searchValue);
|
|
92
|
+
}
|
|
93
|
+
filterBySource(keybindingItems, searchValue) {
|
|
94
|
+
if (/@source:\s*default/i.test(searchValue) || /@source:\s*system/i.test(searchValue)) {
|
|
95
|
+
return keybindingItems.filter(k => k.source === SOURCE_SYSTEM);
|
|
96
|
+
}
|
|
97
|
+
if (/@source:\s*user/i.test(searchValue)) {
|
|
98
|
+
return keybindingItems.filter(k => k.source === SOURCE_USER);
|
|
99
|
+
}
|
|
100
|
+
if (/@source:\s*extension/i.test(searchValue)) {
|
|
101
|
+
return keybindingItems.filter(k => !isString(k.source) || k.source === SOURCE_EXTENSION);
|
|
102
|
+
}
|
|
103
|
+
return keybindingItems;
|
|
104
|
+
}
|
|
105
|
+
filterByExtension(keybindingItems, extension) {
|
|
106
|
+
extension = extension.toLowerCase().trim();
|
|
107
|
+
return keybindingItems.filter(k => !isString(k.source) && (ExtensionIdentifier.equals(k.source.identifier, extension) || k.source.displayName?.toLowerCase() === extension.toLowerCase()));
|
|
108
|
+
}
|
|
109
|
+
filterByText(keybindingItems, searchValue) {
|
|
110
|
+
const quoteAtFirstChar = searchValue.charAt(0) === '"';
|
|
111
|
+
const quoteAtLastChar = searchValue.charAt(searchValue.length - 1) === '"';
|
|
112
|
+
const completeMatch = quoteAtFirstChar && quoteAtLastChar;
|
|
113
|
+
if (quoteAtFirstChar) {
|
|
114
|
+
searchValue = searchValue.substring(1);
|
|
115
|
+
}
|
|
116
|
+
if (quoteAtLastChar) {
|
|
117
|
+
searchValue = searchValue.substring(0, searchValue.length - 1);
|
|
118
|
+
}
|
|
119
|
+
searchValue = searchValue.trim();
|
|
120
|
+
const result = [];
|
|
121
|
+
const words = searchValue.split(' ');
|
|
122
|
+
const keybindingWords = this.splitKeybindingWords(words);
|
|
123
|
+
for (const keybindingItem of keybindingItems) {
|
|
124
|
+
const keybindingMatches = ( (new KeybindingItemMatches(
|
|
125
|
+
this.modifierLabels,
|
|
126
|
+
keybindingItem,
|
|
127
|
+
searchValue,
|
|
128
|
+
words,
|
|
129
|
+
keybindingWords,
|
|
130
|
+
completeMatch
|
|
131
|
+
)));
|
|
132
|
+
if (keybindingMatches.commandIdMatches
|
|
133
|
+
|| keybindingMatches.commandLabelMatches
|
|
134
|
+
|| keybindingMatches.commandDefaultLabelMatches
|
|
135
|
+
|| keybindingMatches.sourceMatches
|
|
136
|
+
|| keybindingMatches.whenMatches
|
|
137
|
+
|| keybindingMatches.keybindingMatches
|
|
138
|
+
|| keybindingMatches.extensionIdMatches
|
|
139
|
+
|| keybindingMatches.extensionLabelMatches) {
|
|
140
|
+
result.push({
|
|
141
|
+
id: KeybindingsEditorModel.getId(keybindingItem),
|
|
142
|
+
templateId: KEYBINDING_ENTRY_TEMPLATE_ID,
|
|
143
|
+
commandLabelMatches: keybindingMatches.commandLabelMatches || undefined,
|
|
144
|
+
commandDefaultLabelMatches: keybindingMatches.commandDefaultLabelMatches || undefined,
|
|
145
|
+
keybindingItem,
|
|
146
|
+
keybindingMatches: keybindingMatches.keybindingMatches || undefined,
|
|
147
|
+
commandIdMatches: keybindingMatches.commandIdMatches || undefined,
|
|
148
|
+
sourceMatches: keybindingMatches.sourceMatches || undefined,
|
|
149
|
+
whenMatches: keybindingMatches.whenMatches || undefined,
|
|
150
|
+
extensionIdMatches: keybindingMatches.extensionIdMatches || undefined,
|
|
151
|
+
extensionLabelMatches: keybindingMatches.extensionLabelMatches || undefined
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
splitKeybindingWords(wordsSeparatedBySpaces) {
|
|
158
|
+
const result = [];
|
|
159
|
+
for (const word of wordsSeparatedBySpaces) {
|
|
160
|
+
result.push(...coalesce(word.split('+')));
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
async resolve(actionLabels = ( (new Map()))) {
|
|
165
|
+
const extensions = ( (new ExtensionIdentifierMap()));
|
|
166
|
+
for (const extension of this.extensionService.extensions) {
|
|
167
|
+
extensions.set(extension.identifier, extension);
|
|
168
|
+
}
|
|
169
|
+
this._keybindingItemsSortedByPrecedence = [];
|
|
170
|
+
const boundCommands = ( (new Map()));
|
|
171
|
+
for (const keybinding of this.keybindingsService.getKeybindings()) {
|
|
172
|
+
if (keybinding.command) {
|
|
173
|
+
this._keybindingItemsSortedByPrecedence.push(KeybindingsEditorModel.toKeybindingEntry(keybinding.command, keybinding, actionLabels, extensions));
|
|
174
|
+
boundCommands.set(keybinding.command, true);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const commandsWithDefaultKeybindings = ( (this.keybindingsService.getDefaultKeybindings().map(keybinding => keybinding.command)));
|
|
178
|
+
for (const command of getAllUnboundCommands(boundCommands)) {
|
|
179
|
+
const keybindingItem = ( (new ResolvedKeybindingItem(
|
|
180
|
+
undefined,
|
|
181
|
+
command,
|
|
182
|
+
null,
|
|
183
|
+
undefined,
|
|
184
|
+
commandsWithDefaultKeybindings.indexOf(command) === -1,
|
|
185
|
+
null,
|
|
186
|
+
false
|
|
187
|
+
)));
|
|
188
|
+
this._keybindingItemsSortedByPrecedence.push(KeybindingsEditorModel.toKeybindingEntry(command, keybindingItem, actionLabels, extensions));
|
|
189
|
+
}
|
|
190
|
+
this._keybindingItemsSortedByPrecedence = distinct(this._keybindingItemsSortedByPrecedence, keybindingItem => KeybindingsEditorModel.getId(keybindingItem));
|
|
191
|
+
this._keybindingItems = this._keybindingItemsSortedByPrecedence.slice(0).sort((a, b) => KeybindingsEditorModel.compareKeybindingData(a, b));
|
|
192
|
+
return super.resolve();
|
|
193
|
+
}
|
|
194
|
+
static getId(keybindingItem) {
|
|
195
|
+
return keybindingItem.command + (keybindingItem?.keybinding?.getAriaLabel() ?? '') + keybindingItem.when + (isString(keybindingItem.source) ? keybindingItem.source : keybindingItem.source.identifier.value);
|
|
196
|
+
}
|
|
197
|
+
static compareKeybindingData(a, b) {
|
|
198
|
+
if (a.keybinding && !b.keybinding) {
|
|
199
|
+
return -1;
|
|
200
|
+
}
|
|
201
|
+
if (b.keybinding && !a.keybinding) {
|
|
202
|
+
return 1;
|
|
203
|
+
}
|
|
204
|
+
if (a.commandLabel && !b.commandLabel) {
|
|
205
|
+
return -1;
|
|
206
|
+
}
|
|
207
|
+
if (b.commandLabel && !a.commandLabel) {
|
|
208
|
+
return 1;
|
|
209
|
+
}
|
|
210
|
+
if (a.commandLabel && b.commandLabel) {
|
|
211
|
+
if (a.commandLabel !== b.commandLabel) {
|
|
212
|
+
return a.commandLabel.localeCompare(b.commandLabel);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (a.command === b.command) {
|
|
216
|
+
return a.keybindingItem.isDefault ? 1 : -1;
|
|
217
|
+
}
|
|
218
|
+
return a.command.localeCompare(b.command);
|
|
219
|
+
}
|
|
220
|
+
static toKeybindingEntry(command, keybindingItem, actions, extensions) {
|
|
221
|
+
const menuCommand = MenuRegistry.getCommand(command);
|
|
222
|
+
const editorActionLabel = actions.get(command);
|
|
223
|
+
let source = SOURCE_USER;
|
|
224
|
+
if (keybindingItem.isDefault) {
|
|
225
|
+
const extensionId = keybindingItem.extensionId ?? (keybindingItem.resolvedKeybinding ? undefined : menuCommand?.source?.id);
|
|
226
|
+
source = extensionId ? extensions.get(extensionId) ?? SOURCE_EXTENSION : SOURCE_SYSTEM;
|
|
227
|
+
}
|
|
228
|
+
return {
|
|
229
|
+
keybinding: keybindingItem.resolvedKeybinding,
|
|
230
|
+
keybindingItem,
|
|
231
|
+
command,
|
|
232
|
+
commandLabel: KeybindingsEditorModel.getCommandLabel(menuCommand, editorActionLabel),
|
|
233
|
+
commandDefaultLabel: KeybindingsEditorModel.getCommandDefaultLabel(menuCommand),
|
|
234
|
+
when: keybindingItem.when ? keybindingItem.when.serialize() : '',
|
|
235
|
+
source
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
static getCommandDefaultLabel(menuCommand) {
|
|
239
|
+
if (!Language.isDefaultVariant()) {
|
|
240
|
+
if (menuCommand && menuCommand.title && menuCommand.title.original) {
|
|
241
|
+
const category = menuCommand.category ? menuCommand.category.original : undefined;
|
|
242
|
+
const title = menuCommand.title.original;
|
|
243
|
+
return category ? ( (localize('cat.title', "{0}: {1}", category, title))) : title;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
static getCommandLabel(menuCommand, editorActionLabel) {
|
|
249
|
+
if (menuCommand) {
|
|
250
|
+
const category = menuCommand.category ? typeof menuCommand.category === 'string' ? menuCommand.category : menuCommand.category.value : undefined;
|
|
251
|
+
const title = typeof menuCommand.title === 'string' ? menuCommand.title : menuCommand.title.value;
|
|
252
|
+
return category ? ( (localize('cat.title', "{0}: {1}", category, title))) : title;
|
|
253
|
+
}
|
|
254
|
+
if (editorActionLabel) {
|
|
255
|
+
return editorActionLabel;
|
|
256
|
+
}
|
|
257
|
+
return '';
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
KeybindingsEditorModel = ( (__decorate([
|
|
261
|
+
( (__param(1, IKeybindingService))),
|
|
262
|
+
( (__param(2, IExtensionService)))
|
|
263
|
+
], KeybindingsEditorModel)));
|
|
264
|
+
class KeybindingItemMatches {
|
|
265
|
+
constructor(modifierLabels, keybindingItem, searchValue, words, keybindingWords, completeMatch) {
|
|
266
|
+
this.modifierLabels = modifierLabels;
|
|
267
|
+
this.commandIdMatches = null;
|
|
268
|
+
this.commandLabelMatches = null;
|
|
269
|
+
this.commandDefaultLabelMatches = null;
|
|
270
|
+
this.sourceMatches = null;
|
|
271
|
+
this.whenMatches = null;
|
|
272
|
+
this.keybindingMatches = null;
|
|
273
|
+
this.extensionIdMatches = null;
|
|
274
|
+
this.extensionLabelMatches = null;
|
|
275
|
+
if (!completeMatch) {
|
|
276
|
+
this.commandIdMatches = this.matches(searchValue, keybindingItem.command, or(matchesWords, matchesCamelCase), words);
|
|
277
|
+
this.commandLabelMatches = keybindingItem.commandLabel ? this.matches(searchValue, keybindingItem.commandLabel, (word, wordToMatchAgainst) => matchesWords(word, keybindingItem.commandLabel, true), words) : null;
|
|
278
|
+
this.commandDefaultLabelMatches = keybindingItem.commandDefaultLabel ? this.matches(searchValue, keybindingItem.commandDefaultLabel, (word, wordToMatchAgainst) => matchesWords(word, keybindingItem.commandDefaultLabel, true), words) : null;
|
|
279
|
+
this.whenMatches = keybindingItem.when ? this.matches(null, keybindingItem.when, or(matchesWords, matchesCamelCase), words) : null;
|
|
280
|
+
if (isString(keybindingItem.source)) {
|
|
281
|
+
this.sourceMatches = this.matches(searchValue, keybindingItem.source, (word, wordToMatchAgainst) => matchesWords(word, keybindingItem.source, true), words);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
this.extensionLabelMatches = keybindingItem.source.displayName ? this.matches(searchValue, keybindingItem.source.displayName, (word, wordToMatchAgainst) => matchesWords(word, keybindingItem.commandLabel, true), words) : null;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
this.keybindingMatches = keybindingItem.keybinding ? this.matchesKeybinding(keybindingItem.keybinding, searchValue, keybindingWords, completeMatch) : null;
|
|
288
|
+
}
|
|
289
|
+
matches(searchValue, wordToMatchAgainst, wordMatchesFilter, words) {
|
|
290
|
+
let matches = searchValue ? wordFilter(searchValue, wordToMatchAgainst) : null;
|
|
291
|
+
if (!matches) {
|
|
292
|
+
matches = this.matchesWords(words, wordToMatchAgainst, wordMatchesFilter);
|
|
293
|
+
}
|
|
294
|
+
if (matches) {
|
|
295
|
+
matches = this.filterAndSort(matches);
|
|
296
|
+
}
|
|
297
|
+
return matches;
|
|
298
|
+
}
|
|
299
|
+
matchesWords(words, wordToMatchAgainst, wordMatchesFilter) {
|
|
300
|
+
let matches = [];
|
|
301
|
+
for (const word of words) {
|
|
302
|
+
const wordMatches = wordMatchesFilter(word, wordToMatchAgainst);
|
|
303
|
+
if (wordMatches) {
|
|
304
|
+
matches = [...(matches || []), ...wordMatches];
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
matches = null;
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return matches;
|
|
312
|
+
}
|
|
313
|
+
filterAndSort(matches) {
|
|
314
|
+
return distinct(matches, (a => a.start + '.' + a.end)).filter(match => !matches.some(m => !(m.start === match.start && m.end === match.end) && (m.start <= match.start && m.end >= match.end))).sort((a, b) => a.start - b.start);
|
|
315
|
+
}
|
|
316
|
+
matchesKeybinding(keybinding, searchValue, words, completeMatch) {
|
|
317
|
+
const [firstPart, chordPart] = keybinding.getChords();
|
|
318
|
+
const userSettingsLabel = keybinding.getUserSettingsLabel();
|
|
319
|
+
const ariaLabel = keybinding.getAriaLabel();
|
|
320
|
+
const label = keybinding.getLabel();
|
|
321
|
+
if ((userSettingsLabel && compareIgnoreCase(searchValue, userSettingsLabel) === 0)
|
|
322
|
+
|| (ariaLabel && compareIgnoreCase(searchValue, ariaLabel) === 0)
|
|
323
|
+
|| (label && compareIgnoreCase(searchValue, label) === 0)) {
|
|
324
|
+
return {
|
|
325
|
+
firstPart: this.createCompleteMatch(firstPart),
|
|
326
|
+
chordPart: this.createCompleteMatch(chordPart)
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
const firstPartMatch = {};
|
|
330
|
+
let chordPartMatch = {};
|
|
331
|
+
const matchedWords = [];
|
|
332
|
+
const firstPartMatchedWords = [];
|
|
333
|
+
let chordPartMatchedWords = [];
|
|
334
|
+
let matchFirstPart = true;
|
|
335
|
+
for (let index = 0; index < words.length; index++) {
|
|
336
|
+
const word = words[index];
|
|
337
|
+
let firstPartMatched = false;
|
|
338
|
+
let chordPartMatched = false;
|
|
339
|
+
matchFirstPart = matchFirstPart && !firstPartMatch.keyCode;
|
|
340
|
+
let matchChordPart = !chordPartMatch.keyCode;
|
|
341
|
+
if (matchFirstPart) {
|
|
342
|
+
firstPartMatched = this.matchPart(firstPart, firstPartMatch, word, completeMatch);
|
|
343
|
+
if (firstPartMatch.keyCode) {
|
|
344
|
+
for (const cordPartMatchedWordIndex of chordPartMatchedWords) {
|
|
345
|
+
if (firstPartMatchedWords.indexOf(cordPartMatchedWordIndex) === -1) {
|
|
346
|
+
matchedWords.splice(matchedWords.indexOf(cordPartMatchedWordIndex), 1);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
chordPartMatch = {};
|
|
350
|
+
chordPartMatchedWords = [];
|
|
351
|
+
matchChordPart = false;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
if (matchChordPart) {
|
|
355
|
+
chordPartMatched = this.matchPart(chordPart, chordPartMatch, word, completeMatch);
|
|
356
|
+
}
|
|
357
|
+
if (firstPartMatched) {
|
|
358
|
+
firstPartMatchedWords.push(index);
|
|
359
|
+
}
|
|
360
|
+
if (chordPartMatched) {
|
|
361
|
+
chordPartMatchedWords.push(index);
|
|
362
|
+
}
|
|
363
|
+
if (firstPartMatched || chordPartMatched) {
|
|
364
|
+
matchedWords.push(index);
|
|
365
|
+
}
|
|
366
|
+
matchFirstPart = matchFirstPart && this.isModifier(word);
|
|
367
|
+
}
|
|
368
|
+
if (matchedWords.length !== words.length) {
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
if (completeMatch) {
|
|
372
|
+
if (!this.isCompleteMatch(firstPart, firstPartMatch)) {
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
if (!isEmptyObject(chordPartMatch) && !this.isCompleteMatch(chordPart, chordPartMatch)) {
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return this.hasAnyMatch(firstPartMatch) || this.hasAnyMatch(chordPartMatch) ? { firstPart: firstPartMatch, chordPart: chordPartMatch } : null;
|
|
380
|
+
}
|
|
381
|
+
matchPart(chord, match, word, completeMatch) {
|
|
382
|
+
let matched = false;
|
|
383
|
+
if (this.matchesMetaModifier(chord, word)) {
|
|
384
|
+
matched = true;
|
|
385
|
+
match.metaKey = true;
|
|
386
|
+
}
|
|
387
|
+
if (this.matchesCtrlModifier(chord, word)) {
|
|
388
|
+
matched = true;
|
|
389
|
+
match.ctrlKey = true;
|
|
390
|
+
}
|
|
391
|
+
if (this.matchesShiftModifier(chord, word)) {
|
|
392
|
+
matched = true;
|
|
393
|
+
match.shiftKey = true;
|
|
394
|
+
}
|
|
395
|
+
if (this.matchesAltModifier(chord, word)) {
|
|
396
|
+
matched = true;
|
|
397
|
+
match.altKey = true;
|
|
398
|
+
}
|
|
399
|
+
if (this.matchesKeyCode(chord, word, completeMatch)) {
|
|
400
|
+
match.keyCode = true;
|
|
401
|
+
matched = true;
|
|
402
|
+
}
|
|
403
|
+
return matched;
|
|
404
|
+
}
|
|
405
|
+
matchesKeyCode(chord, word, completeMatch) {
|
|
406
|
+
if (!chord) {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
const ariaLabel = chord.keyAriaLabel || '';
|
|
410
|
+
if (completeMatch || ariaLabel.length === 1 || word.length === 1) {
|
|
411
|
+
if (compareIgnoreCase(ariaLabel, word) === 0) {
|
|
412
|
+
return true;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
if (matchesContiguousSubString(word, ariaLabel)) {
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
matchesMetaModifier(chord, word) {
|
|
423
|
+
if (!chord) {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
if (!chord.metaKey) {
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
return this.wordMatchesMetaModifier(word);
|
|
430
|
+
}
|
|
431
|
+
matchesCtrlModifier(chord, word) {
|
|
432
|
+
if (!chord) {
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
if (!chord.ctrlKey) {
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
return this.wordMatchesCtrlModifier(word);
|
|
439
|
+
}
|
|
440
|
+
matchesShiftModifier(chord, word) {
|
|
441
|
+
if (!chord) {
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
if (!chord.shiftKey) {
|
|
445
|
+
return false;
|
|
446
|
+
}
|
|
447
|
+
return this.wordMatchesShiftModifier(word);
|
|
448
|
+
}
|
|
449
|
+
matchesAltModifier(chord, word) {
|
|
450
|
+
if (!chord) {
|
|
451
|
+
return false;
|
|
452
|
+
}
|
|
453
|
+
if (!chord.altKey) {
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
456
|
+
return this.wordMatchesAltModifier(word);
|
|
457
|
+
}
|
|
458
|
+
hasAnyMatch(keybindingMatch) {
|
|
459
|
+
return !!keybindingMatch.altKey ||
|
|
460
|
+
!!keybindingMatch.ctrlKey ||
|
|
461
|
+
!!keybindingMatch.metaKey ||
|
|
462
|
+
!!keybindingMatch.shiftKey ||
|
|
463
|
+
!!keybindingMatch.keyCode;
|
|
464
|
+
}
|
|
465
|
+
isCompleteMatch(chord, match) {
|
|
466
|
+
if (!chord) {
|
|
467
|
+
return true;
|
|
468
|
+
}
|
|
469
|
+
if (!match.keyCode) {
|
|
470
|
+
return false;
|
|
471
|
+
}
|
|
472
|
+
if (chord.metaKey && !match.metaKey) {
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
if (chord.altKey && !match.altKey) {
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
478
|
+
if (chord.ctrlKey && !match.ctrlKey) {
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
if (chord.shiftKey && !match.shiftKey) {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
return true;
|
|
485
|
+
}
|
|
486
|
+
createCompleteMatch(chord) {
|
|
487
|
+
const match = {};
|
|
488
|
+
if (chord) {
|
|
489
|
+
match.keyCode = true;
|
|
490
|
+
if (chord.metaKey) {
|
|
491
|
+
match.metaKey = true;
|
|
492
|
+
}
|
|
493
|
+
if (chord.altKey) {
|
|
494
|
+
match.altKey = true;
|
|
495
|
+
}
|
|
496
|
+
if (chord.ctrlKey) {
|
|
497
|
+
match.ctrlKey = true;
|
|
498
|
+
}
|
|
499
|
+
if (chord.shiftKey) {
|
|
500
|
+
match.shiftKey = true;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
return match;
|
|
504
|
+
}
|
|
505
|
+
isModifier(word) {
|
|
506
|
+
if (this.wordMatchesAltModifier(word)) {
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
509
|
+
if (this.wordMatchesCtrlModifier(word)) {
|
|
510
|
+
return true;
|
|
511
|
+
}
|
|
512
|
+
if (this.wordMatchesMetaModifier(word)) {
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
515
|
+
if (this.wordMatchesShiftModifier(word)) {
|
|
516
|
+
return true;
|
|
517
|
+
}
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
wordMatchesAltModifier(word) {
|
|
521
|
+
if (equalsIgnoreCase(this.modifierLabels.ui.altKey, word)) {
|
|
522
|
+
return true;
|
|
523
|
+
}
|
|
524
|
+
if (equalsIgnoreCase(this.modifierLabels.aria.altKey, word)) {
|
|
525
|
+
return true;
|
|
526
|
+
}
|
|
527
|
+
if (equalsIgnoreCase(this.modifierLabels.user.altKey, word)) {
|
|
528
|
+
return true;
|
|
529
|
+
}
|
|
530
|
+
if (equalsIgnoreCase(( (localize('option', "option"))), word)) {
|
|
531
|
+
return true;
|
|
532
|
+
}
|
|
533
|
+
return false;
|
|
534
|
+
}
|
|
535
|
+
wordMatchesCtrlModifier(word) {
|
|
536
|
+
if (equalsIgnoreCase(this.modifierLabels.ui.ctrlKey, word)) {
|
|
537
|
+
return true;
|
|
538
|
+
}
|
|
539
|
+
if (equalsIgnoreCase(this.modifierLabels.aria.ctrlKey, word)) {
|
|
540
|
+
return true;
|
|
541
|
+
}
|
|
542
|
+
if (equalsIgnoreCase(this.modifierLabels.user.ctrlKey, word)) {
|
|
543
|
+
return true;
|
|
544
|
+
}
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
wordMatchesMetaModifier(word) {
|
|
548
|
+
if (equalsIgnoreCase(this.modifierLabels.ui.metaKey, word)) {
|
|
549
|
+
return true;
|
|
550
|
+
}
|
|
551
|
+
if (equalsIgnoreCase(this.modifierLabels.aria.metaKey, word)) {
|
|
552
|
+
return true;
|
|
553
|
+
}
|
|
554
|
+
if (equalsIgnoreCase(this.modifierLabels.user.metaKey, word)) {
|
|
555
|
+
return true;
|
|
556
|
+
}
|
|
557
|
+
if (equalsIgnoreCase(( (localize('meta', "meta"))), word)) {
|
|
558
|
+
return true;
|
|
559
|
+
}
|
|
560
|
+
return false;
|
|
561
|
+
}
|
|
562
|
+
wordMatchesShiftModifier(word) {
|
|
563
|
+
if (equalsIgnoreCase(this.modifierLabels.ui.shiftKey, word)) {
|
|
564
|
+
return true;
|
|
565
|
+
}
|
|
566
|
+
if (equalsIgnoreCase(this.modifierLabels.aria.shiftKey, word)) {
|
|
567
|
+
return true;
|
|
568
|
+
}
|
|
569
|
+
if (equalsIgnoreCase(this.modifierLabels.user.shiftKey, word)) {
|
|
570
|
+
return true;
|
|
571
|
+
}
|
|
572
|
+
return false;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
let KeybindingsEditorInput = class KeybindingsEditorInput extends EditorInput {
|
|
576
|
+
constructor(instantiationService) {
|
|
577
|
+
super();
|
|
578
|
+
this.searchOptions = null;
|
|
579
|
+
this.resource = undefined;
|
|
580
|
+
this.keybindingsModel = instantiationService.createInstance(KeybindingsEditorModel, OS);
|
|
581
|
+
}
|
|
582
|
+
get typeId() {
|
|
583
|
+
return KeybindingsEditorInput.ID;
|
|
584
|
+
}
|
|
585
|
+
getName() {
|
|
586
|
+
return (
|
|
587
|
+
(localize('keybindingsInputName', "Keyboard Shortcuts"))
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
async resolve() {
|
|
591
|
+
return this.keybindingsModel;
|
|
592
|
+
}
|
|
593
|
+
matches(otherInput) {
|
|
594
|
+
return otherInput instanceof KeybindingsEditorInput;
|
|
595
|
+
}
|
|
596
|
+
dispose() {
|
|
597
|
+
this.keybindingsModel.dispose();
|
|
598
|
+
super.dispose();
|
|
599
|
+
}
|
|
600
|
+
};
|
|
601
|
+
KeybindingsEditorInput.ID = 'workbench.input.keybindings';
|
|
602
|
+
KeybindingsEditorInput = ( (__decorate([
|
|
603
|
+
( (__param(0, IInstantiationService)))
|
|
604
|
+
], KeybindingsEditorInput)));
|
|
605
|
+
let SettingsEditor2Input = class SettingsEditor2Input extends EditorInput {
|
|
606
|
+
constructor(_preferencesService) {
|
|
607
|
+
super();
|
|
608
|
+
this.resource = ( (URI.from({
|
|
609
|
+
scheme: Schemas.vscodeSettings,
|
|
610
|
+
path: `settingseditor`
|
|
611
|
+
})));
|
|
612
|
+
this._settingsModel = _preferencesService.createSettings2EditorModel();
|
|
613
|
+
}
|
|
614
|
+
matches(otherInput) {
|
|
615
|
+
return super.matches(otherInput) || otherInput instanceof SettingsEditor2Input;
|
|
616
|
+
}
|
|
617
|
+
get typeId() {
|
|
618
|
+
return SettingsEditor2Input.ID;
|
|
619
|
+
}
|
|
620
|
+
getName() {
|
|
621
|
+
return (
|
|
622
|
+
(localize('settingsEditor2InputName', "Settings"))
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
async resolve() {
|
|
626
|
+
return this._settingsModel;
|
|
627
|
+
}
|
|
628
|
+
dispose() {
|
|
629
|
+
this._settingsModel.dispose();
|
|
630
|
+
super.dispose();
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
SettingsEditor2Input.ID = 'workbench.input.settings2';
|
|
634
|
+
SettingsEditor2Input = ( (__decorate([
|
|
635
|
+
( (__param(0, IPreferencesService)))
|
|
636
|
+
], SettingsEditor2Input)));
|
|
637
|
+
function canBeType(propTypes, ...types) {
|
|
638
|
+
return types.some(t => propTypes.includes(t));
|
|
639
|
+
}
|
|
640
|
+
function isNullOrEmpty(value) {
|
|
641
|
+
return value === '' || isUndefinedOrNull(value);
|
|
642
|
+
}
|
|
643
|
+
function createValidator(prop) {
|
|
644
|
+
const type = Array.isArray(prop.type) ? prop.type : [prop.type];
|
|
645
|
+
const isNullable = canBeType(type, 'null');
|
|
646
|
+
const isNumeric = (canBeType(type, 'number') || canBeType(type, 'integer')) && (type.length === 1 || type.length === 2 && isNullable);
|
|
647
|
+
const numericValidations = getNumericValidators(prop);
|
|
648
|
+
const stringValidations = getStringValidators(prop);
|
|
649
|
+
const arrayValidator = getArrayValidator(prop);
|
|
650
|
+
const objectValidator = getObjectValidator(prop);
|
|
651
|
+
return value => {
|
|
652
|
+
if (isNullable && isNullOrEmpty(value)) {
|
|
653
|
+
return '';
|
|
654
|
+
}
|
|
655
|
+
const errors = [];
|
|
656
|
+
if (arrayValidator) {
|
|
657
|
+
const err = arrayValidator(value);
|
|
658
|
+
if (err) {
|
|
659
|
+
errors.push(err);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
if (objectValidator) {
|
|
663
|
+
const err = objectValidator(value);
|
|
664
|
+
if (err) {
|
|
665
|
+
errors.push(err);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
if (prop.type === 'boolean' && value !== true && value !== false) {
|
|
669
|
+
errors.push(( (localize('validations.booleanIncorrectType', 'Incorrect type. Expected "boolean".'))));
|
|
670
|
+
}
|
|
671
|
+
if (isNumeric) {
|
|
672
|
+
if (isNullOrEmpty(value) || typeof value === 'boolean' || Array.isArray(value) || isNaN(+value)) {
|
|
673
|
+
errors.push(( (localize('validations.expectedNumeric', "Value must be a number."))));
|
|
674
|
+
}
|
|
675
|
+
else {
|
|
676
|
+
errors.push(...( (numericValidations.filter(validator => !validator.isValid(+value)).map(validator => validator.message))));
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
if (prop.type === 'string') {
|
|
680
|
+
if (prop.enum && !isStringArray(prop.enum)) {
|
|
681
|
+
errors.push(( (localize(
|
|
682
|
+
'validations.stringIncorrectEnumOptions',
|
|
683
|
+
'The enum options should be strings, but there is a non-string option. Please file an issue with the extension author.'
|
|
684
|
+
))));
|
|
685
|
+
}
|
|
686
|
+
else if (!isString(value)) {
|
|
687
|
+
errors.push(( (localize('validations.stringIncorrectType', 'Incorrect type. Expected "string".'))));
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
errors.push(...( (stringValidations.filter(validator => !validator.isValid(value)).map(validator => validator.message))));
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
if (errors.length) {
|
|
694
|
+
return prop.errorMessage ? [prop.errorMessage, ...errors].join(' ') : errors.join(' ');
|
|
695
|
+
}
|
|
696
|
+
return '';
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
function getStringValidators(prop) {
|
|
700
|
+
const uriRegex = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
|
|
701
|
+
let patternRegex;
|
|
702
|
+
if (typeof prop.pattern === 'string') {
|
|
703
|
+
patternRegex = ( (new RegExp(prop.pattern)));
|
|
704
|
+
}
|
|
705
|
+
return [
|
|
706
|
+
{
|
|
707
|
+
enabled: prop.maxLength !== undefined,
|
|
708
|
+
isValid: ((value) => value.length <= prop.maxLength),
|
|
709
|
+
message: ( (localize(
|
|
710
|
+
'validations.maxLength',
|
|
711
|
+
"Value must be {0} or fewer characters long.",
|
|
712
|
+
prop.maxLength
|
|
713
|
+
)))
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
enabled: prop.minLength !== undefined,
|
|
717
|
+
isValid: ((value) => value.length >= prop.minLength),
|
|
718
|
+
message: ( (localize(
|
|
719
|
+
'validations.minLength',
|
|
720
|
+
"Value must be {0} or more characters long.",
|
|
721
|
+
prop.minLength
|
|
722
|
+
)))
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
enabled: patternRegex !== undefined,
|
|
726
|
+
isValid: ((value) => patternRegex.test(value)),
|
|
727
|
+
message: prop.patternErrorMessage || ( (localize('validations.regex', "Value must match regex `{0}`.", prop.pattern)))
|
|
728
|
+
},
|
|
729
|
+
{
|
|
730
|
+
enabled: prop.format === 'color-hex',
|
|
731
|
+
isValid: ((value) => Color.Format.CSS.parseHex(value)),
|
|
732
|
+
message: ( (localize(
|
|
733
|
+
'validations.colorFormat',
|
|
734
|
+
"Invalid color format. Use #RGB, #RGBA, #RRGGBB or #RRGGBBAA."
|
|
735
|
+
)))
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
enabled: prop.format === 'uri' || prop.format === 'uri-reference',
|
|
739
|
+
isValid: ((value) => !!value.length),
|
|
740
|
+
message: ( (localize('validations.uriEmpty', "URI expected.")))
|
|
741
|
+
},
|
|
742
|
+
{
|
|
743
|
+
enabled: prop.format === 'uri' || prop.format === 'uri-reference',
|
|
744
|
+
isValid: ((value) => uriRegex.test(value)),
|
|
745
|
+
message: ( (localize('validations.uriMissing', "URI is expected.")))
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
enabled: prop.format === 'uri',
|
|
749
|
+
isValid: ((value) => {
|
|
750
|
+
const matches = value.match(uriRegex);
|
|
751
|
+
return !!(matches && matches[2]);
|
|
752
|
+
}),
|
|
753
|
+
message: ( (localize('validations.uriSchemeMissing', "URI with a scheme is expected.")))
|
|
754
|
+
},
|
|
755
|
+
{
|
|
756
|
+
enabled: prop.enum !== undefined,
|
|
757
|
+
isValid: ((value) => {
|
|
758
|
+
return prop.enum.includes(value);
|
|
759
|
+
}),
|
|
760
|
+
message: ( (localize(
|
|
761
|
+
'validations.invalidStringEnumValue',
|
|
762
|
+
"Value is not accepted. Valid values: {0}.",
|
|
763
|
+
prop.enum ? ( (prop.enum.map(key => `"${key}"`))).join(', ') : '[]'
|
|
764
|
+
)))
|
|
765
|
+
}
|
|
766
|
+
].filter(validation => validation.enabled);
|
|
767
|
+
}
|
|
768
|
+
function getNumericValidators(prop) {
|
|
769
|
+
const type = Array.isArray(prop.type) ? prop.type : [prop.type];
|
|
770
|
+
const isNullable = canBeType(type, 'null');
|
|
771
|
+
const isIntegral = (canBeType(type, 'integer')) && (type.length === 1 || type.length === 2 && isNullable);
|
|
772
|
+
const isNumeric = canBeType(type, 'number', 'integer') && (type.length === 1 || type.length === 2 && isNullable);
|
|
773
|
+
if (!isNumeric) {
|
|
774
|
+
return [];
|
|
775
|
+
}
|
|
776
|
+
let exclusiveMax;
|
|
777
|
+
let exclusiveMin;
|
|
778
|
+
if (typeof prop.exclusiveMaximum === 'boolean') {
|
|
779
|
+
exclusiveMax = prop.exclusiveMaximum ? prop.maximum : undefined;
|
|
780
|
+
}
|
|
781
|
+
else {
|
|
782
|
+
exclusiveMax = prop.exclusiveMaximum;
|
|
783
|
+
}
|
|
784
|
+
if (typeof prop.exclusiveMinimum === 'boolean') {
|
|
785
|
+
exclusiveMin = prop.exclusiveMinimum ? prop.minimum : undefined;
|
|
786
|
+
}
|
|
787
|
+
else {
|
|
788
|
+
exclusiveMin = prop.exclusiveMinimum;
|
|
789
|
+
}
|
|
790
|
+
return [
|
|
791
|
+
{
|
|
792
|
+
enabled: exclusiveMax !== undefined && (prop.maximum === undefined || exclusiveMax <= prop.maximum),
|
|
793
|
+
isValid: ((value) => value < exclusiveMax),
|
|
794
|
+
message: ( (localize(
|
|
795
|
+
'validations.exclusiveMax',
|
|
796
|
+
"Value must be strictly less than {0}.",
|
|
797
|
+
exclusiveMax
|
|
798
|
+
)))
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
enabled: exclusiveMin !== undefined && (prop.minimum === undefined || exclusiveMin >= prop.minimum),
|
|
802
|
+
isValid: ((value) => value > exclusiveMin),
|
|
803
|
+
message: ( (localize(
|
|
804
|
+
'validations.exclusiveMin',
|
|
805
|
+
"Value must be strictly greater than {0}.",
|
|
806
|
+
exclusiveMin
|
|
807
|
+
)))
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
enabled: prop.maximum !== undefined && (exclusiveMax === undefined || exclusiveMax > prop.maximum),
|
|
811
|
+
isValid: ((value) => value <= prop.maximum),
|
|
812
|
+
message: ( (localize(
|
|
813
|
+
'validations.max',
|
|
814
|
+
"Value must be less than or equal to {0}.",
|
|
815
|
+
prop.maximum
|
|
816
|
+
)))
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
enabled: prop.minimum !== undefined && (exclusiveMin === undefined || exclusiveMin < prop.minimum),
|
|
820
|
+
isValid: ((value) => value >= prop.minimum),
|
|
821
|
+
message: ( (localize(
|
|
822
|
+
'validations.min',
|
|
823
|
+
"Value must be greater than or equal to {0}.",
|
|
824
|
+
prop.minimum
|
|
825
|
+
)))
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
enabled: prop.multipleOf !== undefined,
|
|
829
|
+
isValid: ((value) => value % prop.multipleOf === 0),
|
|
830
|
+
message: ( (localize(
|
|
831
|
+
'validations.multipleOf',
|
|
832
|
+
"Value must be a multiple of {0}.",
|
|
833
|
+
prop.multipleOf
|
|
834
|
+
)))
|
|
835
|
+
},
|
|
836
|
+
{
|
|
837
|
+
enabled: isIntegral,
|
|
838
|
+
isValid: ((value) => value % 1 === 0),
|
|
839
|
+
message: ( (localize('validations.expectedInteger', "Value must be an integer.")))
|
|
840
|
+
},
|
|
841
|
+
].filter(validation => validation.enabled);
|
|
842
|
+
}
|
|
843
|
+
function getArrayValidator(prop) {
|
|
844
|
+
if (prop.type === 'array' && prop.items && !Array.isArray(prop.items)) {
|
|
845
|
+
const propItems = prop.items;
|
|
846
|
+
if (propItems && !Array.isArray(propItems.type)) {
|
|
847
|
+
const withQuotes = (s) => `'` + s + `'`;
|
|
848
|
+
return value => {
|
|
849
|
+
if (!value) {
|
|
850
|
+
return null;
|
|
851
|
+
}
|
|
852
|
+
let message = '';
|
|
853
|
+
if (!Array.isArray(value)) {
|
|
854
|
+
message += ( (localize('validations.arrayIncorrectType', 'Incorrect type. Expected an array.')));
|
|
855
|
+
message += '\n';
|
|
856
|
+
return message;
|
|
857
|
+
}
|
|
858
|
+
const arrayValue = value;
|
|
859
|
+
if (prop.uniqueItems) {
|
|
860
|
+
if (( (new Set(arrayValue))).size < arrayValue.length) {
|
|
861
|
+
message += ( (localize('validations.stringArrayUniqueItems', 'Array has duplicate items')));
|
|
862
|
+
message += '\n';
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
if (prop.minItems && arrayValue.length < prop.minItems) {
|
|
866
|
+
message += ( (localize(
|
|
867
|
+
'validations.stringArrayMinItem',
|
|
868
|
+
'Array must have at least {0} items',
|
|
869
|
+
prop.minItems
|
|
870
|
+
)));
|
|
871
|
+
message += '\n';
|
|
872
|
+
}
|
|
873
|
+
if (prop.maxItems && arrayValue.length > prop.maxItems) {
|
|
874
|
+
message += ( (localize(
|
|
875
|
+
'validations.stringArrayMaxItem',
|
|
876
|
+
'Array must have at most {0} items',
|
|
877
|
+
prop.maxItems
|
|
878
|
+
)));
|
|
879
|
+
message += '\n';
|
|
880
|
+
}
|
|
881
|
+
if (propItems.type === 'string') {
|
|
882
|
+
if (!isStringArray(arrayValue)) {
|
|
883
|
+
message += ( (localize(
|
|
884
|
+
'validations.stringArrayIncorrectType',
|
|
885
|
+
'Incorrect type. Expected a string array.'
|
|
886
|
+
)));
|
|
887
|
+
message += '\n';
|
|
888
|
+
return message;
|
|
889
|
+
}
|
|
890
|
+
if (typeof propItems.pattern === 'string') {
|
|
891
|
+
const patternRegex = ( (new RegExp(propItems.pattern)));
|
|
892
|
+
arrayValue.forEach(v => {
|
|
893
|
+
if (!patternRegex.test(v)) {
|
|
894
|
+
message +=
|
|
895
|
+
propItems.patternErrorMessage ||
|
|
896
|
+
( (localize(
|
|
897
|
+
'validations.stringArrayItemPattern',
|
|
898
|
+
'Value {0} must match regex {1}.',
|
|
899
|
+
withQuotes(v),
|
|
900
|
+
withQuotes(propItems.pattern)
|
|
901
|
+
)));
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
const propItemsEnum = propItems.enum;
|
|
906
|
+
if (propItemsEnum) {
|
|
907
|
+
arrayValue.forEach(v => {
|
|
908
|
+
if (propItemsEnum.indexOf(v) === -1) {
|
|
909
|
+
message += ( (localize(
|
|
910
|
+
'validations.stringArrayItemEnum',
|
|
911
|
+
'Value {0} is not one of {1}',
|
|
912
|
+
withQuotes(v),
|
|
913
|
+
'[' + ( (propItemsEnum.map(withQuotes))).join(', ') + ']'
|
|
914
|
+
)));
|
|
915
|
+
message += '\n';
|
|
916
|
+
}
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
else if (propItems.type === 'integer' || propItems.type === 'number') {
|
|
921
|
+
arrayValue.forEach(v => {
|
|
922
|
+
const errorMessage = getErrorsForSchema(propItems, v);
|
|
923
|
+
if (errorMessage) {
|
|
924
|
+
message += `${v}: ${errorMessage}\n`;
|
|
925
|
+
}
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
return message;
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
return null;
|
|
933
|
+
}
|
|
934
|
+
function getObjectValidator(prop) {
|
|
935
|
+
if (prop.type === 'object') {
|
|
936
|
+
const { properties, patternProperties, additionalProperties } = prop;
|
|
937
|
+
return value => {
|
|
938
|
+
if (!value) {
|
|
939
|
+
return null;
|
|
940
|
+
}
|
|
941
|
+
const errors = [];
|
|
942
|
+
if (!isObject(value)) {
|
|
943
|
+
errors.push(( (localize('validations.objectIncorrectType', 'Incorrect type. Expected an object.'))));
|
|
944
|
+
}
|
|
945
|
+
else {
|
|
946
|
+
( (Object.keys(value))).forEach((key) => {
|
|
947
|
+
const data = value[key];
|
|
948
|
+
if (properties && key in properties) {
|
|
949
|
+
const errorMessage = getErrorsForSchema(properties[key], data);
|
|
950
|
+
if (errorMessage) {
|
|
951
|
+
errors.push(`${key}: ${errorMessage}\n`);
|
|
952
|
+
}
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
if (patternProperties) {
|
|
956
|
+
for (const pattern in patternProperties) {
|
|
957
|
+
if (RegExp(pattern).test(key)) {
|
|
958
|
+
const errorMessage = getErrorsForSchema(patternProperties[pattern], data);
|
|
959
|
+
if (errorMessage) {
|
|
960
|
+
errors.push(`${key}: ${errorMessage}\n`);
|
|
961
|
+
}
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
if (additionalProperties === false) {
|
|
967
|
+
errors.push(( (localize('validations.objectPattern', 'Property {0} is not allowed.\n', key))));
|
|
968
|
+
}
|
|
969
|
+
else if (typeof additionalProperties === 'object') {
|
|
970
|
+
const errorMessage = getErrorsForSchema(additionalProperties, data);
|
|
971
|
+
if (errorMessage) {
|
|
972
|
+
errors.push(`${key}: ${errorMessage}\n`);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
});
|
|
976
|
+
}
|
|
977
|
+
if (errors.length) {
|
|
978
|
+
return prop.errorMessage ? [prop.errorMessage, ...errors].join(' ') : errors.join(' ');
|
|
979
|
+
}
|
|
980
|
+
return '';
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
return null;
|
|
984
|
+
}
|
|
985
|
+
function getErrorsForSchema(propertySchema, data) {
|
|
986
|
+
const validator = createValidator(propertySchema);
|
|
987
|
+
const errorMessage = validator(data);
|
|
988
|
+
return errorMessage;
|
|
989
|
+
}
|
|
990
|
+
const nullRange = { startLineNumber: -1, startColumn: -1, endLineNumber: -1, endColumn: -1 };
|
|
991
|
+
function isNullRange(range) { return range.startLineNumber === -1 && range.startColumn === -1 && range.endLineNumber === -1 && range.endColumn === -1; }
|
|
992
|
+
class AbstractSettingsModel extends EditorModel {
|
|
993
|
+
constructor() {
|
|
994
|
+
super(...arguments);
|
|
995
|
+
this._currentResultGroups = ( (new Map()));
|
|
996
|
+
}
|
|
997
|
+
updateResultGroup(id, resultGroup) {
|
|
998
|
+
if (resultGroup) {
|
|
999
|
+
this._currentResultGroups.set(id, resultGroup);
|
|
1000
|
+
}
|
|
1001
|
+
else {
|
|
1002
|
+
this._currentResultGroups.delete(id);
|
|
1003
|
+
}
|
|
1004
|
+
this.removeDuplicateResults();
|
|
1005
|
+
return this.update();
|
|
1006
|
+
}
|
|
1007
|
+
removeDuplicateResults() {
|
|
1008
|
+
const settingKeys = ( (new Set()));
|
|
1009
|
+
[...( (this._currentResultGroups.keys()))]
|
|
1010
|
+
.sort((a, b) => this._currentResultGroups.get(a).order - this._currentResultGroups.get(b).order)
|
|
1011
|
+
.forEach(groupId => {
|
|
1012
|
+
const group = this._currentResultGroups.get(groupId);
|
|
1013
|
+
group.result.filterMatches = group.result.filterMatches.filter(s => !settingKeys.has(s.setting.key));
|
|
1014
|
+
group.result.filterMatches.forEach(s => settingKeys.add(s.setting.key));
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
compareTwoNullableNumbers(a, b) {
|
|
1018
|
+
const aOrMax = a ?? Number.MAX_SAFE_INTEGER;
|
|
1019
|
+
const bOrMax = b ?? Number.MAX_SAFE_INTEGER;
|
|
1020
|
+
if (aOrMax < bOrMax) {
|
|
1021
|
+
return -1;
|
|
1022
|
+
}
|
|
1023
|
+
else if (aOrMax > bOrMax) {
|
|
1024
|
+
return 1;
|
|
1025
|
+
}
|
|
1026
|
+
else {
|
|
1027
|
+
return 0;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
filterSettings(filter, groupFilter, settingMatcher) {
|
|
1031
|
+
const allGroups = this.filterGroups;
|
|
1032
|
+
const filterMatches = [];
|
|
1033
|
+
for (const group of allGroups) {
|
|
1034
|
+
const groupMatched = groupFilter(group);
|
|
1035
|
+
for (const section of group.sections) {
|
|
1036
|
+
for (const setting of section.settings) {
|
|
1037
|
+
const settingMatchResult = settingMatcher(setting, group);
|
|
1038
|
+
if (groupMatched || settingMatchResult) {
|
|
1039
|
+
filterMatches.push({
|
|
1040
|
+
setting,
|
|
1041
|
+
matches: settingMatchResult && settingMatchResult.matches,
|
|
1042
|
+
matchType: settingMatchResult?.matchType ?? SettingMatchType.None,
|
|
1043
|
+
score: settingMatchResult?.score ?? 0
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
filterMatches.sort((a, b) => {
|
|
1050
|
+
if (a.matchType !== b.matchType) {
|
|
1051
|
+
return b.matchType - a.matchType;
|
|
1052
|
+
}
|
|
1053
|
+
else {
|
|
1054
|
+
if (a.setting.extensionInfo && b.setting.extensionInfo
|
|
1055
|
+
&& a.setting.extensionInfo.id === b.setting.extensionInfo.id) {
|
|
1056
|
+
if (a.setting.categoryLabel !== b.setting.categoryLabel
|
|
1057
|
+
&& (a.setting.categoryOrder !== undefined || b.setting.categoryOrder !== undefined)
|
|
1058
|
+
&& a.setting.categoryOrder !== b.setting.categoryOrder) {
|
|
1059
|
+
return this.compareTwoNullableNumbers(a.setting.categoryOrder, b.setting.categoryOrder);
|
|
1060
|
+
}
|
|
1061
|
+
else if (a.setting.categoryLabel === b.setting.categoryLabel
|
|
1062
|
+
&& (a.setting.order !== undefined || b.setting.order !== undefined)
|
|
1063
|
+
&& a.setting.order !== b.setting.order) {
|
|
1064
|
+
return this.compareTwoNullableNumbers(a.setting.order, b.setting.order);
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
return b.score - a.score;
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
return filterMatches;
|
|
1071
|
+
}
|
|
1072
|
+
getPreference(key) {
|
|
1073
|
+
for (const group of this.settingsGroups) {
|
|
1074
|
+
for (const section of group.sections) {
|
|
1075
|
+
for (const setting of section.settings) {
|
|
1076
|
+
if (key === setting.key) {
|
|
1077
|
+
return setting;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
return undefined;
|
|
1083
|
+
}
|
|
1084
|
+
collectMetadata(groups) {
|
|
1085
|
+
const metadata = Object.create(null);
|
|
1086
|
+
let hasMetadata = false;
|
|
1087
|
+
groups.forEach(g => {
|
|
1088
|
+
if (g.result.metadata) {
|
|
1089
|
+
metadata[g.id] = g.result.metadata;
|
|
1090
|
+
hasMetadata = true;
|
|
1091
|
+
}
|
|
1092
|
+
});
|
|
1093
|
+
return hasMetadata ? metadata : null;
|
|
1094
|
+
}
|
|
1095
|
+
get filterGroups() {
|
|
1096
|
+
return this.settingsGroups;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
class SettingsEditorModel extends AbstractSettingsModel {
|
|
1100
|
+
constructor(reference, _configurationTarget) {
|
|
1101
|
+
super();
|
|
1102
|
+
this._configurationTarget = _configurationTarget;
|
|
1103
|
+
this._onDidChangeGroups = this._register(( (new Emitter())));
|
|
1104
|
+
this.onDidChangeGroups = this._onDidChangeGroups.event;
|
|
1105
|
+
this.settingsModel = reference.object.textEditorModel;
|
|
1106
|
+
this._register(this.onWillDispose(() => reference.dispose()));
|
|
1107
|
+
this._register(this.settingsModel.onDidChangeContent(() => {
|
|
1108
|
+
this._settingsGroups = undefined;
|
|
1109
|
+
this._onDidChangeGroups.fire();
|
|
1110
|
+
}));
|
|
1111
|
+
}
|
|
1112
|
+
get uri() {
|
|
1113
|
+
return this.settingsModel.uri;
|
|
1114
|
+
}
|
|
1115
|
+
get configurationTarget() {
|
|
1116
|
+
return this._configurationTarget;
|
|
1117
|
+
}
|
|
1118
|
+
get settingsGroups() {
|
|
1119
|
+
if (!this._settingsGroups) {
|
|
1120
|
+
this.parse();
|
|
1121
|
+
}
|
|
1122
|
+
return this._settingsGroups;
|
|
1123
|
+
}
|
|
1124
|
+
get content() {
|
|
1125
|
+
return this.settingsModel.getValue();
|
|
1126
|
+
}
|
|
1127
|
+
findValueMatches(filter, setting) {
|
|
1128
|
+
return (
|
|
1129
|
+
(this.settingsModel.findMatches(filter, setting.valueRange, false, false, null, false).map(match => match.range))
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1132
|
+
isSettingsProperty(property, previousParents) {
|
|
1133
|
+
return previousParents.length === 0;
|
|
1134
|
+
}
|
|
1135
|
+
parse() {
|
|
1136
|
+
this._settingsGroups = parse(this.settingsModel, (property, previousParents) => this.isSettingsProperty(property, previousParents));
|
|
1137
|
+
}
|
|
1138
|
+
update() {
|
|
1139
|
+
const resultGroups = [...( (this._currentResultGroups.values()))];
|
|
1140
|
+
if (!resultGroups.length) {
|
|
1141
|
+
return undefined;
|
|
1142
|
+
}
|
|
1143
|
+
const filteredSettings = [];
|
|
1144
|
+
const matches = [];
|
|
1145
|
+
resultGroups.forEach(group => {
|
|
1146
|
+
group.result.filterMatches.forEach(filterMatch => {
|
|
1147
|
+
filteredSettings.push(filterMatch.setting);
|
|
1148
|
+
if (filterMatch.matches) {
|
|
1149
|
+
matches.push(...filterMatch.matches);
|
|
1150
|
+
}
|
|
1151
|
+
});
|
|
1152
|
+
});
|
|
1153
|
+
let filteredGroup;
|
|
1154
|
+
const modelGroup = this.settingsGroups[0];
|
|
1155
|
+
if (modelGroup) {
|
|
1156
|
+
filteredGroup = {
|
|
1157
|
+
id: modelGroup.id,
|
|
1158
|
+
range: modelGroup.range,
|
|
1159
|
+
sections: [{
|
|
1160
|
+
settings: filteredSettings
|
|
1161
|
+
}],
|
|
1162
|
+
title: modelGroup.title,
|
|
1163
|
+
titleRange: modelGroup.titleRange,
|
|
1164
|
+
order: modelGroup.order,
|
|
1165
|
+
extensionInfo: modelGroup.extensionInfo
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
const metadata = this.collectMetadata(resultGroups);
|
|
1169
|
+
return {
|
|
1170
|
+
allGroups: this.settingsGroups,
|
|
1171
|
+
filteredGroups: filteredGroup ? [filteredGroup] : [],
|
|
1172
|
+
matches,
|
|
1173
|
+
metadata
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
let Settings2EditorModel = class Settings2EditorModel extends AbstractSettingsModel {
|
|
1178
|
+
constructor(_defaultSettings, configurationService) {
|
|
1179
|
+
super();
|
|
1180
|
+
this._defaultSettings = _defaultSettings;
|
|
1181
|
+
this._onDidChangeGroups = this._register(( (new Emitter())));
|
|
1182
|
+
this.onDidChangeGroups = this._onDidChangeGroups.event;
|
|
1183
|
+
this.dirty = false;
|
|
1184
|
+
this._register(configurationService.onDidChangeConfiguration(e => {
|
|
1185
|
+
if (e.source === 7 ) {
|
|
1186
|
+
this.dirty = true;
|
|
1187
|
+
this._onDidChangeGroups.fire();
|
|
1188
|
+
}
|
|
1189
|
+
}));
|
|
1190
|
+
this._register(( (Registry.as(Extensions.Configuration))).onDidSchemaChange(e => {
|
|
1191
|
+
this.dirty = true;
|
|
1192
|
+
this._onDidChangeGroups.fire();
|
|
1193
|
+
}));
|
|
1194
|
+
}
|
|
1195
|
+
get filterGroups() {
|
|
1196
|
+
return this.settingsGroups.slice(1);
|
|
1197
|
+
}
|
|
1198
|
+
get settingsGroups() {
|
|
1199
|
+
const groups = this._defaultSettings.getSettingsGroups(this.dirty);
|
|
1200
|
+
this.dirty = false;
|
|
1201
|
+
return groups;
|
|
1202
|
+
}
|
|
1203
|
+
findValueMatches(filter, setting) {
|
|
1204
|
+
return [];
|
|
1205
|
+
}
|
|
1206
|
+
update() {
|
|
1207
|
+
throw new Error('Not supported');
|
|
1208
|
+
}
|
|
1209
|
+
};
|
|
1210
|
+
Settings2EditorModel = ( (__decorate([
|
|
1211
|
+
( (__param(1, IConfigurationService)))
|
|
1212
|
+
], Settings2EditorModel)));
|
|
1213
|
+
function parse(model, isSettingsProperty) {
|
|
1214
|
+
const settings = [];
|
|
1215
|
+
let overrideSetting = null;
|
|
1216
|
+
let currentProperty = null;
|
|
1217
|
+
let currentParent = [];
|
|
1218
|
+
const previousParents = [];
|
|
1219
|
+
let settingsPropertyIndex = -1;
|
|
1220
|
+
const range = {
|
|
1221
|
+
startLineNumber: 0,
|
|
1222
|
+
startColumn: 0,
|
|
1223
|
+
endLineNumber: 0,
|
|
1224
|
+
endColumn: 0
|
|
1225
|
+
};
|
|
1226
|
+
function onValue(value, offset, length) {
|
|
1227
|
+
if (Array.isArray(currentParent)) {
|
|
1228
|
+
currentParent.push(value);
|
|
1229
|
+
}
|
|
1230
|
+
else if (currentProperty) {
|
|
1231
|
+
currentParent[currentProperty] = value;
|
|
1232
|
+
}
|
|
1233
|
+
if (previousParents.length === settingsPropertyIndex + 1 || (previousParents.length === settingsPropertyIndex + 2 && overrideSetting !== null)) {
|
|
1234
|
+
const setting = previousParents.length === settingsPropertyIndex + 1 ? settings[settings.length - 1] : overrideSetting.overrides[overrideSetting.overrides.length - 1];
|
|
1235
|
+
if (setting) {
|
|
1236
|
+
const valueStartPosition = model.getPositionAt(offset);
|
|
1237
|
+
const valueEndPosition = model.getPositionAt(offset + length);
|
|
1238
|
+
setting.value = value;
|
|
1239
|
+
setting.valueRange = {
|
|
1240
|
+
startLineNumber: valueStartPosition.lineNumber,
|
|
1241
|
+
startColumn: valueStartPosition.column,
|
|
1242
|
+
endLineNumber: valueEndPosition.lineNumber,
|
|
1243
|
+
endColumn: valueEndPosition.column
|
|
1244
|
+
};
|
|
1245
|
+
setting.range = Object.assign(setting.range, {
|
|
1246
|
+
endLineNumber: valueEndPosition.lineNumber,
|
|
1247
|
+
endColumn: valueEndPosition.column
|
|
1248
|
+
});
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
const visitor = {
|
|
1253
|
+
onObjectBegin: (offset, length) => {
|
|
1254
|
+
if (isSettingsProperty(currentProperty, previousParents)) {
|
|
1255
|
+
settingsPropertyIndex = previousParents.length;
|
|
1256
|
+
const position = model.getPositionAt(offset);
|
|
1257
|
+
range.startLineNumber = position.lineNumber;
|
|
1258
|
+
range.startColumn = position.column;
|
|
1259
|
+
}
|
|
1260
|
+
const object = {};
|
|
1261
|
+
onValue(object, offset, length);
|
|
1262
|
+
currentParent = object;
|
|
1263
|
+
currentProperty = null;
|
|
1264
|
+
previousParents.push(currentParent);
|
|
1265
|
+
},
|
|
1266
|
+
onObjectProperty: (name, offset, length) => {
|
|
1267
|
+
currentProperty = name;
|
|
1268
|
+
if (previousParents.length === settingsPropertyIndex + 1 || (previousParents.length === settingsPropertyIndex + 2 && overrideSetting !== null)) {
|
|
1269
|
+
const settingStartPosition = model.getPositionAt(offset);
|
|
1270
|
+
const setting = {
|
|
1271
|
+
description: [],
|
|
1272
|
+
descriptionIsMarkdown: false,
|
|
1273
|
+
key: name,
|
|
1274
|
+
keyRange: {
|
|
1275
|
+
startLineNumber: settingStartPosition.lineNumber,
|
|
1276
|
+
startColumn: settingStartPosition.column + 1,
|
|
1277
|
+
endLineNumber: settingStartPosition.lineNumber,
|
|
1278
|
+
endColumn: settingStartPosition.column + length
|
|
1279
|
+
},
|
|
1280
|
+
range: {
|
|
1281
|
+
startLineNumber: settingStartPosition.lineNumber,
|
|
1282
|
+
startColumn: settingStartPosition.column,
|
|
1283
|
+
endLineNumber: 0,
|
|
1284
|
+
endColumn: 0
|
|
1285
|
+
},
|
|
1286
|
+
value: null,
|
|
1287
|
+
valueRange: nullRange,
|
|
1288
|
+
descriptionRanges: [],
|
|
1289
|
+
overrides: [],
|
|
1290
|
+
overrideOf: withNullAsUndefined(overrideSetting)
|
|
1291
|
+
};
|
|
1292
|
+
if (previousParents.length === settingsPropertyIndex + 1) {
|
|
1293
|
+
settings.push(setting);
|
|
1294
|
+
if (OVERRIDE_PROPERTY_REGEX.test(name)) {
|
|
1295
|
+
overrideSetting = setting;
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
else {
|
|
1299
|
+
overrideSetting.overrides.push(setting);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
},
|
|
1303
|
+
onObjectEnd: (offset, length) => {
|
|
1304
|
+
currentParent = previousParents.pop();
|
|
1305
|
+
if (settingsPropertyIndex !== -1 && (previousParents.length === settingsPropertyIndex + 1 || (previousParents.length === settingsPropertyIndex + 2 && overrideSetting !== null))) {
|
|
1306
|
+
const setting = previousParents.length === settingsPropertyIndex + 1 ? settings[settings.length - 1] : overrideSetting.overrides[overrideSetting.overrides.length - 1];
|
|
1307
|
+
if (setting) {
|
|
1308
|
+
const valueEndPosition = model.getPositionAt(offset + length);
|
|
1309
|
+
setting.valueRange = Object.assign(setting.valueRange, {
|
|
1310
|
+
endLineNumber: valueEndPosition.lineNumber,
|
|
1311
|
+
endColumn: valueEndPosition.column
|
|
1312
|
+
});
|
|
1313
|
+
setting.range = Object.assign(setting.range, {
|
|
1314
|
+
endLineNumber: valueEndPosition.lineNumber,
|
|
1315
|
+
endColumn: valueEndPosition.column
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
if (previousParents.length === settingsPropertyIndex + 1) {
|
|
1319
|
+
overrideSetting = null;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
if (previousParents.length === settingsPropertyIndex) {
|
|
1323
|
+
const position = model.getPositionAt(offset);
|
|
1324
|
+
range.endLineNumber = position.lineNumber;
|
|
1325
|
+
range.endColumn = position.column;
|
|
1326
|
+
settingsPropertyIndex = -1;
|
|
1327
|
+
}
|
|
1328
|
+
},
|
|
1329
|
+
onArrayBegin: (offset, length) => {
|
|
1330
|
+
const array = [];
|
|
1331
|
+
onValue(array, offset, length);
|
|
1332
|
+
previousParents.push(currentParent);
|
|
1333
|
+
currentParent = array;
|
|
1334
|
+
currentProperty = null;
|
|
1335
|
+
},
|
|
1336
|
+
onArrayEnd: (offset, length) => {
|
|
1337
|
+
currentParent = previousParents.pop();
|
|
1338
|
+
if (previousParents.length === settingsPropertyIndex + 1 || (previousParents.length === settingsPropertyIndex + 2 && overrideSetting !== null)) {
|
|
1339
|
+
const setting = previousParents.length === settingsPropertyIndex + 1 ? settings[settings.length - 1] : overrideSetting.overrides[overrideSetting.overrides.length - 1];
|
|
1340
|
+
if (setting) {
|
|
1341
|
+
const valueEndPosition = model.getPositionAt(offset + length);
|
|
1342
|
+
setting.valueRange = Object.assign(setting.valueRange, {
|
|
1343
|
+
endLineNumber: valueEndPosition.lineNumber,
|
|
1344
|
+
endColumn: valueEndPosition.column
|
|
1345
|
+
});
|
|
1346
|
+
setting.range = Object.assign(setting.range, {
|
|
1347
|
+
endLineNumber: valueEndPosition.lineNumber,
|
|
1348
|
+
endColumn: valueEndPosition.column
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
},
|
|
1353
|
+
onLiteralValue: onValue,
|
|
1354
|
+
onError: (error) => {
|
|
1355
|
+
const setting = settings[settings.length - 1];
|
|
1356
|
+
if (setting && (isNullRange(setting.range) || isNullRange(setting.keyRange) || isNullRange(setting.valueRange))) {
|
|
1357
|
+
settings.pop();
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
};
|
|
1361
|
+
if (!model.isDisposed()) {
|
|
1362
|
+
visit(model.getValue(), visitor);
|
|
1363
|
+
}
|
|
1364
|
+
return settings.length > 0 ? [{
|
|
1365
|
+
sections: [
|
|
1366
|
+
{
|
|
1367
|
+
settings
|
|
1368
|
+
}
|
|
1369
|
+
],
|
|
1370
|
+
title: '',
|
|
1371
|
+
titleRange: nullRange,
|
|
1372
|
+
range
|
|
1373
|
+
}] : [];
|
|
1374
|
+
}
|
|
1375
|
+
class WorkspaceConfigurationEditorModel extends SettingsEditorModel {
|
|
1376
|
+
constructor() {
|
|
1377
|
+
super(...arguments);
|
|
1378
|
+
this._configurationGroups = [];
|
|
1379
|
+
}
|
|
1380
|
+
get configurationGroups() {
|
|
1381
|
+
return this._configurationGroups;
|
|
1382
|
+
}
|
|
1383
|
+
parse() {
|
|
1384
|
+
super.parse();
|
|
1385
|
+
this._configurationGroups = parse(this.settingsModel, (property, previousParents) => previousParents.length === 0);
|
|
1386
|
+
}
|
|
1387
|
+
isSettingsProperty(property, previousParents) {
|
|
1388
|
+
return property === 'settings' && previousParents.length === 1;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
class DefaultSettings extends Disposable {
|
|
1392
|
+
constructor(_mostCommonlyUsedSettingsKeys, target) {
|
|
1393
|
+
super();
|
|
1394
|
+
this._mostCommonlyUsedSettingsKeys = _mostCommonlyUsedSettingsKeys;
|
|
1395
|
+
this.target = target;
|
|
1396
|
+
this._settingsByName = ( (new Map()));
|
|
1397
|
+
this._onDidChange = this._register(( (new Emitter())));
|
|
1398
|
+
this.onDidChange = this._onDidChange.event;
|
|
1399
|
+
}
|
|
1400
|
+
getContent(forceUpdate = false) {
|
|
1401
|
+
if (!this._content || forceUpdate) {
|
|
1402
|
+
this.initialize();
|
|
1403
|
+
}
|
|
1404
|
+
return this._content;
|
|
1405
|
+
}
|
|
1406
|
+
getContentWithoutMostCommonlyUsed(forceUpdate = false) {
|
|
1407
|
+
if (!this._contentWithoutMostCommonlyUsed || forceUpdate) {
|
|
1408
|
+
this.initialize();
|
|
1409
|
+
}
|
|
1410
|
+
return this._contentWithoutMostCommonlyUsed;
|
|
1411
|
+
}
|
|
1412
|
+
getSettingsGroups(forceUpdate = false) {
|
|
1413
|
+
if (!this._allSettingsGroups || forceUpdate) {
|
|
1414
|
+
this.initialize();
|
|
1415
|
+
}
|
|
1416
|
+
return this._allSettingsGroups;
|
|
1417
|
+
}
|
|
1418
|
+
initialize() {
|
|
1419
|
+
this._allSettingsGroups = this.parse();
|
|
1420
|
+
this._content = this.toContent(this._allSettingsGroups, 0);
|
|
1421
|
+
this._contentWithoutMostCommonlyUsed = this.toContent(this._allSettingsGroups, 1);
|
|
1422
|
+
}
|
|
1423
|
+
parse() {
|
|
1424
|
+
const settingsGroups = this.getRegisteredGroups();
|
|
1425
|
+
this.initAllSettingsMap(settingsGroups);
|
|
1426
|
+
const mostCommonlyUsed = this.getMostCommonlyUsedSettings(settingsGroups);
|
|
1427
|
+
return [mostCommonlyUsed, ...settingsGroups];
|
|
1428
|
+
}
|
|
1429
|
+
getRegisteredGroups() {
|
|
1430
|
+
const configurations = ( (Registry.as(Extensions.Configuration))).getConfigurations().slice();
|
|
1431
|
+
const groups = this.removeEmptySettingsGroups(configurations.sort(this.compareConfigurationNodes)
|
|
1432
|
+
.reduce((result, config, index, array) => this.parseConfig(config, result, array), []));
|
|
1433
|
+
return this.sortGroups(groups);
|
|
1434
|
+
}
|
|
1435
|
+
sortGroups(groups) {
|
|
1436
|
+
groups.forEach(group => {
|
|
1437
|
+
group.sections.forEach(section => {
|
|
1438
|
+
section.settings.sort((a, b) => a.key.localeCompare(b.key));
|
|
1439
|
+
});
|
|
1440
|
+
});
|
|
1441
|
+
return groups;
|
|
1442
|
+
}
|
|
1443
|
+
initAllSettingsMap(allSettingsGroups) {
|
|
1444
|
+
this._settingsByName = ( (new Map()));
|
|
1445
|
+
for (const group of allSettingsGroups) {
|
|
1446
|
+
for (const section of group.sections) {
|
|
1447
|
+
for (const setting of section.settings) {
|
|
1448
|
+
this._settingsByName.set(setting.key, setting);
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
getMostCommonlyUsedSettings(allSettingsGroups) {
|
|
1454
|
+
const settings = coalesce(( (this._mostCommonlyUsedSettingsKeys.map(key => {
|
|
1455
|
+
const setting = this._settingsByName.get(key);
|
|
1456
|
+
if (setting) {
|
|
1457
|
+
return {
|
|
1458
|
+
description: setting.description,
|
|
1459
|
+
key: setting.key,
|
|
1460
|
+
value: setting.value,
|
|
1461
|
+
keyRange: nullRange,
|
|
1462
|
+
range: nullRange,
|
|
1463
|
+
valueRange: nullRange,
|
|
1464
|
+
overrides: [],
|
|
1465
|
+
scope: 4 ,
|
|
1466
|
+
type: setting.type,
|
|
1467
|
+
enum: setting.enum,
|
|
1468
|
+
enumDescriptions: setting.enumDescriptions,
|
|
1469
|
+
descriptionRanges: []
|
|
1470
|
+
};
|
|
1471
|
+
}
|
|
1472
|
+
return null;
|
|
1473
|
+
}))));
|
|
1474
|
+
return {
|
|
1475
|
+
id: 'mostCommonlyUsed',
|
|
1476
|
+
range: nullRange,
|
|
1477
|
+
title: ( (localize('commonlyUsed', "Commonly Used"))),
|
|
1478
|
+
titleRange: nullRange,
|
|
1479
|
+
sections: [
|
|
1480
|
+
{
|
|
1481
|
+
settings
|
|
1482
|
+
}
|
|
1483
|
+
]
|
|
1484
|
+
};
|
|
1485
|
+
}
|
|
1486
|
+
parseConfig(config, result, configurations, settingsGroup, seenSettings) {
|
|
1487
|
+
seenSettings = seenSettings ? seenSettings : {};
|
|
1488
|
+
let title = config.title;
|
|
1489
|
+
if (!title) {
|
|
1490
|
+
const configWithTitleAndSameId = configurations.find(c => (c.id === config.id) && c.title);
|
|
1491
|
+
if (configWithTitleAndSameId) {
|
|
1492
|
+
title = configWithTitleAndSameId.title;
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
if (title) {
|
|
1496
|
+
if (!settingsGroup) {
|
|
1497
|
+
settingsGroup = result.find(g => g.title === title && g.extensionInfo?.id === config.extensionInfo?.id);
|
|
1498
|
+
if (!settingsGroup) {
|
|
1499
|
+
settingsGroup = { sections: [{ settings: [] }], id: config.id || '', title: title || '', titleRange: nullRange, order: config.order, range: nullRange, extensionInfo: config.extensionInfo };
|
|
1500
|
+
result.push(settingsGroup);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
else {
|
|
1504
|
+
settingsGroup.sections[settingsGroup.sections.length - 1].title = title;
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
if (config.properties) {
|
|
1508
|
+
if (!settingsGroup) {
|
|
1509
|
+
settingsGroup = { sections: [{ settings: [] }], id: config.id || '', title: config.id || '', titleRange: nullRange, order: config.order, range: nullRange, extensionInfo: config.extensionInfo };
|
|
1510
|
+
result.push(settingsGroup);
|
|
1511
|
+
}
|
|
1512
|
+
const configurationSettings = [];
|
|
1513
|
+
for (const setting of [...settingsGroup.sections[settingsGroup.sections.length - 1].settings, ...this.parseSettings(config)]) {
|
|
1514
|
+
if (!seenSettings[setting.key]) {
|
|
1515
|
+
configurationSettings.push(setting);
|
|
1516
|
+
seenSettings[setting.key] = true;
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
if (configurationSettings.length) {
|
|
1520
|
+
settingsGroup.sections[settingsGroup.sections.length - 1].settings = configurationSettings;
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
config.allOf?.forEach(c => this.parseConfig(c, result, configurations, settingsGroup, seenSettings));
|
|
1524
|
+
return result;
|
|
1525
|
+
}
|
|
1526
|
+
removeEmptySettingsGroups(settingsGroups) {
|
|
1527
|
+
const result = [];
|
|
1528
|
+
for (const settingsGroup of settingsGroups) {
|
|
1529
|
+
settingsGroup.sections = settingsGroup.sections.filter(section => section.settings.length > 0);
|
|
1530
|
+
if (settingsGroup.sections.length) {
|
|
1531
|
+
result.push(settingsGroup);
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
return result;
|
|
1535
|
+
}
|
|
1536
|
+
parseSettings(config) {
|
|
1537
|
+
const result = [];
|
|
1538
|
+
const settingsObject = config.properties;
|
|
1539
|
+
const extensionInfo = config.extensionInfo;
|
|
1540
|
+
const categoryLabel = config.extensionInfo?.id === config.id ? config.title : config.id;
|
|
1541
|
+
const categoryOrder = config.order;
|
|
1542
|
+
for (const key in settingsObject) {
|
|
1543
|
+
const prop = settingsObject[key];
|
|
1544
|
+
if (this.matchesScope(prop)) {
|
|
1545
|
+
const value = prop.default;
|
|
1546
|
+
let description = (prop.markdownDescription || prop.description || '');
|
|
1547
|
+
if (typeof description !== 'string') {
|
|
1548
|
+
description = '';
|
|
1549
|
+
}
|
|
1550
|
+
const descriptionLines = description.split('\n');
|
|
1551
|
+
const overrides = OVERRIDE_PROPERTY_REGEX.test(key) ? this.parseOverrideSettings(prop.default) : [];
|
|
1552
|
+
let listItemType;
|
|
1553
|
+
if (prop.type === 'array' && prop.items && !Array.isArray(prop.items) && prop.items.type) {
|
|
1554
|
+
if (prop.items.enum) {
|
|
1555
|
+
listItemType = 'enum';
|
|
1556
|
+
}
|
|
1557
|
+
else if (!Array.isArray(prop.items.type)) {
|
|
1558
|
+
listItemType = prop.items.type;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
const objectProperties = prop.type === 'object' ? prop.properties : undefined;
|
|
1562
|
+
const objectPatternProperties = prop.type === 'object' ? prop.patternProperties : undefined;
|
|
1563
|
+
const objectAdditionalProperties = prop.type === 'object' ? prop.additionalProperties : undefined;
|
|
1564
|
+
let enumToUse = prop.enum;
|
|
1565
|
+
let enumDescriptions = prop.markdownEnumDescriptions ?? prop.enumDescriptions;
|
|
1566
|
+
let enumDescriptionsAreMarkdown = !!prop.markdownEnumDescriptions;
|
|
1567
|
+
if (listItemType === 'enum' && !Array.isArray(prop.items)) {
|
|
1568
|
+
enumToUse = prop.items.enum;
|
|
1569
|
+
enumDescriptions = prop.items.markdownEnumDescriptions ?? prop.items.enumDescriptions;
|
|
1570
|
+
enumDescriptionsAreMarkdown = !!prop.items.markdownEnumDescriptions;
|
|
1571
|
+
}
|
|
1572
|
+
let allKeysAreBoolean = false;
|
|
1573
|
+
if (prop.type === 'object' && !prop.additionalProperties && prop.properties && ( (Object.keys(prop.properties))).length) {
|
|
1574
|
+
allKeysAreBoolean = ( (Object.keys(prop.properties))).every(key => {
|
|
1575
|
+
return prop.properties[key].type === 'boolean';
|
|
1576
|
+
});
|
|
1577
|
+
}
|
|
1578
|
+
let isLanguageTagSetting = false;
|
|
1579
|
+
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
|
|
1580
|
+
isLanguageTagSetting = true;
|
|
1581
|
+
}
|
|
1582
|
+
let defaultValueSource;
|
|
1583
|
+
if (!isLanguageTagSetting) {
|
|
1584
|
+
const registeredConfigurationProp = prop;
|
|
1585
|
+
if (registeredConfigurationProp && registeredConfigurationProp.defaultValueSource) {
|
|
1586
|
+
defaultValueSource = registeredConfigurationProp.defaultValueSource;
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
result.push({
|
|
1590
|
+
key,
|
|
1591
|
+
value,
|
|
1592
|
+
description: descriptionLines,
|
|
1593
|
+
descriptionIsMarkdown: !!prop.markdownDescription,
|
|
1594
|
+
range: nullRange,
|
|
1595
|
+
keyRange: nullRange,
|
|
1596
|
+
valueRange: nullRange,
|
|
1597
|
+
descriptionRanges: [],
|
|
1598
|
+
overrides,
|
|
1599
|
+
scope: prop.scope,
|
|
1600
|
+
type: prop.type,
|
|
1601
|
+
arrayItemType: listItemType,
|
|
1602
|
+
objectProperties,
|
|
1603
|
+
objectPatternProperties,
|
|
1604
|
+
objectAdditionalProperties,
|
|
1605
|
+
enum: enumToUse,
|
|
1606
|
+
enumDescriptions: enumDescriptions,
|
|
1607
|
+
enumDescriptionsAreMarkdown: enumDescriptionsAreMarkdown,
|
|
1608
|
+
uniqueItems: prop.uniqueItems,
|
|
1609
|
+
tags: prop.tags,
|
|
1610
|
+
disallowSyncIgnore: prop.disallowSyncIgnore,
|
|
1611
|
+
restricted: prop.restricted,
|
|
1612
|
+
extensionInfo: extensionInfo,
|
|
1613
|
+
deprecationMessage: prop.markdownDeprecationMessage || prop.deprecationMessage,
|
|
1614
|
+
deprecationMessageIsMarkdown: !!prop.markdownDeprecationMessage,
|
|
1615
|
+
validator: createValidator(prop),
|
|
1616
|
+
enumItemLabels: prop.enumItemLabels,
|
|
1617
|
+
allKeysAreBoolean,
|
|
1618
|
+
editPresentation: prop.editPresentation,
|
|
1619
|
+
order: prop.order,
|
|
1620
|
+
nonLanguageSpecificDefaultValueSource: defaultValueSource,
|
|
1621
|
+
isLanguageTagSetting,
|
|
1622
|
+
categoryLabel,
|
|
1623
|
+
categoryOrder
|
|
1624
|
+
});
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
return result;
|
|
1628
|
+
}
|
|
1629
|
+
parseOverrideSettings(overrideSettings) {
|
|
1630
|
+
return (
|
|
1631
|
+
(( (Object.keys(overrideSettings))).map((key) => ({
|
|
1632
|
+
key,
|
|
1633
|
+
value: overrideSettings[key],
|
|
1634
|
+
description: [],
|
|
1635
|
+
descriptionIsMarkdown: false,
|
|
1636
|
+
range: nullRange,
|
|
1637
|
+
keyRange: nullRange,
|
|
1638
|
+
valueRange: nullRange,
|
|
1639
|
+
descriptionRanges: [],
|
|
1640
|
+
overrides: []
|
|
1641
|
+
})))
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
matchesScope(property) {
|
|
1645
|
+
if (!property.scope) {
|
|
1646
|
+
return true;
|
|
1647
|
+
}
|
|
1648
|
+
if (this.target === 6 ) {
|
|
1649
|
+
return FOLDER_SCOPES.indexOf(property.scope) !== -1;
|
|
1650
|
+
}
|
|
1651
|
+
if (this.target === 5 ) {
|
|
1652
|
+
return WORKSPACE_SCOPES.indexOf(property.scope) !== -1;
|
|
1653
|
+
}
|
|
1654
|
+
return true;
|
|
1655
|
+
}
|
|
1656
|
+
compareConfigurationNodes(c1, c2) {
|
|
1657
|
+
if (typeof c1.order !== 'number') {
|
|
1658
|
+
return 1;
|
|
1659
|
+
}
|
|
1660
|
+
if (typeof c2.order !== 'number') {
|
|
1661
|
+
return -1;
|
|
1662
|
+
}
|
|
1663
|
+
if (c1.order === c2.order) {
|
|
1664
|
+
const title1 = c1.title || '';
|
|
1665
|
+
const title2 = c2.title || '';
|
|
1666
|
+
return title1.localeCompare(title2);
|
|
1667
|
+
}
|
|
1668
|
+
return c1.order - c2.order;
|
|
1669
|
+
}
|
|
1670
|
+
toContent(settingsGroups, startIndex) {
|
|
1671
|
+
const builder = ( (new SettingsContentBuilder()));
|
|
1672
|
+
for (let i = startIndex; i < settingsGroups.length; i++) {
|
|
1673
|
+
builder.pushGroup(settingsGroups[i], i === startIndex, i === settingsGroups.length - 1);
|
|
1674
|
+
}
|
|
1675
|
+
return builder.getContent();
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
class DefaultSettingsEditorModel extends AbstractSettingsModel {
|
|
1679
|
+
constructor(_uri, reference, defaultSettings) {
|
|
1680
|
+
super();
|
|
1681
|
+
this._uri = _uri;
|
|
1682
|
+
this.defaultSettings = defaultSettings;
|
|
1683
|
+
this._onDidChangeGroups = this._register(( (new Emitter())));
|
|
1684
|
+
this.onDidChangeGroups = this._onDidChangeGroups.event;
|
|
1685
|
+
this._register(defaultSettings.onDidChange(() => this._onDidChangeGroups.fire()));
|
|
1686
|
+
this._model = reference.object.textEditorModel;
|
|
1687
|
+
this._register(this.onWillDispose(() => reference.dispose()));
|
|
1688
|
+
}
|
|
1689
|
+
get uri() {
|
|
1690
|
+
return this._uri;
|
|
1691
|
+
}
|
|
1692
|
+
get target() {
|
|
1693
|
+
return this.defaultSettings.target;
|
|
1694
|
+
}
|
|
1695
|
+
get settingsGroups() {
|
|
1696
|
+
return this.defaultSettings.getSettingsGroups();
|
|
1697
|
+
}
|
|
1698
|
+
get filterGroups() {
|
|
1699
|
+
return this.settingsGroups.slice(1);
|
|
1700
|
+
}
|
|
1701
|
+
update() {
|
|
1702
|
+
if (this._model.isDisposed()) {
|
|
1703
|
+
return undefined;
|
|
1704
|
+
}
|
|
1705
|
+
const resultGroups = [...( (this._currentResultGroups.values()))]
|
|
1706
|
+
.sort((a, b) => a.order - b.order);
|
|
1707
|
+
const nonEmptyResultGroups = resultGroups.filter(group => group.result.filterMatches.length);
|
|
1708
|
+
const startLine = tail(this.settingsGroups).range.endLineNumber + 2;
|
|
1709
|
+
const { settingsGroups: filteredGroups, matches } = this.writeResultGroups(nonEmptyResultGroups, startLine);
|
|
1710
|
+
const metadata = this.collectMetadata(resultGroups);
|
|
1711
|
+
return resultGroups.length ?
|
|
1712
|
+
{
|
|
1713
|
+
allGroups: this.settingsGroups,
|
|
1714
|
+
filteredGroups,
|
|
1715
|
+
matches,
|
|
1716
|
+
metadata
|
|
1717
|
+
} :
|
|
1718
|
+
undefined;
|
|
1719
|
+
}
|
|
1720
|
+
writeResultGroups(groups, startLine) {
|
|
1721
|
+
const contentBuilderOffset = startLine - 1;
|
|
1722
|
+
const builder = ( (new SettingsContentBuilder(contentBuilderOffset)));
|
|
1723
|
+
const settingsGroups = [];
|
|
1724
|
+
const matches = [];
|
|
1725
|
+
if (groups.length) {
|
|
1726
|
+
builder.pushLine(',');
|
|
1727
|
+
groups.forEach(resultGroup => {
|
|
1728
|
+
const settingsGroup = this.getGroup(resultGroup);
|
|
1729
|
+
settingsGroups.push(settingsGroup);
|
|
1730
|
+
matches.push(...this.writeSettingsGroupToBuilder(builder, settingsGroup, resultGroup.result.filterMatches));
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
const groupContent = builder.getContent() + '\n';
|
|
1734
|
+
const groupEndLine = this._model.getLineCount();
|
|
1735
|
+
const cursorPosition = ( (new Selection$2(startLine, 1, startLine, 1)));
|
|
1736
|
+
const edit = {
|
|
1737
|
+
text: groupContent,
|
|
1738
|
+
forceMoveMarkers: true,
|
|
1739
|
+
range: ( (new Range$2(startLine, 1, groupEndLine, 1)))
|
|
1740
|
+
};
|
|
1741
|
+
this._model.pushEditOperations([cursorPosition], [edit], () => [cursorPosition]);
|
|
1742
|
+
const tokenizeTo = Math.min(startLine + 60, this._model.getLineCount());
|
|
1743
|
+
this._model.tokenization.forceTokenization(tokenizeTo);
|
|
1744
|
+
return { matches, settingsGroups };
|
|
1745
|
+
}
|
|
1746
|
+
writeSettingsGroupToBuilder(builder, settingsGroup, filterMatches) {
|
|
1747
|
+
filterMatches = ( (filterMatches
|
|
1748
|
+
.map(filteredMatch => {
|
|
1749
|
+
return {
|
|
1750
|
+
setting: filteredMatch.setting,
|
|
1751
|
+
score: filteredMatch.score,
|
|
1752
|
+
matches: filteredMatch.matches && ( (filteredMatch.matches.map(match => {
|
|
1753
|
+
return (
|
|
1754
|
+
(new Range$2(
|
|
1755
|
+
match.startLineNumber - filteredMatch.setting.range.startLineNumber,
|
|
1756
|
+
match.startColumn,
|
|
1757
|
+
match.endLineNumber - filteredMatch.setting.range.startLineNumber,
|
|
1758
|
+
match.endColumn
|
|
1759
|
+
))
|
|
1760
|
+
);
|
|
1761
|
+
})))
|
|
1762
|
+
};
|
|
1763
|
+
})));
|
|
1764
|
+
builder.pushGroup(settingsGroup);
|
|
1765
|
+
const fixedMatches = flatten(( (( (filterMatches
|
|
1766
|
+
.map(m => m.matches || [])))
|
|
1767
|
+
.map((settingMatches, i) => {
|
|
1768
|
+
const setting = settingsGroup.sections[0].settings[i];
|
|
1769
|
+
return (
|
|
1770
|
+
(settingMatches.map(range => {
|
|
1771
|
+
return (
|
|
1772
|
+
(new Range$2(
|
|
1773
|
+
range.startLineNumber + setting.range.startLineNumber,
|
|
1774
|
+
range.startColumn,
|
|
1775
|
+
range.endLineNumber + setting.range.startLineNumber,
|
|
1776
|
+
range.endColumn
|
|
1777
|
+
))
|
|
1778
|
+
);
|
|
1779
|
+
}))
|
|
1780
|
+
);
|
|
1781
|
+
}))));
|
|
1782
|
+
return fixedMatches;
|
|
1783
|
+
}
|
|
1784
|
+
copySetting(setting) {
|
|
1785
|
+
return {
|
|
1786
|
+
description: setting.description,
|
|
1787
|
+
scope: setting.scope,
|
|
1788
|
+
type: setting.type,
|
|
1789
|
+
enum: setting.enum,
|
|
1790
|
+
enumDescriptions: setting.enumDescriptions,
|
|
1791
|
+
key: setting.key,
|
|
1792
|
+
value: setting.value,
|
|
1793
|
+
range: setting.range,
|
|
1794
|
+
overrides: [],
|
|
1795
|
+
overrideOf: setting.overrideOf,
|
|
1796
|
+
tags: setting.tags,
|
|
1797
|
+
deprecationMessage: setting.deprecationMessage,
|
|
1798
|
+
keyRange: nullRange,
|
|
1799
|
+
valueRange: nullRange,
|
|
1800
|
+
descriptionIsMarkdown: undefined,
|
|
1801
|
+
descriptionRanges: []
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1804
|
+
findValueMatches(filter, setting) {
|
|
1805
|
+
return [];
|
|
1806
|
+
}
|
|
1807
|
+
getPreference(key) {
|
|
1808
|
+
for (const group of this.settingsGroups) {
|
|
1809
|
+
for (const section of group.sections) {
|
|
1810
|
+
for (const setting of section.settings) {
|
|
1811
|
+
if (setting.key === key) {
|
|
1812
|
+
return setting;
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
return undefined;
|
|
1818
|
+
}
|
|
1819
|
+
getGroup(resultGroup) {
|
|
1820
|
+
return {
|
|
1821
|
+
id: resultGroup.id,
|
|
1822
|
+
range: nullRange,
|
|
1823
|
+
title: resultGroup.label,
|
|
1824
|
+
titleRange: nullRange,
|
|
1825
|
+
sections: [
|
|
1826
|
+
{
|
|
1827
|
+
settings: ( (resultGroup.result.filterMatches.map(m => this.copySetting(m.setting))))
|
|
1828
|
+
}
|
|
1829
|
+
]
|
|
1830
|
+
};
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
class SettingsContentBuilder {
|
|
1834
|
+
get lineCountWithOffset() {
|
|
1835
|
+
return this._contentByLines.length + this._rangeOffset;
|
|
1836
|
+
}
|
|
1837
|
+
get lastLine() {
|
|
1838
|
+
return this._contentByLines[this._contentByLines.length - 1] || '';
|
|
1839
|
+
}
|
|
1840
|
+
constructor(_rangeOffset = 0) {
|
|
1841
|
+
this._rangeOffset = _rangeOffset;
|
|
1842
|
+
this._contentByLines = [];
|
|
1843
|
+
}
|
|
1844
|
+
pushLine(...lineText) {
|
|
1845
|
+
this._contentByLines.push(...lineText);
|
|
1846
|
+
}
|
|
1847
|
+
pushGroup(settingsGroups, isFirst, isLast) {
|
|
1848
|
+
this._contentByLines.push(isFirst ? '[{' : '{');
|
|
1849
|
+
const lastSetting = this._pushGroup(settingsGroups, ' ');
|
|
1850
|
+
if (lastSetting) {
|
|
1851
|
+
const lineIdx = lastSetting.range.endLineNumber - this._rangeOffset;
|
|
1852
|
+
const content = this._contentByLines[lineIdx - 2];
|
|
1853
|
+
this._contentByLines[lineIdx - 2] = content.substring(0, content.length - 1);
|
|
1854
|
+
}
|
|
1855
|
+
this._contentByLines.push(isLast ? '}]' : '},');
|
|
1856
|
+
}
|
|
1857
|
+
_pushGroup(group, indent) {
|
|
1858
|
+
let lastSetting = null;
|
|
1859
|
+
const groupStart = this.lineCountWithOffset + 1;
|
|
1860
|
+
for (const section of group.sections) {
|
|
1861
|
+
if (section.title) {
|
|
1862
|
+
const sectionTitleStart = this.lineCountWithOffset + 1;
|
|
1863
|
+
this.addDescription([section.title], indent, this._contentByLines);
|
|
1864
|
+
section.titleRange = { startLineNumber: sectionTitleStart, startColumn: 1, endLineNumber: this.lineCountWithOffset, endColumn: this.lastLine.length };
|
|
1865
|
+
}
|
|
1866
|
+
if (section.settings.length) {
|
|
1867
|
+
for (const setting of section.settings) {
|
|
1868
|
+
this.pushSetting(setting, indent);
|
|
1869
|
+
lastSetting = setting;
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
group.range = { startLineNumber: groupStart, startColumn: 1, endLineNumber: this.lineCountWithOffset, endColumn: this.lastLine.length };
|
|
1874
|
+
return lastSetting;
|
|
1875
|
+
}
|
|
1876
|
+
getContent() {
|
|
1877
|
+
return this._contentByLines.join('\n');
|
|
1878
|
+
}
|
|
1879
|
+
pushSetting(setting, indent) {
|
|
1880
|
+
const settingStart = this.lineCountWithOffset + 1;
|
|
1881
|
+
this.pushSettingDescription(setting, indent);
|
|
1882
|
+
let preValueContent = indent;
|
|
1883
|
+
const keyString = JSON.stringify(setting.key);
|
|
1884
|
+
preValueContent += keyString;
|
|
1885
|
+
setting.keyRange = { startLineNumber: this.lineCountWithOffset + 1, startColumn: preValueContent.indexOf(setting.key) + 1, endLineNumber: this.lineCountWithOffset + 1, endColumn: setting.key.length };
|
|
1886
|
+
preValueContent += ': ';
|
|
1887
|
+
const valueStart = this.lineCountWithOffset + 1;
|
|
1888
|
+
this.pushValue(setting, preValueContent, indent);
|
|
1889
|
+
setting.valueRange = { startLineNumber: valueStart, startColumn: preValueContent.length + 1, endLineNumber: this.lineCountWithOffset, endColumn: this.lastLine.length + 1 };
|
|
1890
|
+
this._contentByLines[this._contentByLines.length - 1] += ',';
|
|
1891
|
+
this._contentByLines.push('');
|
|
1892
|
+
setting.range = { startLineNumber: settingStart, startColumn: 1, endLineNumber: this.lineCountWithOffset, endColumn: this.lastLine.length };
|
|
1893
|
+
}
|
|
1894
|
+
pushSettingDescription(setting, indent) {
|
|
1895
|
+
const fixSettingLink = (line) => line.replace(/`#(.*)#`/g, (match, settingName) => `\`${settingName}\``);
|
|
1896
|
+
setting.descriptionRanges = [];
|
|
1897
|
+
const descriptionPreValue = indent + '// ';
|
|
1898
|
+
const deprecationMessageLines = setting.deprecationMessage?.split(/\n/g) ?? [];
|
|
1899
|
+
for (let line of [...deprecationMessageLines, ...setting.description]) {
|
|
1900
|
+
line = fixSettingLink(line);
|
|
1901
|
+
this._contentByLines.push(descriptionPreValue + line);
|
|
1902
|
+
setting.descriptionRanges.push({ startLineNumber: this.lineCountWithOffset, startColumn: this.lastLine.indexOf(line) + 1, endLineNumber: this.lineCountWithOffset, endColumn: this.lastLine.length });
|
|
1903
|
+
}
|
|
1904
|
+
if (setting.enumDescriptions && setting.enumDescriptions.some(desc => !!desc)) {
|
|
1905
|
+
setting.enumDescriptions.forEach((desc, i) => {
|
|
1906
|
+
const displayEnum = escapeInvisibleChars(String(setting.enum[i]));
|
|
1907
|
+
const line = desc ?
|
|
1908
|
+
`${displayEnum}: ${fixSettingLink(desc)}` :
|
|
1909
|
+
displayEnum;
|
|
1910
|
+
const lines = line.split(/\n/g);
|
|
1911
|
+
lines[0] = ' - ' + lines[0];
|
|
1912
|
+
this._contentByLines.push(...( (lines.map(l => `${indent}// ${l}`))));
|
|
1913
|
+
setting.descriptionRanges.push({ startLineNumber: this.lineCountWithOffset, startColumn: this.lastLine.indexOf(line) + 1, endLineNumber: this.lineCountWithOffset, endColumn: this.lastLine.length });
|
|
1914
|
+
});
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
pushValue(setting, preValueConent, indent) {
|
|
1918
|
+
const valueString = JSON.stringify(setting.value, null, indent);
|
|
1919
|
+
if (valueString && (typeof setting.value === 'object')) {
|
|
1920
|
+
if (setting.overrides && setting.overrides.length) {
|
|
1921
|
+
this._contentByLines.push(preValueConent + ' {');
|
|
1922
|
+
for (const subSetting of setting.overrides) {
|
|
1923
|
+
this.pushSetting(subSetting, indent + indent);
|
|
1924
|
+
this._contentByLines.pop();
|
|
1925
|
+
}
|
|
1926
|
+
const lastSetting = setting.overrides[setting.overrides.length - 1];
|
|
1927
|
+
const content = this._contentByLines[lastSetting.range.endLineNumber - 2];
|
|
1928
|
+
this._contentByLines[lastSetting.range.endLineNumber - 2] = content.substring(0, content.length - 1);
|
|
1929
|
+
this._contentByLines.push(indent + '}');
|
|
1930
|
+
}
|
|
1931
|
+
else {
|
|
1932
|
+
const mulitLineValue = valueString.split('\n');
|
|
1933
|
+
this._contentByLines.push(preValueConent + mulitLineValue[0]);
|
|
1934
|
+
for (let i = 1; i < mulitLineValue.length; i++) {
|
|
1935
|
+
this._contentByLines.push(indent + mulitLineValue[i]);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
else {
|
|
1940
|
+
this._contentByLines.push(preValueConent + valueString);
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
addDescription(description, indent, result) {
|
|
1944
|
+
for (const line of description) {
|
|
1945
|
+
result.push(indent + '// ' + line);
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
class RawSettingsContentBuilder extends SettingsContentBuilder {
|
|
1950
|
+
constructor(indent = '\t') {
|
|
1951
|
+
super(0);
|
|
1952
|
+
this.indent = indent;
|
|
1953
|
+
}
|
|
1954
|
+
pushGroup(settingsGroups) {
|
|
1955
|
+
this._pushGroup(settingsGroups, this.indent);
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
class DefaultRawSettingsEditorModel extends Disposable {
|
|
1959
|
+
constructor(defaultSettings) {
|
|
1960
|
+
super();
|
|
1961
|
+
this.defaultSettings = defaultSettings;
|
|
1962
|
+
this._content = null;
|
|
1963
|
+
this._register(defaultSettings.onDidChange(() => this._content = null));
|
|
1964
|
+
}
|
|
1965
|
+
get content() {
|
|
1966
|
+
if (this._content === null) {
|
|
1967
|
+
const builder = ( (new RawSettingsContentBuilder()));
|
|
1968
|
+
builder.pushLine('{');
|
|
1969
|
+
for (const settingsGroup of this.defaultSettings.getRegisteredGroups()) {
|
|
1970
|
+
builder.pushGroup(settingsGroup);
|
|
1971
|
+
}
|
|
1972
|
+
builder.pushLine('}');
|
|
1973
|
+
this._content = builder.getContent();
|
|
1974
|
+
}
|
|
1975
|
+
return this._content;
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
function escapeInvisibleChars(enumValue) {
|
|
1979
|
+
return enumValue && enumValue
|
|
1980
|
+
.replace(/\n/g, '\\n')
|
|
1981
|
+
.replace(/\r/g, '\\r');
|
|
1982
|
+
}
|
|
1983
|
+
function defaultKeybindingsContents(keybindingService) {
|
|
1984
|
+
const defaultsHeader = '// ' + ( (localize(
|
|
1985
|
+
'defaultKeybindingsHeader',
|
|
1986
|
+
"Override key bindings by placing them into your key bindings file."
|
|
1987
|
+
)));
|
|
1988
|
+
return defaultsHeader + '\n' + keybindingService.getDefaultKeybindingsContent();
|
|
1989
|
+
}
|
|
1990
|
+
let DefaultKeybindingsEditorModel = class DefaultKeybindingsEditorModel {
|
|
1991
|
+
constructor(_uri, keybindingService) {
|
|
1992
|
+
this._uri = _uri;
|
|
1993
|
+
this.keybindingService = keybindingService;
|
|
1994
|
+
}
|
|
1995
|
+
get uri() {
|
|
1996
|
+
return this._uri;
|
|
1997
|
+
}
|
|
1998
|
+
get content() {
|
|
1999
|
+
if (!this._content) {
|
|
2000
|
+
this._content = defaultKeybindingsContents(this.keybindingService);
|
|
2001
|
+
}
|
|
2002
|
+
return this._content;
|
|
2003
|
+
}
|
|
2004
|
+
getPreference() {
|
|
2005
|
+
return null;
|
|
2006
|
+
}
|
|
2007
|
+
dispose() {
|
|
2008
|
+
}
|
|
2009
|
+
};
|
|
2010
|
+
DefaultKeybindingsEditorModel = ( (__decorate([
|
|
2011
|
+
( (__param(1, IKeybindingService)))
|
|
2012
|
+
], DefaultKeybindingsEditorModel)));
|
|
2013
|
+
const emptyEditableSettingsContent = '{\n}';
|
|
2014
|
+
let PreferencesService = class PreferencesService extends Disposable {
|
|
2015
|
+
constructor(editorService, editorGroupService, textFileService, configurationService, notificationService, contextService, instantiationService, userDataProfileService, userDataProfilesService, textModelResolverService, keybindingService, modelService, jsonEditingService, languageService, labelService, remoteAgentService, textEditorService) {
|
|
2016
|
+
super();
|
|
2017
|
+
this.editorService = editorService;
|
|
2018
|
+
this.editorGroupService = editorGroupService;
|
|
2019
|
+
this.textFileService = textFileService;
|
|
2020
|
+
this.configurationService = configurationService;
|
|
2021
|
+
this.notificationService = notificationService;
|
|
2022
|
+
this.contextService = contextService;
|
|
2023
|
+
this.instantiationService = instantiationService;
|
|
2024
|
+
this.userDataProfileService = userDataProfileService;
|
|
2025
|
+
this.userDataProfilesService = userDataProfilesService;
|
|
2026
|
+
this.textModelResolverService = textModelResolverService;
|
|
2027
|
+
this.modelService = modelService;
|
|
2028
|
+
this.jsonEditingService = jsonEditingService;
|
|
2029
|
+
this.languageService = languageService;
|
|
2030
|
+
this.labelService = labelService;
|
|
2031
|
+
this.remoteAgentService = remoteAgentService;
|
|
2032
|
+
this.textEditorService = textEditorService;
|
|
2033
|
+
this._onDispose = this._register(( (new Emitter())));
|
|
2034
|
+
this.defaultKeybindingsResource = ( (URI.from(
|
|
2035
|
+
{ scheme: Schemas.vscode, authority: 'defaultsettings', path: '/keybindings.json' }
|
|
2036
|
+
)));
|
|
2037
|
+
this.defaultSettingsRawResource = ( (URI.from(
|
|
2038
|
+
{ scheme: Schemas.vscode, authority: 'defaultsettings', path: '/defaultSettings.json' }
|
|
2039
|
+
)));
|
|
2040
|
+
this._register(keybindingService.onDidUpdateKeybindings(() => {
|
|
2041
|
+
const model = modelService.getModel(this.defaultKeybindingsResource);
|
|
2042
|
+
if (!model) {
|
|
2043
|
+
return;
|
|
2044
|
+
}
|
|
2045
|
+
modelService.updateModel(model, defaultKeybindingsContents(keybindingService));
|
|
2046
|
+
}));
|
|
2047
|
+
}
|
|
2048
|
+
get userSettingsResource() {
|
|
2049
|
+
return this.userDataProfileService.currentProfile.settingsResource;
|
|
2050
|
+
}
|
|
2051
|
+
get workspaceSettingsResource() {
|
|
2052
|
+
if (this.contextService.getWorkbenchState() === 1 ) {
|
|
2053
|
+
return null;
|
|
2054
|
+
}
|
|
2055
|
+
const workspace = this.contextService.getWorkspace();
|
|
2056
|
+
return workspace.configuration || workspace.folders[0].toResource(FOLDER_SETTINGS_PATH);
|
|
2057
|
+
}
|
|
2058
|
+
get settingsEditor2Input() {
|
|
2059
|
+
return this.instantiationService.createInstance(SettingsEditor2Input);
|
|
2060
|
+
}
|
|
2061
|
+
getFolderSettingsResource(resource) {
|
|
2062
|
+
const folder = this.contextService.getWorkspaceFolder(resource);
|
|
2063
|
+
return folder ? folder.toResource(FOLDER_SETTINGS_PATH) : null;
|
|
2064
|
+
}
|
|
2065
|
+
resolveModel(uri) {
|
|
2066
|
+
if (this.isDefaultSettingsResource(uri)) {
|
|
2067
|
+
const target = this.getConfigurationTargetFromDefaultSettingsResource(uri);
|
|
2068
|
+
const languageSelection = this.languageService.createById('jsonc');
|
|
2069
|
+
const model = this._register(this.modelService.createModel('', languageSelection, uri));
|
|
2070
|
+
let defaultSettings;
|
|
2071
|
+
this.configurationService.onDidChangeConfiguration(e => {
|
|
2072
|
+
if (e.source === 7 ) {
|
|
2073
|
+
const model = this.modelService.getModel(uri);
|
|
2074
|
+
if (!model) {
|
|
2075
|
+
return;
|
|
2076
|
+
}
|
|
2077
|
+
defaultSettings = this.getDefaultSettings(target);
|
|
2078
|
+
this.modelService.updateModel(model, defaultSettings.getContentWithoutMostCommonlyUsed(true));
|
|
2079
|
+
defaultSettings._onDidChange.fire();
|
|
2080
|
+
}
|
|
2081
|
+
});
|
|
2082
|
+
if (!defaultSettings) {
|
|
2083
|
+
defaultSettings = this.getDefaultSettings(target);
|
|
2084
|
+
this.modelService.updateModel(model, defaultSettings.getContentWithoutMostCommonlyUsed(true));
|
|
2085
|
+
}
|
|
2086
|
+
return model;
|
|
2087
|
+
}
|
|
2088
|
+
if (( (this.defaultSettingsRawResource.toString())) === ( (uri.toString()))) {
|
|
2089
|
+
const defaultRawSettingsEditorModel = this.instantiationService.createInstance(DefaultRawSettingsEditorModel, this.getDefaultSettings(3 ));
|
|
2090
|
+
const languageSelection = this.languageService.createById('jsonc');
|
|
2091
|
+
const model = this._register(this.modelService.createModel(defaultRawSettingsEditorModel.content, languageSelection, uri));
|
|
2092
|
+
return model;
|
|
2093
|
+
}
|
|
2094
|
+
if (( (this.defaultKeybindingsResource.toString())) === ( (uri.toString()))) {
|
|
2095
|
+
const defaultKeybindingsEditorModel = this.instantiationService.createInstance(DefaultKeybindingsEditorModel, uri);
|
|
2096
|
+
const languageSelection = this.languageService.createById('jsonc');
|
|
2097
|
+
const model = this._register(this.modelService.createModel(defaultKeybindingsEditorModel.content, languageSelection, uri));
|
|
2098
|
+
return model;
|
|
2099
|
+
}
|
|
2100
|
+
return null;
|
|
2101
|
+
}
|
|
2102
|
+
async createPreferencesEditorModel(uri) {
|
|
2103
|
+
if (this.isDefaultSettingsResource(uri)) {
|
|
2104
|
+
return this.createDefaultSettingsEditorModel(uri);
|
|
2105
|
+
}
|
|
2106
|
+
if (( (this.userSettingsResource.toString())) === ( (uri.toString())) || ( (this.userDataProfilesService.defaultProfile.settingsResource.toString())) === ( (uri.toString()))) {
|
|
2107
|
+
return this.createEditableSettingsEditorModel(3 , uri);
|
|
2108
|
+
}
|
|
2109
|
+
const workspaceSettingsUri = await this.getEditableSettingsURI(5 );
|
|
2110
|
+
if (workspaceSettingsUri && ( (workspaceSettingsUri.toString())) === ( (uri.toString()))) {
|
|
2111
|
+
return this.createEditableSettingsEditorModel(5 , workspaceSettingsUri);
|
|
2112
|
+
}
|
|
2113
|
+
if (this.contextService.getWorkbenchState() === 3 ) {
|
|
2114
|
+
const settingsUri = await this.getEditableSettingsURI(6 , uri);
|
|
2115
|
+
if (settingsUri && ( (settingsUri.toString())) === ( (uri.toString()))) {
|
|
2116
|
+
return this.createEditableSettingsEditorModel(6 , uri);
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
const remoteEnvironment = await this.remoteAgentService.getEnvironment();
|
|
2120
|
+
const remoteSettingsUri = remoteEnvironment ? remoteEnvironment.settingsPath : null;
|
|
2121
|
+
if (remoteSettingsUri && ( (remoteSettingsUri.toString())) === ( (uri.toString()))) {
|
|
2122
|
+
return this.createEditableSettingsEditorModel(4 , uri);
|
|
2123
|
+
}
|
|
2124
|
+
return null;
|
|
2125
|
+
}
|
|
2126
|
+
openRawDefaultSettings() {
|
|
2127
|
+
return this.editorService.openEditor({ resource: this.defaultSettingsRawResource });
|
|
2128
|
+
}
|
|
2129
|
+
openRawUserSettings() {
|
|
2130
|
+
return this.editorService.openEditor({ resource: this.userSettingsResource });
|
|
2131
|
+
}
|
|
2132
|
+
shouldOpenJsonByDefault() {
|
|
2133
|
+
return this.configurationService.getValue('workbench.settings.editor') === 'json';
|
|
2134
|
+
}
|
|
2135
|
+
openSettings(options = {}) {
|
|
2136
|
+
options = {
|
|
2137
|
+
...options,
|
|
2138
|
+
target: 3 ,
|
|
2139
|
+
};
|
|
2140
|
+
if (options.query) {
|
|
2141
|
+
options.jsonEditor = false;
|
|
2142
|
+
}
|
|
2143
|
+
return this.open(this.userSettingsResource, options);
|
|
2144
|
+
}
|
|
2145
|
+
openLanguageSpecificSettings(languageId, options = {}) {
|
|
2146
|
+
if (this.shouldOpenJsonByDefault()) {
|
|
2147
|
+
options.query = undefined;
|
|
2148
|
+
options.revealSetting = { key: `[${languageId}]`, edit: true };
|
|
2149
|
+
}
|
|
2150
|
+
else {
|
|
2151
|
+
options.query = `@lang:${languageId}${options.query ? ` ${options.query}` : ''}`;
|
|
2152
|
+
}
|
|
2153
|
+
options.target = options.target ?? 3 ;
|
|
2154
|
+
return this.open(this.userSettingsResource, options);
|
|
2155
|
+
}
|
|
2156
|
+
open(settingsResource, options) {
|
|
2157
|
+
options = {
|
|
2158
|
+
...options,
|
|
2159
|
+
jsonEditor: options.jsonEditor ?? this.shouldOpenJsonByDefault()
|
|
2160
|
+
};
|
|
2161
|
+
return options.jsonEditor ?
|
|
2162
|
+
this.openSettingsJson(settingsResource, options) :
|
|
2163
|
+
this.openSettings2(options);
|
|
2164
|
+
}
|
|
2165
|
+
async openSettings2(options) {
|
|
2166
|
+
const input = this.settingsEditor2Input;
|
|
2167
|
+
options = {
|
|
2168
|
+
...options,
|
|
2169
|
+
focusSearch: true
|
|
2170
|
+
};
|
|
2171
|
+
await this.editorService.openEditor(input, validateSettingsEditorOptions(options), options.openToSide ? SIDE_GROUP : undefined);
|
|
2172
|
+
return this.editorGroupService.activeGroup.activeEditorPane;
|
|
2173
|
+
}
|
|
2174
|
+
openApplicationSettings(options = {}) {
|
|
2175
|
+
options = {
|
|
2176
|
+
...options,
|
|
2177
|
+
target: 3 ,
|
|
2178
|
+
};
|
|
2179
|
+
return this.open(this.userDataProfilesService.defaultProfile.settingsResource, options);
|
|
2180
|
+
}
|
|
2181
|
+
openUserSettings(options = {}) {
|
|
2182
|
+
options = {
|
|
2183
|
+
...options,
|
|
2184
|
+
target: 3 ,
|
|
2185
|
+
};
|
|
2186
|
+
return this.open(this.userSettingsResource, options);
|
|
2187
|
+
}
|
|
2188
|
+
async openRemoteSettings(options = {}) {
|
|
2189
|
+
const environment = await this.remoteAgentService.getEnvironment();
|
|
2190
|
+
if (environment) {
|
|
2191
|
+
options = {
|
|
2192
|
+
...options,
|
|
2193
|
+
target: 4 ,
|
|
2194
|
+
};
|
|
2195
|
+
this.open(environment.settingsPath, options);
|
|
2196
|
+
}
|
|
2197
|
+
return undefined;
|
|
2198
|
+
}
|
|
2199
|
+
openWorkspaceSettings(options = {}) {
|
|
2200
|
+
if (!this.workspaceSettingsResource) {
|
|
2201
|
+
this.notificationService.info(( (localize(
|
|
2202
|
+
'openFolderFirst',
|
|
2203
|
+
"Open a folder or workspace first to create workspace or folder settings."
|
|
2204
|
+
))));
|
|
2205
|
+
return Promise.reject(null);
|
|
2206
|
+
}
|
|
2207
|
+
options = {
|
|
2208
|
+
...options,
|
|
2209
|
+
target: 5
|
|
2210
|
+
};
|
|
2211
|
+
return this.open(this.workspaceSettingsResource, options);
|
|
2212
|
+
}
|
|
2213
|
+
async openFolderSettings(options = {}) {
|
|
2214
|
+
options = {
|
|
2215
|
+
...options,
|
|
2216
|
+
target: 6
|
|
2217
|
+
};
|
|
2218
|
+
if (!options.folderUri) {
|
|
2219
|
+
throw new Error(`Missing folder URI`);
|
|
2220
|
+
}
|
|
2221
|
+
const folderSettingsUri = await this.getEditableSettingsURI(6 , options.folderUri);
|
|
2222
|
+
if (!folderSettingsUri) {
|
|
2223
|
+
throw new Error(`Invalid folder URI - ${options.folderUri.toString()}`);
|
|
2224
|
+
}
|
|
2225
|
+
return this.open(folderSettingsUri, options);
|
|
2226
|
+
}
|
|
2227
|
+
async openGlobalKeybindingSettings(textual, options) {
|
|
2228
|
+
options = { pinned: true, revealIfOpened: true, ...options };
|
|
2229
|
+
if (textual) {
|
|
2230
|
+
const emptyContents = '// ' + ( (localize(
|
|
2231
|
+
'emptyKeybindingsHeader',
|
|
2232
|
+
"Place your key bindings in this file to override the defaults"
|
|
2233
|
+
))) + '\n[\n]';
|
|
2234
|
+
const editableKeybindings = this.userDataProfileService.currentProfile.keybindingsResource;
|
|
2235
|
+
const openDefaultKeybindings = !!this.configurationService.getValue('workbench.settings.openDefaultKeybindings');
|
|
2236
|
+
await this.createIfNotExists(editableKeybindings, emptyContents);
|
|
2237
|
+
if (openDefaultKeybindings) {
|
|
2238
|
+
const activeEditorGroup = this.editorGroupService.activeGroup;
|
|
2239
|
+
const sideEditorGroup = this.editorGroupService.addGroup(activeEditorGroup.id, 3 );
|
|
2240
|
+
await Promise.all([
|
|
2241
|
+
this.editorService.openEditor({ resource: this.defaultKeybindingsResource, options: { pinned: true, preserveFocus: true, revealIfOpened: true, override: DEFAULT_EDITOR_ASSOCIATION.id }, label: ( (localize('defaultKeybindings', "Default Keybindings"))), description: '' }),
|
|
2242
|
+
this.editorService.openEditor({ resource: editableKeybindings, options }, sideEditorGroup.id)
|
|
2243
|
+
]);
|
|
2244
|
+
}
|
|
2245
|
+
else {
|
|
2246
|
+
await this.editorService.openEditor({ resource: editableKeybindings, options });
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
else {
|
|
2250
|
+
const editor = (await this.editorService.openEditor(this.instantiationService.createInstance(KeybindingsEditorInput), { ...options }));
|
|
2251
|
+
if (options.query) {
|
|
2252
|
+
editor.search(options.query);
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
openDefaultKeybindingsFile() {
|
|
2257
|
+
return this.editorService.openEditor({ resource: this.defaultKeybindingsResource, label: ( (localize('defaultKeybindings', "Default Keybindings"))) });
|
|
2258
|
+
}
|
|
2259
|
+
async openSettingsJson(resource, options) {
|
|
2260
|
+
const group = options?.openToSide ? SIDE_GROUP : undefined;
|
|
2261
|
+
const editor = await this.doOpenSettingsJson(resource, options, group);
|
|
2262
|
+
if (editor && options?.revealSetting) {
|
|
2263
|
+
await this.revealSetting(options.revealSetting.key, !!options.revealSetting.edit, editor, resource);
|
|
2264
|
+
}
|
|
2265
|
+
return editor;
|
|
2266
|
+
}
|
|
2267
|
+
async doOpenSettingsJson(resource, options, group) {
|
|
2268
|
+
const openSplitJSON = !!this.configurationService.getValue(USE_SPLIT_JSON_SETTING);
|
|
2269
|
+
const openDefaultSettings = !!this.configurationService.getValue(DEFAULT_SETTINGS_EDITOR_SETTING);
|
|
2270
|
+
if (openSplitJSON || openDefaultSettings) {
|
|
2271
|
+
return this.doOpenSplitJSON(resource, options, group);
|
|
2272
|
+
}
|
|
2273
|
+
const configurationTarget = options?.target ?? 2 ;
|
|
2274
|
+
const editableSettingsEditorInput = await this.getOrCreateEditableSettingsEditorInput(configurationTarget, resource);
|
|
2275
|
+
options = { ...options, pinned: true };
|
|
2276
|
+
return await this.editorService.openEditor(editableSettingsEditorInput, validateSettingsEditorOptions(options), group);
|
|
2277
|
+
}
|
|
2278
|
+
async doOpenSplitJSON(resource, options = {}, group) {
|
|
2279
|
+
const configurationTarget = options.target ?? 2 ;
|
|
2280
|
+
await this.createSettingsIfNotExists(configurationTarget, resource);
|
|
2281
|
+
const preferencesEditorInput = this.createSplitJsonEditorInput(configurationTarget, resource);
|
|
2282
|
+
options = { ...options, pinned: true };
|
|
2283
|
+
return this.editorService.openEditor(preferencesEditorInput, validateSettingsEditorOptions(options), group);
|
|
2284
|
+
}
|
|
2285
|
+
createSplitJsonEditorInput(configurationTarget, resource) {
|
|
2286
|
+
const editableSettingsEditorInput = this.textEditorService.createTextEditor({ resource });
|
|
2287
|
+
const defaultPreferencesEditorInput = this.instantiationService.createInstance(TextResourceEditorInput, this.getDefaultSettingsResource(configurationTarget), undefined, undefined, undefined, undefined);
|
|
2288
|
+
return this.instantiationService.createInstance(SideBySideEditorInput, editableSettingsEditorInput.getName(), undefined, defaultPreferencesEditorInput, editableSettingsEditorInput);
|
|
2289
|
+
}
|
|
2290
|
+
createSettings2EditorModel() {
|
|
2291
|
+
return this.instantiationService.createInstance(Settings2EditorModel, this.getDefaultSettings(3 ));
|
|
2292
|
+
}
|
|
2293
|
+
getConfigurationTargetFromDefaultSettingsResource(uri) {
|
|
2294
|
+
return this.isDefaultWorkspaceSettingsResource(uri) ?
|
|
2295
|
+
5 :
|
|
2296
|
+
this.isDefaultFolderSettingsResource(uri) ?
|
|
2297
|
+
6 :
|
|
2298
|
+
3 ;
|
|
2299
|
+
}
|
|
2300
|
+
isDefaultSettingsResource(uri) {
|
|
2301
|
+
return this.isDefaultUserSettingsResource(uri) || this.isDefaultWorkspaceSettingsResource(uri) || this.isDefaultFolderSettingsResource(uri);
|
|
2302
|
+
}
|
|
2303
|
+
isDefaultUserSettingsResource(uri) {
|
|
2304
|
+
return uri.authority === 'defaultsettings' && uri.scheme === Schemas.vscode && !!uri.path.match(/\/(\d+\/)?settings\.json$/);
|
|
2305
|
+
}
|
|
2306
|
+
isDefaultWorkspaceSettingsResource(uri) {
|
|
2307
|
+
return uri.authority === 'defaultsettings' && uri.scheme === Schemas.vscode && !!uri.path.match(/\/(\d+\/)?workspaceSettings\.json$/);
|
|
2308
|
+
}
|
|
2309
|
+
isDefaultFolderSettingsResource(uri) {
|
|
2310
|
+
return uri.authority === 'defaultsettings' && uri.scheme === Schemas.vscode && !!uri.path.match(/\/(\d+\/)?resourceSettings\.json$/);
|
|
2311
|
+
}
|
|
2312
|
+
getDefaultSettingsResource(configurationTarget) {
|
|
2313
|
+
switch (configurationTarget) {
|
|
2314
|
+
case 5 :
|
|
2315
|
+
return (
|
|
2316
|
+
(URI.from(
|
|
2317
|
+
{ scheme: Schemas.vscode, authority: 'defaultsettings', path: `/workspaceSettings.json` }
|
|
2318
|
+
))
|
|
2319
|
+
);
|
|
2320
|
+
case 6 :
|
|
2321
|
+
return (
|
|
2322
|
+
(URI.from(
|
|
2323
|
+
{ scheme: Schemas.vscode, authority: 'defaultsettings', path: `/resourceSettings.json` }
|
|
2324
|
+
))
|
|
2325
|
+
);
|
|
2326
|
+
}
|
|
2327
|
+
return (
|
|
2328
|
+
(URI.from(
|
|
2329
|
+
{ scheme: Schemas.vscode, authority: 'defaultsettings', path: `/settings.json` }
|
|
2330
|
+
))
|
|
2331
|
+
);
|
|
2332
|
+
}
|
|
2333
|
+
async getOrCreateEditableSettingsEditorInput(target, resource) {
|
|
2334
|
+
await this.createSettingsIfNotExists(target, resource);
|
|
2335
|
+
return this.textEditorService.createTextEditor({ resource });
|
|
2336
|
+
}
|
|
2337
|
+
async createEditableSettingsEditorModel(configurationTarget, settingsUri) {
|
|
2338
|
+
const workspace = this.contextService.getWorkspace();
|
|
2339
|
+
if (workspace.configuration && ( (workspace.configuration.toString())) === ( (settingsUri.toString()))) {
|
|
2340
|
+
const reference = await this.textModelResolverService.createModelReference(settingsUri);
|
|
2341
|
+
return this.instantiationService.createInstance(WorkspaceConfigurationEditorModel, reference, configurationTarget);
|
|
2342
|
+
}
|
|
2343
|
+
const reference = await this.textModelResolverService.createModelReference(settingsUri);
|
|
2344
|
+
return this.instantiationService.createInstance(SettingsEditorModel, reference, configurationTarget);
|
|
2345
|
+
}
|
|
2346
|
+
async createDefaultSettingsEditorModel(defaultSettingsUri) {
|
|
2347
|
+
const reference = await this.textModelResolverService.createModelReference(defaultSettingsUri);
|
|
2348
|
+
const target = this.getConfigurationTargetFromDefaultSettingsResource(defaultSettingsUri);
|
|
2349
|
+
return this.instantiationService.createInstance(DefaultSettingsEditorModel, defaultSettingsUri, reference, this.getDefaultSettings(target));
|
|
2350
|
+
}
|
|
2351
|
+
getDefaultSettings(target) {
|
|
2352
|
+
if (target === 5 ) {
|
|
2353
|
+
if (!this._defaultWorkspaceSettingsContentModel) {
|
|
2354
|
+
this._defaultWorkspaceSettingsContentModel = ( (new DefaultSettings(this.getMostCommonlyUsedSettings(), target)));
|
|
2355
|
+
}
|
|
2356
|
+
return this._defaultWorkspaceSettingsContentModel;
|
|
2357
|
+
}
|
|
2358
|
+
if (target === 6 ) {
|
|
2359
|
+
if (!this._defaultFolderSettingsContentModel) {
|
|
2360
|
+
this._defaultFolderSettingsContentModel = ( (new DefaultSettings(this.getMostCommonlyUsedSettings(), target)));
|
|
2361
|
+
}
|
|
2362
|
+
return this._defaultFolderSettingsContentModel;
|
|
2363
|
+
}
|
|
2364
|
+
if (!this._defaultUserSettingsContentModel) {
|
|
2365
|
+
this._defaultUserSettingsContentModel = ( (new DefaultSettings(this.getMostCommonlyUsedSettings(), target)));
|
|
2366
|
+
}
|
|
2367
|
+
return this._defaultUserSettingsContentModel;
|
|
2368
|
+
}
|
|
2369
|
+
async getEditableSettingsURI(configurationTarget, resource) {
|
|
2370
|
+
switch (configurationTarget) {
|
|
2371
|
+
case 1 :
|
|
2372
|
+
return this.userDataProfilesService.defaultProfile.settingsResource;
|
|
2373
|
+
case 2 :
|
|
2374
|
+
case 3 :
|
|
2375
|
+
return this.userSettingsResource;
|
|
2376
|
+
case 4 : {
|
|
2377
|
+
const remoteEnvironment = await this.remoteAgentService.getEnvironment();
|
|
2378
|
+
return remoteEnvironment ? remoteEnvironment.settingsPath : null;
|
|
2379
|
+
}
|
|
2380
|
+
case 5 :
|
|
2381
|
+
return this.workspaceSettingsResource;
|
|
2382
|
+
case 6 :
|
|
2383
|
+
if (resource) {
|
|
2384
|
+
return this.getFolderSettingsResource(resource);
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
return null;
|
|
2388
|
+
}
|
|
2389
|
+
async createSettingsIfNotExists(target, resource) {
|
|
2390
|
+
if (this.contextService.getWorkbenchState() === 3 && target === 5 ) {
|
|
2391
|
+
const workspaceConfig = this.contextService.getWorkspace().configuration;
|
|
2392
|
+
if (!workspaceConfig) {
|
|
2393
|
+
return;
|
|
2394
|
+
}
|
|
2395
|
+
const content = await this.textFileService.read(workspaceConfig);
|
|
2396
|
+
if (( (Object.keys(parse$1(content.value)))).indexOf('settings') === -1) {
|
|
2397
|
+
await this.jsonEditingService.write(resource, [{ path: ['settings'], value: {} }], true);
|
|
2398
|
+
}
|
|
2399
|
+
return undefined;
|
|
2400
|
+
}
|
|
2401
|
+
await this.createIfNotExists(resource, emptyEditableSettingsContent);
|
|
2402
|
+
}
|
|
2403
|
+
async createIfNotExists(resource, contents) {
|
|
2404
|
+
try {
|
|
2405
|
+
await this.textFileService.read(resource, { acceptTextOnly: true });
|
|
2406
|
+
}
|
|
2407
|
+
catch (error) {
|
|
2408
|
+
if (error.fileOperationResult === 1 ) {
|
|
2409
|
+
try {
|
|
2410
|
+
await this.textFileService.write(resource, contents);
|
|
2411
|
+
return;
|
|
2412
|
+
}
|
|
2413
|
+
catch (error2) {
|
|
2414
|
+
throw new Error(localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.labelService.getUriLabel(resource, { relative: true }), getErrorMessage(error2)));
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
else {
|
|
2418
|
+
throw error;
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
getMostCommonlyUsedSettings() {
|
|
2423
|
+
return [
|
|
2424
|
+
'files.autoSave',
|
|
2425
|
+
'editor.fontSize',
|
|
2426
|
+
'editor.fontFamily',
|
|
2427
|
+
'editor.tabSize',
|
|
2428
|
+
'editor.renderWhitespace',
|
|
2429
|
+
'editor.cursorStyle',
|
|
2430
|
+
'editor.multiCursorModifier',
|
|
2431
|
+
'editor.insertSpaces',
|
|
2432
|
+
'editor.wordWrap',
|
|
2433
|
+
'files.exclude',
|
|
2434
|
+
'files.associations',
|
|
2435
|
+
'workbench.editor.enablePreview'
|
|
2436
|
+
];
|
|
2437
|
+
}
|
|
2438
|
+
async revealSetting(settingKey, edit, editor, settingsResource) {
|
|
2439
|
+
const codeEditor = editor ? getCodeEditor(editor.getControl()) : null;
|
|
2440
|
+
if (!codeEditor) {
|
|
2441
|
+
return;
|
|
2442
|
+
}
|
|
2443
|
+
const settingsModel = await this.createPreferencesEditorModel(settingsResource);
|
|
2444
|
+
if (!settingsModel) {
|
|
2445
|
+
return;
|
|
2446
|
+
}
|
|
2447
|
+
const position = await this.getPositionToReveal(settingKey, edit, settingsModel, codeEditor);
|
|
2448
|
+
if (position) {
|
|
2449
|
+
codeEditor.setPosition(position);
|
|
2450
|
+
codeEditor.revealPositionNearTop(position);
|
|
2451
|
+
codeEditor.focus();
|
|
2452
|
+
if (edit) {
|
|
2453
|
+
SuggestController.get(codeEditor)?.triggerSuggest();
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
}
|
|
2457
|
+
async getPositionToReveal(settingKey, edit, settingsModel, codeEditor) {
|
|
2458
|
+
const model = codeEditor.getModel();
|
|
2459
|
+
if (!model) {
|
|
2460
|
+
return null;
|
|
2461
|
+
}
|
|
2462
|
+
const schema = ( (Registry.as(Extensions.Configuration))).getConfigurationProperties()[settingKey];
|
|
2463
|
+
const isOverrideProperty = OVERRIDE_PROPERTY_REGEX.test(settingKey);
|
|
2464
|
+
if (!schema && !isOverrideProperty) {
|
|
2465
|
+
return null;
|
|
2466
|
+
}
|
|
2467
|
+
let position = null;
|
|
2468
|
+
const type = schema?.type ?? 'object' ;
|
|
2469
|
+
let setting = settingsModel.getPreference(settingKey);
|
|
2470
|
+
if (!setting && edit) {
|
|
2471
|
+
let defaultValue = (type === 'object' || type === 'array') ? this.configurationService.inspect(settingKey).defaultValue : getDefaultValue(type);
|
|
2472
|
+
defaultValue = defaultValue === undefined && isOverrideProperty ? {} : defaultValue;
|
|
2473
|
+
if (defaultValue !== undefined) {
|
|
2474
|
+
const key = settingsModel instanceof WorkspaceConfigurationEditorModel ? ['settings', settingKey] : [settingKey];
|
|
2475
|
+
await this.jsonEditingService.write(settingsModel.uri, [{ path: key, value: defaultValue }], false);
|
|
2476
|
+
setting = settingsModel.getPreference(settingKey);
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
if (setting) {
|
|
2480
|
+
if (edit) {
|
|
2481
|
+
if (isObject(setting.value) || Array.isArray(setting.value)) {
|
|
2482
|
+
position = { lineNumber: setting.valueRange.startLineNumber, column: setting.valueRange.startColumn + 1 };
|
|
2483
|
+
codeEditor.setPosition(position);
|
|
2484
|
+
await CoreEditingCommands.LineBreakInsert.runEditorCommand(null, codeEditor, null);
|
|
2485
|
+
position = { lineNumber: position.lineNumber + 1, column: model.getLineMaxColumn(position.lineNumber + 1) };
|
|
2486
|
+
const firstNonWhiteSpaceColumn = model.getLineFirstNonWhitespaceColumn(position.lineNumber);
|
|
2487
|
+
if (firstNonWhiteSpaceColumn) {
|
|
2488
|
+
codeEditor.setPosition({ lineNumber: position.lineNumber, column: firstNonWhiteSpaceColumn });
|
|
2489
|
+
await CoreEditingCommands.LineBreakInsert.runEditorCommand(null, codeEditor, null);
|
|
2490
|
+
position = { lineNumber: position.lineNumber, column: model.getLineMaxColumn(position.lineNumber) };
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
else {
|
|
2494
|
+
position = { lineNumber: setting.valueRange.startLineNumber, column: setting.valueRange.endColumn };
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
else {
|
|
2498
|
+
position = { lineNumber: setting.keyRange.startLineNumber, column: setting.keyRange.startColumn };
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
return position;
|
|
2502
|
+
}
|
|
2503
|
+
dispose() {
|
|
2504
|
+
this._onDispose.fire();
|
|
2505
|
+
super.dispose();
|
|
2506
|
+
}
|
|
2507
|
+
};
|
|
2508
|
+
PreferencesService = ( (__decorate([
|
|
2509
|
+
( (__param(0, IEditorService))),
|
|
2510
|
+
( (__param(1, IEditorGroupsService))),
|
|
2511
|
+
( (__param(2, ITextFileService))),
|
|
2512
|
+
( (__param(3, IConfigurationService))),
|
|
2513
|
+
( (__param(4, INotificationService))),
|
|
2514
|
+
( (__param(5, IWorkspaceContextService))),
|
|
2515
|
+
( (__param(6, IInstantiationService))),
|
|
2516
|
+
( (__param(7, IUserDataProfileService))),
|
|
2517
|
+
( (__param(8, IUserDataProfilesService))),
|
|
2518
|
+
( (__param(9, ITextModelService))),
|
|
2519
|
+
( (__param(10, IKeybindingService))),
|
|
2520
|
+
( (__param(11, IModelService))),
|
|
2521
|
+
( (__param(12, IJSONEditingService))),
|
|
2522
|
+
( (__param(13, ILanguageService))),
|
|
2523
|
+
( (__param(14, ILabelService))),
|
|
2524
|
+
( (__param(15, IRemoteAgentService))),
|
|
2525
|
+
( (__param(16, ITextEditorService)))
|
|
2526
|
+
], PreferencesService)));
|
|
2527
|
+
function getServiceOverride() {
|
|
2528
|
+
return {
|
|
2529
|
+
[( IPreferencesService.toString())]: new SyncDescriptor(PreferencesService)
|
|
2530
|
+
};
|
|
2531
|
+
}
|
|
2532
|
+
export { getServiceOverride as default };
|