1 | /* |
---|---|
2 | SPDX-FileCopyrightText: KDE Developers |
3 | |
4 | SPDX-License-Identifier: LGPL-2.0-or-later |
5 | */ |
6 | |
7 | #include "lastchangerecorder.h" |
8 | #include "completionreplayer.h" |
9 | #include <vimode/inputmodemanager.h> |
10 | #include <vimode/keyparser.h> |
11 | |
12 | using namespace KateVi; |
13 | |
14 | bool KateVi::isRepeatOfLastShortcutOverrideAsKeyPress(const QKeyEvent ¤tKeyPress, const QList<KeyEvent> &keyEventLog) |
15 | { |
16 | if (keyEventLog.empty()) { |
17 | return false; |
18 | } |
19 | const KeyEvent &lastKeyPress = keyEventLog.last(); |
20 | if (lastKeyPress.type() == QEvent::ShortcutOverride && currentKeyPress.type() == QEvent::KeyPress && lastKeyPress.key() == currentKeyPress.key() |
21 | && lastKeyPress.modifiers() == currentKeyPress.modifiers()) { |
22 | return true; |
23 | } |
24 | return false; |
25 | } |
26 | |
27 | LastChangeRecorder::LastChangeRecorder(InputModeManager *viInputModeManager) |
28 | : m_viInputModeManager(viInputModeManager) |
29 | , m_isReplaying(false) |
30 | { |
31 | } |
32 | |
33 | void LastChangeRecorder::record(const QKeyEvent &e) |
34 | { |
35 | if (isRepeatOfLastShortcutOverrideAsKeyPress(currentKeyPress: e, keyEventLog: m_changeLog)) { |
36 | return; |
37 | } |
38 | |
39 | if (e.key() != Qt::Key_Shift && e.key() != Qt::Key_Control && e.key() != Qt::Key_Meta && e.key() != Qt::Key_Alt) { |
40 | m_changeLog.append(t: KeyEvent::fromQKeyEvent(e)); |
41 | } |
42 | } |
43 | |
44 | void LastChangeRecorder::dropLast() |
45 | { |
46 | Q_ASSERT(!m_changeLog.isEmpty()); |
47 | m_changeLog.pop_back(); |
48 | } |
49 | |
50 | void LastChangeRecorder::clear() |
51 | { |
52 | m_changeLog.clear(); |
53 | } |
54 | |
55 | QString LastChangeRecorder::encodedChanges() const |
56 | { |
57 | QString result; |
58 | |
59 | QList<KeyEvent> keyLog = m_changeLog; |
60 | |
61 | for (int i = 0; i < keyLog.size(); i++) { |
62 | int keyCode = keyLog.at(i).key(); |
63 | QString text = keyLog.at(i).text(); |
64 | int mods = keyLog.at(i).modifiers(); |
65 | QChar key; |
66 | |
67 | if (text.length() > 0) { |
68 | key = text.at(i: 0); |
69 | } |
70 | |
71 | if (text.isEmpty() || (text.length() == 1 && text.at(i: 0) < QChar(0x20)) || (mods != Qt::NoModifier && mods != Qt::ShiftModifier)) { |
72 | QString keyPress; |
73 | |
74 | keyPress.append(c: QLatin1Char('<')); |
75 | keyPress.append(s: (mods & Qt::ShiftModifier) ? QStringLiteral("s-") : QString()); |
76 | keyPress.append(s: (mods & CONTROL_MODIFIER) ? QStringLiteral("c-") : QString()); |
77 | keyPress.append(s: (mods & Qt::AltModifier) ? QStringLiteral("a-") : QString()); |
78 | keyPress.append(s: (mods & META_MODIFIER) ? QStringLiteral("m-") : QString()); |
79 | keyPress.append(s: keyCode <= 0xFF ? QChar(keyCode) : KeyParser::self()->qt2vi(key: keyCode)); |
80 | keyPress.append(c: QLatin1Char('>')); |
81 | |
82 | key = KeyParser::self()->encodeKeySequence(keys: keyPress).at(i: 0); |
83 | } |
84 | |
85 | result.append(c: key); |
86 | } |
87 | |
88 | return result; |
89 | } |
90 | |
91 | bool LastChangeRecorder::isReplaying() const |
92 | { |
93 | return m_isReplaying; |
94 | } |
95 | |
96 | void LastChangeRecorder::replay(const QString &commands, const CompletionList &completions) |
97 | { |
98 | m_isReplaying = true; |
99 | m_viInputModeManager->completionReplayer()->start(completions); |
100 | m_viInputModeManager->feedKeyPresses(keyPresses: commands); |
101 | m_viInputModeManager->completionReplayer()->stop(); |
102 | m_isReplaying = false; |
103 | } |
104 |