File indexing completed on 2024-04-21 03:58:07

0001 /*
0002     SPDX-FileCopyrightText: KDE Developers
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "macrorecorder.h"
0008 #include "completionrecorder.h"
0009 #include "completionreplayer.h"
0010 #include "globalstate.h"
0011 #include "kateview.h"
0012 #include "lastchangerecorder.h"
0013 #include "macros.h"
0014 #include <vimode/inputmodemanager.h>
0015 #include <vimode/keymapper.h>
0016 
0017 namespace
0018 {
0019 const QChar LastPlayedRegister = QLatin1Char('@');
0020 }
0021 
0022 using namespace KateVi;
0023 
0024 MacroRecorder::MacroRecorder(InputModeManager *viInputModeManager)
0025     : m_viInputModeManager(viInputModeManager)
0026     , m_isRecording(false)
0027     , m_macrosBeingReplayedCount(0)
0028     , m_lastPlayedMacroRegister(QChar::Null)
0029 {
0030 }
0031 
0032 void MacroRecorder::start(const QChar &macroRegister)
0033 {
0034     Q_ASSERT(!m_isRecording);
0035     m_isRecording = true;
0036     m_register = macroRegister;
0037     m_viInputModeManager->globalState()->macros()->remove(macroRegister);
0038     m_eventsLog.clear();
0039     m_viInputModeManager->completionRecorder()->start();
0040 }
0041 
0042 void MacroRecorder::stop()
0043 {
0044     Q_ASSERT(m_isRecording);
0045     m_isRecording = false;
0046     CompletionList completions = m_viInputModeManager->completionRecorder()->stop();
0047     m_viInputModeManager->globalState()->macros()->store(m_register, m_eventsLog, completions);
0048 }
0049 
0050 bool MacroRecorder::isRecording() const
0051 {
0052     return m_isRecording;
0053 }
0054 
0055 void MacroRecorder::record(const QKeyEvent &event)
0056 {
0057     if (isRepeatOfLastShortcutOverrideAsKeyPress(event, m_eventsLog)) {
0058         return;
0059     }
0060     m_eventsLog.append(KeyEvent::fromQKeyEvent(event));
0061 }
0062 
0063 void MacroRecorder::dropLast()
0064 {
0065     if (m_isRecording) {
0066         Q_ASSERT(!m_eventsLog.isEmpty());
0067         m_eventsLog.pop_back();
0068     }
0069 }
0070 
0071 void MacroRecorder::replay(const QChar &macroRegister)
0072 {
0073     const QChar reg = (macroRegister == LastPlayedRegister) ? m_lastPlayedMacroRegister : macroRegister;
0074 
0075     m_lastPlayedMacroRegister = reg;
0076     const QString macroAsFeedableKeypresses = m_viInputModeManager->globalState()->macros()->get(reg);
0077 
0078     std::shared_ptr<KeyMapper> mapper(new KeyMapper(m_viInputModeManager, m_viInputModeManager->view()->doc()));
0079     CompletionList completions = m_viInputModeManager->globalState()->macros()->getCompletions(reg);
0080 
0081     m_macrosBeingReplayedCount++;
0082     m_viInputModeManager->completionReplayer()->start(completions);
0083     m_viInputModeManager->pushKeyMapper(mapper);
0084     m_viInputModeManager->feedKeyPresses(macroAsFeedableKeypresses);
0085     m_viInputModeManager->popKeyMapper();
0086     m_viInputModeManager->completionReplayer()->stop();
0087     m_macrosBeingReplayedCount--;
0088 }
0089 
0090 bool MacroRecorder::isReplaying() const
0091 {
0092     return m_macrosBeingReplayedCount > 0;
0093 }