summaryrefslogtreecommitdiff
path: root/src/plugins/fakevim/fakevimhandler.cpp
diff options
context:
space:
mode:
authorhjk <hjk@qt.io>2022-06-23 12:35:48 +0200
committerhjk <hjk@qt.io>2022-06-27 14:43:42 +0000
commit2e85c489447a0ce0249eb54fea701fe27015a6af (patch)
tree7416741a7653486174a1da6cc8b64ca844b35ca1 /src/plugins/fakevim/fakevimhandler.cpp
parent51c798b5176b225d3bf90d9c97ff85dfc3ee4fa3 (diff)
downloadqt-creator-2e85c489447a0ce0249eb54fea701fe27015a6af.tar.gz
FakeVim: Partially implement multi repeat command (:g, :v)
Change-Id: Ifed113e80103b9fdd109cb4a5a6a31098f77d74c Reviewed-by: Christian Stenger <christian.stenger@qt.io> Reviewed-by: Lukas Holecek <hluk@email.cz> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Diffstat (limited to 'src/plugins/fakevim/fakevimhandler.cpp')
-rw-r--r--src/plugins/fakevim/fakevimhandler.cpp59
1 files changed, 58 insertions, 1 deletions
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 812bb994d0..413ddae6ac 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -2270,6 +2270,7 @@ public:
bool handleExHistoryCommand(const ExCommand &cmd);
bool handleExRegisterCommand(const ExCommand &cmd);
bool handleExMapCommand(const ExCommand &cmd);
+ bool handleExMultiRepeatCommand(const ExCommand &cmd);
bool handleExNohlsearchCommand(const ExCommand &cmd);
bool handleExNormalCommand(const ExCommand &cmd);
bool handleExReadCommand(const ExCommand &cmd);
@@ -5907,7 +5908,7 @@ void FakeVimHandler::Private::handleCommand(const QString &cmd)
bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
{
- // :substitute
+ // :[range]s[ubstitute]/{pattern}/{string}/[flags] [count]
if (!cmd.matches("s", "substitute")
&& !(cmd.cmd.isEmpty() && !cmd.args.isEmpty() && QString("&~").contains(cmd.args[0]))) {
return false;
@@ -6504,6 +6505,61 @@ bool FakeVimHandler::Private::handleExShiftCommand(const ExCommand &cmd)
return true;
}
+bool FakeVimHandler::Private::handleExMultiRepeatCommand(const ExCommand &cmd)
+{
+ // :[range]g[lobal]/{pattern}/[cmd]
+ // :[range]g[lobal]!/{pattern}/[cmd]
+ // :[range]v[globa]!/{pattern}/[cmd]
+ const bool hasG = cmd.matches("g", "global");
+ const bool hasV = cmd.matches("v", "vglobal");
+ if (!hasG && !hasV)
+ return false;
+
+ // Force operation on full lines, and full document if only
+ // one line (the current one...) is specified
+ int beginLine = lineForPosition(cmd.range.beginPos);
+ int endLine = lineForPosition(cmd.range.endPos);
+ if (beginLine == endLine) {
+ beginLine = 0;
+ endLine = lineForPosition(lastPositionInDocument());
+ }
+
+ const bool negates = hasV || cmd.hasBang;
+
+ const QChar delim = cmd.args.front();
+ const QString pattern = cmd.args.section(delim, 1, 1);
+ const QRegularExpression re(pattern);
+
+ QString innerCmd = cmd.args.section(delim, 2, 2);
+ if (innerCmd.isEmpty())
+ innerCmd = "p";
+
+ QList<QTextCursor> matches;
+
+ for (int line = beginLine; line <= endLine; ++line) {
+ const int pos = firstPositionInLine(line);
+ const Range range(pos, pos, RangeLineMode);
+ const QString lineContents = selectText(range);
+ const QRegularExpressionMatch match = re.match(lineContents);
+ if (match.hasMatch() ^ negates) {
+ QTextCursor tc(document());
+ tc.setPosition(pos);
+ matches.append(tc);
+ }
+ }
+
+ beginEditBlock();
+
+ for (const QTextCursor &tc : qAsConst(matches)) {
+ setPosition(tc.position());
+ handleExCommand(innerCmd);
+ }
+
+ endEditBlock();
+
+ return true;
+}
+
bool FakeVimHandler::Private::handleExSortCommand(const ExCommand &cmd)
{
// :[range]sor[t][!] [b][f][i][n][o][r][u][x] [/{pattern}/]
@@ -6683,6 +6739,7 @@ bool FakeVimHandler::Private::handleExCommandHelper(ExCommand &cmd)
|| handleExMoveCommand(cmd)
|| handleExJoinCommand(cmd)
|| handleExMapCommand(cmd)
+ || handleExMultiRepeatCommand(cmd)
|| handleExNohlsearchCommand(cmd)
|| handleExNormalCommand(cmd)
|| handleExReadCommand(cmd)