Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/services/keybinding/common/keymapInfo.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 { isWindows, isLinux } from '../../../../base/common/platform.js';
7
import { getKeyboardLayoutId, IKeyboardLayoutInfo } from '../../../../platform/keyboardLayout/common/keyboardLayout.js';
8
9
function deserializeMapping(serializedMapping: ISerializedMapping) {
10
const mapping = serializedMapping;
11
12
const ret: { [key: string]: any } = {};
13
for (const key in mapping) {
14
const result: (string | number)[] = mapping[key];
15
if (result.length) {
16
const value = result[0];
17
const withShift = result[1];
18
const withAltGr = result[2];
19
const withShiftAltGr = result[3];
20
const mask = Number(result[4]);
21
const vkey = result.length === 6 ? result[5] : undefined;
22
ret[key] = {
23
'value': value,
24
'vkey': vkey,
25
'withShift': withShift,
26
'withAltGr': withAltGr,
27
'withShiftAltGr': withShiftAltGr,
28
'valueIsDeadKey': (mask & 1) > 0,
29
'withShiftIsDeadKey': (mask & 2) > 0,
30
'withAltGrIsDeadKey': (mask & 4) > 0,
31
'withShiftAltGrIsDeadKey': (mask & 8) > 0
32
};
33
} else {
34
ret[key] = {
35
'value': '',
36
'valueIsDeadKey': false,
37
'withShift': '',
38
'withShiftIsDeadKey': false,
39
'withAltGr': '',
40
'withAltGrIsDeadKey': false,
41
'withShiftAltGr': '',
42
'withShiftAltGrIsDeadKey': false
43
};
44
}
45
}
46
47
return ret;
48
}
49
50
export interface IRawMixedKeyboardMapping {
51
[key: string]: {
52
value: string;
53
withShift: string;
54
withAltGr: string;
55
withShiftAltGr: string;
56
valueIsDeadKey?: boolean;
57
withShiftIsDeadKey?: boolean;
58
withAltGrIsDeadKey?: boolean;
59
withShiftAltGrIsDeadKey?: boolean;
60
61
};
62
}
63
64
interface ISerializedMapping {
65
[key: string]: (string | number)[];
66
}
67
68
export interface IKeymapInfo {
69
layout: IKeyboardLayoutInfo;
70
secondaryLayouts: IKeyboardLayoutInfo[];
71
mapping: ISerializedMapping;
72
isUserKeyboardLayout?: boolean;
73
}
74
75
export class KeymapInfo {
76
mapping: IRawMixedKeyboardMapping;
77
isUserKeyboardLayout: boolean;
78
79
constructor(public layout: IKeyboardLayoutInfo, public secondaryLayouts: IKeyboardLayoutInfo[], keyboardMapping: ISerializedMapping, isUserKeyboardLayout?: boolean) {
80
this.mapping = deserializeMapping(keyboardMapping);
81
this.isUserKeyboardLayout = !!isUserKeyboardLayout;
82
this.layout.isUserKeyboardLayout = !!isUserKeyboardLayout;
83
}
84
85
static createKeyboardLayoutFromDebugInfo(layout: IKeyboardLayoutInfo, value: IRawMixedKeyboardMapping, isUserKeyboardLayout?: boolean): KeymapInfo {
86
const keyboardLayoutInfo = new KeymapInfo(layout, [], {}, true);
87
keyboardLayoutInfo.mapping = value;
88
return keyboardLayoutInfo;
89
}
90
91
update(other: KeymapInfo) {
92
this.layout = other.layout;
93
this.secondaryLayouts = other.secondaryLayouts;
94
this.mapping = other.mapping;
95
this.isUserKeyboardLayout = other.isUserKeyboardLayout;
96
this.layout.isUserKeyboardLayout = other.isUserKeyboardLayout;
97
}
98
99
getScore(other: IRawMixedKeyboardMapping): number {
100
let score = 0;
101
for (const key in other) {
102
if (isWindows && (key === 'Backslash' || key === 'KeyQ')) {
103
// keymap from Chromium is probably wrong.
104
continue;
105
}
106
107
if (isLinux && (key === 'Backspace' || key === 'Escape')) {
108
// native keymap doesn't align with keyboard event
109
continue;
110
}
111
112
const currentMapping = this.mapping[key];
113
114
if (currentMapping === undefined) {
115
score -= 1;
116
}
117
118
const otherMapping = other[key];
119
120
if (currentMapping && otherMapping && currentMapping.value !== otherMapping.value) {
121
score -= 1;
122
}
123
}
124
125
return score;
126
}
127
128
equal(other: KeymapInfo): boolean {
129
if (this.isUserKeyboardLayout !== other.isUserKeyboardLayout) {
130
return false;
131
}
132
133
if (getKeyboardLayoutId(this.layout) !== getKeyboardLayoutId(other.layout)) {
134
return false;
135
}
136
137
return this.fuzzyEqual(other.mapping);
138
}
139
140
fuzzyEqual(other: IRawMixedKeyboardMapping): boolean {
141
for (const key in other) {
142
if (isWindows && (key === 'Backslash' || key === 'KeyQ')) {
143
// keymap from Chromium is probably wrong.
144
continue;
145
}
146
if (this.mapping[key] === undefined) {
147
return false;
148
}
149
150
const currentMapping = this.mapping[key];
151
const otherMapping = other[key];
152
153
if (currentMapping.value !== otherMapping.value) {
154
return false;
155
}
156
}
157
158
return true;
159
}
160
}
161
162