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

0001 /*
0002     SPDX-FileCopyrightText: KDE Developers
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "registers.h"
0008 #include "katepartdebug.h"
0009 
0010 #include <KConfigGroup>
0011 
0012 #include <QApplication>
0013 #include <QClipboard>
0014 
0015 using namespace KateVi;
0016 
0017 void Registers::readConfig(const KConfigGroup &config)
0018 {
0019     const QStringList names = config.readEntry("ViRegisterNames", QStringList());
0020     const QStringList contents = config.readEntry("ViRegisterContents", QStringList());
0021     const QList<int> flags = config.readEntry("ViRegisterFlags", QList<int>());
0022 
0023     if (names.size() != contents.size() || contents.size() != flags.size()) {
0024         return;
0025     }
0026 
0027     for (int i = 0; i < names.size(); i++) {
0028         if (!names.at(i).isEmpty()) {
0029             set(names.at(i).at(0), contents.at(i), (OperationMode)(flags.at(i)));
0030         }
0031     }
0032 }
0033 
0034 void Registers::writeConfig(KConfigGroup &config) const
0035 {
0036     if (m_registers.empty()) {
0037         return;
0038     }
0039 
0040     QStringList names;
0041     QStringList contents;
0042     QList<int> flags;
0043     for (const auto &[name, reg] : m_registers) {
0044         if (reg.first.length() <= 1000) {
0045             names << name;
0046             contents << reg.first;
0047             flags << int(reg.second);
0048         } else {
0049             qCDebug(LOG_KTE) << "Did not save contents of register " << name << ": contents too long (" << reg.first.length() << " characters)";
0050         }
0051     }
0052 
0053     config.writeEntry("ViRegisterNames", names);
0054     config.writeEntry("ViRegisterContents", contents);
0055     config.writeEntry("ViRegisterFlags", flags);
0056 }
0057 
0058 void Registers::setInsertStopped(const QString &text)
0059 {
0060     set(InsertStoppedRegister, text);
0061 }
0062 
0063 void Registers::set(const QChar &reg, const QString &text, OperationMode flag)
0064 {
0065     if (reg == BlackHoleRegister) {
0066         return;
0067     }
0068 
0069     if (reg == PrependNumberedRegister || (reg >= FirstNumberedRegister && reg <= LastNumberedRegister)) { // "kill ring" registers
0070         setNumberedRegister(reg, text, flag);
0071     } else if (reg == SystemClipboardRegister) {
0072         QApplication::clipboard()->setText(text, QClipboard::Clipboard);
0073     } else if (reg == SystemSelectionRegister) {
0074         QApplication::clipboard()->setText(text, QClipboard::Selection);
0075     } else {
0076         const QChar lowercase_reg = reg.toLower();
0077         if (reg != lowercase_reg) {
0078             m_registers[lowercase_reg].first.append(text);
0079         } else {
0080             m_registers.insert_or_assign(lowercase_reg, Register(text, flag));
0081         }
0082     }
0083 
0084     if (reg == ZeroRegister || reg == PrependNumberedRegister || reg == SmallDeleteRegister) {
0085         m_default = reg;
0086     }
0087 }
0088 
0089 QString Registers::getContent(const QChar &reg) const
0090 {
0091     return getRegister(reg).first;
0092 }
0093 
0094 OperationMode Registers::getFlag(const QChar &reg) const
0095 {
0096     return getRegister(reg).second;
0097 }
0098 
0099 Registers::Register Registers::getRegister(const QChar &reg) const
0100 {
0101     Register regPair;
0102     QChar _reg = (reg != UnnamedRegister ? reg : m_default);
0103 
0104     if (_reg >= FirstNumberedRegister && _reg <= LastNumberedRegister) {
0105         int index = _reg.digitValue() - 1;
0106         if (m_numbered.size() > index) {
0107             regPair = m_numbered.at(index);
0108         }
0109     } else if (_reg == PrependNumberedRegister) {
0110         if (!m_numbered.isEmpty()) {
0111             regPair = m_numbered.front();
0112         }
0113     } else if (_reg == SystemClipboardRegister) {
0114         QString regContent = QApplication::clipboard()->text(QClipboard::Clipboard);
0115         regPair = Register(regContent, CharWise);
0116     } else if (_reg == SystemSelectionRegister) {
0117         QString regContent = QApplication::clipboard()->text(QClipboard::Selection);
0118         regPair = Register(regContent, CharWise);
0119     } else {
0120         const QChar lowercase_reg = _reg.toLower();
0121         auto it = m_registers.find(lowercase_reg);
0122         if (it != m_registers.end()) {
0123             return it->second;
0124         }
0125     }
0126 
0127     return regPair;
0128 }
0129 
0130 void Registers::setNumberedRegister(const QChar &reg, const QString &text, OperationMode flag)
0131 {
0132     int index = reg.digitValue() - 1;
0133     if (reg == PrependNumberedRegister || index > m_numbered.size()) {
0134         if (m_numbered.size() == 9) {
0135             m_numbered.removeLast();
0136         }
0137 
0138         // register 0 is used for the last yank command, so insert at position 1
0139         m_numbered.prepend(Register(text, flag));
0140     } else {
0141         m_numbered[index].first = text;
0142         m_numbered[index].second = flag;
0143     }
0144 }