From 2f997060311f09e4495c4217b430aafb16ab8bc1 Mon Sep 17 00:00:00 2001 From: hjk <qtc-committer@nokia.com> Date: Tue, 18 May 2010 14:48:12 +0200 Subject: [PATCH] fakevim: prepare for better integration with creator core For :ex commands, the plugin is now asked first unconditionally. The handler only provides fallbacks for the standalone case. --- src/plugins/fakevim/fakevimactions.cpp | 5 - src/plugins/fakevim/fakevimactions.h | 1 - src/plugins/fakevim/fakevimhandler.cpp | 276 ++++++++++++------------- src/plugins/fakevim/fakevimhandler.h | 42 +++- src/plugins/fakevim/fakevimplugin.cpp | 119 +++++------ 5 files changed, 219 insertions(+), 224 deletions(-) diff --git a/src/plugins/fakevim/fakevimactions.cpp b/src/plugins/fakevim/fakevimactions.cpp index 8f9aeba53af..a17fbe146c1 100644 --- a/src/plugins/fakevim/fakevimactions.cpp +++ b/src/plugins/fakevim/fakevimactions.cpp @@ -209,11 +209,6 @@ FakeVimSettings *theFakeVimSettings() item->setSettingsKey(group, _("IsKeyword")); instance->insertItem(ConfigIsKeyword, item, _("iskeyword"), _("isk")); - item = new SavedAction(instance); - item->setText(QCoreApplication::translate("FakeVim::Internal", - "FakeVim properties...")); - instance->insertItem(SettingsDialog, item); - // Invented here. item = new SavedAction(instance); item->setDefaultValue(false); diff --git a/src/plugins/fakevim/fakevimactions.h b/src/plugins/fakevim/fakevimactions.h index 2b8c2fbd7df..5929376bc68 100644 --- a/src/plugins/fakevim/fakevimactions.h +++ b/src/plugins/fakevim/fakevimactions.h @@ -64,7 +64,6 @@ enum FakeVimSettingsCode ConfigIsKeyword, // other actions - SettingsDialog, ConfigShowMarks, }; diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 94d34687409..ca6147d1406 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -217,14 +217,6 @@ enum MoveType all characters in the affected lines up to the end of these lines. */ -enum RangeMode -{ - RangeCharMode, // v - RangeLineMode, // V - RangeLineModeExclusive, - RangeBlockMode, // Ctrl-v - RangeBlockAndTailMode, // Ctrl-v for D and X -}; enum EventResult { @@ -258,38 +250,36 @@ struct Register RangeMode rangemode; }; -struct Range -{ - Range() - : beginPos(-1), endPos(-1), rangemode(RangeCharMode) - {} - Range(int b, int e, RangeMode m = RangeCharMode) - : beginPos(qMin(b, e)), endPos(qMax(b, e)), rangemode(m) - {} - QString toString() const - { - return QString("%1-%2 (mode: %3)").arg(beginPos).arg(endPos) - .arg(rangemode); - } +Range::Range() + : beginPos(-1), endPos(-1), rangemode(RangeCharMode) +{} - int beginPos; - int endPos; - RangeMode rangemode; -}; +Range::Range(int b, int e, RangeMode m) + : beginPos(qMin(b, e)), endPos(qMax(b, e)), rangemode(m) +{} -struct ExCommand +QString Range::toString() const { - ExCommand(const QString &c, int b = -1, int e = -1) - : line(c), range(b, e, RangeLineMode) {} - QString line; - Range range; -}; + return QString("%1-%2 (mode: %3)").arg(beginPos).arg(endPos) + .arg(rangemode); +} + +QDebug operator<<(QDebug ts, const Range &range) +{ + return ts << '[' << range.beginPos << ',' << range.endPos << ']'; +} + + + +ExCommand::ExCommand(const QString &c, const QString &a, const Range &r) + : cmd(c), hasBang(false), args(a), range(r) +{} QDebug operator<<(QDebug ts, const ExCommand &cmd) { - return ts << cmd.line << cmd.range.beginPos << cmd.range.endPos; + return ts << cmd.cmd << ' ' << cmd.args << ' ' << cmd.range; } QDebug operator<<(QDebug ts, const QList<QTextEdit::ExtraSelection> &sels) @@ -650,13 +640,6 @@ public: { m_tc.beginEditBlock(); m_tc.insertText("x"); m_tc.deletePreviousChar(); m_tc.endEditBlock(); } - // this asks the layer above (e.g. the fake vim plugin or the - // stand-alone test application to handle the command) - void passUnknownExCommand(const QString &cmd); - // this asks the layer above (e.g. the fake vim plugin or the - // stand-alone test application to handle the set command) - void passUnknownSetCommand(const QString &cmd); - bool isVisualMode() const { return m_visualMode != NoVisualMode; } bool isNoVisualMode() const { return m_visualMode == NoVisualMode; } bool isVisualCharMode() const { return m_visualMode == VisualCharMode; } @@ -806,6 +789,7 @@ public: QString m_oldNeedle; bool handleExCommandHelper(const ExCommand &cmd); // Returns success. + bool handleExPluginCommand(const ExCommand &cmd); // Handled by plugin? bool handleExBangCommand(const ExCommand &cmd); bool handleExDeleteCommand(const ExCommand &cmd); bool handleExGotoCommand(const ExCommand &cmd); @@ -815,7 +799,7 @@ public: bool handleExReadCommand(const ExCommand &cmd); bool handleExRedoCommand(const ExCommand &cmd); bool handleExSetCommand(const ExCommand &cmd); - bool handleExShiftRightCommand(const ExCommand &cmd); + bool handleExShiftCommand(const ExCommand &cmd); bool handleExSourceCommand(const ExCommand &cmd); bool handleExSubstituteCommand(const ExCommand &cmd); bool handleExWriteCommand(const ExCommand &cmd); @@ -2819,7 +2803,8 @@ void FakeVimHandler::Private::handleCommand(const QString &cmd) bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) // :substitute { - QString line = cmd.line; + 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 @@ -2827,6 +2812,7 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) line = line.mid(1); else return false; + // we have /{pattern}/{string}/[flags] now if (line.isEmpty()) return false; @@ -2899,12 +2885,10 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map { - const int pos1 = cmd0.line.indexOf(QLatin1Char(' ')); - QByteArray modes; enum Type { Map, Noremap, Unmap } type; - QByteArray cmd = cmd0.line.left(pos1).toLatin1(); + QByteArray cmd = cmd0.cmd.toLatin1(); // Strange formatting. But everything else is even uglier. if (cmd == "map") { modes = "nvo"; type = Map; } else @@ -2942,15 +2926,15 @@ bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map else return false; - const int pos2 = cmd0.line.indexOf(QLatin1Char(' '), pos1 + 1); - if (pos1 == -1 || pos2 == -1) { + const int pos = cmd0.args.indexOf(QLatin1Char(' ')); + if (pos == -1) { // FIXME: Dump mappings here. //qDebug() << g.mappings; return true;; } - QString lhs = cmd0.line.mid(pos1 + 1, pos2 - pos1 - 1); - QString rhs = cmd0.line.mid(pos2 + 1); + QString lhs = cmd0.args.left(pos); + QString rhs = cmd0.args.mid(pos + 1); Inputs key; key.parseFrom(lhs); //qDebug() << "MAPPING: " << modes << lhs << rhs; @@ -2973,14 +2957,13 @@ bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map return true; } -bool FakeVimHandler::Private::handleExHistoryCommand(const ExCommand &cmd) // :history +bool FakeVimHandler::Private::handleExHistoryCommand(const ExCommand &cmd) { - static QRegExp reHistory("^his(tory)?( (.*))?$"); - if (reHistory.indexIn(cmd.line) == -1) + // :history + if (cmd.cmd != "his" && cmd.cmd != "history") return false; - QString arg = reHistory.cap(3); - if (arg.isEmpty()) { + if (cmd.args.isEmpty()) { QString info; info += "# command history\n"; int i = 0; @@ -2996,67 +2979,65 @@ bool FakeVimHandler::Private::handleExHistoryCommand(const ExCommand &cmd) // :h return true; } -bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) // :set +bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) { - static QRegExp reSet("^set?( (.*))?$"); - if (reSet.indexIn(cmd.line) == -1) + // :set + if (cmd.cmd != "se" && cmd.cmd != "set") return false; showBlackMessage(QString()); - QString arg = reSet.cap(2).trimmed(); - SavedAction *act = theFakeVimSettings()->item(arg); - if (arg.isEmpty()) { - theFakeVimSetting(SettingsDialog)->trigger(QVariant()); - } else if (act && act->value().type() == QVariant::Bool) { - // boolean config to be switched on + SavedAction *act = theFakeVimSettings()->item(cmd.args); + QTC_ASSERT(!cmd.args.isEmpty(), /**/); // Handled by plugin. + if (act && act->value().type() == QVariant::Bool) { + // Boolean config to be switched on. bool oldValue = act->value().toBool(); if (oldValue == false) act->setValue(true); else if (oldValue == true) {} // nothing to do } else if (act) { - // non-boolean to show - showBlackMessage(arg + '=' + act->value().toString()); - } else if (arg.startsWith(_("no")) - && (act = theFakeVimSettings()->item(arg.mid(2)))) { - // boolean config to be switched off + // Non-boolean to show. + showBlackMessage(cmd.args + '=' + act->value().toString()); + } else if (cmd.args.startsWith(_("no")) + && (act = theFakeVimSettings()->item(cmd.args.mid(2)))) { + // Boolean config to be switched off. bool oldValue = act->value().toBool(); if (oldValue == true) act->setValue(false); else if (oldValue == false) {} // nothing to do - } else if (arg.contains('=')) { - // non-boolean config to set - int p = arg.indexOf('='); - act = theFakeVimSettings()->item(arg.left(p)); + } else if (cmd.args.contains('=')) { + // Non-boolean config to set. + int p = cmd.args.indexOf('='); + act = theFakeVimSettings()->item(cmd.args.left(p)); if (act) - act->setValue(arg.mid(p + 1)); + act->setValue(cmd.args.mid(p + 1)); } else { - passUnknownSetCommand(arg); + showRedMessage(FakeVimHandler::tr("Unknown option: ") + cmd.args); } updateMiniBuffer(); updateEditor(); return true; } -bool FakeVimHandler::Private::handleExNormalCommand(const ExCommand &cmd) // :normal +bool FakeVimHandler::Private::handleExNormalCommand(const ExCommand &cmd) { - static QRegExp reNormal("^norm(al)?( (.*))?$"); - if (reNormal.indexIn(cmd.line) == -1) + // :normal + if (cmd.cmd != "norm" && cmd.cmd != "normal") return false; //qDebug() << "REPLAY NORMAL: " << quoteUnprintable(reNormal.cap(3)); - replay(reNormal.cap(3), 1); + replay(cmd.args, 1); return true; } -bool FakeVimHandler::Private::handleExDeleteCommand(const ExCommand &cmd) // :d +bool FakeVimHandler::Private::handleExDeleteCommand(const ExCommand &cmd) { - static QRegExp reDelete("^d(elete)?( (.*))?$"); - if (reDelete.indexIn(cmd.line) == -1) + // :delete + if (cmd.cmd != "d" && cmd.cmd != "delete") return false; setCurrentRange(cmd.range); - QString reg = reDelete.cap(3); + QString reg = cmd.args; QString text = selectText(cmd.range); removeText(currentRange()); if (!reg.isEmpty()) { @@ -3068,10 +3049,10 @@ bool FakeVimHandler::Private::handleExDeleteCommand(const ExCommand &cmd) // :d } bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) - // :w, :x, :q, :wq, ... { - static QRegExp reWrite("^[wx]q?a?!?( (.*))?$"); - if (reWrite.indexIn(cmd.line) == -1) // :w and :x + // :w, :x, :wq, ... + //static QRegExp reWrite("^[wx]q?a?!?( (.*))?$"); + if (cmd.cmd != "w" && cmd.cmd != "x" && cmd.cmd != "wq") return false; int beginLine = lineForPosition(cmd.range.beginPos); @@ -3082,16 +3063,11 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) if (endLine == -1) endLine = linesInDocument(); //qDebug() << "LINES: " << beginLine << endLine; - int indexOfSpace = cmd.line.indexOf(QChar(' ')); - QString prefix; - if (indexOfSpace < 0) - prefix = cmd.line; - else - prefix = cmd.line.left(indexOfSpace); - const bool forced = prefix.contains(QChar('!')); - const bool quit = prefix.contains(QChar('q')) || prefix.contains(QChar('x')); - const bool quitAll = quit && prefix.contains(QChar('a')); - QString fileName = reWrite.cap(2); + QString prefix = cmd.args; + const bool forced = cmd.hasBang; + //const bool quit = prefix.contains(QChar('q')) || prefix.contains(QChar('x')); + //const bool quitAll = quit && prefix.contains(QChar('a')); + QString fileName = cmd.args; if (fileName.isEmpty()) fileName = m_currentFileName; QFile file1(fileName); @@ -3100,25 +3076,21 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) showRedMessage(FakeVimHandler::tr ("File \"%1\" exists (add ! to override)").arg(fileName)); } else if (file1.open(QIODevice::ReadWrite)) { + // Nobody cared, so act ourselves. file1.close(); QTextCursor tc = m_tc; Range range(firstPositionInLine(beginLine), firstPositionInLine(endLine), RangeLineMode); QString contents = selectText(range); m_tc = tc; - bool handled = false; - emit q->writeFileRequested(&handled, fileName, contents); - // Nobody cared, so act ourselves. - if (!handled) { - QFile::remove(fileName); - QFile file2(fileName); - if (file2.open(QIODevice::ReadWrite)) { - QTextStream ts(&file2); - ts << contents; - } else { - showRedMessage(FakeVimHandler::tr - ("Cannot open file \"%1\" for writing").arg(fileName)); - } + QFile::remove(fileName); + QFile file2(fileName); + if (file2.open(QIODevice::ReadWrite)) { + QTextStream ts(&file2); + ts << contents; + } else { + showRedMessage(FakeVimHandler::tr + ("Cannot open file \"%1\" for writing").arg(fileName)); } // Check result by reading back. QFile file3(fileName); @@ -3127,10 +3099,10 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) showBlackMessage(FakeVimHandler::tr("\"%1\" %2 %3L, %4C written") .arg(fileName).arg(exists ? " " : " [New] ") .arg(ba.count('\n')).arg(ba.size())); - if (quitAll) - passUnknownExCommand(forced ? "qa!" : "qa"); - else if (quit) - passUnknownExCommand(forced ? "q!" : "q"); + //if (quitAll) + // passUnknownExCommand(forced ? "qa!" : "qa"); + //else if (quit) + // passUnknownExCommand(forced ? "q!" : "q"); } else { showRedMessage(FakeVimHandler::tr ("Cannot open file \"%1\" for reading").arg(fileName)); @@ -3138,16 +3110,17 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) return true; } -bool FakeVimHandler::Private::handleExReadCommand(const ExCommand &cmd) // :r +bool FakeVimHandler::Private::handleExReadCommand(const ExCommand &cmd) { - if (!cmd.line.startsWith(_("r "))) + // :read + if (cmd.cmd != "r" && cmd.cmd != "read") return false; beginEditBlock(); moveToStartOfLine(); setTargetColumn(); moveDown(); - m_currentFileName = cmd.line.mid(2).trimmed(); + m_currentFileName = cmd.args; QFile file(m_currentFileName); file.open(QIODevice::ReadOnly); QTextStream ts(&file); @@ -3161,12 +3134,12 @@ bool FakeVimHandler::Private::handleExReadCommand(const ExCommand &cmd) // :r bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :! { - if (!cmd.line.startsWith(QLatin1Char('!'))) + if (!cmd.cmd.startsWith(QLatin1Char('!'))) return false; setCurrentRange(cmd.range); int targetPosition = firstPositionInLine(lineForPosition(cmd.range.beginPos)); - QString command = cmd.line.mid(1).trimmed(); + QString command = QString(cmd.cmd.mid(1) + ' ' + cmd.args).trimmed(); QString text = selectText(cmd.range); QProcess proc; proc.start(command); @@ -3190,24 +3163,29 @@ bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :! return true; } -bool FakeVimHandler::Private::handleExShiftRightCommand(const ExCommand &cmd) // :> +bool FakeVimHandler::Private::handleExShiftCommand(const ExCommand &cmd) { - if (!cmd.line.startsWith(QLatin1Char('>'))) + if (cmd.cmd != "<" && cmd.cmd != ">") return false; setCurrentRange(cmd.range); - shiftRegionRight(1); + int count = qMin(1, cmd.args.toInt()); + if (cmd.cmd == "<") + shiftRegionLeft(count); + else + shiftRegionRight(count); leaveVisualMode(); const int beginLine = lineForPosition(cmd.range.beginPos); const int endLine = lineForPosition(cmd.range.endPos); - showBlackMessage(FakeVimHandler::tr("%n lines >ed %1 time", 0, - (endLine - beginLine + 1)).arg(1)); + showBlackMessage(FakeVimHandler::tr("%n lines %1ed %2 time", 0, + (endLine - beginLine + 1)).arg(cmd.cmd).arg(count)); return true; } -bool FakeVimHandler::Private::handleExRedoCommand(const ExCommand &cmd) // :redo +bool FakeVimHandler::Private::handleExRedoCommand(const ExCommand &cmd) { - if (cmd.line != "red" && cmd.line != "redo") + // :redo + if (cmd.cmd != "red" && cmd.cmd != "redo") return false; redo(); @@ -3215,10 +3193,10 @@ bool FakeVimHandler::Private::handleExRedoCommand(const ExCommand &cmd) // :redo return true; } -bool FakeVimHandler::Private::handleExGotoCommand(const ExCommand &cmd) // :<nr> +bool FakeVimHandler::Private::handleExGotoCommand(const ExCommand &cmd) { - // Only "range" given. - if (!cmd.line.isEmpty()) + // :<nr> + if (!cmd.cmd.isEmpty()) return false; const int beginLine = lineForPosition(cmd.range.beginPos); @@ -3227,13 +3205,13 @@ bool FakeVimHandler::Private::handleExGotoCommand(const ExCommand &cmd) // :<nr> return true; } -bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd) // :source +bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd) { - const int pos = cmd.line.indexOf(' '); - if (cmd.line.leftRef(pos) != "so" && cmd.line.leftRef(pos) != "source") + // :source + if (cmd.cmd != "so" && cmd.cmd != "source") return false; - QString fileName = cmd.line.mid(pos + 1).trimmed(); + QString fileName = cmd.args; QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { showRedMessage(FakeVimHandler::tr("Can't open file %1").arg(fileName)); @@ -3266,8 +3244,6 @@ bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd) // :so void FakeVimHandler::Private::handleExCommand(const QString &line0) { QString line = line0; // Make sure we have a copy to prevent aliasing. - ExCommand cmd(line, -1, -1); - // FIXME: that seems to be different for %w and %s if (line.startsWith(QLatin1Char('%'))) line = "1,$" + line.mid(1); @@ -3282,19 +3258,26 @@ void FakeVimHandler::Private::handleExCommand(const QString &line0) endLine = beginLine; const int beginPos = firstPositionInLine(beginLine); const int endPos = lastPositionInLine(endLine); + ExCommand cmd; + const QString arg0 = line.section(' ', 0, 0); + cmd.cmd = arg0; + cmd.args = line.mid(arg0.size() + 1).trimmed(); cmd.range = Range(beginPos, endPos, RangeLineMode); - cmd.line = line; + cmd.hasBang = arg0.endsWith('!'); + if (cmd.hasBang) + cmd.cmd.chop(1); //qDebug() << "CMD: " << cmd; enterCommandMode(); showBlackMessage(QString()); if (!handleExCommandHelper(cmd)) - passUnknownExCommand(cmd.line); + showRedMessage(tr("Not an editor command: %1").arg(cmd.cmd)); } bool FakeVimHandler::Private::handleExCommandHelper(const ExCommand &cmd) { - return handleExGotoCommand(cmd) + return handleExPluginCommand(cmd) + || handleExGotoCommand(cmd) || handleExBangCommand(cmd) || handleExHistoryCommand(cmd) || handleExDeleteCommand(cmd) @@ -3303,27 +3286,21 @@ bool FakeVimHandler::Private::handleExCommandHelper(const ExCommand &cmd) || handleExReadCommand(cmd) || handleExRedoCommand(cmd) || handleExSetCommand(cmd) - || handleExShiftRightCommand(cmd) + || handleExShiftCommand(cmd) || handleExSourceCommand(cmd) || handleExSubstituteCommand(cmd) || handleExWriteCommand(cmd); } -void FakeVimHandler::Private::passUnknownExCommand(const QString &cmd) +bool FakeVimHandler::Private::handleExPluginCommand(const ExCommand &cmd) { EDITOR(setTextCursor(m_tc)); - emit q->handleExCommandRequested(cmd); + bool handled = false; + emit q->handleExCommandRequested(&handled, cmd); if (m_plaintextedit || m_textedit) m_tc = EDITOR(textCursor()); -} - -void FakeVimHandler::Private::passUnknownSetCommand(const QString &arg) -{ - bool handled = false; - emit q->handleSetCommandRequested(&handled, arg); - if (!handled) { - showRedMessage(FakeVimHandler::tr("Unknown option: ") + arg); - } + //qDebug() << "HANDLER REQUEST: " << cmd.cmd << handled; + return handled; } static void vimPatternToQtPattern(QString *needle, QTextDocument::FindFlags *flags) @@ -4585,6 +4562,11 @@ void FakeVimHandler::setCurrentFileName(const QString &fileName) d->m_currentFileName = fileName; } +QString FakeVimHandler::currentFileName() const +{ + return d->m_currentFileName; +} + void FakeVimHandler::showBlackMessage(const QString &msg) { d->showBlackMessage(msg); diff --git a/src/plugins/fakevim/fakevimhandler.h b/src/plugins/fakevim/fakevimhandler.h index 7543d8cf862..4e877d31c8e 100644 --- a/src/plugins/fakevim/fakevimhandler.h +++ b/src/plugins/fakevim/fakevimhandler.h @@ -38,6 +38,38 @@ namespace FakeVim { namespace Internal { +enum RangeMode +{ + RangeCharMode, // v + RangeLineMode, // V + RangeLineModeExclusive, + RangeBlockMode, // Ctrl-v + RangeBlockAndTailMode, // Ctrl-v for D and X +}; + +struct Range +{ + Range(); + Range(int b, int e, RangeMode m = RangeCharMode); + QString toString() const; + + int beginPos; + int endPos; + RangeMode rangemode; +}; + +struct ExCommand +{ + ExCommand() : hasBang(false) {} + ExCommand(const QString &cmd, const QString &args = QString(), + const Range &range = Range()); + + QString cmd; + bool hasBang; + QString args; + Range range; +}; + class FakeVimHandler : public QObject { Q_OBJECT @@ -53,6 +85,8 @@ public: public slots: void setCurrentFileName(const QString &fileName); + QString currentFileName() const; + void showBlackMessage(const QString &msg); void showRedMessage(const QString &msg); @@ -76,8 +110,6 @@ signals: void statusDataChanged(const QString &msg); void extraInformationChanged(const QString &msg); void selectionChanged(const QList<QTextEdit::ExtraSelection> &selection); - void writeFileRequested(bool *handled, - const QString &fileName, const QString &contents); void writeAllRequested(QString *error); void moveToMatchingParenthesis(bool *moved, bool *forward, QTextCursor *cursor); void checkForElectricCharacter(bool *result, QChar c); @@ -86,8 +118,7 @@ signals: void windowCommandRequested(int key); void findRequested(bool reverse); void findNextRequested(bool reverse); - void handleExCommandRequested(const QString &cmd); - void handleSetCommandRequested(bool *handled, const QString &cmd); + void handleExCommandRequested(bool *handled, const ExCommand &cmd); public: class Private; @@ -101,4 +132,7 @@ private: } // namespace Internal } // namespace FakeVim +Q_DECLARE_METATYPE(FakeVim::Internal::ExCommand); + + #endif // FAKEVIM_HANDLER_H diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index 58f44ff0987..17510545b90 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -73,9 +73,9 @@ #include <indenter.h> #include <QtCore/QDebug> +#include <QtCore/QFile> #include <QtCore/QtPlugin> #include <QtCore/QObject> -#include <QtCore/QPoint> #include <QtCore/QSettings> #include <QtCore/QTextStream> @@ -503,12 +503,10 @@ private slots: void showCommandBuffer(const QString &contents); void showExtraInformation(const QString &msg); void changeSelection(const QList<QTextEdit::ExtraSelection> &selections); - void writeFile(bool *handled, const QString &fileName, const QString &contents); void moveToMatchingParenthesis(bool *moved, bool *forward, QTextCursor *cursor); void checkForElectricCharacter(bool *result, QChar c); void indentRegion(int *amount, int beginLine, int endLine, QChar typedChar); - void handleExCommand(const QString &cmd); - void handleSetCommand(bool *handled, QString cmd); + void handleExCommand(bool *handled, const ExCommand &cmd); void handleDelayedQuitAll(bool forced); void handleDelayedQuit(bool forced, Core::IEditor *editor); @@ -611,8 +609,6 @@ bool FakeVimPluginPrivate::initialize() connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)), this, SLOT(editorOpened(Core::IEditor*))); - connect(theFakeVimSetting(SettingsDialog), SIGNAL(triggered()), - this, SLOT(showSettingsDialog())); connect(theFakeVimSetting(ConfigUseFakeVim), SIGNAL(valueChanged(QVariant)), this, SLOT(setUseFakeVim(QVariant))); connect(theFakeVimSetting(ConfigReadVimRc), SIGNAL(valueChanged(QVariant)), @@ -628,7 +624,7 @@ bool FakeVimPluginPrivate::initialize() cmd->setAttribute(Command::CA_Hide); connect(switchFilePrevAction, SIGNAL(triggered()), this, SLOT(switchFilePrev())); - // Delayed operatiosn + // Delayed operations. connect(this, SIGNAL(delayedQuitRequested(bool,Core::IEditor*)), this, SLOT(handleDelayedQuit(bool,Core::IEditor*)), Qt::QueuedConnection); connect(this, SIGNAL(delayedQuitAllRequested(bool)), @@ -830,8 +826,6 @@ void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor) this, SLOT(showExtraInformation(QString))); connect(handler, SIGNAL(commandBufferChanged(QString)), this, SLOT(showCommandBuffer(QString))); - connect(handler, SIGNAL(writeFileRequested(bool*,QString,QString)), - this, SLOT(writeFile(bool*,QString,QString))); connect(handler, SIGNAL(selectionChanged(QList<QTextEdit::ExtraSelection>)), this, SLOT(changeSelection(QList<QTextEdit::ExtraSelection>))); connect(handler, SIGNAL(moveToMatchingParenthesis(bool*,bool*,QTextCursor*)), @@ -849,10 +843,8 @@ void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor) connect(handler, SIGNAL(findNextRequested(bool)), this, SLOT(findNext(bool))); - connect(handler, SIGNAL(handleExCommandRequested(QString)), - this, SLOT(handleExCommand(QString))); - connect(handler, SIGNAL(handleSetCommandRequested(bool *,QString)), - this, SLOT(handleSetCommand(bool *,QString))); + connect(handler, SIGNAL(handleExCommandRequested(bool*,ExCommand)), + this, SLOT(handleExCommand(bool*,ExCommand))); handler->setCurrentFileName(editor->file()->fileName()); handler->installEventFilter(); @@ -913,36 +905,12 @@ void FakeVimPluginPrivate::checkForElectricCharacter(bool *result, QChar c) *result = bt->isElectricCharacter(c); } -void FakeVimPluginPrivate::writeFile(bool *handled, - const QString &fileName, const QString &contents) -{ - Q_UNUSED(contents) - - FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender()); - if (!handler) - return; - - Core::IEditor *editor = m_editorToHandler.key(handler); - if (editor && editor->file()->fileName() == fileName) { - // Handle that as a special case for nicer interaction with core - Core::IFile *file = editor->file(); - Core::ICore::instance()->fileManager()->blockFileChange(file); - file->save(fileName); - Core::ICore::instance()->fileManager()->unblockFileChange(file); - *handled = true; - } -} - -void FakeVimPluginPrivate::handleExCommand(const QString &cmd) +void FakeVimPluginPrivate::handleExCommand(bool *handled, const ExCommand &cmd) { using namespace Core; + //qDebug() << "PLUGIN HANDLE: " << cmd.cmd; - QString cmd0 = cmd.section(QLatin1Char(' '), 0, 0); - bool hasBang = false; - if (cmd.endsWith('!')) { - hasBang = true; - cmd0.chop(1); - } + *handled = false; FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender()); if (!handler) @@ -951,7 +919,27 @@ void FakeVimPluginPrivate::handleExCommand(const QString &cmd) EditorManager *editorManager = EditorManager::instance(); QTC_ASSERT(editorManager, return); - if (cmd0 == "wa" || cmd0 == "wall") { + *handled = true; + if (cmd.cmd == "w" || cmd.cmd == "write") { + Core::IEditor *editor = m_editorToHandler.key(handler); + const QString fileName = handler->currentFileName(); + if (editor && editor->file()->fileName() == fileName) { + // Handle that as a special case for nicer interaction with core + Core::IFile *file = editor->file(); + Core::ICore::instance()->fileManager()->blockFileChange(file); + file->save(fileName); + Core::ICore::instance()->fileManager()->unblockFileChange(file); + // Check result by reading back. + QFile file3(fileName); + file3.open(QIODevice::ReadOnly); + QByteArray ba = file3.readAll(); + handler->showBlackMessage(FakeVimHandler::tr("\"%1\" %2 %3L, %4C written") + .arg(fileName).arg(" ") + .arg(ba.count('\n')).arg(ba.size())); + } else { + handler->showRedMessage(tr("File not saved")); + } + } else if (cmd.cmd == "wa" || cmd.cmd == "wall") { // :wa FileManager *fm = ICore::instance()->fileManager(); QList<IFile *> toSave = fm->modifiedFiles(); @@ -960,50 +948,47 @@ void FakeVimPluginPrivate::handleExCommand(const QString &cmd) handler->showBlackMessage(tr("Saving succeeded")); else handler->showRedMessage(tr("%n files not saved", 0, failed.size())); - } else if (cmd0 == "q" || cmd0 == "quit") { + } else if (cmd.cmd == "q" || cmd.cmd == "quit") { // :q[uit] - emit delayedQuitRequested(hasBang, m_editorToHandler.key(handler)); - } else if (cmd0 == "qa" || cmd0 == "qall") { + emit delayedQuitRequested(cmd.hasBang, m_editorToHandler.key(handler)); + } else if (cmd.cmd == "qa" || cmd.cmd == "qall") { // :qa - emit delayedQuitAllRequested(hasBang); - } else if (cmd0 == "sp" || cmd0 == "split") { + emit delayedQuitAllRequested(cmd.hasBang); + } else if (cmd.cmd == "sp" || cmd.cmd == "split") { // :sp[lit] triggerAction(Core::Constants::SPLIT); - } else if (cmd0 == "vs" || cmd0 == "vsplit") { + } else if (cmd.cmd == "vs" || cmd.cmd == "vsplit") { // :vs[plit] triggerAction(Core::Constants::SPLIT_SIDE_BY_SIDE); - } else if (cmd0 == "mak" || cmd0 == "make") { + } else if (cmd.cmd == "mak" || cmd.cmd == "make") { // :mak[e][!] [arguments] triggerAction(ProjectExplorer::Constants::BUILD); + } else if (cmd.cmd == "se" || cmd.cmd == "set") { + if (cmd.args.isEmpty()) { + // :set + showSettingsDialog(); + } else if (cmd.args == "ic" || cmd.args == "ignorecase") { + // :set noic + setActionChecked(Find::Constants::CASE_SENSITIVE, false); + *handled = false; // Let the handler see it as well. + } else if (cmd.args == "noic" || cmd.args == "noignorecase") { + // :set noic + setActionChecked(Find::Constants::CASE_SENSITIVE, true); + *handled = false; // Let the handler see it as well. + } } else { + // Check whether one of the configure commands matches. typedef QMap<QString, QRegExp>::const_iterator Iterator; const Iterator end = s_exCommandMap.constEnd(); for (Iterator it = s_exCommandMap.constBegin(); it != end; ++it) { const QString &id = it.key(); const QRegExp &re = it.value(); - - if (!re.pattern().isEmpty() && re.indexIn(cmd) != -1) { + if (!re.pattern().isEmpty() && re.indexIn(cmd.args) != -1) { triggerAction(id); return; } } - - handler->showRedMessage(tr("Not an editor command: %1").arg(cmd)); - } -} - -void FakeVimPluginPrivate::handleSetCommand(bool *handled, QString cmd) -{ - *handled = false; - bool value = true; - if (cmd.startsWith("no")) { - value = false; - cmd = cmd.mid(2); - } - - if (cmd == "ic" || cmd == "ignorecase") { - setActionChecked(Find::Constants::CASE_SENSITIVE, value); - *handled = true; + *handled = false; } } -- GitLab