aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/fakevim/fakevimhandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/fakevim/fakevimhandler.cpp')
-rw-r--r--src/plugins/fakevim/fakevimhandler.cpp157
1 files changed, 89 insertions, 68 deletions
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 601377ed69..66ebe44a46 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -63,7 +63,7 @@
#include <QObject>
#include <QPointer>
#include <QProcess>
-#include <QRegExp>
+#include <QRegularExpression>
#include <QTextStream>
#include <QTimer>
#include <QStack>
@@ -387,9 +387,9 @@ static bool eatString(const QString &prefix, QString *str)
return true;
}
-static QRegExp vimPatternToQtPattern(QString needle, bool ignoreCaseOption, bool smartCaseOption)
+static QRegularExpression vimPatternToQtPattern(QString needle, bool ignoreCaseOption, bool smartCaseOption)
{
- /* Transformations (Vim regexp -> QRegExp):
+ /* Transformations (Vim regexp -> QRegularExpression):
* \a -> [A-Za-z]
* \A -> [^A-Za-z]
* \h -> [A-Za-z_]
@@ -420,7 +420,7 @@ static QRegExp vimPatternToQtPattern(QString needle, bool ignoreCaseOption, bool
*/
// FIXME: Option smartcase should be used only if search was typed by user.
bool ignorecase = ignoreCaseOption
- && !(smartCaseOption && needle.contains(QRegExp("[A-Z]")));
+ && !(smartCaseOption && needle.contains(QRegularExpression("[A-Z]")));
QString pattern;
pattern.reserve(2 * needle.size());
@@ -530,7 +530,7 @@ static QRegExp vimPatternToQtPattern(QString needle, bool ignoreCaseOption, bool
else if (brace)
pattern.append('[');
- return QRegExp(pattern);
+ return QRegularExpression(pattern);
}
static bool afterEndOfLine(const QTextDocument *doc, int position)
@@ -539,7 +539,7 @@ static bool afterEndOfLine(const QTextDocument *doc, int position)
&& doc->findBlock(position).length() > 1;
}
-static void searchForward(QTextCursor *tc, QRegExp &needleExp, int *repeat)
+static void searchForward(QTextCursor *tc, const QRegularExpression &needleExp, int *repeat)
{
const QTextDocument *doc = tc->document();
const int startPos = tc->position();
@@ -577,16 +577,18 @@ static void searchForward(QTextCursor *tc, QRegExp &needleExp, int *repeat)
tc->movePosition(Left);
}
-static void searchBackward(QTextCursor *tc, QRegExp &needleExp, int *repeat)
+static void searchBackward(QTextCursor *tc, const QRegularExpression &needleExp, int *repeat)
{
// Search from beginning of line so that matched text is the same.
QTextBlock block = tc->block();
QString line = block.text();
- int i = line.indexOf(needleExp, 0);
+ QRegularExpressionMatch match;
+ int i = line.indexOf(needleExp, 0, &match);
while (i != -1 && i < tc->positionInBlock()) {
--*repeat;
- i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength()));
+ const int offset = i + qMax(1, match.capturedLength());
+ i = line.indexOf(needleExp, offset, &match);
if (i == line.size())
i = -1;
}
@@ -599,10 +601,11 @@ static void searchBackward(QTextCursor *tc, QRegExp &needleExp, int *repeat)
if (!block.isValid())
break;
line = block.text();
- i = line.indexOf(needleExp, 0);
+ i = line.indexOf(needleExp, 0, &match);
while (i != -1) {
--*repeat;
- i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength()));
+ const int offset = i + qMax(1, match.capturedLength());
+ i = line.indexOf(needleExp, offset, &match);
if (i == line.size())
i = -1;
}
@@ -613,19 +616,20 @@ static void searchBackward(QTextCursor *tc, QRegExp &needleExp, int *repeat)
return;
}
- i = line.indexOf(needleExp, 0);
+ i = line.indexOf(needleExp, 0, &match);
while (*repeat < 0) {
- i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength()));
+ const int offset = i + qMax(1, match.capturedLength());
+ i = line.indexOf(needleExp, offset, &match);
++*repeat;
}
tc->setPosition(block.position() + i);
- tc->setPosition(tc->position() + needleExp.matchedLength(), KeepAnchor);
+ tc->setPosition(tc->position() + match.capturedLength(), KeepAnchor);
}
// Commands [[, []
static void bracketSearchBackward(QTextCursor *tc, const QString &needleExp, int repeat)
{
- QRegExp re(needleExp);
+ const QRegularExpression re(needleExp);
QTextCursor tc2 = *tc;
tc2.setPosition(tc2.position() - 1);
searchBackward(&tc2, re, &repeat);
@@ -638,7 +642,7 @@ static void bracketSearchBackward(QTextCursor *tc, const QString &needleExp, int
static void bracketSearchForward(QTextCursor *tc, const QString &needleExp, int repeat,
bool searchWithCommand)
{
- QRegExp re(searchWithCommand ? QString("^\\}|^\\{") : needleExp);
+ QRegularExpression re(searchWithCommand ? QString("^\\}|^\\{") : needleExp);
QTextCursor tc2 = *tc;
tc2.setPosition(tc2.position() + 1);
searchForward(&tc2, re, &repeat);
@@ -668,17 +672,21 @@ static char backslashed(char t)
return t;
}
-static bool substituteText(QString *text, QRegExp &pattern, const QString &replacement,
- bool global)
+static bool substituteText(QString *text,
+ const QRegularExpression &pattern,
+ const QString &replacement,
+ bool global)
{
bool substituted = false;
int pos = 0;
int right = -1;
while (true) {
- pos = pattern.indexIn(*text, pos, QRegExp::CaretAtZero);
- if (pos == -1)
+ const QRegularExpressionMatch match = pattern.match(*text, pos);
+ if (!match.hasMatch())
break;
+ pos = match.capturedStart();
+
// ensure that substitution is advancing towards end of line
if (right == text->size() - pos) {
++pos;
@@ -690,7 +698,7 @@ static bool substituteText(QString *text, QRegExp &pattern, const QString &repla
right = text->size() - pos;
substituted = true;
- QString matched = text->mid(pos, pattern.cap(0).size());
+ QString matched = text->mid(pos, match.captured(0).size());
QString repl;
bool escape = false;
// insert captured texts
@@ -699,8 +707,8 @@ static bool substituteText(QString *text, QRegExp &pattern, const QString &repla
if (escape) {
escape = false;
if (c.isDigit()) {
- if (c.digitValue() <= pattern.captureCount())
- repl += pattern.cap(c.digitValue());
+ if (c.digitValue() <= match.lastCapturedIndex())
+ repl += match.captured(c.digitValue());
} else {
repl += backslashed(c.unicode());
}
@@ -708,7 +716,7 @@ static bool substituteText(QString *text, QRegExp &pattern, const QString &repla
if (c == '\\')
escape = true;
else if (c == '&')
- repl += pattern.cap(0);
+ repl += match.captured(0);
else
repl += c;
}
@@ -893,6 +901,11 @@ static bool isOnlyControlModifier(const Qt::KeyboardModifiers &mods)
return (mods ^ ControlModifier) == Qt::NoModifier;
}
+static bool hasControlModifier(const Qt::KeyboardModifiers &mods)
+{
+ return mods.testFlag(ControlModifier);
+}
+
Range::Range(int b, int e, RangeMode m)
: beginPos(qMin(b, e)), endPos(qMax(b, e)), rangemode(m)
@@ -1065,7 +1078,7 @@ public:
bool is(int c) const
{
- return m_xkey == c && !isControl();
+ return m_xkey == c && !hasControlModifier(m_modifiers);
}
bool isControl() const
@@ -1346,7 +1359,7 @@ class History
public:
History() : m_items(QString()) {}
void append(const QString &item);
- const QString &move(const QStringRef &prefix, int skip);
+ const QString &move(QStringView prefix, int skip);
const QString &current() const { return m_items[m_index]; }
const QStringList &items() const { return m_items; }
void restart() { m_index = m_items.size() - 1; }
@@ -1367,7 +1380,7 @@ void History::append(const QString &item)
restart();
}
-const QString &History::move(const QStringRef &prefix, int skip)
+const QString &History::move(QStringView prefix, int skip)
{
if (!current().startsWith(prefix))
restart();
@@ -1397,7 +1410,7 @@ public:
m_buffer = s; m_pos = m_userPos = pos; m_anchor = anchor >= 0 ? anchor : pos;
}
- QStringRef userContents() const { return m_buffer.leftRef(m_userPos); }
+ QStringView userContents() const { return QStringView{m_buffer}.left(m_userPos); }
const QChar &prompt() const { return m_prompt; }
const QString &contents() const { return m_buffer; }
bool isEmpty() const { return m_buffer.isEmpty(); }
@@ -1418,8 +1431,9 @@ public:
void moveEnd() { m_userPos = m_pos = m_buffer.size(); }
void setHistoryAutoSave(bool autoSave) { m_historyAutoSave = autoSave; }
- void historyDown() { setContents(m_history.move(userContents(), 1)); }
- void historyUp() { setContents(m_history.move(userContents(), -1)); }
+ bool userContentsValid() const { return m_userPos >= 0 && m_userPos <= m_buffer.size(); }
+ void historyDown() { if (userContentsValid()) setContents(m_history.move(userContents(), 1)); }
+ void historyUp() { if (userContentsValid()) setContents(m_history.move(userContents(), -1)); }
const QStringList &historyItems() const { return m_history.items(); }
void historyPush(const QString &item = QString())
{
@@ -1590,7 +1604,7 @@ public:
bool walk(const Inputs &inputs)
{
- foreach (const Input &input, inputs) {
+ for (const Input &input : inputs) {
if (!walk(input))
return false;
}
@@ -1628,7 +1642,7 @@ public:
void setInputs(const Inputs &key, const Inputs &inputs, bool unique = false)
{
ModeMapping *current = &(*m_parent)[m_mode];
- foreach (const Input &input, key)
+ for (const Input &input : key)
current = &(*current)[input];
if (!unique || current->value().isEmpty())
current->setValue(inputs);
@@ -2626,7 +2640,7 @@ void FakeVimHandler::Private::commitInsertState()
lastInsertion.prepend(QString("<DELETE>").repeated(insertState.deletes));
// Remove indentation.
- lastInsertion.replace(QRegExp("(^|\n)[\\t ]+"), "\\1");
+ lastInsertion.replace(QRegularExpression("(^|\n)[\\t ]+"), "\\1");
}
void FakeVimHandler::Private::invalidateInsertState()
@@ -2850,7 +2864,7 @@ void FakeVimHandler::Private::prependMapping(const Inputs &inputs)
// FIXME: Implement Vim option maxmapdepth (default value is 1000).
if (g.mapDepth >= 1000) {
const int i = qMax(0, g.pendingInput.lastIndexOf(Input()));
- QList<Input> inputs = g.pendingInput.mid(i);
+ const QList<Input> inputs = g.pendingInput.mid(i);
clearPendingInput();
g.pendingInput.append(inputs);
showMessage(MessageError, Tr::tr("Recursive mapping"));
@@ -3913,7 +3927,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input)
QString needle;
QTextCursor tc = m_cursor;
tc.select(QTextCursor::WordUnderCursor);
- needle = QRegExp::escape(tc.selection().toPlainText());
+ needle = QRegularExpression::escape(tc.selection().toPlainText());
if (!g.gflag) {
needle.prepend("\\<");
needle.append("\\>");
@@ -4598,7 +4612,7 @@ bool FakeVimHandler::Private::handleReplaceSubMode(const Input &input)
++range.endPos;
// Replace each character but preserve lines.
transformText(range, [&c](const QString &text) {
- return QString(text).replace(QRegExp("[^\\n]"), c);
+ return QString(text).replace(QRegularExpression("[^\\n]"), c);
});
} else if (count() <= rightDist()) {
pushUndoState();
@@ -5427,7 +5441,7 @@ bool FakeVimHandler::Private::parseExCommand(QString *line, ExCommand *cmd)
cmd->cmd = line->mid(0, i).trimmed();
// command arguments starts with first non-letter character
- cmd->args = cmd->cmd.section(QRegExp("(?=[^a-zA-Z])"), 1);
+ cmd->args = cmd->cmd.section(QRegularExpression("(?=[^a-zA-Z])"), 1);
if (!cmd->args.isEmpty()) {
cmd->cmd.chop(cmd->args.size());
cmd->args = cmd->args.trimmed();
@@ -5447,7 +5461,7 @@ bool FakeVimHandler::Private::parseExCommand(QString *line, ExCommand *cmd)
bool FakeVimHandler::Private::parseLineRange(QString *line, ExCommand *cmd)
{
// remove leading colons and spaces
- line->remove(QRegExp("^\\s*(:+\\s*)*"));
+ line->remove(QRegularExpression("^\\s*(:+\\s*)*"));
// special case ':!...' (use invalid range)
if (line->startsWith('!')) {
@@ -5506,10 +5520,10 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
int count = 1;
QString line = cmd.args;
- const int countIndex = line.lastIndexOf(QRegExp("\\d+$"));
- if (countIndex != -1) {
- count = line.midRef(countIndex).toInt();
- line = line.mid(0, countIndex).trimmed();
+ const QRegularExpressionMatch match = QRegularExpression("\\d+$").match(line);
+ if (match.hasMatch()) {
+ count = match.captured().toInt();
+ line = line.left(match.capturedStart()).trimmed();
}
if (cmd.cmd.isEmpty()) {
@@ -5545,8 +5559,9 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
if (g.lastSubstituteFlags.contains('i'))
needle.prepend("\\c");
- QRegExp pattern = vimPatternToQtPattern(needle, hasConfig(ConfigIgnoreCase),
- hasConfig(ConfigSmartCase));
+ const QRegularExpression pattern = vimPatternToQtPattern(needle,
+ hasConfig(ConfigIgnoreCase),
+ hasConfig(ConfigSmartCase));
QTextBlock lastBlock;
QTextBlock firstBlock;
@@ -5671,8 +5686,8 @@ bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map
break;
}
- const QString lhs = args.section(QRegExp("\\s+"), 0, 0);
- const QString rhs = args.section(QRegExp("\\s+"), 1);
+ const QString lhs = args.section(QRegularExpression("\\s+"), 0, 0);
+ const QString rhs = args.section(QRegularExpression("\\s+"), 1);
if ((rhs.isNull() && type != Unmap) || (!rhs.isNull() && type == Unmap)) {
// FIXME: Dump mappings here.
//qDebug() << g.mappings;
@@ -5735,7 +5750,7 @@ bool FakeVimHandler::Private::handleExRegisterCommand(const ExCommand &cmd)
}
QString info;
info += "--- Registers ---\n";
- foreach (char reg, regs) {
+ for (char reg : qAsConst(regs)) {
QString value = quoteUnprintable(registerContents(reg));
info += QString("\"%1 %2\n").arg(reg).arg(value);
}
@@ -5947,7 +5962,7 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd)
{
// Note: The cmd.args.isEmpty() case is handled by handleExPluginCommand.
// :w, :x, :wq, ...
- //static QRegExp reWrite("^[wx]q?a?!?( (.*))?$");
+ //static QRegularExpression reWrite("^[wx]q?a?!?( (.*))?$");
if (cmd.cmd != "w" && cmd.cmd != "x" && cmd.cmd != "wq")
return false;
@@ -6340,8 +6355,9 @@ void FakeVimHandler::Private::searchBalanced(bool forward, QChar needle, QChar o
QTextCursor FakeVimHandler::Private::search(const SearchData &sd, int startPos, int count,
bool showMessages)
{
- QRegExp needleExp = vimPatternToQtPattern(sd.needle, hasConfig(ConfigIgnoreCase),
- hasConfig(ConfigSmartCase));
+ const QRegularExpression needleExp = vimPatternToQtPattern(sd.needle,
+ hasConfig(ConfigIgnoreCase),
+ hasConfig(ConfigSmartCase));
if (!needleExp.isValid()) {
if (showMessages) {
QString error = needleExp.errorString();
@@ -6684,7 +6700,7 @@ void FakeVimHandler::Private::setupCharClass()
m_charClass[i] = c.isSpace() ? 0 : 1;
}
const QString conf = config(ConfigIsKeyword).toString();
- foreach (const QString &part, conf.split(',')) {
+ for (const QString &part : conf.split(',')) {
if (part.contains('-')) {
const int from = someInt(part.section('-', 0, 0));
const int to = someInt(part.section('-', 1, 1));
@@ -7177,7 +7193,7 @@ void FakeVimHandler::Private::insertText(QTextCursor &tc, const QString &text)
passEventToEditor(event, tc);
}
- foreach (QChar c, text) {
+ for (QChar c : text) {
QKeyEvent event(QEvent::KeyPress, -1, Qt::NoModifier, QString(c));
passEventToEditor(event, tc);
}
@@ -7218,8 +7234,8 @@ void FakeVimHandler::Private::invertCase(const Range &range)
[] (const QString &text) -> QString {
QString result = text;
for (int i = 0; i < result.length(); ++i) {
- QCharRef c = result[i];
- c = c.isUpper() ? c.toLower() : c.toUpper();
+ const QChar c = result[i];
+ result[i] = c.isUpper() ? c.toLower() : c.toUpper();
}
return result;
});
@@ -8129,9 +8145,9 @@ void FakeVimHandler::Private::replay(const QString &command, int repeat)
//qDebug() << "REPLAY: " << quoteUnprintable(command);
clearCurrentMode();
- Inputs inputs(command);
+ const Inputs inputs(command);
for (int i = 0; i < repeat; ++i) {
- foreach (const Input &in, inputs) {
+ for (const Input &in : inputs) {
if (handleDefaultKey(in) != EventHandled)
return;
}
@@ -8389,17 +8405,22 @@ bool FakeVimHandler::Private::changeNumberTextObject(int count)
const int posMin = m_cursor.positionInBlock() + 1;
// find first decimal, hexadecimal or octal number under or after cursor position
- QRegExp re("(0[xX])(0*[0-9a-fA-F]+)|(0)(0*[0-7]+)(?=\\D|$)|(\\d+)");
- int pos = 0;
- while ((pos = re.indexIn(lineText, pos)) != -1 && pos + re.matchedLength() < posMin)
- ++pos;
- if (pos == -1)
- return false;
- int len = re.matchedLength();
- QString prefix = re.cap(1) + re.cap(3);
+ QRegularExpression re("(0[xX])(0*[0-9a-fA-F]+)|(0)(0*[0-7]+)(?=\\D|$)|(\\d+)");
+ QRegularExpressionMatch match;
+ QRegularExpressionMatchIterator it = re.globalMatch(lineText);
+ while (true) {
+ if (!it.hasNext())
+ return false;
+ match = it.next();
+ if (match.capturedEnd() >= posMin)
+ break;
+ }
+ int pos = match.capturedStart();
+ int len = match.capturedLength();
+ QString prefix = match.captured(1) + match.captured(3);
bool hex = prefix.length() >= 2 && (prefix[1].toLower() == 'x');
bool octal = !hex && !prefix.isEmpty();
- const QString num = hex ? re.cap(2) : octal ? re.cap(4) : re.cap(5);
+ const QString num = hex ? match.captured(2) : octal ? match.captured(4) : match.captured(5);
// parse value
bool ok;
@@ -8431,7 +8452,7 @@ bool FakeVimHandler::Private::changeNumberTextObject(int count)
// convert hexadecimal number to upper-case if last letter was upper-case
if (hex) {
- const int lastLetter = num.lastIndexOf(QRegExp("[a-fA-F]"));
+ const int lastLetter = num.lastIndexOf(QRegularExpression("[a-fA-F]"));
if (lastLetter != -1 && num[lastLetter].isUpper())
repl = repl.toUpper();
}
@@ -8760,9 +8781,9 @@ void FakeVimHandler::handleReplay(const QString &keys)
void FakeVimHandler::handleInput(const QString &keys)
{
- Inputs inputs(keys);
+ const Inputs inputs(keys);
d->enterFakeVim();
- foreach (const Input &input, inputs)
+ for (const Input &input : inputs)
d->handleKey(input);
d->leaveFakeVim();
}