fakevim: rework support for marks

This commit is contained in:
hjk
2010-05-11 14:26:37 +02:00
parent cb8c40d7e9
commit a13530eba0

View File

@@ -128,6 +128,7 @@ namespace Internal {
#define EDITOR(s) (m_textedit ? m_textedit->s : m_plaintextedit->s) #define EDITOR(s) (m_textedit ? m_textedit->s : m_plaintextedit->s)
const int ParagraphSeparator = 0x00002029; const int ParagraphSeparator = 0x00002029;
typedef QLatin1String _;
using namespace Qt; using namespace Qt;
@@ -232,6 +233,20 @@ enum EventResult
EventPassedToCore EventPassedToCore
}; };
struct ExCommand
{
ExCommand(const QString &c, int b = -1, int e = -1)
: line(c), beginLine(b), endLine(e) {}
QString line;
int beginLine;
int endLine;
};
QDebug operator<<(QDebug ts, const ExCommand &cmd)
{
return ts << cmd.line << cmd.beginLine << cmd.endLine;
}
struct Column struct Column
{ {
Column(int p, int l) : physical(p), logical(l) {} Column(int p, int l) : physical(p), logical(l) {}
@@ -251,6 +266,7 @@ struct CursorPosition
struct Register struct Register
{ {
Register() : rangemode(RangeCharMode) {} Register() : rangemode(RangeCharMode) {}
Register(const QString &c) : contents(c), rangemode(RangeCharMode) {}
Register(const QString &c, RangeMode m) : contents(c), rangemode(m) {} Register(const QString &c, RangeMode m) : contents(c), rangemode(m) {}
QString contents; QString contents;
RangeMode rangemode; RangeMode rangemode;
@@ -293,7 +309,7 @@ QString quoteUnprintable(const QString &ba)
if (c.isPrint()) if (c.isPrint())
res += c; res += c;
else if (cc == '\n') else if (cc == '\n')
res += QLatin1String("<CR>"); res += _("<CR>");
else else
res += QString("\\x%1").arg(c.unicode(), 2, 16, QLatin1Char('0')); res += QString("\\x%1").arg(c.unicode(), 2, 16, QLatin1Char('0'));
} }
@@ -313,7 +329,7 @@ static bool startsWithWhitespace(const QString &str, int col)
inline QString msgMarkNotSet(const QString &text) inline QString msgMarkNotSet(const QString &text)
{ {
return FakeVimHandler::tr("E20: Mark '%1' not set").arg(text); return FakeVimHandler::tr("Mark '%1' not set").arg(text);
} }
class Input class Input
@@ -378,6 +394,11 @@ public:
QString text() const { return m_text; } QString text() const { return m_text; }
QChar asChar() const
{
return (m_text.size() == 1 ? m_text.at(0) : QChar());
}
int key() const { return m_key; } int key() const { return m_key; }
QDebug dump(QDebug ts) const QDebug dump(QDebug ts) const
@@ -551,7 +572,7 @@ public:
int lastPositionInLine(int line) const; // 1 based line, 0 based pos int lastPositionInLine(int line) const; // 1 based line, 0 based pos
int lineForPosition(int pos) const; // 1 based line, 0 based pos int lineForPosition(int pos) const; // 1 based line, 0 based pos
QString lineContents(int line) const; // 1 based line QString lineContents(int line) const; // 1 based line
void setLineContents(int line, const QString &contents) const; // 1 based line void setLineContents(int line, const QString &contents); // 1 based line
int linesOnScreen() const; int linesOnScreen() const;
int columnsOnScreen() const; int columnsOnScreen() const;
@@ -706,6 +727,7 @@ public:
void transformText(const Range &range, Transformation transformation, void transformText(const Range &range, Transformation transformation,
const QVariant &extraData = QVariant()); const QVariant &extraData = QVariant());
void insertText(const Register &reg);
void removeSelectedText(); void removeSelectedText();
void removeText(const Range &range); void removeText(const Range &range);
void removeTransform(TransformationData *td); void removeTransform(TransformationData *td);
@@ -756,8 +778,9 @@ public:
VisualMode m_visualMode; VisualMode m_visualMode;
// marks as lines // marks as lines
int mark(int code) const;
void setMark(int code, int position);
QHash<int, int> m_marks; QHash<int, int> m_marks;
QString m_oldNeedle;
// vi style configuration // vi style configuration
QVariant config(int code) const { return theFakeVimSetting(code)->value(); } QVariant config(int code) const { return theFakeVimSetting(code)->value(); }
@@ -783,22 +806,23 @@ public:
QVector<CursorPosition> m_jumpListRedo; QVector<CursorPosition> m_jumpListRedo;
QList<QTextEdit::ExtraSelection> m_searchSelections; QList<QTextEdit::ExtraSelection> m_searchSelections;
QString m_oldNeedle;
bool handleExCommandHelper(const QString &cmd); // Returns success. bool handleExCommandHelper(const ExCommand &cmd); // Returns success.
QString extractCommand(const QString &line, int *beginLine, int *endLine); ExCommand extractExCommand(const QString &line);
bool handleExBangCommand(const QString &line); bool handleExBangCommand(const ExCommand &cmd);
bool handleExDeleteCommand(const QString &line); bool handleExDeleteCommand(const ExCommand &cmd);
bool handleExGotoCommand(const QString &line); bool handleExGotoCommand(const ExCommand &cmd);
bool handleExHistoryCommand(const QString &line); bool handleExHistoryCommand(const ExCommand &cmd);
bool handleExMapCommand(const QString &line); bool handleExMapCommand(const ExCommand &cmd);
bool handleExNormalCommand(const QString &line); bool handleExNormalCommand(const ExCommand &cmd);
bool handleExReadCommand(const QString &line); bool handleExReadCommand(const ExCommand &cmd);
bool handleExRedoCommand(const QString &line); bool handleExRedoCommand(const ExCommand &cmd);
bool handleExSetCommand(const QString &line); bool handleExSetCommand(const ExCommand &cmd);
bool handleExShiftRightCommand(const QString &line); bool handleExShiftRightCommand(const ExCommand &cmd);
bool handleExSourceCommand(const QString &line); bool handleExSourceCommand(const ExCommand &cmd);
bool handleExSubstituteCommand(const QString &line); bool handleExSubstituteCommand(const ExCommand &cmd);
bool handleExWriteCommand(const QString &line); bool handleExWriteCommand(const ExCommand &cmd);
void timerEvent(QTimerEvent *ev); void timerEvent(QTimerEvent *ev);
@@ -1028,8 +1052,8 @@ void FakeVimHandler::Private::importSelection()
else else
tc.movePosition(Left, KeepAnchor); tc.movePosition(Left, KeepAnchor);
} }
m_marks['<'] = anc; setMark('<', anc);
m_marks['>'] = pos; setMark('>', pos);
m_anchor = anc; m_anchor = anc;
Qt::KeyboardModifiers mods = QApplication::keyboardModifiers(); Qt::KeyboardModifiers mods = QApplication::keyboardModifiers();
if (!tc.hasSelection()) if (!tc.hasSelection())
@@ -1067,15 +1091,15 @@ void FakeVimHandler::Private::restoreWidget(int tabSize)
if (isVisualLineMode()) { if (isVisualLineMode()) {
m_tc = EDITOR(textCursor()); m_tc = EDITOR(textCursor());
int beginLine = lineForPosition(m_marks['<']); int beginLine = lineForPosition(mark('<'));
int endLine = lineForPosition(m_marks['>']); int endLine = lineForPosition(mark('>'));
m_tc.setPosition(firstPositionInLine(beginLine), MoveAnchor); m_tc.setPosition(firstPositionInLine(beginLine), MoveAnchor);
m_tc.setPosition(lastPositionInLine(endLine), KeepAnchor); m_tc.setPosition(lastPositionInLine(endLine), KeepAnchor);
EDITOR(setTextCursor(m_tc)); EDITOR(setTextCursor(m_tc));
} else if (isVisualCharMode() || isVisualBlockMode()) { } else if (isVisualCharMode() || isVisualBlockMode()) {
m_tc = EDITOR(textCursor()); m_tc = EDITOR(textCursor());
m_tc.setPosition(m_marks['<'], MoveAnchor); m_tc.setPosition(mark('<'), MoveAnchor);
m_tc.setPosition(m_marks['>'], KeepAnchor); m_tc.setPosition(mark('>'), KeepAnchor);
EDITOR(setTextCursor(m_tc)); EDITOR(setTextCursor(m_tc));
} }
@@ -1172,7 +1196,7 @@ void FakeVimHandler::Private::setAnchor()
if (!isVisualMode()) { if (!isVisualMode()) {
m_anchor = m_tc.position(); m_anchor = m_tc.position();
} else { } else {
// m_marks['<'] = m_tc.position(); // setMark('<', m_tc.position());
} }
} }
@@ -1246,7 +1270,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
} }
if (isVisualMode()) if (isVisualMode())
m_marks['>'] = m_tc.position(); setMark('>', m_tc.position());
if (m_submode == ChangeSubMode if (m_submode == ChangeSubMode
|| m_submode == DeleteSubMode || m_submode == DeleteSubMode
@@ -1314,7 +1338,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
const int la = lineForPosition(anchor()); const int la = lineForPosition(anchor());
const int lp = lineForPosition(position()); const int lp = lineForPosition(position());
if (m_register != '"') { if (m_register != '"') {
setPosition(m_marks[m_register]); setPosition(mark(m_register));
moveToStartOfLine(); moveToStartOfLine();
} else { } else {
if (anchor() <= position()) if (anchor() <= position())
@@ -1394,7 +1418,7 @@ void FakeVimHandler::Private::updateSelection()
sel.format.setBackground(Qt::black); sel.format.setBackground(Qt::black);
#endif #endif
const int cursorPos = m_tc.position(); const int cursorPos = m_tc.position();
const int anchorPos = m_marks['<']; const int anchorPos = mark('<');
//qDebug() << "POS: " << cursorPos << " ANCHOR: " << anchorPos; //qDebug() << "POS: " << cursorPos << " ANCHOR: " << anchorPos;
if (isVisualCharMode()) { if (isVisualCharMode()) {
sel.cursor.setPosition(qMin(cursorPos, anchorPos), MoveAnchor); sel.cursor.setPosition(qMin(cursorPos, anchorPos), MoveAnchor);
@@ -1602,12 +1626,13 @@ EventResult FakeVimHandler::Private::handleCommandSubSubMode(const Input &input)
finishMovement(); finishMovement();
} }
} else if (m_subsubmode == MarkSubSubMode) { } else if (m_subsubmode == MarkSubSubMode) {
m_marks[input.key()] = m_tc.position(); setMark(input.asChar().unicode(), m_tc.position());
m_subsubmode = NoSubSubMode; m_subsubmode = NoSubSubMode;
} else if (m_subsubmode == BackTickSubSubMode } else if (m_subsubmode == BackTickSubSubMode
|| m_subsubmode == TickSubSubMode) { || m_subsubmode == TickSubSubMode) {
if (m_marks.contains(input.key())) { int m = mark(input.asChar().unicode());
setPosition(m_marks[input.key()]); if (m != -1) {
setPosition(m);
if (m_subsubmode == TickSubSubMode) if (m_subsubmode == TickSubSubMode)
moveToFirstNonBlankOnLine(); moveToFirstNonBlankOnLine();
finishMovement(); finishMovement();
@@ -1756,7 +1781,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input)
} else if (input.is(':')) { } else if (input.is(':')) {
enterExMode(); enterExMode();
m_currentMessage.clear(); m_currentMessage.clear();
m_commandPrefix = input.text().at(0); m_commandPrefix = input.asChar();
m_commandBuffer.clear(); m_commandBuffer.clear();
if (isVisualMode()) if (isVisualMode())
m_commandBuffer = "'<,'>"; m_commandBuffer = "'<,'>";
@@ -2414,7 +2439,7 @@ EventResult FakeVimHandler::Private::handleReplaceMode(const Input &input)
} }
const QString text = input.text(); const QString text = input.text();
m_lastInsertion += text; m_lastInsertion += text;
m_tc.insertText(text); insertText(text);
//qDebug() << "REM/INS: " << m_lastDeletion << m_lastInsertion; //qDebug() << "REM/INS: " << m_lastDeletion << m_lastInsertion;
endEditBlock(); endEditBlock();
// m_movetype = MoveExclusive; // m_movetype = MoveExclusive;
@@ -2439,7 +2464,7 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input)
setTargetColumn(); setTargetColumn();
for (int i = 0; i < m_visualInsertCount; ++i) { for (int i = 0; i < m_visualInsertCount; ++i) {
moveDown(); moveDown();
m_tc.insertText(m_lastInsertion); insertText(m_lastInsertion);
} }
moveLeft(1); moveLeft(1);
Range range(pos, position(), RangeBlockMode); Range range(pos, position(), RangeBlockMode);
@@ -2448,13 +2473,12 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input)
setDotCommand("p"); setDotCommand("p");
endEditBlock(); endEditBlock();
} else { } else {
// normal insertion. start with '1', as one instance was // Normal insertion. Start with '1', as one instance was
// already physically inserted while typing // already physically inserted while typing.
QString data = m_lastInsertion; QString data;
for (int i = 1; i < count(); ++i) { for (int i = 1; i < count(); ++i)
m_tc.insertText(m_lastInsertion);
data += m_lastInsertion; data += m_lastInsertion;
} insertText(data);
moveLeft(qMin(1, leftDist())); moveLeft(qMin(1, leftDist()));
setTargetColumn(); setTargetColumn();
leaveVisualMode(); leaveVisualMode();
@@ -2544,7 +2568,7 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input)
const int col = physicalCursorColumnInDocument(); const int col = physicalCursorColumnInDocument();
QString str = QString(ts - col % ts, ' '); QString str = QString(ts - col % ts, ' ');
m_lastInsertion.append(str); m_lastInsertion.append(str);
m_tc.insertText(str); insertText(str);
setTargetColumn(); setTargetColumn();
} else if (input.isControl('d')) { } else if (input.isControl('d')) {
// remove one level of indentation from the current line // remove one level of indentation from the current line
@@ -2571,7 +2595,7 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input)
m_justAutoIndented = 0; m_justAutoIndented = 0;
const QString text = input.text(); const QString text = input.text();
m_lastInsertion.append(text); m_lastInsertion.append(text);
m_tc.insertText(text); insertText(text);
if (hasConfig(ConfigSmartIndent) && isElectricCharacter(text.at(0))) { if (hasConfig(ConfigSmartIndent) && isElectricCharacter(text.at(0))) {
const QString leftText = m_tc.block().text() const QString leftText = m_tc.block().text()
.left(m_tc.position() - 1 - m_tc.block().position()); .left(m_tc.position() - 1 - m_tc.block().position());
@@ -2706,7 +2730,7 @@ EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input)
return EventHandled; return EventHandled;
} }
// 1 based. // This uses 1 based line counting.
int FakeVimHandler::Private::readLineCode(QString &cmd) int FakeVimHandler::Private::readLineCode(QString &cmd)
{ {
//qDebug() << "CMD: " << cmd; //qDebug() << "CMD: " << cmd;
@@ -2714,19 +2738,32 @@ int FakeVimHandler::Private::readLineCode(QString &cmd)
return -1; return -1;
QChar c = cmd.at(0); QChar c = cmd.at(0);
cmd = cmd.mid(1); cmd = cmd.mid(1);
if (c == '.') if (c == '.') {
if (cmd.isEmpty())
return cursorLineInDocument() + 1;
QChar c1 = cmd.at(0);
if (c1 == '+' || c1 == '-') {
// Repeat for things like .+4
cmd = cmd.mid(1);
return cursorLineInDocument() + readLineCode(cmd);
}
return cursorLineInDocument() + 1; return cursorLineInDocument() + 1;
}
if (c == '$') if (c == '$')
return linesInDocument(); return linesInDocument();
if (c == '\'' && !cmd.isEmpty()) { if (c == '\'' && !cmd.isEmpty()) {
int mark = m_marks.value(cmd.at(0).unicode()); if (cmd.isEmpty()) {
if (!mark) { showRedMessage(msgMarkNotSet(QString()));
return -1;
}
int m = mark(cmd.at(0).unicode());
if (m == -1) {
showRedMessage(msgMarkNotSet(cmd.at(0))); showRedMessage(msgMarkNotSet(cmd.at(0)));
cmd = cmd.mid(1); cmd = cmd.mid(1);
return -1; return -1;
} }
cmd = cmd.mid(1); cmd = cmd.mid(1);
return lineForPosition(mark); return lineForPosition(m);
} }
if (c == '-') { if (c == '-') {
int n = readLineCode(cmd); int n = readLineCode(cmd);
@@ -2737,8 +2774,7 @@ int FakeVimHandler::Private::readLineCode(QString &cmd)
return cursorLineInDocument() + 1 + (n == -1 ? 1 : n); return cursorLineInDocument() + 1 + (n == -1 ? 1 : n);
} }
if (c == '\'' && !cmd.isEmpty()) { if (c == '\'' && !cmd.isEmpty()) {
int pos = m_marks.value(cmd.at(0).unicode(), -1); int pos = mark(cmd.at(0).unicode());
//qDebug() << " MARK: " << cmd.at(0) << pos << lineForPosition(pos);
if (pos == -1) { if (pos == -1) {
showRedMessage(msgMarkNotSet(cmd.at(0))); showRedMessage(msgMarkNotSet(cmd.at(0)));
cmd = cmd.mid(1); cmd = cmd.mid(1);
@@ -2756,16 +2792,17 @@ int FakeVimHandler::Private::readLineCode(QString &cmd)
cmd = cmd.mid(1); cmd = cmd.mid(1);
n = n * 10 + (c.unicode() - '0'); n = n * 10 + (c.unicode() - '0');
} }
//qDebug() << "N: " << n; qDebug() << "N: " << n;
return n; return n;
} }
// not parsed // Parsing failed.
cmd = c + cmd; cmd = c + cmd;
return -1; return -1;
} }
void FakeVimHandler::Private::selectRange(int beginLine, int endLine) void FakeVimHandler::Private::selectRange(int beginLine, int endLine)
{ {
m_rangemode = RangeLineMode;
if (beginLine == -1) if (beginLine == -1)
beginLine = cursorLineInDocument(); beginLine = cursorLineInDocument();
if (endLine == -1) if (endLine == -1)
@@ -2787,71 +2824,44 @@ void FakeVimHandler::Private::handleCommand(const QString &cmd)
EDITOR(setTextCursor(m_tc)); EDITOR(setTextCursor(m_tc));
} }
QString FakeVimHandler::Private::extractCommand(const QString &line, bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
int *beginLine, int *endLine)
{
QString cmd = line;
*beginLine = -1;
*endLine = -1;
// FIXME: that seems to be different for %w and %s
if (cmd.startsWith(QLatin1Char('%')))
cmd = "1,$" + cmd.mid(1);
int lineNumber = readLineCode(cmd);
if (lineNumber != -1)
*beginLine = lineNumber;
if (cmd.startsWith(',')) {
cmd = cmd.mid(1);
lineNumber = readLineCode(cmd);
if (lineNumber != -1)
*endLine = lineNumber;
}
//qDebug() << "RANGE: " << beginLine << endLine << cmd << lineNumber << m_marks;
return cmd;
}
bool FakeVimHandler::Private::handleExSubstituteCommand(const QString &line)
// :substitute // :substitute
{ {
int beginLine, endLine; QString line = cmd.line;
QString cmd = extractCommand(line, &beginLine, &endLine); if (line.startsWith(_("substitute")))
line = line.mid(10);
if (cmd.startsWith(QLatin1String("substitute"))) else if (line.startsWith('s') && line.size() > 1
cmd = cmd.mid(10); && !isalpha(line.at(1).unicode()))
else if (cmd.startsWith('s') && line.size() > 1 line = line.mid(1);
&& !isalpha(cmd.at(1).unicode()))
cmd = cmd.mid(1);
else else
return false; return false;
// we have /{pattern}/{string}/[flags] now // we have /{pattern}/{string}/[flags] now
if (cmd.isEmpty()) if (line.isEmpty())
return false; return false;
const QChar separator = cmd.at(0); const QChar separator = line.at(0);
int pos1 = -1; int pos1 = -1;
int pos2 = -1; int pos2 = -1;
int i; int i;
for (i = 1; i < cmd.size(); ++i) { for (i = 1; i < line.size(); ++i) {
if (cmd.at(i) == separator && cmd.at(i - 1) != '\\') { if (line.at(i) == separator && line.at(i - 1) != '\\') {
pos1 = i; pos1 = i;
break; break;
} }
} }
if (pos1 == -1) if (pos1 == -1)
return false; return false;
for (++i; i < cmd.size(); ++i) { for (++i; i < line.size(); ++i) {
if (cmd.at(i) == separator && cmd.at(i - 1) != '\\') { if (line.at(i) == separator && line.at(i - 1) != '\\') {
pos2 = i; pos2 = i;
break; break;
} }
} }
if (pos2 == -1) if (pos2 == -1)
pos2 = cmd.size(); pos2 = line.size();
QString needle = cmd.mid(1, pos1 - 1); QString needle = line.mid(1, pos1 - 1);
const QString replacement = cmd.mid(pos1 + 1, pos2 - pos1 - 1); const QString replacement = line.mid(pos1 + 1, pos2 - pos1 - 1);
QString flags = cmd.mid(pos2 + 1); QString flags = line.mid(pos2 + 1);
needle.replace('$', '\n'); needle.replace('$', '\n');
needle.replace("\\\n", "\\$"); needle.replace("\\\n", "\\$");
@@ -2860,7 +2870,7 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const QString &line)
pattern.setCaseSensitivity(Qt::CaseInsensitive); pattern.setCaseSensitivity(Qt::CaseInsensitive);
const bool global = flags.contains('g'); const bool global = flags.contains('g');
beginEditBlock(); beginEditBlock();
for (int line = endLine; line >= beginLine; --line) { for (int line = cmd.endLine; line >= cmd.beginLine; --line) {
QString origText = lineContents(line); QString origText = lineContents(line);
QString text = origText; QString text = origText;
int pos = 0; int pos = 0;
@@ -2893,14 +2903,14 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const QString &line)
return true; return true;
} }
bool FakeVimHandler::Private::handleExMapCommand(const QString &line) // :map bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map
{ {
const int pos1 = line.indexOf(QLatin1Char(' ')); const int pos1 = cmd0.line.indexOf(QLatin1Char(' '));
QByteArray modes; QByteArray modes;
enum Type { Map, Noremap, Unmap } type; enum Type { Map, Noremap, Unmap } type;
QByteArray cmd = line.left(pos1).toLatin1(); QByteArray cmd = cmd0.line.left(pos1).toLatin1();
// Strange formatting. But everything else is even uglier. // Strange formatting. But everything else is even uglier.
if (cmd == "map") { modes = "nvo"; type = Map; } else if (cmd == "map") { modes = "nvo"; type = Map; } else
@@ -2938,15 +2948,15 @@ bool FakeVimHandler::Private::handleExMapCommand(const QString &line) // :map
else else
return false; return false;
const int pos2 = line.indexOf(QLatin1Char(' '), pos1 + 1); const int pos2 = cmd0.line.indexOf(QLatin1Char(' '), pos1 + 1);
if (pos1 == -1 || pos2 == -1) { if (pos1 == -1 || pos2 == -1) {
// FIXME: Dump mappings here. // FIXME: Dump mappings here.
//qDebug() << g.mappings; //qDebug() << g.mappings;
return true;; return true;;
} }
QString lhs = line.mid(pos1 + 1, pos2 - pos1 - 1); QString lhs = cmd0.line.mid(pos1 + 1, pos2 - pos1 - 1);
QString rhs = line.mid(pos2 + 1); QString rhs = cmd0.line.mid(pos2 + 1);
Inputs key; Inputs key;
key.parseFrom(lhs); key.parseFrom(lhs);
//qDebug() << "MAPPING: " << modes << lhs << rhs; //qDebug() << "MAPPING: " << modes << lhs << rhs;
@@ -2969,10 +2979,10 @@ bool FakeVimHandler::Private::handleExMapCommand(const QString &line) // :map
return true; return true;
} }
bool FakeVimHandler::Private::handleExHistoryCommand(const QString &cmd) // :history bool FakeVimHandler::Private::handleExHistoryCommand(const ExCommand &cmd) // :history
{ {
static QRegExp reHistory("^his(tory)?( (.*))?$"); static QRegExp reHistory("^his(tory)?( (.*))?$");
if (reHistory.indexIn(cmd) == -1) if (reHistory.indexIn(cmd.line) == -1)
return false; return false;
QString arg = reHistory.cap(3); QString arg = reHistory.cap(3);
@@ -2992,10 +3002,10 @@ bool FakeVimHandler::Private::handleExHistoryCommand(const QString &cmd) // :his
return true; return true;
} }
bool FakeVimHandler::Private::handleExSetCommand(const QString &cmd) // :set bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) // :set
{ {
static QRegExp reSet("^set?( (.*))?$"); static QRegExp reSet("^set?( (.*))?$");
if (reSet.indexIn(cmd) == -1) if (reSet.indexIn(cmd.line) == -1)
return false; return false;
showBlackMessage(QString()); showBlackMessage(QString());
@@ -3013,7 +3023,7 @@ bool FakeVimHandler::Private::handleExSetCommand(const QString &cmd) // :set
} else if (act) { } else if (act) {
// non-boolean to show // non-boolean to show
showBlackMessage(arg + '=' + act->value().toString()); showBlackMessage(arg + '=' + act->value().toString());
} else if (arg.startsWith(QLatin1String("no")) } else if (arg.startsWith(_("no"))
&& (act = theFakeVimSettings()->item(arg.mid(2)))) { && (act = theFakeVimSettings()->item(arg.mid(2)))) {
// boolean config to be switched off // boolean config to be switched off
bool oldValue = act->value().toBool(); bool oldValue = act->value().toBool();
@@ -3035,27 +3045,24 @@ bool FakeVimHandler::Private::handleExSetCommand(const QString &cmd) // :set
return true; return true;
} }
bool FakeVimHandler::Private::handleExNormalCommand(const QString &cmd) // :normal bool FakeVimHandler::Private::handleExNormalCommand(const ExCommand &cmd) // :normal
{ {
static QRegExp reNormal("^norm(al)?( (.*))?$"); static QRegExp reNormal("^norm(al)?( (.*))?$");
if (reNormal.indexIn(cmd) == -1) if (reNormal.indexIn(cmd.line) == -1)
return false; return false;
//qDebug() << "REPLAY NORMAL: " << quoteUnprintable(reNormal.cap(3)); //qDebug() << "REPLAY NORMAL: " << quoteUnprintable(reNormal.cap(3));
replay(reNormal.cap(3), 1); replay(reNormal.cap(3), 1);
return true; return true;
} }
bool FakeVimHandler::Private::handleExDeleteCommand(const QString &line) // :d bool FakeVimHandler::Private::handleExDeleteCommand(const ExCommand &cmd) // :d
{ {
int beginLine, endLine; static QRegExp reDelete("^d(elete)?( (.*))?$");
QString cmd = extractCommand(line, &beginLine, &endLine); if (reDelete.indexIn(cmd.line) == -1)
static QRegExp reDelete("^d( (.*))?$");
if (reDelete.indexIn(cmd) != -1)
return false; return false;
selectRange(beginLine, endLine); selectRange(cmd.beginLine, cmd.endLine);
QString reg = reDelete.cap(2); QString reg = reDelete.cap(3);
QString text = selectedText(); QString text = selectedText();
removeSelectedText(); removeSelectedText();
if (!reg.isEmpty()) { if (!reg.isEmpty()) {
@@ -3066,28 +3073,27 @@ bool FakeVimHandler::Private::handleExDeleteCommand(const QString &line) // :d
return true; return true;
} }
bool FakeVimHandler::Private::handleExWriteCommand(const QString &line) bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd)
// :w, :x, :q, :wq, ... // :w, :x, :q, :wq, ...
{ {
int beginLine, endLine;
QString cmd = extractCommand(line, &beginLine, &endLine);
static QRegExp reWrite("^[wx]q?a?!?( (.*))?$"); static QRegExp reWrite("^[wx]q?a?!?( (.*))?$");
if (reWrite.indexIn(cmd) == -1) // :w and :x if (reWrite.indexIn(cmd.line) == -1) // :w and :x
return false; return false;
int beginLine = cmd.beginLine;
int endLine = cmd.endLine;
bool noArgs = (beginLine == -1); bool noArgs = (beginLine == -1);
if (beginLine == -1) if (beginLine == -1)
beginLine = 0; beginLine = 0;
if (endLine == -1) if (endLine == -1)
endLine = linesInDocument(); endLine = linesInDocument();
//qDebug() << "LINES: " << beginLine << endLine; //qDebug() << "LINES: " << beginLine << endLine;
int indexOfSpace = cmd.indexOf(QChar(' ')); int indexOfSpace = cmd.line.indexOf(QChar(' '));
QString prefix; QString prefix;
if (indexOfSpace < 0) if (indexOfSpace < 0)
prefix = cmd; prefix = cmd.line;
else else
prefix = cmd.left(indexOfSpace); prefix = cmd.line.left(indexOfSpace);
bool forced = prefix.contains(QChar('!')); bool forced = prefix.contains(QChar('!'));
bool quit = prefix.contains(QChar('q')) || prefix.contains(QChar('x')); bool quit = prefix.contains(QChar('q')) || prefix.contains(QChar('x'));
bool quitAll = quit && prefix.contains(QChar('a')); bool quitAll = quit && prefix.contains(QChar('a'));
@@ -3140,16 +3146,16 @@ bool FakeVimHandler::Private::handleExWriteCommand(const QString &line)
return true; return true;
} }
bool FakeVimHandler::Private::handleExReadCommand(const QString &line) // :r bool FakeVimHandler::Private::handleExReadCommand(const ExCommand &cmd) // :r
{ {
if (!line.startsWith(QLatin1String("r "))) if (!cmd.line.startsWith(_("r ")))
return false; return false;
beginEditBlock(); beginEditBlock();
moveToStartOfLine(); moveToStartOfLine();
setTargetColumn(); setTargetColumn();
moveDown(); moveDown();
m_currentFileName = line.mid(2); m_currentFileName = cmd.line.mid(2).trimmed();
QFile file(m_currentFileName); QFile file(m_currentFileName);
file.open(QIODevice::ReadOnly); file.open(QIODevice::ReadOnly);
QTextStream ts(&file); QTextStream ts(&file);
@@ -3161,23 +3167,20 @@ bool FakeVimHandler::Private::handleExReadCommand(const QString &line) // :r
return true; return true;
} }
bool FakeVimHandler::Private::handleExBangCommand(const QString &line) // :! bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :!
{ {
int beginLine, endLine; if (!cmd.line.startsWith(QLatin1Char('!')))
QString cmd = extractCommand(line, &beginLine, &endLine);
if (!cmd.startsWith(QLatin1Char('!')))
return false; return false;
selectRange(beginLine, endLine); selectRange(cmd.beginLine, cmd.endLine);
int targetPosition = firstPositionInLine(beginLine); int targetPosition = firstPositionInLine(cmd.beginLine);
QString command = cmd.mid(1).trimmed(); QString command = cmd.line.mid(1).trimmed();
QString text = selectedText(); QString text = selectedText();
QProcess proc; QProcess proc;
proc.start(command); proc.start(command);
proc.waitForStarted(); proc.waitForStarted();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
text.replace(QLatin1String("\n"), QLatin1String("\r\n")); text.replace(_("\n"), _("\r\n"));
#endif #endif
proc.write(text.toUtf8()); proc.write(text.toUtf8());
proc.closeWriteChannel(); proc.closeWriteChannel();
@@ -3185,7 +3188,7 @@ bool FakeVimHandler::Private::handleExBangCommand(const QString &line) // :!
QString result = QString::fromUtf8(proc.readAllStandardOutput()); QString result = QString::fromUtf8(proc.readAllStandardOutput());
beginEditBlock(targetPosition); beginEditBlock(targetPosition);
removeSelectedText(); removeSelectedText();
m_tc.insertText(result); insertText(result);
setPosition(targetPosition); setPosition(targetPosition);
endEditBlock(); endEditBlock();
leaveVisualMode(); leaveVisualMode();
@@ -3195,26 +3198,23 @@ bool FakeVimHandler::Private::handleExBangCommand(const QString &line) // :!
return true; return true;
} }
bool FakeVimHandler::Private::handleExShiftRightCommand(const QString &line) // :> bool FakeVimHandler::Private::handleExShiftRightCommand(const ExCommand &cmd) // :>
{ {
int beginLine, endLine; if (!cmd.line.startsWith(QLatin1Char('>')))
QString cmd = extractCommand(line, &beginLine, &endLine);
if (!cmd.startsWith(QLatin1Char('>')))
return false; return false;
m_anchor = firstPositionInLine(beginLine); m_anchor = firstPositionInLine(cmd.beginLine);
setPosition(firstPositionInLine(endLine)); setPosition(firstPositionInLine(cmd.endLine));
shiftRegionRight(1); shiftRegionRight(1);
leaveVisualMode(); leaveVisualMode();
showBlackMessage(FakeVimHandler::tr("%n lines >ed %1 time", 0, showBlackMessage(FakeVimHandler::tr("%n lines >ed %1 time", 0,
(endLine - beginLine + 1)).arg(1)); (cmd.endLine - cmd.beginLine + 1)).arg(1));
return true; return true;
} }
bool FakeVimHandler::Private::handleExRedoCommand(const QString &line) // :redo bool FakeVimHandler::Private::handleExRedoCommand(const ExCommand &cmd) // :redo
{ {
if (line != "red" && line != "redo") if (cmd.line != "red" && cmd.line != "redo")
return false; return false;
redo(); redo();
@@ -3222,26 +3222,23 @@ bool FakeVimHandler::Private::handleExRedoCommand(const QString &line) // :redo
return true; return true;
} }
bool FakeVimHandler::Private::handleExGotoCommand(const QString &line) // :<nr> bool FakeVimHandler::Private::handleExGotoCommand(const ExCommand &cmd) // :<nr>
{ {
int beginLine, endLine; if (!cmd.line.isEmpty())
QString cmd = extractCommand(line, &beginLine, &endLine);
if (!cmd.isEmpty())
return false; return false;
setPosition(firstPositionInLine(beginLine)); setPosition(firstPositionInLine(cmd.beginLine));
showBlackMessage(QString()); showBlackMessage(QString());
return true; return true;
} }
bool FakeVimHandler::Private::handleExSourceCommand(const QString &line) // :source bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd) // :source
{ {
int pos = line.indexOf(' '); const int pos = cmd.line.indexOf(' ');
if (line.leftRef(pos) != "so" && line.leftRef(pos) != "source") if (cmd.line.leftRef(pos) != "so" && cmd.line.leftRef(pos) != "source")
return false; return false;
QString fileName = line.mid(pos + 1); QString fileName = cmd.line.mid(pos + 1).trimmed();
QFile file(fileName); QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
showRedMessage(FakeVimHandler::tr("Can't open file %1").arg(fileName)); showRedMessage(FakeVimHandler::tr("Can't open file %1").arg(fileName));
@@ -3274,28 +3271,41 @@ bool FakeVimHandler::Private::handleExSourceCommand(const QString &line) // :sou
void FakeVimHandler::Private::handleExCommand(const QString &line0) void FakeVimHandler::Private::handleExCommand(const QString &line0)
{ {
QString line = line0; // Make sure we have a copy to prevent aliasing. 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);
cmd.beginLine = readLineCode(line);
if (line.startsWith(',')) {
line = line.mid(1);
cmd.endLine = readLineCode(line);
}
cmd.line = line;
//qDebug() << "CMD: " << cmd;
enterCommandMode(); enterCommandMode();
showBlackMessage(QString()); showBlackMessage(QString());
if (handleExCommandHelper(line)) if (!handleExCommandHelper(cmd))
return; passUnknownExCommand(cmd.line);
int beginLine, endLine;
passUnknownExCommand(extractCommand(line, &beginLine, &endLine));
} }
bool FakeVimHandler::Private::handleExCommandHelper(const QString &line) bool FakeVimHandler::Private::handleExCommandHelper(const ExCommand &cmd)
{ {
return handleExGotoCommand(line) return handleExGotoCommand(cmd)
|| handleExBangCommand(line) || handleExBangCommand(cmd)
|| handleExHistoryCommand(line) || handleExHistoryCommand(cmd)
|| handleExMapCommand(line) || handleExDeleteCommand(cmd)
|| handleExNormalCommand(line) || handleExMapCommand(cmd)
|| handleExReadCommand(line) || handleExNormalCommand(cmd)
|| handleExRedoCommand(line) || handleExReadCommand(cmd)
|| handleExSetCommand(line) || handleExRedoCommand(cmd)
|| handleExShiftRightCommand(line) || handleExSetCommand(cmd)
|| handleExSourceCommand(line) || handleExShiftRightCommand(cmd)
|| handleExSubstituteCommand(line) || handleExSourceCommand(cmd)
|| handleExWriteCommand(line); || handleExSubstituteCommand(cmd)
|| handleExWriteCommand(cmd);
} }
void FakeVimHandler::Private::passUnknownExCommand(const QString &cmd) void FakeVimHandler::Private::passUnknownExCommand(const QString &cmd)
@@ -3311,17 +3321,17 @@ void FakeVimHandler::Private::passUnknownSetCommand(const QString &arg)
bool handled = false; bool handled = false;
emit q->handleSetCommandRequested(&handled, arg); emit q->handleSetCommandRequested(&handled, arg);
if (!handled) { if (!handled) {
showRedMessage(FakeVimHandler::tr("E512: Unknown option: ") + arg); showRedMessage(FakeVimHandler::tr("Unknown option: ") + arg);
} }
} }
static void vimPatternToQtPattern(QString *needle, QTextDocument::FindFlags *flags) static void vimPatternToQtPattern(QString *needle, QTextDocument::FindFlags *flags)
{ {
// FIXME: Rough mapping of a common case // FIXME: Rough mapping of a common case
if (needle->startsWith(QLatin1String("\\<")) && needle->endsWith(QLatin1String("\\>"))) if (needle->startsWith(_("\\<")) && needle->endsWith(_("\\>")))
(*flags) |= QTextDocument::FindWholeWords; (*flags) |= QTextDocument::FindWholeWords;
needle->remove(QLatin1String("\\<")); // start of word needle->remove(_("\\<")); // start of word
needle->remove(QLatin1String("\\>")); // end of word needle->remove(_("\\>")); // end of word
//qDebug() << "NEEDLE " << needle0 << needle; //qDebug() << "NEEDLE " << needle0 << needle;
} }
@@ -3462,6 +3472,7 @@ int FakeVimHandler::Private::indentText(const Range &range, QChar typedChar)
// lineForPosition has returned 1-based line numbers // lineForPosition has returned 1-based line numbers
emit q->indentRegion(&amount, beginLine-1, endLine-1, typedChar); emit q->indentRegion(&amount, beginLine-1, endLine-1, typedChar);
showBlackMessage("MARKS ARE OFF NOW");
return amount; return amount;
} }
@@ -3970,6 +3981,14 @@ void FakeVimHandler::Private::transformText(const Range &range,
} }
} }
void FakeVimHandler::Private::insertText(const Register &reg)
{
QTC_ASSERT(reg.rangemode == RangeCharMode,
qDebug() << "WRONG INSERT MODE: " << reg.rangemode; return);
fixMarks(position(), reg.contents.length());
m_tc.insertText(reg.contents);
}
void FakeVimHandler::Private::removeSelectedText() void FakeVimHandler::Private::removeSelectedText()
{ {
Range range(anchor(), position(), m_rangemode); Range range(anchor(), position(), m_rangemode);
@@ -4047,8 +4066,7 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
for (int i = count(); --i >= 0; ) { for (int i = count(); --i >= 0; ) {
if (afterCursor && rightDist() > 0) if (afterCursor && rightDist() > 0)
moveRight(); moveRight();
fixMarks(position(), text.length()); insertText(text);
m_tc.insertText(text);
if (!afterCursor && atEndOfLine()) if (!afterCursor && atEndOfLine())
moveLeft(); moveLeft();
moveLeft(); moveLeft();
@@ -4062,8 +4080,7 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
for (int i = count(); --i >= 0; ) { for (int i = count(); --i >= 0; ) {
if (afterCursor) if (afterCursor)
moveDown(); moveDown();
fixMarks(position(), text.length()); insertText(text);
m_tc.insertText(text);
moveUp(lines.size() - 1); moveUp(lines.size() - 1);
} }
moveToFirstNonBlankOnLine(); moveToFirstNonBlankOnLine();
@@ -4088,8 +4105,8 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
} else { } else {
tc.movePosition(Right, MoveAnchor, col - 1 + afterCursor); tc.movePosition(Right, MoveAnchor, col - 1 + afterCursor);
} }
qDebug() << "INSERT " << line << " AT " << tc.position() //qDebug() << "INSERT " << line << " AT " << tc.position()
<< "COL: " << col; // << "COL: " << col;
fixMarks(position(), line.length()); fixMarks(position(), line.length());
tc.insertText(line); tc.insertText(line);
tc.movePosition(StartOfLine, MoveAnchor); tc.movePosition(StartOfLine, MoveAnchor);
@@ -4109,16 +4126,38 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
} }
//FIXME: This needs to called after undo/insert //FIXME: This needs to called after undo/insert
void FakeVimHandler::Private::fixMarks(int positionAction, int positionChange) // The position 'from' is the cursor position after the change. If 'delta'
// is positive there was a string of size 'delta' inserted after 'from'
// and consequently all marks beyond 'from + delta' need to be incremented
// by 'delta'. If text was removed, 'delta' is negative. All marks between
// 'from' and 'from - delta' need to be removed, everything behing
// 'from - delta' adjusted by 'delta'.
void FakeVimHandler::Private::fixMarks(int from, int delta)
{ {
QHashIterator<int, int> i(m_marks); //qDebug() << "ADJUSTING MARKS FROM " << from << " BY " << delta;
while (i.hasNext()) { if (delta == 0)
i.next(); return;
if (i.value() >= positionAction) { QHashIterator<int, int> it(m_marks);
if (i.value() + positionChange > 0) while (it.hasNext()) {
m_marks[i.key()] = i.value() + positionChange; it.next();
else int pos = it.value();
m_marks.remove(i.key()); if (delta > 0) {
// Inserted text.
if (pos >= from) {
//qDebug() << "MODIFIED: " << it.key() << pos;
setMark(it.key(), pos + delta);
}
} else {
// Removed text.
if (pos < from) {
// Nothing to do.
} else if (pos < from - delta) {
//qDebug() << "GONE: " << it.key();
m_marks.remove(it.key());
} else {
//qDebug() << "MODIFIED: " << it.key() << pos;
setMark(it.key(), pos + delta);
}
} }
} }
} }
@@ -4128,13 +4167,15 @@ QString FakeVimHandler::Private::lineContents(int line) const
return m_tc.document()->findBlockByNumber(line - 1).text(); return m_tc.document()->findBlockByNumber(line - 1).text();
} }
void FakeVimHandler::Private::setLineContents(int line, const QString &contents) const void FakeVimHandler::Private::setLineContents(int line, const QString &contents)
{ {
QTextBlock block = m_tc.document()->findBlockByNumber(line - 1); QTextBlock block = m_tc.document()->findBlockByNumber(line - 1);
QTextCursor tc = m_tc; QTextCursor tc = m_tc;
tc.setPosition(block.position()); tc.setPosition(block.position());
tc.setPosition(block.position() + block.length() - 1, KeepAnchor); tc.setPosition(block.position() + block.length() - 1, KeepAnchor);
tc.removeSelectedText(); tc.removeSelectedText();
fixMarks(block.position(),
block.position() + block.length() - 1 - contents.size());
tc.insertText(contents); tc.insertText(contents);
} }
@@ -4161,8 +4202,8 @@ void FakeVimHandler::Private::enterVisualMode(VisualMode visualMode)
setAnchor(); setAnchor();
m_positionPastEnd = m_anchorPastEnd = false; m_positionPastEnd = m_anchorPastEnd = false;
m_visualMode = visualMode; m_visualMode = visualMode;
m_marks['<'] = m_tc.position(); setMark('<', m_tc.position());
m_marks['>'] = m_tc.position(); setMark('>', m_tc.position());
updateMiniBuffer(); updateMiniBuffer();
updateSelection(); updateSelection();
} }
@@ -4189,11 +4230,16 @@ QWidget *FakeVimHandler::Private::editor() const
void FakeVimHandler::Private::undo() void FakeVimHandler::Private::undo()
{ {
//qDebug() << " CURSOR POS: " << m_undoCursorPosition; //qDebug() << " CURSOR POS: " << m_undoCursorPosition;
int current = m_tc.document()->availableUndoSteps(); QTextDocument *doc = m_tc.document();
//endEditBlock(); // FIXME: That's only an approximaxtion. The real solution might
// be to store marks and old userData with QTextBlock setUserData
// and retrieve them afterward.
const int current = doc->availableUndoSteps();
const int oldCount = doc->characterCount();
EDITOR(undo()); EDITOR(undo());
//beginEditBlock(); const int delta = doc->characterCount() - oldCount;
int rev = m_tc.document()->availableUndoSteps(); fixMarks(position(), delta);
const int rev = doc->availableUndoSteps();
if (current == rev) if (current == rev)
showBlackMessage(FakeVimHandler::tr("Already at oldest change")); showBlackMessage(FakeVimHandler::tr("Already at oldest change"));
else else
@@ -4207,11 +4253,13 @@ void FakeVimHandler::Private::undo()
void FakeVimHandler::Private::redo() void FakeVimHandler::Private::redo()
{ {
int current = m_tc.document()->availableUndoSteps(); QTextDocument *doc = m_tc.document();
//endEditBlock(); const int current = m_tc.document()->availableUndoSteps();
const int oldCount = doc->characterCount();
EDITOR(redo()); EDITOR(redo());
//beginEditBlock(); const int delta = doc->characterCount() - oldCount;
int rev = m_tc.document()->availableUndoSteps(); fixMarks(position(), delta);
const int rev = doc->availableUndoSteps();
if (rev == current) if (rev == current)
showBlackMessage(FakeVimHandler::tr("Already at newest change")); showBlackMessage(FakeVimHandler::tr("Already at newest change"));
else else
@@ -4319,6 +4367,7 @@ void FakeVimHandler::Private::insertAutomaticIndentation(bool goingDown)
if (hasConfig(ConfigSmartIndent)) { if (hasConfig(ConfigSmartIndent)) {
Range range(m_tc.block().position(), m_tc.block().position()); Range range(m_tc.block().position(), m_tc.block().position());
m_justAutoIndented = indentText(range, QLatin1Char('\n')); m_justAutoIndented = indentText(range, QLatin1Char('\n'));
fixMarks(m_tc.block().position(), m_justAutoIndented);
} else { } else {
QTextBlock block = goingDown ? m_tc.block().previous() : m_tc.block().next(); QTextBlock block = goingDown ? m_tc.block().previous() : m_tc.block().next();
QString text = block.text(); QString text = block.text();
@@ -4328,7 +4377,7 @@ void FakeVimHandler::Private::insertAutomaticIndentation(bool goingDown)
++pos; ++pos;
text.truncate(pos); text.truncate(pos);
// FIXME: handle 'smartindent' and 'cindent' // FIXME: handle 'smartindent' and 'cindent'
m_tc.insertText(text); insertText(text);
m_justAutoIndented = text.size(); m_justAutoIndented = text.size();
} }
} }
@@ -4339,6 +4388,7 @@ bool FakeVimHandler::Private::removeAutomaticIndentation()
return false; return false;
m_tc.movePosition(StartOfLine, KeepAnchor); m_tc.movePosition(StartOfLine, KeepAnchor);
m_tc.removeSelectedText(); m_tc.removeSelectedText();
fixMarks(m_tc.position(), -m_justAutoIndented);
m_lastInsertion.chop(m_justAutoIndented); m_lastInsertion.chop(m_justAutoIndented);
m_justAutoIndented = 0; m_justAutoIndented = 0;
return true; return true;
@@ -4371,7 +4421,7 @@ void FakeVimHandler::Private::selectWordTextObject(bool inner)
setAnchor(); setAnchor();
// FIXME: Rework the 'anchor' concept. // FIXME: Rework the 'anchor' concept.
if (isVisualMode()) if (isVisualMode())
m_marks['<'] = m_tc.position(); setMark('<', m_tc.position());
moveToWordBoundary(false, true, true); moveToWordBoundary(false, true, true);
m_movetype = MoveInclusive; m_movetype = MoveInclusive;
} }
@@ -4384,7 +4434,7 @@ void FakeVimHandler::Private::selectWORDTextObject(bool inner)
setAnchor(); setAnchor();
// FIXME: Rework the 'anchor' concept. // FIXME: Rework the 'anchor' concept.
if (isVisualMode()) if (isVisualMode())
m_marks['<'] = m_tc.position(); setMark('<', m_tc.position());
moveToWordBoundary(true, true, true); moveToWordBoundary(true, true, true);
m_movetype = MoveInclusive; m_movetype = MoveInclusive;
} }
@@ -4412,6 +4462,18 @@ void FakeVimHandler::Private::selectQuotedStringTextObject(bool inner, int type)
Q_UNUSED(type); Q_UNUSED(type);
} }
int FakeVimHandler::Private::mark(int code) const
{
// FIXME: distinguish local and global marks.
//qDebug() << "MARK: " << code << m_marks.value(code, -1) << m_marks;
return m_marks.value(code, -1);
}
void FakeVimHandler::Private::setMark(int code, int position)
{
// FIXME: distinguish local and global marks.
m_marks[code] = position;
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// //