From c5bd62f063103e57331a3e1eb7eba22059f833f0 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sun, 23 Jun 2019 21:48:38 +0200 Subject: [PATCH] adopt keybindings to user data service --- .../environment/common/environment.ts | 1 - .../environment/node/environmentService.ts | 3 - .../platform/keybinding/common/keybinding.ts | 2 + .../browser/preferences.contribution.ts | 4 +- .../environment/browser/environmentService.ts | 2 - .../keybinding/browser/keybindingService.ts | 86 ++----------- .../keybinding/common/keybindingEditing.ts | 113 ++++++++---------- .../keybindingEditing.test.ts | 15 +-- .../preferences/browser/preferencesService.ts | 6 +- .../textfile/common/textFileEditorModel.ts | 6 +- 10 files changed, 78 insertions(+), 160 deletions(-) diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 2679dd2d68b..196b47933c1 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -97,7 +97,6 @@ export interface IEnvironmentService { appNameLong: string; appQuality?: string; appSettingsHome: URI; - keybindingsResource: URI; keyboardLayoutResource: URI; machineSettingsHome: URI; diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index e2b0934a468..aa956e5f306 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -132,9 +132,6 @@ export class EnvironmentService implements IEnvironmentService { @memoize get settingsSearchUrl(): string | undefined { return product.settingsSearchUrl; } - @memoize - get keybindingsResource(): URI { return resources.joinPath(this.appSettingsHome, 'keybindings.json'); } - @memoize get keyboardLayoutResource(): URI { return resources.joinPath(this.appSettingsHome, 'keyboardLayout.json'); } diff --git a/src/vs/platform/keybinding/common/keybinding.ts b/src/vs/platform/keybinding/common/keybinding.ts index 57b2f701fce..7ceaf162a3d 100644 --- a/src/vs/platform/keybinding/common/keybinding.ts +++ b/src/vs/platform/keybinding/common/keybinding.ts @@ -10,6 +10,8 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { IResolveResult } from 'vs/platform/keybinding/common/keybindingResolver'; import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem'; +export const USER_KEYBINDINGS_KEY = 'keybindings.json'; + export interface IUserFriendlyKeybinding { key: string; command: string; diff --git a/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts b/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts index cf6d46bc632..02013097199 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts @@ -40,6 +40,7 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IKeybindingEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing'; Registry.as(EditorExtensions.Editors).registerEditor( new EditorDescriptor( @@ -371,6 +372,7 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon constructor( @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, + @IKeybindingEditingService keybindingEditingService: IKeybindingEditingService, @IConfigurationService configurationService: IConfigurationService, @IPreferencesService private readonly preferencesService: IPreferencesService, @IWorkspaceContextService private readonly workpsaceContextService: IWorkspaceContextService, @@ -387,7 +389,7 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon dark: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/preferences-editor-inverse.svg`)) } }, - when: ResourceContextKey.Resource.isEqualTo(environmentService.keybindingsResource.toString()), + when: ResourceContextKey.Resource.isEqualTo(keybindingEditingService.userKeybindingsResource.toString()), group: 'navigation', order: 1 }); diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index e3911e2833a..dfed462b94b 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -71,7 +71,6 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { this.configuration.remoteAuthority = configuration.remoteAuthority; this.appSettingsHome = joinPath(URI.revive(JSON.parse(document.getElementById('vscode-remote-user-data-uri')!.getAttribute('data-settings')!)), 'User'); - this.keybindingsResource = joinPath(this.appSettingsHome, 'keybindings.json'); this.keyboardLayoutResource = joinPath(this.appSettingsHome, 'keyboardLayout.json'); this.logsPath = '/web/logs'; @@ -96,7 +95,6 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { appNameLong: string; appQuality?: string; appSettingsHome: URI; - keybindingsResource: URI; keyboardLayoutResource: URI; machineSettingsHome: URI; machineSettingsResource: URI; diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index fb7e5465845..f0ddd401ce9 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -19,7 +19,7 @@ import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/commo import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService'; -import { IKeyboardEvent, IUserFriendlyKeybinding, KeybindingSource, IKeybindingService, IKeybindingEvent } from 'vs/platform/keybinding/common/keybinding'; +import { IKeyboardEvent, IUserFriendlyKeybinding, KeybindingSource, IKeybindingService, IKeybindingEvent, USER_KEYBINDINGS_KEY } from 'vs/platform/keybinding/common/keybinding'; import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver'; import { IKeybindingItem, IKeybindingRule2, KeybindingWeight, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem'; @@ -36,17 +36,15 @@ import { MenuRegistry } from 'vs/platform/actions/common/actions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; // tslint:disable-next-line: import-patterns import { commandsExtensionPoint } from 'vs/workbench/api/common/menusExtensionPoint'; -import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { RunOnceScheduler } from 'vs/base/common/async'; -import { URI } from 'vs/base/common/uri'; -import { IFileService, FileChangesEvent, FileChangeType } from 'vs/platform/files/common/files'; -import { dirname, isEqual } from 'vs/base/common/resources'; import { parse } from 'vs/base/common/json'; import * as objects from 'vs/base/common/objects'; import { IKeymapService } from 'vs/workbench/services/keybinding/common/keymapInfo'; import { getDispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; import { isArray } from 'vs/base/common/types'; import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; +import { IUserDataService } from 'vs/workbench/services/userData/common/userData'; interface ContributedKeyBinding { command: string; @@ -158,8 +156,8 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { @IConfigurationService configurationService: IConfigurationService, @IWindowService private readonly windowService: IWindowService, @IExtensionService extensionService: IExtensionService, - @IFileService fileService: IFileService, - @IKeymapService private readonly keymapService: IKeymapService + @IKeymapService private readonly keymapService: IKeymapService, + @IUserDataService userDataService: IUserDataService, ) { super(contextKeyService, commandService, telemetryService, notificationService); @@ -185,7 +183,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { this._cachedResolver = null; - this.userKeybindings = this._register(new UserKeybindings(environmentService.keybindingsResource, fileService)); + this.userKeybindings = this._register(new UserKeybindings(userDataService)); this.userKeybindings.initialize().then(() => { if (this.userKeybindings.keybindings.length) { this.updateResolver({ source: KeybindingSource.User }); @@ -552,100 +550,40 @@ class UserKeybindings extends Disposable { private _keybindings: IUserFriendlyKeybinding[] = []; get keybindings(): IUserFriendlyKeybinding[] { return this._keybindings; } + private readonly reloadConfigurationScheduler: RunOnceScheduler; + protected readonly _onDidChange: Emitter = this._register(new Emitter()); readonly onDidChange: Event = this._onDidChange.event; - private fileWatcherDisposable: IDisposable = Disposable.None; - private directoryWatcherDisposable: IDisposable = Disposable.None; - constructor( - private readonly keybindingsResource: URI, - private readonly fileService: IFileService + private readonly userDataService: IUserDataService ) { super(); - this._register(fileService.onFileChanges(e => this.handleFileEvents(e))); + this._register(Event.filter(this.userDataService.onDidChange, e => e.contains(USER_KEYBINDINGS_KEY))(() => this.reloadConfigurationScheduler.schedule())); this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(changed => { if (changed) { this._onDidChange.fire(); } }), 50)); - this._register(toDisposable(() => { - this.stopWatchingResource(); - this.stopWatchingDirectory(); - })); - } - - private watchResource(): void { - this.fileWatcherDisposable = this.fileService.watch(this.keybindingsResource); - } - - private stopWatchingResource(): void { - this.fileWatcherDisposable.dispose(); - this.fileWatcherDisposable = Disposable.None; - } - - private watchDirectory(): void { - const directory = dirname(this.keybindingsResource); - this.directoryWatcherDisposable = this.fileService.watch(directory); - } - - private stopWatchingDirectory(): void { - this.directoryWatcherDisposable.dispose(); - this.directoryWatcherDisposable = Disposable.None; } async initialize(): Promise { - const exists = await this.fileService.exists(this.keybindingsResource); - this.onResourceExists(exists); await this.reload(); } private async reload(): Promise { const existing = this._keybindings; try { - const content = await this.fileService.readFile(this.keybindingsResource); - const value = parse(content.value.toString()); + const content = (await this.userDataService.read(USER_KEYBINDINGS_KEY)) || '[]'; + const value = parse(content); this._keybindings = isArray(value) ? value : []; } catch (e) { this._keybindings = []; } return existing ? !objects.equals(existing, this._keybindings) : true; } - - private async handleFileEvents(event: FileChangesEvent): Promise { - const events = event.changes; - - let affectedByChanges = false; - - // Find changes that affect the resource - for (const event of events) { - affectedByChanges = isEqual(this.keybindingsResource, event.resource); - if (affectedByChanges) { - if (event.type === FileChangeType.ADDED) { - this.onResourceExists(true); - } else if (event.type === FileChangeType.DELETED) { - this.onResourceExists(false); - } - break; - } - } - - if (affectedByChanges) { - this.reloadConfigurationScheduler.schedule(); - } - } - - private onResourceExists(exists: boolean): void { - if (exists) { - this.stopWatchingDirectory(); - this.watchResource(); - } else { - this.stopWatchingResource(); - this.watchDirectory(); - } - } } let schemaId = 'vscode://schemas/keybindings'; diff --git a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts index 49b53c2d234..f3cbd16af4b 100644 --- a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts +++ b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts @@ -8,23 +8,24 @@ import { Queue } from 'vs/base/common/async'; import * as json from 'vs/base/common/json'; import { setProperty } from 'vs/base/common/jsonEdit'; import { Edit } from 'vs/base/common/jsonFormatter'; -import { Disposable, IReference } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { isArray } from 'vs/base/common/types'; -import { URI } from 'vs/base/common/uri'; import { EditOperation } from 'vs/editor/common/core/editOperation'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { ITextModel } from 'vs/editor/common/model'; -import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IFileService } from 'vs/platform/files/common/files'; import { ServiceIdentifier, createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding'; +import { IUserFriendlyKeybinding, USER_KEYBINDINGS_KEY } from 'vs/platform/keybinding/common/keybinding'; import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem'; -import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IUserDataService } from 'vs/workbench/services/userData/common/userData'; +import { IModeService } from 'vs/editor/common/services/modeService'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { Emitter } from 'vs/base/common/event'; +import { LanguageIdentifier } from 'vs/editor/common/modes'; +import { Schemas } from 'vs/base/common/network'; +import { URI } from 'vs/base/common/uri'; export const IKeybindingEditingService = createDecorator('keybindingEditingService'); @@ -32,6 +33,8 @@ export interface IKeybindingEditingService { _serviceBrand: ServiceIdentifier; + userKeybindingsResource: URI; + editKeybinding(keybindingItem: ResolvedKeybindingItem, key: string, when: string | undefined): Promise; removeKeybinding(keybindingItem: ResolvedKeybindingItem): Promise; @@ -42,18 +45,17 @@ export interface IKeybindingEditingService { export class KeybindingsEditingService extends Disposable implements IKeybindingEditingService { public _serviceBrand: any; - private queue: Queue; - private resource: URI = this.environmentService.keybindingsResource; + readonly userKeybindingsResource: URI; + private queue: Queue; constructor( - @ITextModelService private readonly textModelResolverService: ITextModelService, - @ITextFileService private readonly textFileService: ITextFileService, - @IFileService private readonly fileService: IFileService, - @IConfigurationService private readonly configurationService: IConfigurationService, - @IEnvironmentService private readonly environmentService: IEnvironmentService + @IUserDataService private readonly userDataService: IUserDataService, + @IModeService private readonly modeService: IModeService, + @IModelService private readonly modelService: IModelService ) { super(); + this.userKeybindingsResource = userDataService.toResource(USER_KEYBINDINGS_KEY); this.queue = new Queue(); } @@ -71,45 +73,44 @@ export class KeybindingsEditingService extends Disposable implements IKeybinding private doEditKeybinding(keybindingItem: ResolvedKeybindingItem, key: string, when: string | undefined): Promise { return this.resolveAndValidate() - .then(reference => { - const model = reference.object.textEditorModel; + .then(model => { const userKeybindingEntries = json.parse(model.getValue()); const userKeybindingEntryIndex = this.findUserKeybindingEntryIndex(keybindingItem, userKeybindingEntries); this.updateKeybinding(keybindingItem, key, when, model, userKeybindingEntryIndex); if (keybindingItem.isDefault && keybindingItem.resolvedKeybinding) { this.removeDefaultKeybinding(keybindingItem, model); } - return this.save().then(() => reference.dispose()); + return this.save(model); }); } private doRemoveKeybinding(keybindingItem: ResolvedKeybindingItem): Promise { return this.resolveAndValidate() - .then(reference => { - const model = reference.object.textEditorModel; + .then(model => { if (keybindingItem.isDefault) { this.removeDefaultKeybinding(keybindingItem, model); } else { this.removeUserKeybinding(keybindingItem, model); } - return this.save().then(() => reference.dispose()); + return this.save(model); }); } private doResetKeybinding(keybindingItem: ResolvedKeybindingItem): Promise { return this.resolveAndValidate() - .then(reference => { - const model = reference.object.textEditorModel; + .then(model => { if (!keybindingItem.isDefault) { this.removeUserKeybinding(keybindingItem, model); this.removeUnassignedDefaultKeybinding(keybindingItem, model); } - return this.save().then(() => reference.dispose()); + return this.save(model); }); } - private save(): Promise { - return this.textFileService.save(this.resource); + private async save(model: ITextModel): Promise { + await this.userDataService.write(USER_KEYBINDINGS_KEY, model.getValue()); + model.dispose(); + this.modelService.destroyModel(model.uri); } private updateKeybinding(keybindingItem: ResolvedKeybindingItem, newKey: string, when: string | undefined, model: ITextModel, userKeybindingEntryIndex: number): void { @@ -207,45 +208,33 @@ export class KeybindingsEditingService extends Disposable implements IKeybinding } - private resolveModelReference(): Promise> { - return this.fileService.exists(this.resource) - .then(exists => { - const EOL = this.configurationService.getValue<{}>('files', { overrideIdentifier: 'json' })['eol']; - const result: Promise = exists ? Promise.resolve(null) : this.textFileService.write(this.resource, this.getEmptyContent(EOL), { encoding: 'utf8' }); - return result.then(() => this.textModelResolverService.createModelReference(this.resource)); - }); + private async resolveModel(): Promise { + const content = (await this.userDataService.read(USER_KEYBINDINGS_KEY)) || '[]'; + const languageIdentifier = this.modeService.getLanguageIdentifier('jsonc'); + return this.modelService.createModel(content, languageIdentifier ? { languageIdentifier, onDidChange: new Emitter().event, dispose: () => { } } : null, this.userKeybindingsResource.with({ scheme: Schemas.vscode })); } - private resolveAndValidate(): Promise> { - - // Target cannot be dirty if not writing into buffer - if (this.textFileService.isDirty(this.resource)) { - return Promise.reject(new Error(localize('errorKeybindingsFileDirty', "Unable to write because the keybindings configuration file is dirty. Please save it first and then try again."))); - } - - return this.resolveModelReference() - .then(reference => { - const model = reference.object.textEditorModel; - const EOL = model.getEOL(); - if (model.getValue()) { - const parsed = this.parse(model); - if (parsed.parseErrors.length) { - return Promise.reject(new Error(localize('parseErrors', "Unable to write to the keybindings configuration file. Please open it to correct errors/warnings in the file and try again."))); - } - if (parsed.result) { - if (!isArray(parsed.result)) { - return Promise.reject(new Error(localize('errorInvalidConfiguration', "Unable to write to the keybindings configuration file. It has an object which is not of type Array. Please open the file to clean up and try again."))); - } - } else { - const content = EOL + '[]'; - this.applyEditsToBuffer({ content, length: content.length, offset: model.getValue().length }, model); - } - } else { - const content = this.getEmptyContent(EOL); - this.applyEditsToBuffer({ content, length: content.length, offset: 0 }, model); + private async resolveAndValidate(): Promise { + const model = await this.resolveModel(); + const EOL = model.getEOL(); + if (model.getValue()) { + const parsed = this.parse(model); + if (parsed.parseErrors.length) { + return Promise.reject(new Error(localize('parseErrors', "Unable to write to the keybindings configuration file. Please open it to correct errors/warnings in the file and try again."))); + } + if (parsed.result) { + if (!isArray(parsed.result)) { + return Promise.reject(new Error(localize('errorInvalidConfiguration', "Unable to write to the keybindings configuration file. It has an object which is not of type Array. Please open the file to clean up and try again."))); } - return reference; - }); + } else { + const content = EOL + '[]'; + this.applyEditsToBuffer({ content, length: content.length, offset: model.getValue().length }, model); + } + } else { + const content = this.getEmptyContent(EOL); + this.applyEditsToBuffer({ content, length: content.length, offset: 0 }, model); + } + return model; } private parse(model: ITextModel): { result: IUserFriendlyKeybinding[], parseErrors: json.ParseError[] } { diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts index f91983980e5..c79ddfea801 100644 --- a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts +++ b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts @@ -21,7 +21,6 @@ import { ITextResourcePropertiesService } from 'vs/editor/common/services/resour import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding'; @@ -45,6 +44,8 @@ import { FileService } from 'vs/workbench/services/files/common/fileService'; import { Schemas } from 'vs/base/common/network'; import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFileSystemProvider'; import { URI } from 'vs/base/common/uri'; +import { IUserDataService } from 'vs/workbench/services/userData/common/userData'; +import { FileUserDataService } from 'vs/workbench/services/userData/common/fileUserDataService'; interface Modifiers { metaKey?: boolean; @@ -66,7 +67,6 @@ suite('KeybindingsEditing', () => { instantiationService = new TestInstantiationService(); - instantiationService.stub(IEnvironmentService, { keybindingsResource: URI.file(keybindingsFile) }); instantiationService.stub(IConfigurationService, ConfigurationService); instantiationService.stub(IConfigurationService, 'getValue', { 'eol': '\n' }); instantiationService.stub(IConfigurationService, 'onDidUpdateConfiguration', () => { }); @@ -85,6 +85,7 @@ suite('KeybindingsEditing', () => { const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); instantiationService.stub(IFileService, fileService); + instantiationService.stub(IUserDataService, new FileUserDataService(URI.file(testDir), fileService)); instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService)); instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService)); instantiationService.stub(ITextModelService, instantiationService.createInstance(TextModelResolverService)); @@ -144,16 +145,6 @@ suite('KeybindingsEditing', () => { .then(() => assert.deepEqual(getUserKeybindings(), expected)); }); - test('edit a default keybinding to a non existing keybindings file', () => { - keybindingsFile = path.join(testDir, 'nonExistingFile.json'); - instantiationService.get(IEnvironmentService).keybindingsResource = URI.file(keybindingsFile); - testObject = instantiationService.createInstance(KeybindingsEditingService); - - const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }]; - return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }), 'alt+c', undefined) - .then(() => assert.deepEqual(getUserKeybindings(), expected)); - }); - test('edit a default keybinding to an empty array', () => { writeToKeybindingsFile(); const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }]; diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index 2de8150a4c4..ce7695b8f78 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -20,7 +20,6 @@ import { ITextModelService } from 'vs/editor/common/services/resolverService'; import * as nls from 'vs/nls'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { FileOperationError, FileOperationResult } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -38,6 +37,7 @@ import { defaultKeybindingsContents, DefaultKeybindingsEditorModel, DefaultSetti import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { IKeybindingEditingService } from '../../keybinding/common/keybindingEditing'; const emptyEditableSettingsContent = '{\n}'; @@ -64,7 +64,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic @INotificationService private readonly notificationService: INotificationService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IInstantiationService private readonly instantiationService: IInstantiationService, - @IEnvironmentService private readonly environmentService: IEnvironmentService, + @IKeybindingEditingService private readonly keybindingEditingService: IKeybindingEditingService, @ITelemetryService private readonly telemetryService: ITelemetryService, @ITextModelService private readonly textModelResolverService: ITextModelService, @IKeybindingService keybindingService: IKeybindingService, @@ -273,7 +273,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic this.telemetryService.publicLog('openKeybindings', { textual }); if (textual) { const emptyContents = '// ' + nls.localize('emptyKeybindingsHeader', "Place your key bindings in this file to override the defaults") + '\n[\n]'; - const editableKeybindings = this.environmentService.keybindingsResource; + const editableKeybindings = this.keybindingEditingService.userKeybindingsResource; const openDefaultKeybindings = !!this.configurationService.getValue('workbench.settings.openDefaultKeybindings'); // Create as needed and open in editor diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 866ee212c2e..60c009b6b56 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -31,6 +31,7 @@ import { isEqual, isEqualOrParent, extname, basename, joinPath } from 'vs/base/c import { onUnexpectedError } from 'vs/base/common/errors'; import { Schemas } from 'vs/base/common/network'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IKeybindingEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing'; export interface IBackupMetaData { mtime: number; @@ -106,7 +107,8 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil @IEnvironmentService private readonly environmentService: IEnvironmentService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @ILogService private readonly logService: ILogService, - @IConfigurationService private readonly configurationService: IConfigurationService + @IConfigurationService private readonly configurationService: IConfigurationService, + @IKeybindingEditingService private readonly keybindingEditingService: IKeybindingEditingService ) { super(modelService, modeService); @@ -782,7 +784,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } // Check for keybindings file - if (isEqual(this.resource, this.environmentService.keybindingsResource, !isLinux)) { + if (isEqual(this.resource, this.keybindingEditingService.userKeybindingsResource, !isLinux)) { return 'keybindings'; } -- GitLab