File indexing completed on 2024-04-28 15:31:19

0001 /*
0002     SPDX-FileCopyrightText: KDE Developers
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "lastchangerecorder.h"
0008 #include "completionreplayer.h"
0009 #include <vimode/inputmodemanager.h>
0010 #include <vimode/keyparser.h>
0011 
0012 using namespace KateVi;
0013 
0014 bool KateVi::isRepeatOfLastShortcutOverrideAsKeyPress(const QKeyEvent &currentKeyPress, const QList<KeyEvent> &keyEventLog)
0015 {
0016     if (keyEventLog.empty()) {
0017         return false;
0018     }
0019     const KeyEvent &lastKeyPress = keyEventLog.last();
0020     if (lastKeyPress.type() == QEvent::ShortcutOverride && currentKeyPress.type() == QEvent::KeyPress && lastKeyPress.key() == currentKeyPress.key()
0021         && lastKeyPress.modifiers() == currentKeyPress.modifiers()) {
0022         return true;
0023     }
0024     return false;
0025 }
0026 
0027 LastChangeRecorder::LastChangeRecorder(InputModeManager *viInputModeManager)
0028     : m_viInputModeManager(viInputModeManager)
0029     , m_isReplaying(false)
0030 {
0031 }
0032 
0033 void LastChangeRecorder::record(const QKeyEvent &e)
0034 {
0035     if (isRepeatOfLastShortcutOverrideAsKeyPress(e, m_changeLog)) {
0036         return;
0037     }
0038 
0039     if (e.key() != Qt::Key_Shift && e.key() != Qt::Key_Control && e.key() != Qt::Key_Meta && e.key() != Qt::Key_Alt) {
0040         m_changeLog.append(KeyEvent::fromQKeyEvent(e));
0041     }
0042 }
0043 
0044 void LastChangeRecorder::dropLast()
0045 {
0046     Q_ASSERT(!m_changeLog.isEmpty());
0047     m_changeLog.pop_back();
0048 }
0049 
0050 void LastChangeRecorder::clear()
0051 {
0052     m_changeLog.clear();
0053 }
0054 
0055 QString LastChangeRecorder::encodedChanges() const
0056 {
0057     QString result;
0058 
0059     QList<KeyEvent> keyLog = m_changeLog;
0060 
0061     for (int i = 0; i < keyLog.size(); i++) {
0062         int keyCode = keyLog.at(i).key();
0063         QString text = keyLog.at(i).text();
0064         int mods = keyLog.at(i).modifiers();
0065         QChar key;
0066 
0067         if (text.length() > 0) {
0068             key = text.at(0);
0069         }
0070 
0071         if (text.isEmpty() || (text.length() == 1 && text.at(0) < QChar(0x20)) || (mods != Qt::NoModifier && mods != Qt::ShiftModifier)) {
0072             QString keyPress;
0073 
0074             keyPress.append(QLatin1Char('<'));
0075             keyPress.append((mods & Qt::ShiftModifier) ? QStringLiteral("s-") : QString());
0076             keyPress.append((mods & CONTROL_MODIFIER) ? QStringLiteral("c-") : QString());
0077             keyPress.append((mods & Qt::AltModifier) ? QStringLiteral("a-") : QString());
0078             keyPress.append((mods & META_MODIFIER) ? QStringLiteral("m-") : QString());
0079             keyPress.append(keyCode <= 0xFF ? QChar(keyCode) : KeyParser::self()->qt2vi(keyCode));
0080             keyPress.append(QLatin1Char('>'));
0081 
0082             key = KeyParser::self()->encodeKeySequence(keyPress).at(0);
0083         }
0084 
0085         result.append(key);
0086     }
0087 
0088     return result;
0089 }
0090 
0091 bool LastChangeRecorder::isReplaying() const
0092 {
0093     return m_isReplaying;
0094 }
0095 
0096 void LastChangeRecorder::replay(const QString &commands, const CompletionList &completions)
0097 {
0098     m_isReplaying = true;
0099     m_viInputModeManager->completionReplayer()->start(completions);
0100     m_viInputModeManager->feedKeyPresses(commands);
0101     m_viInputModeManager->completionReplayer()->stop();
0102     m_isReplaying = false;
0103 }