forked from qt-creator/qt-creator
FakeVim: Don't overwrite document with ":!..." commands
Ignore range in ":!..." commands. Task-number: QTCREATORBUG-7396 Change-Id: I428a403b105499024ed84c6253240e808b3cdcd8 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -693,6 +693,33 @@ static void setClipboardData(const QString &content, RangeMode mode,
|
||||
clipboard->setMimeData(data, clipboardMode);
|
||||
}
|
||||
|
||||
static QByteArray toLocalEncoding(const QString &text)
|
||||
{
|
||||
return HostOsInfo::isWindowsHost() ? QString(text).replace(_("\n"), _("\r\n")).toLocal8Bit()
|
||||
: text.toLocal8Bit();
|
||||
}
|
||||
|
||||
static QString fromLocalEncoding(const QByteArray &data)
|
||||
{
|
||||
return HostOsInfo::isWindowsHost() ? QString::fromLocal8Bit(data).replace(_("\n"), _("\r\n"))
|
||||
: QString::fromLocal8Bit(data);
|
||||
}
|
||||
|
||||
static QString getProcessOutput(const QString &command, const QString &input)
|
||||
{
|
||||
QProcess proc;
|
||||
proc.start(command);
|
||||
proc.waitForStarted();
|
||||
proc.write(toLocalEncoding(input));
|
||||
proc.closeWriteChannel();
|
||||
|
||||
// FIXME: Process should be interruptable by user.
|
||||
// Solution is to create a QObject for each process and emit finished state.
|
||||
proc.waitForFinished();
|
||||
|
||||
return fromLocalEncoding(proc.readAllStandardOutput());
|
||||
}
|
||||
|
||||
static const QMap<QString, int> &vimKeyNames()
|
||||
{
|
||||
static QMap<QString, int> k;
|
||||
@@ -804,6 +831,11 @@ QString Range::toString() const
|
||||
.arg(rangemode);
|
||||
}
|
||||
|
||||
bool Range::isValid() const
|
||||
{
|
||||
return beginPos >= 0 && endPos >= 0;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug ts, const Range &range)
|
||||
{
|
||||
return ts << '[' << range.beginPos << ',' << range.endPos << ']';
|
||||
@@ -5038,9 +5070,6 @@ bool FakeVimHandler::Private::parseExCommmand(QString *line, ExCommand *cmd)
|
||||
if (line->isEmpty())
|
||||
return false;
|
||||
|
||||
// remove leading colons and spaces
|
||||
line->remove(QRegExp(_("^\\s*(:+\\s*)*")));
|
||||
|
||||
// parse range first
|
||||
if (!parseLineRange(line, cmd))
|
||||
return false;
|
||||
@@ -5093,6 +5122,15 @@ bool FakeVimHandler::Private::parseExCommmand(QString *line, ExCommand *cmd)
|
||||
|
||||
bool FakeVimHandler::Private::parseLineRange(QString *line, ExCommand *cmd)
|
||||
{
|
||||
// remove leading colons and spaces
|
||||
line->remove(QRegExp(_("^\\s*(:+\\s*)*")));
|
||||
|
||||
// special case ':!...' (use invalid range)
|
||||
if (line->startsWith(QLatin1Char('!'))) {
|
||||
cmd->range = Range();
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME: that seems to be different for %w and %s
|
||||
if (line->startsWith(QLatin1Char('%')))
|
||||
line->replace(0, 1, _("1,$"));
|
||||
@@ -5655,22 +5693,15 @@ bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :!
|
||||
if (!cmd.cmd.isEmpty() || !cmd.hasBang)
|
||||
return false;
|
||||
|
||||
setCurrentRange(cmd.range);
|
||||
int targetPosition = firstPositionInLine(lineForPosition(cmd.range.beginPos));
|
||||
QString command = QString(cmd.cmd.mid(1) + QLatin1Char(' ') + cmd.args).trimmed();
|
||||
QString text = selectText(cmd.range);
|
||||
QProcess proc;
|
||||
proc.start(command);
|
||||
proc.waitForStarted();
|
||||
if (HostOsInfo::isWindowsHost())
|
||||
text.replace(_("\n"), _("\r\n"));
|
||||
proc.write(text.toUtf8());
|
||||
proc.closeWriteChannel();
|
||||
proc.waitForFinished();
|
||||
QString result = QString::fromUtf8(proc.readAllStandardOutput());
|
||||
if (text.isEmpty()) {
|
||||
emit q->extraInformationChanged(result);
|
||||
} else {
|
||||
bool replaceText = cmd.range.isValid();
|
||||
const QString command = QString(cmd.cmd.mid(1) + QLatin1Char(' ') + cmd.args).trimmed();
|
||||
const QString input = replaceText ? selectText(cmd.range) : QString();
|
||||
|
||||
const QString result = getProcessOutput(command, input);
|
||||
|
||||
if (replaceText) {
|
||||
setCurrentRange(cmd.range);
|
||||
int targetPosition = firstPositionInLine(lineForPosition(cmd.range.beginPos));
|
||||
beginEditBlock();
|
||||
removeText(currentRange());
|
||||
insertText(result);
|
||||
@@ -5679,8 +5710,11 @@ bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :!
|
||||
leaveVisualMode();
|
||||
//qDebug() << "FILTER: " << command;
|
||||
showMessage(MessageInfo, FakeVimHandler::tr("%n lines filtered.", 0,
|
||||
text.count(QLatin1Char('\n'))));
|
||||
input.count(QLatin1Char('\n'))));
|
||||
} else if (!result.isEmpty()) {
|
||||
emit q->extraInformationChanged(result);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ struct Range
|
||||
Range();
|
||||
Range(int b, int e, RangeMode m = RangeCharMode);
|
||||
QString toString() const;
|
||||
bool isValid() const;
|
||||
|
||||
int beginPos;
|
||||
int endPos;
|
||||
|
||||
Reference in New Issue
Block a user