File indexing completed on 2024-03-24 04:00:57
0001 /* 0002 SPDX-FileCopyrightText: KDE Developers 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "macros.h" 0008 #include <vimode/keyparser.h> 0009 0010 #include <KConfigGroup> 0011 0012 using namespace KateVi; 0013 0014 Macros::Macros() = default; 0015 0016 Macros::~Macros() = default; 0017 0018 void Macros::writeConfig(KConfigGroup &config) const 0019 { 0020 const auto macroKeys = m_macros.keys(); 0021 QStringList macroRegisters; 0022 for (const QChar macroRegister : macroKeys) { 0023 macroRegisters.append(macroRegister); 0024 } 0025 QStringList macroContents; 0026 for (const QChar macroRegister : macroKeys) { 0027 macroContents.append(KeyParser::self()->decodeKeySequence(m_macros[macroRegister])); 0028 } 0029 QStringList macroCompletions; 0030 for (const QChar macroRegister : macroKeys) { 0031 macroCompletions.append(QString::number(m_completions[macroRegister].length())); 0032 for (const Completion &completionForMacro : m_completions[macroRegister]) { 0033 macroCompletions.append(encodeMacroCompletionForConfig(completionForMacro)); 0034 } 0035 } 0036 config.writeEntry("Macro Registers", macroRegisters); 0037 config.writeEntry("Macro Contents", macroContents); 0038 config.writeEntry("Macro Completions", macroCompletions); 0039 } 0040 0041 void Macros::readConfig(const KConfigGroup &config) 0042 { 0043 const QStringList macroRegisters = config.readEntry("Macro Registers", QStringList()); 0044 const QStringList macroContents = config.readEntry("Macro Contents", QStringList()); 0045 const QStringList macroCompletions = config.readEntry("Macro Completions", QStringList()); 0046 int macroCompletionsIndex = 0; 0047 if (macroRegisters.length() == macroContents.length()) { 0048 for (int macroIndex = 0; macroIndex < macroRegisters.length(); macroIndex++) { 0049 const QChar macroRegister = macroRegisters[macroIndex].at(0); 0050 m_macros[macroRegister] = KeyParser::self()->encodeKeySequence(macroContents[macroIndex]); 0051 macroCompletionsIndex = readMacroCompletions(macroRegister, macroCompletions, macroCompletionsIndex); 0052 } 0053 } 0054 } 0055 0056 void Macros::clear() 0057 { 0058 m_macros.clear(); 0059 } 0060 0061 void Macros::remove(const QChar ®) 0062 { 0063 m_macros.remove(reg); 0064 } 0065 0066 void Macros::store(const QChar ®, const QList<KeyEvent> ¯oKeyEventLog, const CompletionList &completions) 0067 { 0068 m_macros[reg].clear(); 0069 QList<KeyEvent> withoutClosingQ = macroKeyEventLog; 0070 Q_ASSERT(!macroKeyEventLog.isEmpty() && macroKeyEventLog.last().key() == Qt::Key_Q); 0071 withoutClosingQ.pop_back(); 0072 for (const KeyEvent &keyEvent : std::as_const(withoutClosingQ)) { 0073 const QChar key = KeyParser::self()->KeyEventToQChar(keyEvent); 0074 m_macros[reg].append(key); 0075 } 0076 m_completions[reg] = completions; 0077 } 0078 0079 QString Macros::get(const QChar ®) const 0080 { 0081 return m_macros.contains(reg) ? m_macros[reg] : QString(); 0082 } 0083 0084 CompletionList Macros::getCompletions(const QChar ®) const 0085 { 0086 return m_completions.contains(reg) ? m_completions[reg] : CompletionList(); 0087 } 0088 0089 int Macros::readMacroCompletions(const QChar ®, const QStringList &encodedMacroCompletions, int macroCompletionsIndex) 0090 { 0091 if (macroCompletionsIndex < encodedMacroCompletions.length()) { 0092 bool parsedNumCompletionsSuccessfully = false; 0093 const QString numCompletionsAsString = encodedMacroCompletions[macroCompletionsIndex++]; 0094 const int numCompletions = numCompletionsAsString.toInt(&parsedNumCompletionsSuccessfully); 0095 int count = 0; 0096 m_completions[reg].clear(); 0097 while (count < numCompletions && macroCompletionsIndex < encodedMacroCompletions.length()) { 0098 const QString encodedMacroCompletion = encodedMacroCompletions[macroCompletionsIndex++]; 0099 count++; 0100 m_completions[reg].append(decodeMacroCompletionFromConfig(encodedMacroCompletion)); 0101 } 0102 } 0103 return macroCompletionsIndex; 0104 } 0105 0106 QString Macros::encodeMacroCompletionForConfig(const Completion &completionForMacro) 0107 { 0108 const bool endedWithSemiColon = completionForMacro.completedText().endsWith(QLatin1Char(';')); 0109 QString encodedMacroCompletion = completionForMacro.completedText().remove(QStringLiteral("()")).remove(QLatin1Char(';')); 0110 if (completionForMacro.completionType() == Completion::FunctionWithArgs) { 0111 encodedMacroCompletion += QLatin1String("(...)"); 0112 } else if (completionForMacro.completionType() == Completion::FunctionWithoutArgs) { 0113 encodedMacroCompletion += QLatin1String("()"); 0114 } 0115 if (endedWithSemiColon) { 0116 encodedMacroCompletion += QLatin1Char(';'); 0117 } 0118 if (completionForMacro.removeTail()) { 0119 encodedMacroCompletion += QLatin1Char('|'); 0120 } 0121 return encodedMacroCompletion; 0122 } 0123 0124 Completion Macros::decodeMacroCompletionFromConfig(const QString &encodedMacroCompletion) 0125 { 0126 const bool removeTail = encodedMacroCompletion.endsWith(QLatin1Char('|')); 0127 Completion::CompletionType completionType = Completion::PlainText; 0128 if (encodedMacroCompletion.contains(QLatin1String("(...)"))) { 0129 completionType = Completion::FunctionWithArgs; 0130 } else if (encodedMacroCompletion.contains(QLatin1String("()"))) { 0131 completionType = Completion::FunctionWithoutArgs; 0132 } 0133 QString completionText = encodedMacroCompletion; 0134 completionText.replace(QLatin1String("(...)"), QLatin1String("()")).remove(QLatin1Char('|')); 0135 0136 return Completion(completionText, removeTail, completionType); 0137 }