KTextEditor

mappings.cpp
1/*
2 SPDX-FileCopyrightText: KDE Developers
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "katepartdebug.h"
8#include "kateviinputmode.h"
9#include <vimode/emulatedcommandbar/emulatedcommandbar.h>
10#include <vimode/inputmodemanager.h>
11#include <vimode/keyparser.h>
12#include <vimode/mappings.h>
13
14#include <KConfigGroup>
15
16using namespace KateVi;
17
18void Mappings::readConfig(const KConfigGroup &config)
19{
20 readMappings(config, QStringLiteral("Normal"), NormalModeMapping);
21 readMappings(config, QStringLiteral("Visual"), VisualModeMapping);
22 readMappings(config, QStringLiteral("Insert"), InsertModeMapping);
23 readMappings(config, QStringLiteral("Command"), CommandModeMapping);
24}
25
26void Mappings::writeConfig(KConfigGroup &config) const
27{
28 writeMappings(config, QStringLiteral("Normal"), NormalModeMapping);
29 writeMappings(config, QStringLiteral("Visual"), VisualModeMapping);
30 writeMappings(config, QStringLiteral("Insert"), InsertModeMapping);
31 writeMappings(config, QStringLiteral("Command"), CommandModeMapping);
32}
33
34void Mappings::writeMappings(KConfigGroup &config, const QString &mappingModeName, MappingMode mappingMode) const
35{
36 config.writeEntry(mappingModeName + QLatin1String(" Mode Mapping Keys"), getAll(mappingMode, true));
38 QList<bool> recursives;
39 const auto all = getAll(mappingMode);
40 l.reserve(all.size());
41 recursives.reserve(all.size());
42 for (const QString &s : all) {
43 l << KeyParser::self()->decodeKeySequence(get(mappingMode, s));
44 recursives << isRecursive(mappingMode, s);
45 }
46 config.writeEntry(mappingModeName + QLatin1String(" Mode Mappings"), l);
47 config.writeEntry(mappingModeName + QLatin1String(" Mode Mappings Recursion"), recursives);
48
49 QChar leader = (m_leader.isNull()) ? QChar::fromLatin1('\\') : m_leader;
50 config.writeEntry(QStringLiteral("Map Leader"), QString(leader));
51}
52
53void Mappings::readMappings(const KConfigGroup &config, const QString &mappingModeName, MappingMode mappingMode)
54{
55 const QStringList keys = config.readEntry(mappingModeName + QLatin1String(" Mode Mapping Keys"), QStringList());
56 const QStringList mappings = config.readEntry(mappingModeName + QLatin1String(" Mode Mappings"), QStringList());
57 const QList<bool> isRecursive = config.readEntry(mappingModeName + QLatin1String(" Mode Mappings Recursion"), QList<bool>());
58
59 const QString &mapLeader = config.readEntry(QStringLiteral("Map Leader"), QString());
60 m_leader = (mapLeader.isEmpty()) ? QChar::fromLatin1('\\') : mapLeader[0];
61
62 // sanity check
63 if (keys.length() == mappings.length()) {
64 for (int i = 0; i < keys.length(); i++) {
65 // "Recursion" is a newly-introduced part of the config that some users won't have,
66 // so rather than abort (and lose our mappings) if there are not enough entries, simply
67 // treat any missing ones as Recursive (for backwards compatibility).
68 MappingRecursion recursion = Recursive;
69 if (isRecursive.size() > i && !isRecursive.at(i)) {
70 recursion = NonRecursive;
71 }
72 add(mappingMode, keys.at(i), mappings.at(i), recursion);
73 }
74 } else {
75 qCDebug(LOG_KTE) << "Error when reading mappings from " << mappingModeName << " config: number of keys != number of values";
76 }
77}
78
79void Mappings::add(MappingMode mode, const QString &from, const QString &to, MappingRecursion recursion)
80{
81 const QString &encodedMapping = KeyParser::self()->encodeKeySequence(from);
82
83 if (from.isEmpty()) {
84 return;
85 }
86
87 const QString encodedTo = KeyParser::self()->encodeKeySequence(to);
88 Mapping mapping = {encodedTo, (recursion == Recursive), false};
89
90 // Add this mapping as is.
91 m_mappings[mode][encodedMapping] = mapping;
92
93 // In normal mode replace the <leader> with its value.
94 if (mode == NormalModeMapping) {
95 QString other = from;
96 other.replace(QLatin1String("<leader>"), m_leader);
97 other = KeyParser::self()->encodeKeySequence(other);
98 if (other != encodedMapping) {
99 mapping.temporary = true;
100 m_mappings[mode][other] = mapping;
101 }
102 }
103}
104
105void Mappings::remove(MappingMode mode, const QString &from)
106{
107 const QString &encodedMapping = KeyParser::self()->encodeKeySequence(from);
108 m_mappings[mode].remove(encodedMapping);
109}
110
111void Mappings::clear(MappingMode mode)
112{
113 m_mappings[mode].clear();
114}
115
116QString Mappings::get(MappingMode mode, const QString &from, bool decode, bool includeTemporary) const
117{
118 if (!m_mappings[mode].contains(from)) {
119 return QString();
120 }
121
122 const Mapping &mapping = m_mappings[mode][from];
123 if (mapping.temporary && !includeTemporary) {
124 return QString();
125 }
126
127 const QString &ret = mapping.encoded;
128 if (decode) {
129 return KeyParser::self()->decodeKeySequence(ret);
130 }
131
132 return ret;
133}
134
135QStringList Mappings::getAll(MappingMode mode, bool decode, bool includeTemporary) const
136{
137 QStringList mappings;
138 const QHash<QString, Mapping> mappingsForMode = m_mappings[mode];
139
140 for (auto i = mappingsForMode.begin(); i != mappingsForMode.end(); i++) {
141 if (!includeTemporary && i.value().temporary) {
142 continue;
143 }
144
145 if (decode) {
146 mappings << KeyParser::self()->decodeKeySequence(i.key());
147 } else {
148 mappings << i.key();
149 }
150 }
151 return mappings;
152}
153
154bool Mappings::isRecursive(MappingMode mode, const QString &from) const
155{
156 if (!m_mappings[mode].contains(from)) {
157 return false;
158 }
159
160 return m_mappings[mode][from].recursive;
161}
162
163void Mappings::setLeader(const QChar &leader)
164{
165 m_leader = leader;
166}
167
168Mappings::MappingMode Mappings::mappingModeForCurrentViMode(KateViInputMode *viInputMode)
169{
170 if (viInputMode->viModeEmulatedCommandBar()->isActive()) {
171 return CommandModeMapping;
172 }
173 const ViMode mode = viInputMode->viInputModeManager()->getCurrentViMode();
174 switch (mode) {
175 case ViMode::NormalMode:
176 return NormalModeMapping;
177 case ViMode::VisualMode:
178 case ViMode::VisualLineMode:
179 case ViMode::VisualBlockMode:
180 return VisualModeMapping;
181 case ViMode::InsertMode:
182 case ViMode::ReplaceMode:
183 return InsertModeMapping;
184 default:
185 Q_ASSERT(false && "unrecognised ViMode!");
186 return NormalModeMapping; // Return arbitrary mode to satisfy compiler.
187 }
188}
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
QString readEntry(const char *key, const char *aDefault=nullptr) const
QChar fromLatin1(char c)
bool isNull() const const
iterator begin()
void clear()
iterator end()
bool remove(const Key &key)
const_reference at(qsizetype i) const const
qsizetype length() const const
void reserve(qsizetype size)
qsizetype size() const const
bool isEmpty() const const
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:56:22 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.