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>
This commit is contained in:
Timon Riedelbauch
2021-02-01 02:46:07 +01:00
parent d1934fa1c4
commit 002db1fa42
2 changed files with 76 additions and 4 deletions

View File

@@ -3006,6 +3006,18 @@ void FakeVimPlugin::test_vim_substitute()
COMMAND("undo | s/[bcef]//g", "a d"); COMMAND("undo | s/[bcef]//g", "a d");
COMMAND("undo | s/\\w//g", " "); COMMAND("undo | s/\\w//g", " ");
COMMAND("undo | s/f\\|$/-/g", "abc de-"); 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() void FakeVimPlugin::test_vim_ex_commandbuffer_paste()

View File

@@ -700,6 +700,47 @@ static char backslashed(char t)
return 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, static bool substituteText(QString *text,
const QRegularExpression &pattern, const QRegularExpression &pattern,
const QString &replacement, const QString &replacement,
@@ -729,14 +770,31 @@ static bool substituteText(QString *text,
QString matched = text->mid(pos, match.captured(0).size()); QString matched = text->mid(pos, match.captured(0).size());
QString repl; QString repl;
bool escape = false; bool escape = false;
Modifier toggledModifier = Modifier::NONE;
Modifier nextCharacterModifier = Modifier::NONE;
// insert captured texts // insert captured texts
for (int i = 0; i < replacement.size(); ++i) { for (int i = 0; i < replacement.size(); ++i) {
const QChar &c = replacement[i]; const QChar &c = replacement[i];
if (escape) { if (escape) {
escape = false; escape = false;
if (c.isDigit()) { if (c.isDigit()) {
if (c.digitValue() <= match.lastCapturedIndex()) if (c.digitValue() <= match.lastCapturedIndex()) {
repl += match.captured(c.digitValue()); 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 { } else {
repl += backslashed(c.unicode()); repl += backslashed(c.unicode());
} }
@@ -744,9 +802,11 @@ static bool substituteText(QString *text,
if (c == '\\') if (c == '\\')
escape = true; escape = true;
else if (c == '&') else if (c == '&')
repl += match.captured(0); repl += applyReplacementLetterCases(match.captured(0),
toggledModifier,
nextCharacterModifier);
else else
repl += c; repl += applyReplacementLetterCases(c, toggledModifier, nextCharacterModifier);
} }
} }
text->replace(pos, matched.size(), repl); text->replace(pos, matched.size(), repl);