1 /**
2  * Consoleur: a package for interaction with character-oriented terminal emulators
3  *
4  * Copyright: Maxim Freck, 2017.
5  * Authors:   Maxim Freck <maxim@freck.pp.ru>
6  * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  */
8 module consoleur.input.key;
9 version(Posix) {
10 
11 import consoleur.core;
12 import consoleur.core.termparam;
13 import consoleur.terminfo;
14 
15 public import consoleur.input.types;
16 import consoleur.input.util;
17 
18 /*******
19  * Synchronously reads Key from STDIN.
20  * Returns: Key structure
21  *
22  * Params:
23  *  escDelay = The escape key detection delay. The default value is -1,
24  *             this means that the function always waits for two \x1b
25  *             characters from STDIN.
26  */
27 Key getKeyPressed(int escDelay = -1) @safe
28 {
29 	immutable tparam = setTermparam(Term.quiet|Term.raw);
30 	return processKeyPressed(escDelay);
31 }
32 
33 /*******
34  * Asynchronously reads Key from STDIN.
35  * Returns: Key structure or Command.empty if STDIN is empty
36  *
37  * Params:
38  *  escDelay = The escape key detection delay. The default value is -1,
39  *             this means that the function always waits for two \x1b
40  *             characters from STDIN.
41  */
42 Key peekKeyPressed(int escDelay = -1) @safe
43 {
44 	immutable tparam = setTermparam(Term.quiet|Term.raw|Term.async);
45 	return processKeyPressed(escDelay);
46 }
47 
48 private Key processKeyPressed(int escDelay) @safe
49 {
50 	ubyte b;
51 
52 	if (!popStdin(b)) {
53 		return Key(KeyType.COMMAND, KeyValue(Command.empty));
54 	}
55 
56 	if (b == 0x1b) {
57 		if (escDelay == -1) {
58 			immutable tparam = setTermparam(Term.quiet|Term.raw);
59 			popStdin(b);
60 		} else {
61 			immutable tparam = setTermparam(Term.quiet|Term.raw|Term.async, cast(ubyte)(escDelay));
62 			if (!popStdin(b)) return Key(KeyType.COMMAND, KeyValue(Command.escape));
63 		}
64 
65 		pushStdin(b);
66 
67 		return readCommandSequence();
68 	}
69 
70 	version(WithSuperKey) {
71 		if (b == 0x18) {
72 			return readSuperKey();
73 		}
74 	}
75 
76 	if (b > 128) {
77 		return readUtf8Char(Key(KeyType.UTF8, KeyValue(cast(ubyte[6])[b,0,0,0,0,0])));
78 	}
79 
80 	if (b < 0x20 || b == 0x7f) {
81 		return Key(KeyType.COMMAND, KeyValue(cast(Command)b));
82 	}
83 
84 	return Key(KeyType.ASCII, KeyValue(cast(char)b));
85 }
86 
87 private Key readCommandSequence() @safe
88 {
89 	ubyte b;
90 	popStdin(b);
91 
92 	if (b == 0x1b) {
93 		auto tparam = setTermparam(Term.quiet|Term.raw|Term.async, 0);
94 
95 		if (!popStdin(b)) { //C0
96 			return Key(KeyType.COMMAND, KeyValue(cast(Command)0x1b));
97 		}
98 
99 		if (b == 0x5b) { //alt + CSI
100 			tparam.restoreBack();
101 			auto key = mapSequence(readCsiSequence());
102 			key.modifier |= KeyModifier.alt;
103 			return key;
104 		}
105 
106 		if (b == 0x4f) { //alt + SS3
107 			tparam.restoreBack();
108 			auto key = mapSequence(readSs3Sequence());
109 			key.modifier |= KeyModifier.alt;
110 			return key;
111 		}
112 
113 		pushStdin(b);
114 		return Key(KeyType.COMMAND, KeyValue(cast(Command)0x1b));
115 	}
116 
117 	if (b == 0x5b) {
118 		return mapSequence(readCsiSequence());
119 	}
120 
121 	if (b == 0x4f) {
122 		return mapSequence(readSs3Sequence());
123 	}
124 
125 	if (b < 0x20 || b == 0x7f) {
126 		return Key(KeyType.COMMAND, KeyValue(cast(Command)b), KeyModifier.alt);
127 	}
128 
129 	if (b < 128) {
130 		return Key(KeyType.ASCII, KeyValue(b), KeyModifier.alt);
131 	}
132 
133 	if (b > 128) {
134 		return readUtf8Char(Key(KeyType.UTF8, KeyValue(cast(ubyte[6])[b,0,0,0,0,0]), KeyModifier.alt));
135 	}
136 
137 	return Key(KeyType.COMMAND, KeyValue(cast(Command)-1));
138 }
139 
140 private Key mapSequence(string sequence) @safe
141 {
142 	auto cmd = (sequence in keyMap);
143 	if (cmd is null) return Key(KeyType.RAW, KeyValue(sequence));
144 	return *cmd;
145 }
146 
147 private string readCsiSequence() @safe
148 {
149 	string csi;
150 	ubyte b;
151 
152 	while (popStdin(b)) {
153 		csi~=b;
154 		if (b == 0x24 || (b >= 0x40 && b <= 0x7e && b != 0x5b)) break;
155 	}
156 
157 	return "\x1b["~csi;
158 }
159 
160 private string readSs3Sequence() @safe
161 {
162 	string ss3;
163 	ubyte b;
164 
165 	while (popStdin(b)) {
166 		ss3 ~= b;
167 		if (b < 0x30 || b > 0x39) break;
168 	}
169 
170 	return "\x1bO"~ss3;
171 }
172 
173 version(WithSuperKey) {
174 	private Key readSuperKey() @safe
175 	{
176 		immutable tparam = setTermparam(Term.quiet|Term.raw|Term.async, 0);
177 		int modifier = KeyModifier.supr;
178 		ubyte b1, b2, b3;
179 
180 		if (!popStdin(b1)) return Key(KeyType.COMMAND, KeyValue(cast(Command)0x18));
181 		if (b1 != 0x40) {
182 			pushStdin(b1);
183 			return Key(KeyType.COMMAND, KeyValue(cast(Command)0x18));
184 		}
185 
186 		if (!popStdin(b2)) {
187 			pushStdin(b1);
188 			return Key(KeyType.COMMAND, KeyValue(cast(Command)0x18));
189 		}
190 		if (b2 != 0x73) {
191 			pushStdin(b1);
192 			pushStdin(b2);
193 			return Key(KeyType.COMMAND, KeyValue(cast(Command)0x18));
194 		}
195 
196 		if (!popStdin(b3)) {
197 			pushStdin(b1);
198 			pushStdin(b2);
199 			return Key(KeyType.COMMAND, KeyValue(cast(Command)0x18));
200 		}
201 
202 		if (b3 == 0x1b) {
203 			if (!popStdin(b3)) return Key(KeyType.COMMAND, KeyValue(cast(Command)b3), modifier);
204 			modifier |= KeyModifier.alt;
205 		}
206 
207 		if (b3 < 0x20 || b3 == 0x7f) {
208 			return Key(KeyType.COMMAND, KeyValue(cast(Command)b3), modifier);
209 		}
210 
211 		if (b3 > 128) {
212 			return readUtf8Char(Key(KeyType.UTF8, KeyValue(cast(ubyte[6])[b3,0,0,0,0,0]), modifier));
213 		}
214 
215 		return Key(KeyType.ASCII, KeyValue(cast(char)b3), modifier);
216 	}
217 }
218 
219 
220 private Key readUtf8Char(Key ch) @safe
221 {
222 	foreach (size_t n; 1 .. ch.content.utf[0].codepointLength) {
223 		popStdin(ch.content.utf[n]);
224 	}
225 	return ch;
226 }
227 
228 // ubyte codepointLength(ubyte src) @safe
229 // {
230 // 	if ((src & 0b11111100) == 0b11111100) return 6;
231 // 	if ((src & 0b11111000) == 0b11111000) return 5;
232 // 	if ((src & 0b11110000) == 0b11110000) return 4;
233 // 	if ((src & 0b11100000) == 0b11100000) return 3;
234 // 	if ((src & 0b11000000) == 0b11000000) return 2;
235 // 	if ((src & 0b10000000) == 0b10000000) return 1;
236 // 	return 0;
237 // }
238 
239 
240 private static Key[string] keyMap;
241 
242 shared static this()
243 {
244 	addCommonKeys();
245 	version (WithSuperKey) addSuperKeys();
246 }
247 
248 private void addCommonKeys()
249 {
250 	import std.process: environment, get;
251 
252 	// Relying on the terminfo database is dangerous: the environment variable $TERM can often be set incorrectly (e.g.
253 	// during PuTTY sessions), and many escape sequences are not listed in the database file. Therefore, we simply
254 	// collect all the most common sequences.
255 	keyMap = [
256 		"\x1b[[A": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.none), //Linux
257 		"\x1b[[B": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.none), //Linux
258 		"\x1b[[C": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.none), //Linux
259 		"\x1b[[D": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.none), //Linux
260 		"\x1b[[E": Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.none), //Linux
261 		"\x1b[1;2A": Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.shift), //Konsole
262 		"\x1b[1;2B": Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.shift), //Konsole
263 		"\x1b[1;2C": Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.shift), //Konsole, Xterm
264 		"\x1b[1;2D": Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.shift), //Konsole, Xterm
265 		"\x1b[1;2F": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.shift), //Konsole, Xterm
266 		"\x1b[1;2H": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.shift), //Konsole, Xterm
267 		"\x1b[1;2P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.shift), //Xterm
268 		"\x1b[1;2Q": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.shift), //Xterm
269 		"\x1b[1;2R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.shift), //Xterm
270 		"\x1b[1;2S": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.shift), //Xterm
271 		"\x1b[1;3A": Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.alt), //Konsole, Xterm
272 		"\x1b[1;3B": Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.alt), //Konsole, Xterm
273 		"\x1b[1;3C": Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.alt), //Konsole, Xterm
274 		"\x1b[1;3D": Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.alt), //Konsole, Xterm
275 		"\x1b[1;3E": Key(KeyType.COMMAND, KeyValue(Command.keyB2), KeyModifier.alt), //Xterm
276 		"\x1b[1;3F": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.alt), //Konsole, Xterm
277 		"\x1b[1;3H": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.alt), //Konsole, Xterm
278 		"\x1b[1;3P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.alt), //Xterm
279 		"\x1b[1;3Q": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.alt), //Xterm
280 		"\x1b[1;3R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.alt), //Xterm
281 		"\x1b[1;3S": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.alt), //Xterm
282 		"\x1b[1;4A": Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
283 		"\x1b[1;4B": Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
284 		"\x1b[1;4C": Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
285 		"\x1b[1;4D": Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
286 		"\x1b[1;4E": Key(KeyType.COMMAND, KeyValue(Command.keyB2), KeyModifier.shift|KeyModifier.alt), //Xterm
287 		"\x1b[1;4F": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
288 		"\x1b[1;4H": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
289 		"\x1b[1;4P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.shift|KeyModifier.alt), //Xterm
290 		"\x1b[1;4R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.shift|KeyModifier.alt), //Xterm
291 		"\x1b[1;4S": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.shift|KeyModifier.alt), //Xterm
292 		"\x1b[1;5A": Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.control), //Konsole, Xterm
293 		"\x1b[1;5B": Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.control), //Konsole, Xterm
294 		"\x1b[1;5C": Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.control), //Konsole, Xterm
295 		"\x1b[1;5D": Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.control), //Konsole, Xterm
296 		"\x1b[1;5E": Key(KeyType.COMMAND, KeyValue(Command.keyB2), KeyModifier.control), //Xterm
297 		"\x1b[1;5F": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.control), //Konsole, Xterm
298 		"\x1b[1;5H": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.control), //Konsole, Xterm
299 		"\x1b[1;5P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.control), //Xterm
300 		"\x1b[1;5Q": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.control), //Xterm
301 		"\x1b[1;5R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.control), //Xterm
302 		"\x1b[1;5S": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.control), //Xterm
303 		"\x1b[1;6A": Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
304 		"\x1b[1;6B": Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
305 		"\x1b[1;6C": Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.shift|KeyModifier.control), //Xterm
306 		"\x1b[1;6D": Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.shift|KeyModifier.control), //Xterm
307 		"\x1b[1;6E": Key(KeyType.COMMAND, KeyValue(Command.keyB2), KeyModifier.shift|KeyModifier.control), //Xterm
308 		"\x1b[1;6F": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
309 		"\x1b[1;6H": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
310 		"\x1b[1;6P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.shift|KeyModifier.control), //Xterm
311 		"\x1b[1;6P": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.shift|KeyModifier.control), //Xterm
312 		"\x1b[1;6R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.shift|KeyModifier.control), //Xterm
313 		"\x1b[1;6S": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.shift|KeyModifier.control), //Xterm
314 		"\x1b[1;7A": Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
315 		"\x1b[1;7B": Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
316 		"\x1b[1;7C": Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
317 		"\x1b[1;7D": Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
318 		"\x1b[1;7E": Key(KeyType.COMMAND, KeyValue(Command.keyB2), KeyModifier.alt|KeyModifier.control), //Xterm
319 		"\x1b[1;7F": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
320 		"\x1b[1;7H": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
321 		"\x1b[1;8A": Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
322 		"\x1b[1;8B": Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
323 		"\x1b[1;8C": Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
324 		"\x1b[1;8D": Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
325 		"\x1b[1;8F": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
326 		"\x1b[1;8H": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
327 		"\x1b[1;8P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Xterm
328 		"\x1b[1;8Q": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Xterm
329 		"\x1b[1;8R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Xterm
330 		"\x1b[1;8S": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Xterm
331 		"\x1b[1~": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.none), //PuTTY, Linux
332 		"\x1b[11^": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.control), //rxvt
333 		"\x1b[11~": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.none), //PuTTY, rxvt
334 		"\x1b[12^": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.control), //rxvt
335 		"\x1b[12~": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.none), //PuTTY, rxvt
336 		"\x1b[13^": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.control), //rxvt
337 		"\x1b[13~": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.none), //PuTTY, rxvt
338 		"\x1b[14^": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.control), //rxvt
339 		"\x1b[14~": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.none), //PuTTY, rxvt
340 		"\x1b[15;2~": Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.shift), //Konsole, Xterm
341 		"\x1b[15;3": Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.alt), //Konsole, Xterm
342 		"\x1b[15;4~": Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
343 		"\x1b[15;5~": Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.control), //Konsole, Xterm
344 		"\x1b[15;6~": Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
345 		"\x1b[15;8~": Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
346 		"\x1b[15^": Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.control), //rxvt
347 		"\x1b[15~": Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt
348 		"\x1b[17;2~": Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.shift), //Konsole, Xterm
349 		"\x1b[17;3~": Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.alt), //Konsole, Xterm
350 		"\x1b[17;4~": Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
351 		"\x1b[17;5~": Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.control), //Konsole, Xterm
352 		"\x1b[17;6~": Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
353 		"\x1b[17;8~": Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
354 		"\x1b[17^": Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.control), //rxvt
355 		"\x1b[17~": Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
356 		"\x1b[18;2~": Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.shift), //Konsole, Xterm
357 		"\x1b[18;3~": Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.alt), //Konsole, Xterm
358 		"\x1b[18;4~": Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
359 		"\x1b[18;5~": Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.control), //Konsole
360 		"\x1b[18;6~": Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
361 		"\x1b[18;8~": Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
362 		"\x1b[18^": Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.control), //rxvt
363 		"\x1b[18~": Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
364 		"\x1b[19;2~": Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.shift), //Konsole, Xterm
365 		"\x1b[19;3~": Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.alt), //Konsole, Xterm
366 		"\x1b[19;4~": Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
367 		"\x1b[19;5~": Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.control), //Konsole
368 		"\x1b[19;6~": Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
369 		"\x1b[19;8~": Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
370 		"\x1b[19^": Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.control), //rxvt
371 		"\x1b[19~": Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
372 		"\x1b[2;3~": Key(KeyType.COMMAND, KeyValue(Command.keyInsert), KeyModifier.alt), //Konsole, Xterm
373 		"\x1b[2;4~": Key(KeyType.COMMAND, KeyValue(Command.keyInsert), KeyModifier.shift|KeyModifier.alt), //Konsole
374 		"\x1b[2;5~": Key(KeyType.COMMAND, KeyValue(Command.keyInsert), KeyModifier.control), //Konsole, Xterm
375 		"\x1b[2;7~": Key(KeyType.COMMAND, KeyValue(Command.keyInsert), KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
376 		"\x1b[2;8~": Key(KeyType.COMMAND, KeyValue(Command.keyInsert), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole
377 		"\x1b[2@": Key(KeyType.COMMAND, KeyValue(Command.keyInsert), KeyModifier.shift|KeyModifier.control), //rxvt
378 		"\x1b[2^": Key(KeyType.COMMAND, KeyValue(Command.keyInsert), KeyModifier.control), //rxvt
379 		"\x1b[2~": Key(KeyType.COMMAND, KeyValue(Command.keyInsert), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
380 		"\x1b[20;2~": Key(KeyType.COMMAND, KeyValue(Command.keyF9), KeyModifier.shift), //Konsole, Xterm
381 		"\x1b[20;3~": Key(KeyType.COMMAND, KeyValue(Command.keyF9), KeyModifier.alt), //Konsole, Xterm
382 		"\x1b[20;4~": Key(KeyType.COMMAND, KeyValue(Command.keyF9), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
383 		"\x1b[20;5~": Key(KeyType.COMMAND, KeyValue(Command.keyF9), KeyModifier.control), //Konsole
384 		"\x1b[20;6~": Key(KeyType.COMMAND, KeyValue(Command.keyF9), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
385 		"\x1b[20;8~": Key(KeyType.COMMAND, KeyValue(Command.keyF9), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
386 		"\x1b[20^": Key(KeyType.COMMAND, KeyValue(Command.keyF9), KeyModifier.control), //rxvt
387 		"\x1b[20~": Key(KeyType.COMMAND, KeyValue(Command.keyF9), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
388 		"\x1b[21;2~": Key(KeyType.COMMAND, KeyValue(Command.keyF10), KeyModifier.shift), //Konsole, Xterm
389 		"\x1b[21;3~": Key(KeyType.COMMAND, KeyValue(Command.keyF10), KeyModifier.alt), //Konsole, Xterm
390 		"\x1b[21;4~": Key(KeyType.COMMAND, KeyValue(Command.keyF10), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
391 		"\x1b[21;5~": Key(KeyType.COMMAND, KeyValue(Command.keyF10), KeyModifier.control), //Konsole
392 		"\x1b[21;6~": Key(KeyType.COMMAND, KeyValue(Command.keyF10), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
393 		"\x1b[21;8~": Key(KeyType.COMMAND, KeyValue(Command.keyF10), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
394 		"\x1b[21^": Key(KeyType.COMMAND, KeyValue(Command.keyF10), KeyModifier.control), //rxvt
395 		"\x1b[21~": Key(KeyType.COMMAND, KeyValue(Command.keyF10), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
396 		"\x1b[23;2~": Key(KeyType.COMMAND, KeyValue(Command.keyF11), KeyModifier.shift), //Konsole, Xterm
397 		"\x1b[23;3~": Key(KeyType.COMMAND, KeyValue(Command.keyF11), KeyModifier.alt), //Konsole, Xterm
398 		"\x1b[23;4~": Key(KeyType.COMMAND, KeyValue(Command.keyF11), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
399 		"\x1b[23;5~": Key(KeyType.COMMAND, KeyValue(Command.keyF11), KeyModifier.control), //Konsole, Xterm
400 		"\x1b[23;6~": Key(KeyType.COMMAND, KeyValue(Command.keyF11), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
401 		"\x1b[23;8~": Key(KeyType.COMMAND, KeyValue(Command.keyF11), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
402 		"\x1b[23@": Key(KeyType.COMMAND, KeyValue(Command.keyF11), KeyModifier.shift|KeyModifier.control), //rxvt
403 		"\x1b[23^": Key(KeyType.COMMAND, KeyValue(Command.keyF11), KeyModifier.control), //rxvt
404 		"\x1b[23~": Key(KeyType.COMMAND, KeyValue(Command.keyF11), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
405 		"\x1b[23$": Key(KeyType.COMMAND, KeyValue(Command.keyF11), KeyModifier.shift), //rxvt
406 		"\x1b[24;2~": Key(KeyType.COMMAND, KeyValue(Command.keyF12), KeyModifier.shift), //Konsole, Xterm
407 		"\x1b[24;3~": Key(KeyType.COMMAND, KeyValue(Command.keyF12), KeyModifier.alt), //Konsole, Xterm
408 		"\x1b[24;6~": Key(KeyType.COMMAND, KeyValue(Command.keyF12), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
409 		"\x1b[24;8~": Key(KeyType.COMMAND, KeyValue(Command.keyF12), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
410 		"\x1b[24@": Key(KeyType.COMMAND, KeyValue(Command.keyF12), KeyModifier.shift|KeyModifier.control), //rxvt
411 		"\x1b[24^": Key(KeyType.COMMAND, KeyValue(Command.keyF12), KeyModifier.control), //rxvt
412 		"\x1b[24~": Key(KeyType.COMMAND, KeyValue(Command.keyF12), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
413 		"\x1b[24$": Key(KeyType.COMMAND, KeyValue(Command.keyF12), KeyModifier.shift), //rxvt
414 		"\x1b[25^": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.shift|KeyModifier.control), //rxvt
415 		"\x1b[26^": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.shift|KeyModifier.control), //rxvt
416 		"\x1b[28^": Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.shift|KeyModifier.control), //rxvt
417 		"\x1b[29^": Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.shift|KeyModifier.control), //rxvt
418 		"\x1b[3;2~": Key(KeyType.COMMAND, KeyValue(Command.keyDelete), KeyModifier.shift), //Konsole, Xterm
419 		"\x1b[3;3~": Key(KeyType.COMMAND, KeyValue(Command.keyDelete), KeyModifier.alt), //Konsole, Xterm
420 		"\x1b[3;4~": Key(KeyType.COMMAND, KeyValue(Command.keyDelete), KeyModifier.shift|KeyModifier.alt), //Konsole, Xterm
421 		"\x1b[3;5~": Key(KeyType.COMMAND, KeyValue(Command.keyDelete), KeyModifier.control), //Konsole, Xterm
422 		"\x1b[3;6~": Key(KeyType.COMMAND, KeyValue(Command.keyDelete), KeyModifier.shift|KeyModifier.control), //Konsole, Xterm
423 		"\x1b[3@": Key(KeyType.COMMAND, KeyValue(Command.keyDelete), KeyModifier.shift|KeyModifier.control), //rxvt
424 		"\x1b[3^": Key(KeyType.COMMAND, KeyValue(Command.keyDelete), KeyModifier.control), //rxvt
425 		"\x1b[3~": Key(KeyType.COMMAND, KeyValue(Command.keyDelete), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
426 		"\x1b[3$": Key(KeyType.COMMAND, KeyValue(Command.keyDelete), KeyModifier.shift), //rxvt
427 		"\x1b[31^": Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.shift|KeyModifier.control), //rxvt
428 		"\x1b[32^": Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.shift|KeyModifier.control), //rxvt
429 		"\x1b[33^": Key(KeyType.COMMAND, KeyValue(Command.keyF9), KeyModifier.shift|KeyModifier.control), //rxvt
430 		"\x1b[34^": Key(KeyType.COMMAND, KeyValue(Command.keyF10), KeyModifier.shift|KeyModifier.control), //rxvt
431 		"\x1b[4~": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.none), //PuTTY, Linux
432 		"\x1b[5;3~": Key(KeyType.COMMAND, KeyValue(Command.keyPageUp), KeyModifier.alt), //Konsole, Xterm
433 		"\x1b[5;5~": Key(KeyType.COMMAND, KeyValue(Command.keyPageUp), KeyModifier.control), //Konsole, Xterm
434 		"\x1b[5;7~": Key(KeyType.COMMAND, KeyValue(Command.keyPageUp), KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
435 		"\x1b[5@": Key(KeyType.COMMAND, KeyValue(Command.keyPageUp), KeyModifier.shift|KeyModifier.control), //rxvt
436 		"\x1b[5^": Key(KeyType.COMMAND, KeyValue(Command.keyPageUp), KeyModifier.control), //rxvt
437 		"\x1b[5~": Key(KeyType.COMMAND, KeyValue(Command.keyPageUp), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
438 		"\x1b[6;3~": Key(KeyType.COMMAND, KeyValue(Command.keyPageDown), KeyModifier.alt), //Konsole, Xterm
439 		"\x1b[6;5~": Key(KeyType.COMMAND, KeyValue(Command.keyPageDown), KeyModifier.control), //Konsole, Xterm
440 		"\x1b[6;7~": Key(KeyType.COMMAND, KeyValue(Command.keyPageDown), KeyModifier.alt|KeyModifier.control), //Konsole, Xterm
441 		"\x1b[6@": Key(KeyType.COMMAND, KeyValue(Command.keyPageDown), KeyModifier.shift|KeyModifier.control), //rxvt
442 		"\x1b[6^": Key(KeyType.COMMAND, KeyValue(Command.keyPageDown), KeyModifier.control), //rxvt
443 		"\x1b[6~": Key(KeyType.COMMAND, KeyValue(Command.keyPageDown), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
444 		"\x1b[7@": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.shift|KeyModifier.control), //rxvt
445 		"\x1b[7^": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.control), //rxvt
446 		"\x1b[7~": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.none), //rxvt
447 		"\x1b[7$": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.shift), //rxvt
448 		"\x1b[8@": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.shift|KeyModifier.control), //rxvt
449 		"\x1b[8^": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.control), //rxvt
450 		"\x1b[8~": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.none), //rxvt
451 		"\x1b[8$": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.shift), //rxvt
452 		"\x1b[A": Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
453 		"\x1b[a": Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.shift), //rxvt
454 		"\x1b[B": Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
455 		"\x1b[b": Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.shift), //rxvt
456 		"\x1b[C": Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
457 		"\x1b[c": Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.shift), //rxvt
458 		"\x1b[D": Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.none), //PuTTY, Konsole, Xterm, rxvt, Linux
459 		"\x1b[d": Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.shift), //rxvt
460 		"\x1b[E": Key(KeyType.COMMAND, KeyValue(Command.keyB2), KeyModifier.none), //Xterm
461 		"\x1b[F": Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.none), //Konsole, Xterm
462 		"\x1b[G": Key(KeyType.COMMAND, KeyValue(Command.keyB2), KeyModifier.none), //PuTTY, Linux
463 		"\x1b[H": Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.none), //Konsole, Xterm
464 		"\x1b[Z": Key(KeyType.COMMAND, KeyValue(Command.horizontalTabulation), KeyModifier.shift), //PuTTY, Konsole, Xterm, rxvt
465 		"\x1bO2P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.shift), //Konsole
466 		"\x1bO2Q": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.shift), //Konsole
467 		"\x1bO2R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.shift), //Konsole
468 		"\x1bO2S": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.shift), //Konsole
469 		"\x1bO3P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.alt), //Konsole
470 		"\x1bO3Q": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.alt), //Konsole
471 		"\x1bO3R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.alt), //Konsole
472 		"\x1bO4P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.shift|KeyModifier.alt), //Konsole
473 		"\x1bO4Q": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.shift|KeyModifier.alt), //Konsole
474 		"\x1bO4R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.shift|KeyModifier.alt), //Konsole
475 		"\x1bO4S": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.shift|KeyModifier.alt), //Konsole
476 		"\x1bO5P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.control), //Konsole
477 		"\x1bO5Q": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.control), //Konsole
478 		"\x1bO5R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.control), //Konsole
479 		"\x1bO5R": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.control), //Konsole
480 		"\x1bO6P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.shift|KeyModifier.control), //Konsole
481 		"\x1bO6Q": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.shift|KeyModifier.control), //Konsole
482 		"\x1bO6R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.shift|KeyModifier.control), //Konsole
483 		"\x1bO6S": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.shift|KeyModifier.control), //Konsole
484 		"\x1bO8P": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole
485 		"\x1bO8Q": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole
486 		"\x1bO8R": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole
487 		"\x1bO8S": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.shift|KeyModifier.alt|KeyModifier.control), //Konsole
488 		"\x1bOA": Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.shift), //PuTTY
489 		"\x1bOa": Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.control), //rxvt
490 		"\x1bOB": Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.shift), //PuTTY
491 		"\x1bOb": Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.control), //rxvt
492 		"\x1bOC": Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.shift), //PuTTY
493 		"\x1bOc": Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.control), //rxvt
494 		"\x1bOD": Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.shift), //PuTTY
495 		"\x1bOd": Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.control), //rxvt
496 		"\x1bOG": Key(KeyType.COMMAND, KeyValue(Command.keyB2), KeyModifier.shift), //PuTTY
497 		"\x1bOP": Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.none), //Konsole, Xterm
498 		"\x1bOQ": Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.none), //Konsole, Xterm
499 		"\x1bOR": Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.none), //Konsole, Xterm
500 		"\x1bOS": Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.none), //Konsole, Xterm
501 		"\x1bOu": Key(KeyType.COMMAND, KeyValue(Command.keyB2), KeyModifier.shift), //rxvt
502 	];
503 
504 	//rxvt and Linux terminal assign the same escape sequences to different keyboard shortcuts
505 	immutable term = environment.get("TERM", "unknown");
506 	if (term == "linux" || term == "screen") {
507 		keyMap["\x1b[25~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.shift);
508 		keyMap["\x1b[26~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.shift);
509 		keyMap["\x1b[28~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.shift);
510 		keyMap["\x1b[29~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.shift);
511 		keyMap["\x1b[31~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.shift);
512 		keyMap["\x1b[32~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.shift);
513 		keyMap["\x1b[33~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.shift);
514 		keyMap["\x1b[34~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.shift);
515 	} else {
516 		keyMap["\x1b[25~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.shift);
517 		keyMap["\x1b[26~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.shift);
518 		keyMap["\x1b[28~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.shift);
519 		keyMap["\x1b[29~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.shift);
520 		keyMap["\x1b[31~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.shift);
521 		keyMap["\x1b[32~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.shift);
522 		keyMap["\x1b[33~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF9), KeyModifier.shift);
523 		keyMap["\x1b[34~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF10), KeyModifier.shift);
524 	}
525 
526 	//Some service escape sequences
527 	//During terminal resize Consoleur generates this sequence
528 	keyMap["\x1b[480w"] = Key(KeyType.COMMAND, KeyValue(Command.winch), KeyModifier.none);
529 	//Bracketed Pasting
530 	keyMap["\x1b[200~"] = Key(KeyType.COMMAND, KeyValue(Command.pasteStart), KeyModifier.none);
531 	keyMap["\x1b[201~"] = Key(KeyType.COMMAND, KeyValue(Command.pasteEnd), KeyModifier.none);
532 }
533 
534 version (WithSuperKey) {
535 	private void addSuperKeys()
536 	{
537 		keyMap["\x1b[1;1A"] = Key(KeyType.COMMAND, KeyValue(Command.keyUp), KeyModifier.supr);
538 		keyMap["\x1b[1;1B"] = Key(KeyType.COMMAND, KeyValue(Command.keyDown), KeyModifier.supr);
539 		keyMap["\x1b[1;1C"] = Key(KeyType.COMMAND, KeyValue(Command.keyRight), KeyModifier.supr);
540 		keyMap["\x1b[1;1D"] = Key(KeyType.COMMAND, KeyValue(Command.keyLeft), KeyModifier.supr);
541 
542 		keyMap["\x1b[2;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyInsert), KeyModifier.supr);
543 		keyMap["\x1b[3;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyDelete), KeyModifier.supr);
544 		keyMap["\x1b[1;1F"] = Key(KeyType.COMMAND, KeyValue(Command.keyEnd), KeyModifier.supr);
545 		keyMap["\x1b[1;1H"] = Key(KeyType.COMMAND, KeyValue(Command.keyHome), KeyModifier.supr);
546 		keyMap["\x1b[5;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyPageUp), KeyModifier.supr);
547 		keyMap["\x1b[6;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyPageDown), KeyModifier.supr);
548 
549 		keyMap["\x1bO1P"] = Key(KeyType.COMMAND, KeyValue(Command.keyF1), KeyModifier.supr);
550 		keyMap["\x1bO1Q"] = Key(KeyType.COMMAND, KeyValue(Command.keyF2), KeyModifier.supr);
551 		keyMap["\x1bO1R"] = Key(KeyType.COMMAND, KeyValue(Command.keyF3), KeyModifier.supr);
552 		keyMap["\x1bO1S"] = Key(KeyType.COMMAND, KeyValue(Command.keyF4), KeyModifier.supr);
553 		keyMap["\x1b[15;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF5), KeyModifier.supr);
554 		keyMap["\x1b[17;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF6), KeyModifier.supr);
555 		keyMap["\x1b[18;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF7), KeyModifier.supr);
556 		keyMap["\x1b[19;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF8), KeyModifier.supr);
557 		keyMap["\x1b[20;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF9), KeyModifier.supr);
558 		keyMap["\x1b[21;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF10), KeyModifier.supr);
559 		keyMap["\x1b[23;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF11), KeyModifier.supr);
560 		keyMap["\x1b[24;1~"] = Key(KeyType.COMMAND, KeyValue(Command.keyF12), KeyModifier.supr);
561 	}
562 }
563 
564 }