aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/fakevim
diff options
context:
space:
mode:
authorTimon Riedelbauch <timonriedelbauch@gmail.com>2021-02-01 02:46:07 +0100
committerTimon Riedelbauch <timonriedelbauch@gmail.com>2021-02-03 09:34:54 +0000
commit002db1fa4288b8e88bb1740c0eb84f06d601e462 (patch)
tree789ff0cfe95e790dc7db908e671afacdaefb7bf1 /src/plugins/fakevim
parentd1934fa1c420962761b2e6be922865b7f91b7542 (diff)
add special characters \u \U \l \L to fakevim substitute command
vim substitute (:s/) hast the option to use special characters \u \U \l \L in the replacement part to change the case of the following letters. This was not present in fakevim. Change-Id: I13785db24018283c242d94fd7892765657570176 Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/plugins/fakevim')
-rw-r--r--src/plugins/fakevim/fakevim_test.cpp12
-rw-r--r--src/plugins/fakevim/fakevimhandler.cpp68
2 files changed, 76 insertions, 4 deletions
diff --git a/src/plugins/fakevim/fakevim_test.cpp b/src/plugins/fakevim/fakevim_test.cpp
index 88973a5200e..81eee1973f0 100644
--- a/src/plugins/fakevim/fakevim_test.cpp
+++ b/src/plugins/fakevim/fakevim_test.cpp
@@ -3006,6 +3006,18 @@ void FakeVimPlugin::test_vim_substitute()
COMMAND("undo | s/[bcef]//g", "a d");
COMMAND("undo | s/\\w//g", " ");
COMMAND("undo | s/f\\|$/-/g", "abc de-");
+
+ // modifiers
+ data.setText("abC dEfGh");
+ COMMAND("s/b...E/\\u&", "aBC dEfGh");
+ COMMAND("undo | s/b...E/\\U&/g", "aBC DEfGh");
+ COMMAND("undo | s/C..E/\\l&/g", "abc dEfGh");
+ COMMAND("undo | s/b...E/\\L&/g", "abc defGh");
+
+ COMMAND("undo | s/\\(b...E\\)/\\u\\1/g", "aBC dEfGh");
+ COMMAND("undo | s/\\(b...E\\)/\\U\\1/g", "aBC DEfGh");
+ COMMAND("undo | s/\\(C..E\\)/\\l\\1/g", "abc dEfGh");
+ COMMAND("undo | s/\\(b...E\\)/\\L\\1/g", "abc defGh");
}
void FakeVimPlugin::test_vim_ex_commandbuffer_paste()
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index ea0be66d54a..e4147e55806 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -700,6 +700,47 @@ static char backslashed(char t)
return t;
}
+enum class Modifier {NONE,UPPERCASE,LOWERCASE};
+
+static QString applyReplacementLetterCases(QString repl,
+ Modifier &toggledModifier,
+ Modifier &nextCharacterModifier)
+{
+ if (toggledModifier == Modifier::UPPERCASE)
+ repl = repl.toUpper();
+ else if (toggledModifier == Modifier::LOWERCASE)
+ repl = repl.toLower();
+
+ if (nextCharacterModifier == Modifier::UPPERCASE) {
+ repl.replace(0, 1, repl.at(0).toUpper());
+ nextCharacterModifier = Modifier::NONE;
+ } else if (nextCharacterModifier == Modifier::LOWERCASE) {
+ repl.replace(0, 1, repl.at(0).toLower());
+ nextCharacterModifier = Modifier::NONE;
+ }
+ return repl;
+}
+
+static QChar applyReplacementLetterCases(QChar repl,
+ Modifier &toggledModifier,
+ Modifier &nextCharacterModifier)
+{
+ if (nextCharacterModifier == Modifier::UPPERCASE){
+ nextCharacterModifier = Modifier::NONE;
+ return repl.toUpper();
+ }
+ else if (nextCharacterModifier == Modifier::LOWERCASE) {
+ nextCharacterModifier = Modifier::NONE;
+ return repl.toLower();
+ }
+ else if (toggledModifier == Modifier::UPPERCASE)
+ return repl.toUpper();
+ else if (toggledModifier == Modifier::LOWERCASE)
+ return repl.toLower();
+ else
+ return repl;
+}
+
static bool substituteText(QString *text,
const QRegularExpression &pattern,
const QString &replacement,
@@ -729,14 +770,31 @@ static bool substituteText(QString *text,
QString matched = text->mid(pos, match.captured(0).size());
QString repl;
bool escape = false;
+ Modifier toggledModifier = Modifier::NONE;
+ Modifier nextCharacterModifier = Modifier::NONE;
// insert captured texts
for (int i = 0; i < replacement.size(); ++i) {
const QChar &c = replacement[i];
if (escape) {
escape = false;
if (c.isDigit()) {
- if (c.digitValue() <= match.lastCapturedIndex())
- repl += match.captured(c.digitValue());
+ if (c.digitValue() <= match.lastCapturedIndex()) {
+ repl += applyReplacementLetterCases(match.captured(c.digitValue()),
+ toggledModifier,
+ nextCharacterModifier);
+
+ }
+ } else if (c == 'u') {
+ nextCharacterModifier = Modifier::UPPERCASE;
+ } else if (c == 'l') {
+ nextCharacterModifier = Modifier::LOWERCASE;
+ } else if (c == 'U') {
+ toggledModifier = Modifier::UPPERCASE;
+ } else if (c == 'L') {
+ toggledModifier = Modifier::LOWERCASE;
+ } else if (c == 'e' || c == 'E') {
+ nextCharacterModifier = Modifier::NONE;
+ toggledModifier = Modifier::NONE;
} else {
repl += backslashed(c.unicode());
}
@@ -744,9 +802,11 @@ static bool substituteText(QString *text,
if (c == '\\')
escape = true;
else if (c == '&')
- repl += match.captured(0);
+ repl += applyReplacementLetterCases(match.captured(0),
+ toggledModifier,
+ nextCharacterModifier);
else
- repl += c;
+ repl += applyReplacementLetterCases(c, toggledModifier, nextCharacterModifier);
}
}
text->replace(pos, matched.size(), repl);