aboutsummaryrefslogtreecommitdiff
path: root/src/keymap/KeymapEvaluator.cpp
blob: baae81968238488640a311abb7b1232201bdce5c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <QWidget>
#include <QtCore>

#include "keymap/KeymapEvaluator.hpp"

KeymapEvaluator::KeymapEvaluator() : QObject() {}

// TODO: Clear mapping after some time

void KeymapEvaluator::addKeymap(KeyMode mode, QString key, KeyAction action) {
  if (!modalKeys.contains(mode))
    modalKeys.insert(mode, {});

  auto keySeq = keySeqParser.parse(key);
  modalKeys[mode].append((KeyMap){.keySequence = keySeq, .action = action});
}

bool KeymapEvaluator::evaluate(Qt::KeyboardModifiers modifiers, Qt::Key key) {
  if (key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Meta ||
      key == Qt::Key_Alt)
    return true;

  auto keymaps = currentModeKeys();
  auto foundPendingMatches = false;

  activeKeySequence.append((KeyChord){.mod = modifiers, .key = key});

  for (auto &keymap : *keymaps) {
    auto matchType =
        KeySeqParser::keySequenceMatch(keymap.keySequence, activeKeySequence);

    if (matchType == KeyMatchType::Match) {
      keymap.action();
      activeKeySequence.clear();
      return true;
    } else if (matchType == KeyMatchType::Pending) {
      foundPendingMatches = true;
    }
  }

  if (!foundPendingMatches)
    activeKeySequence.clear();

  if (isInsertableMode())
    return foundPendingMatches;

  return true;
}

bool KeymapEvaluator::isInsertableMode() {
  return currentMode == KeyMode::Insert;
}

const QList<KeyMap> *KeymapEvaluator::currentModeKeys() {
  if (!modalKeys.contains(currentMode))
    return new QList<KeyMap>();

  return &modalKeys[currentMode];
}