forked from qt-creator/qt-creator
fakevim: implement '&'
Change-Id: I64f214d27306733a2840036816366d7a204cbc89 Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
@@ -1030,6 +1030,9 @@ public:
|
|||||||
QList<QTextEdit::ExtraSelection> m_searchSelections;
|
QList<QTextEdit::ExtraSelection> m_searchSelections;
|
||||||
QTextCursor m_searchCursor;
|
QTextCursor m_searchCursor;
|
||||||
QString m_oldNeedle;
|
QString m_oldNeedle;
|
||||||
|
QString m_lastSubstituteFlags;
|
||||||
|
QRegExp m_lastSubstitutePattern;
|
||||||
|
QString m_lastSubstituteReplacement;
|
||||||
|
|
||||||
bool handleExCommandHelper(const ExCommand &cmd); // Returns success.
|
bool handleExCommandHelper(const ExCommand &cmd); // Returns success.
|
||||||
bool handleExPluginCommand(const ExCommand &cmd); // Handled by plugin?
|
bool handleExPluginCommand(const ExCommand &cmd); // Handled by plugin?
|
||||||
@@ -2062,6 +2065,8 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input)
|
|||||||
handleFfTt(m_semicolonKey);
|
handleFfTt(m_semicolonKey);
|
||||||
m_subsubmode = NoSubSubMode;
|
m_subsubmode = NoSubSubMode;
|
||||||
finishMovement();
|
finishMovement();
|
||||||
|
} else if (input.is('&')) {
|
||||||
|
handleExCommand(m_gflag ? "%s//~/&" : "s");
|
||||||
} else if (input.is(':')) {
|
} else if (input.is(':')) {
|
||||||
enterExMode();
|
enterExMode();
|
||||||
g.commandHistory.restart();
|
g.commandHistory.restart();
|
||||||
@@ -3267,84 +3272,124 @@ void FakeVimHandler::Private::handleCommand(const QString &cmd)
|
|||||||
bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
|
bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
|
||||||
// :substitute
|
// :substitute
|
||||||
{
|
{
|
||||||
QString line = cmd.cmd + ' ' + cmd.args;
|
QString flags;
|
||||||
line = line.trimmed();
|
QRegExp pattern;
|
||||||
if (line.startsWith(_("substitute")))
|
QString replacement;
|
||||||
line = line.mid(10);
|
int count = 0;
|
||||||
else if (line.startsWith('s') && line.size() > 1
|
|
||||||
&& !isalpha(line.at(1).unicode()))
|
|
||||||
line = line.mid(1);
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// we have /{pattern}/{string}/[flags] now
|
if (cmd.cmd.startsWith("&&")) {
|
||||||
if (line.isEmpty())
|
flags = cmd.cmd.mid(2);
|
||||||
return false;
|
if (flags.isEmpty())
|
||||||
const QChar separator = line.at(0);
|
flags = m_lastSubstituteFlags;
|
||||||
int pos1 = -1;
|
pattern = m_lastSubstitutePattern;
|
||||||
int pos2 = -1;
|
replacement = m_lastSubstituteReplacement;
|
||||||
int i;
|
count = cmd.args.section(QLatin1Char(' '), 1, 1).toInt();
|
||||||
for (i = 1; i < line.size(); ++i) {
|
} else if (cmd.cmd.startsWith("&")) {
|
||||||
if (line.at(i) == separator && line.at(i - 1) != '\\') {
|
flags = cmd.cmd.mid(1);
|
||||||
pos1 = i;
|
if (flags.isEmpty())
|
||||||
break;
|
flags = m_lastSubstituteFlags;
|
||||||
|
pattern = m_lastSubstitutePattern;
|
||||||
|
replacement = m_lastSubstituteReplacement;
|
||||||
|
count = cmd.args.section(QLatin1Char(' '), 1, 1).toInt();
|
||||||
|
} else if (cmd.matches("s", "substitute")) {
|
||||||
|
flags = m_lastSubstituteFlags;
|
||||||
|
if (flags.isEmpty())
|
||||||
|
flags = m_lastSubstituteFlags;
|
||||||
|
pattern = m_lastSubstitutePattern;
|
||||||
|
replacement = m_lastSubstituteReplacement;
|
||||||
|
count = cmd.args.section(QLatin1Char(' '), 2, 2).toInt();
|
||||||
|
} else {
|
||||||
|
QString line = cmd.cmd + ' ' + cmd.args;
|
||||||
|
line = line.trimmed();
|
||||||
|
if (line.startsWith(_("substitute")))
|
||||||
|
line = line.mid(10);
|
||||||
|
else if (line.startsWith('s') && line.size() > 1
|
||||||
|
&& !isalpha(line.at(1).unicode()))
|
||||||
|
line = line.mid(1);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
// we have /{pattern}/{string}/[flags] now
|
||||||
|
if (line.isEmpty())
|
||||||
|
return false;
|
||||||
|
const QChar separator = line.at(0);
|
||||||
|
int pos1 = -1;
|
||||||
|
int pos2 = -1;
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < line.size(); ++i) {
|
||||||
|
if (line.at(i) == separator && line.at(i - 1) != '\\') {
|
||||||
|
pos1 = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (pos1 == -1)
|
||||||
if (pos1 == -1)
|
return false;
|
||||||
return false;
|
for (++i; i < line.size(); ++i) {
|
||||||
for (++i; i < line.size(); ++i) {
|
if (line.at(i) == separator && line.at(i - 1) != '\\') {
|
||||||
if (line.at(i) == separator && line.at(i - 1) != '\\') {
|
pos2 = i;
|
||||||
pos2 = i;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
if (pos2 == -1)
|
||||||
|
pos2 = line.size();
|
||||||
|
|
||||||
|
QString needle = line.mid(1, pos1 - 1);
|
||||||
|
replacement = line.mid(pos1 + 1, pos2 - pos1 - 1);
|
||||||
|
flags = line.mid(pos2 + 1);
|
||||||
|
|
||||||
|
needle.replace('$', '\n');
|
||||||
|
needle.replace("\\\n", "\\$");
|
||||||
|
pattern.setPattern(needle);
|
||||||
|
|
||||||
|
m_lastSubstituteFlags = flags;
|
||||||
|
m_lastSubstitutePattern = pattern;
|
||||||
|
m_lastSubstituteReplacement = replacement;
|
||||||
}
|
}
|
||||||
if (pos2 == -1)
|
|
||||||
pos2 = line.size();
|
|
||||||
|
|
||||||
QString needle = line.mid(1, pos1 - 1);
|
if (count == 0)
|
||||||
const QString replacement = line.mid(pos1 + 1, pos2 - pos1 - 1);
|
count = 1;
|
||||||
QString flags = line.mid(pos2 + 1);
|
|
||||||
|
|
||||||
needle.replace('$', '\n');
|
|
||||||
needle.replace("\\\n", "\\$");
|
|
||||||
QRegExp pattern(needle);
|
|
||||||
if (flags.contains('i'))
|
if (flags.contains('i'))
|
||||||
pattern.setCaseSensitivity(Qt::CaseInsensitive);
|
pattern.setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
const bool global = flags.contains('g');
|
|
||||||
const Range range = cmd.range.endPos == 0 ? rangeFromCurrentLine() : cmd.range;
|
|
||||||
const int beginLine = lineForPosition(range.beginPos);
|
|
||||||
const int endLine = lineForPosition(range.endPos);
|
|
||||||
beginEditBlock();
|
beginEditBlock();
|
||||||
for (int line = endLine; line >= beginLine; --line) {
|
const bool global = flags.contains('g');
|
||||||
QString origText = lineContents(line);
|
for (int a = 0; a != count; ++a) {
|
||||||
QString text = origText;
|
const Range range = cmd.range.endPos == 0 ? rangeFromCurrentLine() : cmd.range;
|
||||||
int pos = 0;
|
const int beginLine = lineForPosition(range.beginPos);
|
||||||
while (true) {
|
const int endLine = lineForPosition(range.endPos);
|
||||||
pos = pattern.indexIn(text, pos, QRegExp::CaretAtZero);
|
for (int line = endLine; line >= beginLine; --line) {
|
||||||
if (pos == -1)
|
QString origText = lineContents(line);
|
||||||
break;
|
QString text = origText;
|
||||||
if (pattern.cap(0).isEmpty())
|
int pos = 0;
|
||||||
break;
|
while (true) {
|
||||||
QStringList caps = pattern.capturedTexts();
|
pos = pattern.indexIn(text, pos, QRegExp::CaretAtZero);
|
||||||
QString matched = text.mid(pos, caps.at(0).size());
|
if (pos == -1)
|
||||||
QString repl = replacement;
|
break;
|
||||||
for (int i = 1; i < caps.size(); ++i)
|
if (pattern.cap(0).isEmpty())
|
||||||
repl.replace("\\" + QString::number(i), caps.at(i));
|
break;
|
||||||
for (int i = 0; i < repl.size(); ++i) {
|
QStringList caps = pattern.capturedTexts();
|
||||||
if (repl.at(i) == '&' && (i == 0 || repl.at(i - 1) != '\\')) {
|
QString matched = text.mid(pos, caps.at(0).size());
|
||||||
repl.replace(i, 1, caps.at(0));
|
QString repl = replacement;
|
||||||
i += caps.at(0).size();
|
for (int i = 1; i < caps.size(); ++i)
|
||||||
|
repl.replace("\\" + QString::number(i), caps.at(i));
|
||||||
|
for (int i = 0; i < repl.size(); ++i) {
|
||||||
|
if (repl.at(i) == '&' && (i == 0 || repl.at(i - 1) != '\\')) {
|
||||||
|
repl.replace(i, 1, caps.at(0));
|
||||||
|
i += caps.at(0).size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
repl.replace("\\&", "&");
|
||||||
|
text = text.left(pos) + repl + text.mid(pos + matched.size());
|
||||||
|
pos += repl.size();
|
||||||
|
if (!global)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
repl.replace("\\&", "&");
|
if (text != origText)
|
||||||
text = text.left(pos) + repl + text.mid(pos + matched.size());
|
setLineContents(line, text);
|
||||||
pos += repl.size();
|
|
||||||
if (!global)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (text != origText)
|
|
||||||
setLineContents(line, text);
|
|
||||||
}
|
}
|
||||||
|
moveToStartOfLine();
|
||||||
|
setTargetColumn();
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user