8#include "definitions.h"
11#include <vimode/keyevent.h>
12#include <vimode/keyparser.h>
14using namespace KateVi;
16KeyParser *KeyParser::m_instance =
nullptr;
25 if (m_instance ==
nullptr) {
32void KeyParser::initKeyTables()
219 m_katevi2qt.
insert(i.value(), i.key());
224 {QStringLiteral(
"invalid"), -1},
225 {QStringLiteral(
"esc"), 1},
226 {QStringLiteral(
"tab"), 2},
227 {QStringLiteral(
"backtab"), 3},
228 {QStringLiteral(
"backspace"), 4},
229 {QStringLiteral(
"return"), 5},
230 {QStringLiteral(
"enter"), 6},
231 {QStringLiteral(
"insert"), 7},
232 {QStringLiteral(
"delete"), 8},
233 {QStringLiteral(
"pause"), 9},
234 {QStringLiteral(
"print"), 10},
235 {QStringLiteral(
"sysreq"), 11},
236 {QStringLiteral(
"clear"), 12},
237 {QStringLiteral(
"home"), 13},
238 {QStringLiteral(
"end"), 14},
239 {QStringLiteral(
"left"), 15},
240 {QStringLiteral(
"up"), 16},
241 {QStringLiteral(
"right"), 17},
242 {QStringLiteral(
"down"), 18},
243 {QStringLiteral(
"pageup"), 19},
244 {QStringLiteral(
"pagedown"), 20},
245 {QStringLiteral(
"shift"), 21},
246 {QStringLiteral(
"control"), 22},
247 {QStringLiteral(
"meta"), 23},
248 {QStringLiteral(
"alt"), 24},
249 {QStringLiteral(
"altgr"), 25},
250 {QStringLiteral(
"capslock"), 26},
251 {QStringLiteral(
"numlock"), 27},
252 {QStringLiteral(
"scrolllock"), 28},
253 {QStringLiteral(
"f1"), 29},
254 {QStringLiteral(
"f2"), 30},
255 {QStringLiteral(
"f3"), 31},
256 {QStringLiteral(
"f4"), 32},
257 {QStringLiteral(
"f5"), 33},
258 {QStringLiteral(
"f6"), 34},
259 {QStringLiteral(
"f7"), 35},
260 {QStringLiteral(
"f8"), 36},
261 {QStringLiteral(
"f9"), 37},
262 {QStringLiteral(
"f10"), 38},
263 {QStringLiteral(
"f11"), 39},
264 {QStringLiteral(
"f12"), 40},
265 {QStringLiteral(
"f13"), 41},
266 {QStringLiteral(
"f14"), 42},
267 {QStringLiteral(
"f15"), 43},
268 {QStringLiteral(
"f16"), 44},
269 {QStringLiteral(
"f17"), 45},
270 {QStringLiteral(
"f18"), 46},
271 {QStringLiteral(
"f19"), 47},
272 {QStringLiteral(
"f20"), 48},
273 {QStringLiteral(
"f21"), 49},
274 {QStringLiteral(
"f22"), 50},
275 {QStringLiteral(
"f23"), 51},
276 {QStringLiteral(
"f24"), 52},
277 {QStringLiteral(
"f25"), 53},
278 {QStringLiteral(
"f26"), 54},
279 {QStringLiteral(
"f27"), 55},
280 {QStringLiteral(
"f28"), 56},
281 {QStringLiteral(
"f29"), 57},
282 {QStringLiteral(
"f30"), 58},
283 {QStringLiteral(
"f31"), 59},
284 {QStringLiteral(
"f32"), 60},
285 {QStringLiteral(
"f33"), 61},
286 {QStringLiteral(
"f34"), 62},
287 {QStringLiteral(
"f35"), 63},
288 {QStringLiteral(
"super_l"), 64},
289 {QStringLiteral(
"super_r"), 65},
290 {QStringLiteral(
"menu"), 66},
291 {QStringLiteral(
"hyper_l"), 67},
292 {QStringLiteral(
"hyper_r"), 68},
293 {QStringLiteral(
"help"), 69},
294 {QStringLiteral(
"direction_l"), 70},
295 {QStringLiteral(
"direction_r"), 71},
296 {QStringLiteral(
"multi_key"), 172},
297 {QStringLiteral(
"codeinput"), 173},
298 {QStringLiteral(
"singlecandidate"), 174},
299 {QStringLiteral(
"multiplecandidate"), 175},
300 {QStringLiteral(
"previouscandidate"), 176},
301 {QStringLiteral(
"mode_switch"), 177},
302 {QStringLiteral(
"kanji"), 178},
303 {QStringLiteral(
"muhenkan"), 179},
304 {QStringLiteral(
"henkan"), 180},
305 {QStringLiteral(
"romaji"), 181},
306 {QStringLiteral(
"hiragana"), 182},
307 {QStringLiteral(
"katakana"), 183},
308 {QStringLiteral(
"hiragana_katakana"), 184},
309 {QStringLiteral(
"zenkaku"), 185},
310 {QStringLiteral(
"hankaku"), 186},
311 {QStringLiteral(
"zenkaku_hankaku"), 187},
312 {QStringLiteral(
"touroku"), 188},
313 {QStringLiteral(
"massyo"), 189},
314 {QStringLiteral(
"kana_lock"), 190},
315 {QStringLiteral(
"kana_shift"), 191},
316 {QStringLiteral(
"eisu_shift"), 192},
317 {QStringLiteral(
"eisu_toggle"), 193},
318 {QStringLiteral(
"hangul"), 194},
319 {QStringLiteral(
"hangul_start"), 195},
320 {QStringLiteral(
"hangul_end"), 196},
321 {QStringLiteral(
"hangul_hanja"), 197},
322 {QStringLiteral(
"hangul_jamo"), 198},
323 {QStringLiteral(
"hangul_romaja"), 199},
324 {QStringLiteral(
"hangul_jeonja"), 200},
325 {QStringLiteral(
"hangul_banja"), 201},
326 {QStringLiteral(
"hangul_prehanja"), 202},
327 {QStringLiteral(
"hangul_posthanja"), 203},
328 {QStringLiteral(
"hangul_special"), 204},
329 {QStringLiteral(
"dead_grave"), 205},
330 {QStringLiteral(
"dead_acute"), 206},
331 {QStringLiteral(
"dead_circumflex"), 207},
332 {QStringLiteral(
"dead_tilde"), 208},
333 {QStringLiteral(
"dead_macron"), 209},
334 {QStringLiteral(
"dead_breve"), 210},
335 {QStringLiteral(
"dead_abovedot"), 211},
336 {QStringLiteral(
"dead_diaeresis"), 212},
337 {QStringLiteral(
"dead_abovering"), 213},
338 {QStringLiteral(
"dead_doubleacute"), 214},
339 {QStringLiteral(
"dead_caron"), 215},
340 {QStringLiteral(
"dead_cedilla"), 216},
341 {QStringLiteral(
"dead_ogonek"), 217},
342 {QStringLiteral(
"dead_iota"), 218},
343 {QStringLiteral(
"dead_voiced_sound"), 219},
344 {QStringLiteral(
"dead_semivoiced_sound"), 220},
345 {QStringLiteral(
"dead_belowdot"), 221},
346 {QStringLiteral(
"dead_hook"), 222},
347 {QStringLiteral(
"dead_horn"), 223},
348 {QStringLiteral(
"back"), 224},
349 {QStringLiteral(
"forward"), 225},
350 {QStringLiteral(
"stop"), 226},
351 {QStringLiteral(
"refresh"), 227},
352 {QStringLiteral(
"volumedown"), 228},
353 {QStringLiteral(
"volumemute"), 229},
354 {QStringLiteral(
"volumeup"), 230},
355 {QStringLiteral(
"bassboost"), 231},
356 {QStringLiteral(
"bassup"), 232},
357 {QStringLiteral(
"bassdown"), 233},
358 {QStringLiteral(
"trebleup"), 234},
359 {QStringLiteral(
"trebledown"), 235},
360 {QStringLiteral(
"mediaplay"), 236},
361 {QStringLiteral(
"mediastop"), 237},
362 {QStringLiteral(
"mediaprevious"), 238},
363 {QStringLiteral(
"medianext"), 239},
364 {QStringLiteral(
"mediarecord"), 240},
365 {QStringLiteral(
"homepage"), 241},
366 {QStringLiteral(
"favorites"), 242},
367 {QStringLiteral(
"search"), 243},
368 {QStringLiteral(
"standby"), 244},
369 {QStringLiteral(
"openurl"), 245},
370 {QStringLiteral(
"launchmail"), 246},
371 {QStringLiteral(
"launchmedia"), 247},
372 {QStringLiteral(
"launch0"), 248},
373 {QStringLiteral(
"launch1"), 249},
374 {QStringLiteral(
"launch2"), 250},
375 {QStringLiteral(
"launch3"), 251},
376 {QStringLiteral(
"launch4"), 252},
377 {QStringLiteral(
"launch5"), 253},
378 {QStringLiteral(
"launch6"), 254},
379 {QStringLiteral(
"launch7"), 255},
380 {QStringLiteral(
"launch8"), 256},
381 {QStringLiteral(
"launch9"), 257},
382 {QStringLiteral(
"launcha"), 258},
383 {QStringLiteral(
"launchb"), 259},
384 {QStringLiteral(
"launchc"), 260},
385 {QStringLiteral(
"launchd"), 261},
386 {QStringLiteral(
"launche"), 262},
387 {QStringLiteral(
"launchf"), 263},
388 {QStringLiteral(
"medialast"), 264},
389 {QStringLiteral(
"unknown"), 265},
390 {QStringLiteral(
"call"), 266},
391 {QStringLiteral(
"context1"), 267},
392 {QStringLiteral(
"context2"), 268},
393 {QStringLiteral(
"context3"), 269},
394 {QStringLiteral(
"context4"), 270},
395 {QStringLiteral(
"flip"), 271},
396 {QStringLiteral(
"hangup"), 272},
397 {QStringLiteral(
"no"), 273},
398 {QStringLiteral(
"select"), 274},
399 {QStringLiteral(
"yes"), 275},
400 {QStringLiteral(
"execute"), 276},
401 {QStringLiteral(
"printer"), 277},
402 {QStringLiteral(
"play"), 278},
403 {QStringLiteral(
"sleep"), 279},
404 {QStringLiteral(
"zoom"), 280},
405 {QStringLiteral(
"cancel"), 281},
407 {QStringLiteral(
"a"), 282},
408 {QStringLiteral(
"b"), 283},
409 {QStringLiteral(
"c"), 284},
410 {QStringLiteral(
"d"), 285},
411 {QStringLiteral(
"e"), 286},
412 {QStringLiteral(
"f"), 287},
413 {QStringLiteral(
"g"), 288},
414 {QStringLiteral(
"h"), 289},
415 {QStringLiteral(
"i"), 290},
416 {QStringLiteral(
"j"), 291},
417 {QStringLiteral(
"k"), 292},
418 {QStringLiteral(
"l"), 293},
419 {QStringLiteral(
"m"), 294},
420 {QStringLiteral(
"n"), 295},
421 {QStringLiteral(
"o"), 296},
422 {QStringLiteral(
"p"), 297},
423 {QStringLiteral(
"q"), 298},
424 {QStringLiteral(
"r"), 299},
425 {QStringLiteral(
"s"), 300},
426 {QStringLiteral(
"t"), 301},
427 {QStringLiteral(
"u"), 302},
428 {QStringLiteral(
"v"), 303},
429 {QStringLiteral(
"w"), 304},
430 {QStringLiteral(
"x"), 305},
431 {QStringLiteral(
"y"), 306},
432 {QStringLiteral(
"z"), 307},
433 {QStringLiteral(
"`"), 308},
434 {QStringLiteral(
"!"), 309},
435 {QStringLiteral(
"\""), 310},
436 {QStringLiteral(
"$"), 311},
437 {QStringLiteral(
"%"), 312},
438 {QStringLiteral(
"^"), 313},
439 {QStringLiteral(
"&"), 314},
440 {QStringLiteral(
"*"), 315},
441 {QStringLiteral(
"("), 316},
442 {QStringLiteral(
")"), 317},
443 {QStringLiteral(
"-"), 318},
444 {QStringLiteral(
"_"), 319},
445 {QStringLiteral(
"="), 320},
446 {QStringLiteral(
"+"), 321},
447 {QStringLiteral(
"["), 322},
448 {QStringLiteral(
"]"), 323},
449 {QStringLiteral(
"{"), 324},
450 {QStringLiteral(
"}"), 325},
451 {QStringLiteral(
":"), 326},
452 {QStringLiteral(
";"), 327},
453 {QStringLiteral(
"@"), 328},
454 {QStringLiteral(
"'"), 329},
455 {QStringLiteral(
"#"), 330},
456 {QStringLiteral(
"~"), 331},
457 {QStringLiteral(
"\\"), 332},
458 {QStringLiteral(
"|"), 333},
459 {QStringLiteral(
","), 334},
460 {QStringLiteral(
"."), 335},
462 {QStringLiteral(
"/"), 337},
463 {QStringLiteral(
"?"), 338},
464 {QStringLiteral(
" "), 339},
466 {QStringLiteral(
"0"), 340},
467 {QStringLiteral(
"1"), 341},
468 {QStringLiteral(
"2"), 342},
469 {QStringLiteral(
"3"), 343},
470 {QStringLiteral(
"4"), 344},
471 {QStringLiteral(
"5"), 345},
472 {QStringLiteral(
"6"), 346},
473 {QStringLiteral(
"7"), 347},
474 {QStringLiteral(
"8"), 348},
475 {QStringLiteral(
"9"), 349},
476 {QStringLiteral(
"cr"), 350},
477 {QStringLiteral(
"leader"), 351},
478 {QStringLiteral(
"nop"), 352},
482 m_keyCodeToName.
insert(i.value(), i.key());
486QString KeyParser::qt2vi(
int key)
const
489 if (it != m_qt2katevi.
cend()) {
492 return QStringLiteral(
"invalid");
495int KeyParser::vi2qt(
const QString &keypress)
const
497 auto it = m_katevi2qt.
constFind(keypress);
498 if (it != m_katevi2qt.
cend()) {
504int KeyParser::encoded2qt(
const QString &keypress)
const
506 QString key = KeyParser::self()->decodeKeySequence(keypress);
512 if (it != m_katevi2qt.
cend())
517const QString KeyParser::encodeKeySequence(
const QString &keys)
const
520 unsigned int keyCodeTemp = 0;
523 bool insideTag =
false;
525 for (
int i = 0; i < keys.
length(); i++) {
529 QChar code(0xE000 + keyCodeTemp);
530 encodedSequence.
append(code);
546 tokens << untilClosing.
mid(currentPos, nextHypen - currentPos + 1);
547 currentPos = nextHypen + 1;
549 tokens << untilClosing.
mid(currentPos);
551 for (
const QString &str : std::as_const(tokens)) {
552 if (str ==
QLatin1String(
"s-") && (keyCodeTemp & 0x01) != 0x1) {
554 }
else if (str ==
QLatin1String(
"c-") && (keyCodeTemp & 0x02) != 0x2) {
556 }
else if (str ==
QLatin1String(
"a-") && (keyCodeTemp & 0x04) != 0x4) {
558 }
else if (str ==
QLatin1String(
"m-") && (keyCodeTemp & 0x08) != 0x8) {
561 if (m_nameToKeyCode.
contains(str) || (str.length() == 1 && str.at(0).isLetterOrNumber())) {
562 if (m_nameToKeyCode.
contains(str)) {
563 keyCodeTemp += m_nameToKeyCode.
value(str) * 0x10;
565 keyCodeTemp += str.at(0).unicode() * 0x10;
569 if (endOfBlock -= -1) {
570 endOfBlock = keys.
length() - 1;
572 encodedSequence.
clear();
581 if (m_nameToKeyCode.
contains(str)) {
582 keyCodeTemp += m_nameToKeyCode.
value(str) * 0x10;
584 keyCodeTemp += str.
at(0).
unicode() * 0x10;
588 if (endOfBlock -= -1) {
589 endOfBlock = keys.
length() - 1;
591 encodedSequence.
clear();
592 keyCodeTemp = m_nameToKeyCode.
value(QStringLiteral(
"invalid")) * 0x10;
595 i += keysView.mid(i, keysView.mid(i).indexOf(
QLatin1Char(
'>'))).length() - 1;
608 encodedSequence.
append(c);
614 encodedSequence.
append(c);
619 return encodedSequence;
622const QString KeyParser::decodeKeySequence(
const QString &keys)
const
627 for (
int i = 0; i < keys.
length(); i++) {
631 if ((keycode & 0xE000) != 0xE000) {
636 if ((keycode & 0x1) == 0x1) {
640 if ((keycode & 0x2) == 0x2) {
644 if ((keycode & 0x4) == 0x4) {
648 if ((keycode & 0x8) == 0x8) {
653 if ((keycode & 0xE000) == 0xE000) {
654 ret.
append(m_keyCodeToName.
value((keycode - 0xE000) / 0x10));
670const QChar KeyParser::KeyEventToQChar(
const KeyEvent &keyEvent)
690 keyPress.append((mods & CONTROL_MODIFIER) ? QStringLiteral(
"c-") :
QString());
692 keyPress.append((mods & META_MODIFIER) ? QStringLiteral(
"m-") :
QString());
693 keyPress.append(keyCode <= 0xFF ?
QChar(keyCode) : qt2vi(keyCode));
696 return encodeKeySequence(keyPress).
at(0);
QEvent wrapper for copying/storing key events.
for encoding keypresses w/ modifiers into an internal QChar representation and back again to a descri...
bool isLetterOrNumber(char32_t ucs4)
const_iterator cend() const const
const_iterator constBegin() const const
const_iterator constEnd() const const
const_iterator constFind(const Key &key) const const
bool contains(const Key &key) const const
iterator insert(const Key &key, const T &value)
T value(const Key &key) const const
QString & append(QChar ch)
const QChar at(qsizetype position) const const
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype length() const const
QString mid(qsizetype position, qsizetype n) const const
void reserve(qsizetype size)
QString toLower() const const
QStringView mid(qsizetype start, qsizetype length) const const
qsizetype indexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs) const const
typedef KeyboardModifiers
void keyEvent(KeyAction action, QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier, int delay)
void keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier, int delay)