Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as nls from '../../../../nls.js';
7
import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor } from '../../../services/statusbar/browser/statusbar.js';
8
import { Disposable, MutableDisposable } from '../../../../base/common/lifecycle.js';
9
import { parseKeyboardLayoutDescription, areKeyboardLayoutsEqual, getKeyboardLayoutId, IKeyboardLayoutService, IKeyboardLayoutInfo } from '../../../../platform/keyboardLayout/common/keyboardLayout.js';
10
import { IWorkbenchContribution, WorkbenchPhase, registerWorkbenchContribution2 } from '../../../common/contributions.js';
11
import { KEYBOARD_LAYOUT_OPEN_PICKER } from '../common/preferences.js';
12
import { isMacintosh, isWindows } from '../../../../base/common/platform.js';
13
import { QuickPickInput, IQuickInputService, IQuickPickItem } from '../../../../platform/quickinput/common/quickInput.js';
14
import { Action2, registerAction2 } from '../../../../platform/actions/common/actions.js';
15
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
16
import { IEnvironmentService } from '../../../../platform/environment/common/environment.js';
17
import { IFileService } from '../../../../platform/files/common/files.js';
18
import { IEditorService } from '../../../services/editor/common/editorService.js';
19
import { VSBuffer } from '../../../../base/common/buffer.js';
20
import { IEditorPane } from '../../../common/editor.js';
21
import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
22
23
export class KeyboardLayoutPickerContribution extends Disposable implements IWorkbenchContribution {
24
25
static readonly ID = 'workbench.contrib.keyboardLayoutPicker';
26
27
private readonly pickerElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
28
29
constructor(
30
@IKeyboardLayoutService private readonly keyboardLayoutService: IKeyboardLayoutService,
31
@IStatusbarService private readonly statusbarService: IStatusbarService,
32
) {
33
super();
34
35
const name = nls.localize('status.workbench.keyboardLayout', "Keyboard Layout");
36
37
const layout = this.keyboardLayoutService.getCurrentKeyboardLayout();
38
if (layout) {
39
const layoutInfo = parseKeyboardLayoutDescription(layout);
40
const text = nls.localize('keyboardLayout', "Layout: {0}", layoutInfo.label);
41
42
this.pickerElement.value = this.statusbarService.addEntry(
43
{
44
name,
45
text,
46
ariaLabel: text,
47
command: KEYBOARD_LAYOUT_OPEN_PICKER
48
},
49
'status.workbench.keyboardLayout',
50
StatusbarAlignment.RIGHT
51
);
52
}
53
54
this._register(this.keyboardLayoutService.onDidChangeKeyboardLayout(() => {
55
const layout = this.keyboardLayoutService.getCurrentKeyboardLayout();
56
const layoutInfo = parseKeyboardLayoutDescription(layout);
57
58
if (this.pickerElement.value) {
59
const text = nls.localize('keyboardLayout', "Layout: {0}", layoutInfo.label);
60
this.pickerElement.value.update({
61
name,
62
text,
63
ariaLabel: text,
64
command: KEYBOARD_LAYOUT_OPEN_PICKER
65
});
66
} else {
67
const text = nls.localize('keyboardLayout', "Layout: {0}", layoutInfo.label);
68
this.pickerElement.value = this.statusbarService.addEntry(
69
{
70
name,
71
text,
72
ariaLabel: text,
73
command: KEYBOARD_LAYOUT_OPEN_PICKER
74
},
75
'status.workbench.keyboardLayout',
76
StatusbarAlignment.RIGHT
77
);
78
}
79
}));
80
}
81
}
82
83
registerWorkbenchContribution2(KeyboardLayoutPickerContribution.ID, KeyboardLayoutPickerContribution, WorkbenchPhase.BlockStartup);
84
85
interface LayoutQuickPickItem extends IQuickPickItem {
86
layout: IKeyboardLayoutInfo;
87
}
88
89
interface IUnknownLayout {
90
text?: string;
91
lang?: string;
92
layout?: string;
93
}
94
95
const DEFAULT_CONTENT: string = [
96
`// ${nls.localize('displayLanguage', 'Defines the keyboard layout used in VS Code in the browser environment.')}`,
97
`// ${nls.localize('doc', 'Open VS Code and run "Developer: Inspect Key Mappings (JSON)" from Command Palette.')}`,
98
``,
99
`// Once you have the keyboard layout info, please paste it below.`,
100
'\n'
101
].join('\n');
102
103
registerAction2(class extends Action2 {
104
constructor() {
105
super({
106
id: KEYBOARD_LAYOUT_OPEN_PICKER,
107
title: nls.localize2('keyboard.chooseLayout', "Change Keyboard Layout"),
108
f1: true
109
});
110
}
111
112
async run(accessor: ServicesAccessor): Promise<void> {
113
const keyboardLayoutService = accessor.get(IKeyboardLayoutService);
114
const quickInputService = accessor.get(IQuickInputService);
115
const configurationService = accessor.get(IConfigurationService);
116
const environmentService = accessor.get(IEnvironmentService);
117
const editorService = accessor.get(IEditorService);
118
const fileService = accessor.get(IFileService);
119
120
const layouts = keyboardLayoutService.getAllKeyboardLayouts();
121
const currentLayout = keyboardLayoutService.getCurrentKeyboardLayout();
122
const layoutConfig = configurationService.getValue('keyboard.layout');
123
const isAutoDetect = layoutConfig === 'autodetect';
124
125
const picks: QuickPickInput[] = layouts.map(layout => {
126
const picked = !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout);
127
const layoutInfo = parseKeyboardLayoutDescription(layout);
128
return {
129
layout: layout,
130
label: [layoutInfo.label, (layout && layout.isUserKeyboardLayout) ? '(User configured layout)' : ''].join(' '),
131
id: (layout as IUnknownLayout).text || (layout as IUnknownLayout).lang || (layout as IUnknownLayout).layout,
132
description: layoutInfo.description + (picked ? ' (Current layout)' : ''),
133
picked: !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout)
134
};
135
}).sort((a: IQuickPickItem, b: IQuickPickItem) => {
136
return a.label < b.label ? -1 : (a.label > b.label ? 1 : 0);
137
});
138
139
if (picks.length > 0) {
140
const platform = isMacintosh ? 'Mac' : isWindows ? 'Win' : 'Linux';
141
picks.unshift({ type: 'separator', label: nls.localize('layoutPicks', "Keyboard Layouts ({0})", platform) });
142
}
143
144
const configureKeyboardLayout: IQuickPickItem = { label: nls.localize('configureKeyboardLayout', "Configure Keyboard Layout") };
145
146
picks.unshift(configureKeyboardLayout);
147
148
// Offer to "Auto Detect"
149
const autoDetectMode: IQuickPickItem = {
150
label: nls.localize('autoDetect', "Auto Detect"),
151
description: isAutoDetect ? `Current: ${parseKeyboardLayoutDescription(currentLayout).label}` : undefined,
152
picked: isAutoDetect ? true : undefined
153
};
154
155
picks.unshift(autoDetectMode);
156
157
const pick = await quickInputService.pick(picks, { placeHolder: nls.localize('pickKeyboardLayout', "Select Keyboard Layout"), matchOnDescription: true });
158
if (!pick) {
159
return;
160
}
161
162
if (pick === autoDetectMode) {
163
// set keymap service to auto mode
164
configurationService.updateValue('keyboard.layout', 'autodetect');
165
return;
166
}
167
168
if (pick === configureKeyboardLayout) {
169
const file = environmentService.keyboardLayoutResource;
170
171
await fileService.stat(file).then(undefined, () => {
172
return fileService.createFile(file, VSBuffer.fromString(DEFAULT_CONTENT));
173
}).then((stat): Promise<IEditorPane | undefined> | undefined => {
174
if (!stat) {
175
return undefined;
176
}
177
return editorService.openEditor({
178
resource: stat.resource,
179
languageId: 'jsonc',
180
options: { pinned: true }
181
});
182
}, (error) => {
183
throw new Error(nls.localize('fail.createSettings', "Unable to create '{0}' ({1}).", file.toString(), error));
184
});
185
186
return Promise.resolve();
187
}
188
189
configurationService.updateValue('keyboard.layout', getKeyboardLayoutId((<LayoutQuickPickItem>pick).layout));
190
}
191
});
192
193