forked from qt-creator/qt-creator
fakevim: handle block mode for yank, cut and paste
This commit is contained in:
1
dist/changes-1.3.0
vendored
1
dist/changes-1.3.0
vendored
@@ -25,6 +25,7 @@ Editing
|
||||
* Objective-C: Added partial semantic checking and symbol navigation
|
||||
* Fixed searching in files to take open documents into account
|
||||
* Added a Locator filter for symbols in the current document
|
||||
* Handle block selection in fakevim
|
||||
|
||||
Project support
|
||||
* Added support for adding and removing files from a generic Makefile-based
|
||||
|
@@ -172,6 +172,52 @@ enum MoveType
|
||||
MoveLineWise,
|
||||
};
|
||||
|
||||
enum RangeMode
|
||||
{
|
||||
RangeCharMode,
|
||||
RangeLineMode,
|
||||
RangeBlockMode,
|
||||
};
|
||||
|
||||
enum EventResult
|
||||
{
|
||||
EventHandled,
|
||||
EventUnhandled,
|
||||
EventPassedToCore
|
||||
};
|
||||
|
||||
struct CursorPosition
|
||||
{
|
||||
// for jump history
|
||||
CursorPosition() : position(-1), scrollLine(-1) {}
|
||||
CursorPosition(int pos, int line) : position(pos), scrollLine(line) {}
|
||||
int position; // Position in document
|
||||
int scrollLine; // First visible line
|
||||
};
|
||||
|
||||
struct Register
|
||||
{
|
||||
Register() : rangemode(RangeCharMode) {}
|
||||
Register(const QString &c, RangeMode m) : contents(c), rangemode(m) {}
|
||||
QString contents;
|
||||
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)
|
||||
{}
|
||||
|
||||
int beginPos;
|
||||
int endPos;
|
||||
RangeMode rangemode;
|
||||
};
|
||||
|
||||
QDebug &operator<<(QDebug &ts, const QList<QTextEdit::ExtraSelection> &sels)
|
||||
{
|
||||
foreach (QTextEdit::ExtraSelection sel, sels)
|
||||
@@ -192,21 +238,6 @@ QString quoteUnprintable(const QString &ba)
|
||||
return res;
|
||||
}
|
||||
|
||||
enum EventResult
|
||||
{
|
||||
EventHandled,
|
||||
EventUnhandled,
|
||||
EventPassedToCore
|
||||
};
|
||||
|
||||
struct CursorPosition
|
||||
{
|
||||
CursorPosition() : position(-1), scrollLine(-1) {}
|
||||
CursorPosition(int pos, int line) : position(pos), scrollLine(line) {}
|
||||
int position; // Position in document
|
||||
int scrollLine; // First visible line
|
||||
};
|
||||
|
||||
class FakeVimHandler::Private
|
||||
{
|
||||
public:
|
||||
@@ -335,11 +366,12 @@ public:
|
||||
QTextCursor m_tc;
|
||||
QTextCursor m_oldTc; // copy from last event to check for external changes
|
||||
int m_anchor;
|
||||
static QHash<int, QString> m_registers;
|
||||
static QHash<int, Register> m_registers;
|
||||
int m_register;
|
||||
QString m_mvcount;
|
||||
QString m_opcount;
|
||||
MoveType m_moveType;
|
||||
MoveType m_movetype;
|
||||
RangeMode m_rangemode;
|
||||
|
||||
bool m_fakeEnd;
|
||||
|
||||
@@ -354,10 +386,19 @@ public:
|
||||
bool m_lastSearchForward;
|
||||
QString m_lastInsertion;
|
||||
|
||||
QString removeSelectedText();
|
||||
int anchor() const { return m_anchor; }
|
||||
int position() const { return m_tc.position(); }
|
||||
QString selectedText(MoveType moveType = MoveExclusive) const;
|
||||
|
||||
void removeSelectedText();
|
||||
void removeText(const Range &range);
|
||||
|
||||
QString selectedText() const { return text(Range(position(), anchor())); }
|
||||
QString text(const Range &range) const;
|
||||
|
||||
void yankSelectedText();
|
||||
void yankText(const Range &range, int toregister = '"');
|
||||
|
||||
void pasteText(bool afterCursor);
|
||||
|
||||
// undo handling
|
||||
void undo();
|
||||
@@ -423,7 +464,7 @@ public:
|
||||
|
||||
QStringList FakeVimHandler::Private::m_searchHistory;
|
||||
QStringList FakeVimHandler::Private::m_commandHistory;
|
||||
QHash<int, QString> FakeVimHandler::Private::m_registers;
|
||||
QHash<int, Register> FakeVimHandler::Private::m_registers;
|
||||
|
||||
FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget)
|
||||
{
|
||||
@@ -445,12 +486,13 @@ void FakeVimHandler::Private::init()
|
||||
m_gflag = false;
|
||||
m_visualMode = NoVisualMode;
|
||||
m_targetColumn = 0;
|
||||
m_moveType = MoveInclusive;
|
||||
m_movetype = MoveInclusive;
|
||||
m_anchor = 0;
|
||||
m_savedYankPosition = 0;
|
||||
m_cursorWidth = EDITOR(cursorWidth());
|
||||
m_inReplay = false;
|
||||
m_justAutoIndented = 0;
|
||||
m_rangemode = RangeCharMode;
|
||||
}
|
||||
|
||||
bool FakeVimHandler::Private::wantsOverride(QKeyEvent *ev)
|
||||
@@ -688,32 +730,35 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
|
||||
m_marks['>'] = m_tc.position();
|
||||
|
||||
if (m_submode == ChangeSubMode) {
|
||||
if (m_moveType == MoveInclusive)
|
||||
if (m_movetype == MoveInclusive)
|
||||
moveRight(); // correction
|
||||
if (anchor() >= position())
|
||||
m_anchor++;
|
||||
if (!dotCommand.isEmpty())
|
||||
setDotCommand("c" + dotCommand);
|
||||
QString text = removeSelectedText();
|
||||
//QString text = removeSelectedText();
|
||||
//qDebug() << "CHANGING TO INSERT MODE" << text;
|
||||
m_registers[m_register] = text;
|
||||
//m_registers[m_register] = text;
|
||||
yankSelectedText();
|
||||
removeSelectedText();
|
||||
enterInsertMode();
|
||||
m_submode = NoSubMode;
|
||||
} else if (m_submode == DeleteSubMode) {
|
||||
if (m_moveType == MoveInclusive)
|
||||
if (m_movetype == MoveInclusive)
|
||||
moveRight(); // correction
|
||||
if (anchor() >= position())
|
||||
m_anchor++;
|
||||
if (!dotCommand.isEmpty())
|
||||
setDotCommand("d" + dotCommand);
|
||||
m_registers[m_register] = removeSelectedText();
|
||||
yankSelectedText();
|
||||
removeSelectedText();
|
||||
m_submode = NoSubMode;
|
||||
if (atEndOfLine())
|
||||
moveLeft();
|
||||
else
|
||||
setTargetColumn();
|
||||
} else if (m_submode == YankSubMode) {
|
||||
m_registers[m_register] = selectedText();
|
||||
yankSelectedText();
|
||||
setPosition(m_savedYankPosition);
|
||||
m_submode = NoSubMode;
|
||||
} else if (m_submode == ReplaceSubMode) {
|
||||
@@ -735,12 +780,13 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
|
||||
updateMiniBuffer();
|
||||
}
|
||||
|
||||
m_moveType = MoveInclusive;
|
||||
m_movetype = MoveInclusive;
|
||||
m_mvcount.clear();
|
||||
m_opcount.clear();
|
||||
m_gflag = false;
|
||||
m_register = '"';
|
||||
m_tc.clearSelection();
|
||||
m_rangemode = RangeCharMode;
|
||||
|
||||
updateSelection();
|
||||
updateMiniBuffer();
|
||||
@@ -901,7 +947,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
moveToStartOfLine();
|
||||
setTargetColumn();
|
||||
moveUp(count() - 1);
|
||||
m_moveType = MoveLineWise;
|
||||
m_movetype = MoveLineWise;
|
||||
m_lastInsertion.clear();
|
||||
setDotCommand("%1cc", count());
|
||||
finishMovement();
|
||||
@@ -910,32 +956,33 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
setTargetColumn();
|
||||
setAnchor();
|
||||
moveDown(count());
|
||||
m_moveType = MoveLineWise;
|
||||
m_movetype = MoveLineWise;
|
||||
setDotCommand("%1dd", count());
|
||||
finishMovement();
|
||||
} else if (m_submode == YankSubMode && key == 'y') {
|
||||
moveToStartOfLine();
|
||||
setAnchor();
|
||||
moveDown(count() - 1);
|
||||
moveBehindEndOfLine();
|
||||
m_moveType = MoveLineWise;
|
||||
m_movetype = MoveLineWise;
|
||||
int endPos = firstPositionInLine(lineForPosition(position()) + count() - 1);
|
||||
Range range(position(), endPos, RangeLineMode);
|
||||
///range.extendByLines(count() - 1);
|
||||
yankText(range);
|
||||
m_submode = NoSubMode;
|
||||
finishMovement();
|
||||
} else if (m_submode == ShiftLeftSubMode && key == '<') {
|
||||
setAnchor();
|
||||
moveDown(count() - 1);
|
||||
m_moveType = MoveLineWise;
|
||||
m_movetype = MoveLineWise;
|
||||
setDotCommand("%1<<", count());
|
||||
finishMovement();
|
||||
} else if (m_submode == ShiftRightSubMode && key == '>') {
|
||||
setAnchor();
|
||||
moveDown(count() - 1);
|
||||
m_moveType = MoveLineWise;
|
||||
m_movetype = MoveLineWise;
|
||||
setDotCommand("%1>>", count());
|
||||
finishMovement();
|
||||
} else if (m_submode == IndentSubMode && key == '=') {
|
||||
setAnchor();
|
||||
moveDown(count() - 1);
|
||||
m_moveType = MoveLineWise;
|
||||
m_movetype = MoveLineWise;
|
||||
setDotCommand("%1==", count());
|
||||
finishMovement();
|
||||
} else if (m_submode == ZSubMode) {
|
||||
@@ -988,9 +1035,9 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
moveLeft();
|
||||
setAnchor();
|
||||
moveRight(count());
|
||||
QString rem = removeSelectedText();
|
||||
removeSelectedText();
|
||||
m_tc.insertText(QString(count(), text.at(0)));
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
setDotCommand("%1r" + text, count());
|
||||
}
|
||||
setTargetColumn();
|
||||
@@ -1105,7 +1152,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
} else if (key == '$' || key == Key_End) {
|
||||
int submode = m_submode;
|
||||
moveToEndOfLine();
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
setTargetColumn();
|
||||
if (submode == NoSubMode)
|
||||
m_targetColumn = -1;
|
||||
@@ -1138,7 +1185,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
indentRegion();
|
||||
leaveVisualMode();
|
||||
} else if (key == '%') {
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
moveToMatchingParanthesis();
|
||||
finishMovement();
|
||||
} else if (key == 'a') {
|
||||
@@ -1155,11 +1202,11 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
} else if (key == control('a')) {
|
||||
// FIXME: eat it to prevent the global "select all" shortcut to trigger
|
||||
} else if (key == 'b') {
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
moveToWordBoundary(false, false);
|
||||
finishMovement();
|
||||
} else if (key == 'B') {
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
moveToWordBoundary(true, false);
|
||||
finishMovement();
|
||||
} else if (key == 'c' && m_visualMode == NoVisualMode) {
|
||||
@@ -1172,7 +1219,8 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
} else if (key == 'C') {
|
||||
setAnchor();
|
||||
moveToEndOfLine();
|
||||
m_registers[m_register] = removeSelectedText();
|
||||
yankSelectedText();
|
||||
removeSelectedText();
|
||||
enterInsertMode();
|
||||
setDotCommand("C");
|
||||
finishMovement();
|
||||
@@ -1191,15 +1239,20 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
finishMovement();
|
||||
} else if ((key == 'd' || key == 'x') && m_visualMode == VisualLineMode) {
|
||||
leaveVisualMode();
|
||||
int beginLine = lineForPosition(m_marks['<']);
|
||||
int endLine = lineForPosition(m_marks['>']);
|
||||
selectRange(beginLine, endLine);
|
||||
m_registers[m_register] = removeSelectedText();
|
||||
m_rangemode = RangeLineMode;
|
||||
yankSelectedText();
|
||||
removeSelectedText();
|
||||
} else if ((key == 'd' || key == 'x') && m_visualMode == VisualBlockMode) {
|
||||
leaveVisualMode();
|
||||
m_rangemode = RangeBlockMode;
|
||||
yankSelectedText();
|
||||
removeSelectedText();
|
||||
setPosition(qMin(position(), anchor()));
|
||||
} else if (key == 'D') {
|
||||
setAnchor();
|
||||
m_submode = DeleteSubMode;
|
||||
moveDown(qMax(count() - 1, 0));
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
moveToEndOfLine();
|
||||
setDotCommand("D");
|
||||
finishMovement();
|
||||
@@ -1211,11 +1264,11 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
scrollToLineInDocument(cursorLineInDocument() - sline);
|
||||
finishMovement();
|
||||
} else if (key == 'e') { // tested
|
||||
m_moveType = MoveInclusive;
|
||||
m_movetype = MoveInclusive;
|
||||
moveToWordBoundary(false, true);
|
||||
finishMovement();
|
||||
} else if (key == 'E') {
|
||||
m_moveType = MoveInclusive;
|
||||
m_movetype = MoveInclusive;
|
||||
moveToWordBoundary(true, true);
|
||||
finishMovement();
|
||||
} else if (key == control('e')) {
|
||||
@@ -1226,11 +1279,11 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
finishMovement();
|
||||
} else if (key == 'f') {
|
||||
m_subsubmode = FtSubSubMode;
|
||||
m_moveType = MoveInclusive;
|
||||
m_movetype = MoveInclusive;
|
||||
m_subsubdata = key;
|
||||
} else if (key == 'F') {
|
||||
m_subsubmode = FtSubSubMode;
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
m_subsubdata = key;
|
||||
} else if (key == 'g') {
|
||||
if (m_gflag) {
|
||||
@@ -1284,7 +1337,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
|| m_submode == CapitalZSubMode || m_submode == RegisterSubMode) {
|
||||
moveDown(count());
|
||||
} else {
|
||||
m_moveType = MoveLineWise;
|
||||
m_movetype = MoveLineWise;
|
||||
moveToStartOfLine();
|
||||
setAnchor();
|
||||
moveDown(count() + 1);
|
||||
@@ -1310,7 +1363,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
|| m_submode == CapitalZSubMode || m_submode == RegisterSubMode) {
|
||||
moveUp(count());
|
||||
} else {
|
||||
m_moveType = MoveLineWise;
|
||||
m_movetype = MoveLineWise;
|
||||
moveToStartOfLine();
|
||||
moveDown();
|
||||
setAnchor();
|
||||
@@ -1318,7 +1371,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
}
|
||||
finishMovement("k");
|
||||
} else if (key == 'l' || key == Key_Right || key == ' ') {
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
moveRight(qMin(count(), rightDist()));
|
||||
setTargetColumn();
|
||||
finishMovement("l");
|
||||
@@ -1363,29 +1416,8 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
m_jumpListUndo.pop_back();
|
||||
}
|
||||
} else if (key == 'p' || key == 'P') {
|
||||
QString text = m_registers[m_register];
|
||||
int n = text.count(QChar('\n'));
|
||||
//qDebug() << "REGISTERS: " << m_registers << "MOVE: " << m_moveType;
|
||||
//qDebug() << "LINES: " << n << text << m_register;
|
||||
if (n > 0) {
|
||||
moveToStartOfLine();
|
||||
m_targetColumn = 0;
|
||||
for (int i = count(); --i >= 0; ) {
|
||||
if (key == 'p')
|
||||
moveDown();
|
||||
m_tc.insertText(text);
|
||||
moveUp(n);
|
||||
}
|
||||
moveToFirstNonBlankOnLine();
|
||||
} else {
|
||||
m_targetColumn = 0;
|
||||
for (int i = count(); --i >= 0; ) {
|
||||
if (key == 'p')
|
||||
moveRight();
|
||||
m_tc.insertText(text);
|
||||
moveLeft();
|
||||
}
|
||||
}
|
||||
pasteText(key == 'p');
|
||||
setTargetColumn();
|
||||
setDotCommand("%1p", count());
|
||||
finishMovement();
|
||||
} else if (key == 'r') {
|
||||
@@ -1405,17 +1437,18 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
moveLeft();
|
||||
setAnchor();
|
||||
moveRight(qMin(count(), rightDist()));
|
||||
m_registers[m_register] = removeSelectedText();
|
||||
yankSelectedText();
|
||||
removeSelectedText();
|
||||
setDotCommand("s"); // setDotCommand("%1s", count());
|
||||
m_opcount.clear();
|
||||
m_mvcount.clear();
|
||||
enterInsertMode();
|
||||
} else if (key == 't') {
|
||||
m_moveType = MoveInclusive;
|
||||
m_movetype = MoveInclusive;
|
||||
m_subsubmode = FtSubSubMode;
|
||||
m_subsubdata = key;
|
||||
} else if (key == 'T') {
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
m_subsubmode = FtSubSubMode;
|
||||
m_subsubdata = key;
|
||||
} else if (key == 'u') {
|
||||
@@ -1438,25 +1471,25 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
// cursor is on a non-blank.
|
||||
if (m_submode == ChangeSubMode) {
|
||||
moveToWordBoundary(false, true);
|
||||
m_moveType = MoveInclusive;
|
||||
m_movetype = MoveInclusive;
|
||||
} else {
|
||||
moveToNextWord(false);
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
}
|
||||
finishMovement("w");
|
||||
} else if (key == 'W') {
|
||||
if (m_submode == ChangeSubMode) {
|
||||
moveToWordBoundary(true, true);
|
||||
m_moveType = MoveInclusive;
|
||||
m_movetype = MoveInclusive;
|
||||
} else {
|
||||
moveToNextWord(true);
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
}
|
||||
finishMovement("W");
|
||||
} else if (key == control('w')) {
|
||||
m_submode = WindowSubMode;
|
||||
} else if (key == 'x' && m_visualMode == NoVisualMode) { // = "dl"
|
||||
m_moveType = MoveExclusive;
|
||||
m_movetype = MoveExclusive;
|
||||
if (atEndOfLine())
|
||||
moveLeft();
|
||||
setAnchor();
|
||||
@@ -1468,7 +1501,8 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
if (leftDist() > 0) {
|
||||
setAnchor();
|
||||
moveLeft(qMin(count(), leftDist()));
|
||||
m_registers[m_register] = removeSelectedText();
|
||||
yankSelectedText();
|
||||
removeSelectedText();
|
||||
}
|
||||
finishMovement();
|
||||
} else if (key == 'y' && m_visualMode == NoVisualMode) {
|
||||
@@ -1477,30 +1511,36 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
moveLeft();
|
||||
setAnchor();
|
||||
m_submode = YankSubMode;
|
||||
m_rangemode = RangeCharMode;
|
||||
} else if (key == 'y' && m_visualMode == VisualCharMode) {
|
||||
m_registers[m_register] = selectedText(MoveInclusive);
|
||||
Range range(position(), anchor(), RangeCharMode);
|
||||
range.endPos++; // MoveInclusive
|
||||
yankText(range, m_register);
|
||||
setPosition(qMin(position(), anchor()));
|
||||
leaveVisualMode();
|
||||
finishMovement();
|
||||
} else if (key == 'Y' && m_visualMode == NoVisualMode) {
|
||||
const int line = cursorLineInDocument() + 1;
|
||||
selectRange(line, line + count() - 1);
|
||||
m_registers[m_register] = selectedText();
|
||||
m_rangemode = RangeLineMode;
|
||||
yankSelectedText();
|
||||
setPosition(qMin(position(), anchor()));
|
||||
finishMovement();
|
||||
} else if ((key == 'y' && m_visualMode == VisualLineMode)
|
||||
|| (key == 'Y' && m_visualMode == VisualLineMode)
|
||||
|| (key == 'Y' && m_visualMode == VisualCharMode)) {
|
||||
int beginLine = lineForPosition(m_marks['<']);
|
||||
int endLine = lineForPosition(m_marks['>']);
|
||||
selectRange(beginLine, endLine);
|
||||
m_registers[m_register] = selectedText();
|
||||
m_rangemode = RangeLineMode;
|
||||
yankSelectedText();
|
||||
setPosition(qMin(position(), anchor()));
|
||||
moveToStartOfLine();
|
||||
leaveVisualMode();
|
||||
finishMovement();
|
||||
} else if ((key == 'y' || key == 'Y') && m_visualMode == VisualBlockMode) {
|
||||
// not implemented
|
||||
m_rangemode = RangeBlockMode;
|
||||
yankSelectedText();
|
||||
setPosition(qMin(position(), anchor()));
|
||||
leaveVisualMode();
|
||||
finishMovement();
|
||||
} else if (key == 'z') {
|
||||
m_submode = ZSubMode;
|
||||
} else if (key == 'Z') {
|
||||
@@ -1508,7 +1548,8 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
} else if (key == '~' && !atEndOfLine()) {
|
||||
setAnchor();
|
||||
moveRight(qMin(count(), rightDist()));
|
||||
QString str = removeSelectedText();
|
||||
QString str = selectedText();
|
||||
removeSelectedText();
|
||||
for (int i = str.size(); --i >= 0; ) {
|
||||
QChar c = str.at(i);
|
||||
str[i] = c.isUpper() ? c.toLower() : c.toUpper();
|
||||
@@ -1840,9 +1881,13 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
|
||||
} else if (reDelete.indexIn(cmd) != -1) { // :d
|
||||
selectRange(beginLine, endLine);
|
||||
QString reg = reDelete.cap(2);
|
||||
QString text = removeSelectedText();
|
||||
if (!reg.isEmpty())
|
||||
m_registers[reg.at(0).unicode()] = text;
|
||||
QString text = selectedText();
|
||||
removeSelectedText();
|
||||
if (!reg.isEmpty()) {
|
||||
Register &r = m_registers[reg.at(0).unicode()];
|
||||
r.contents = text;
|
||||
r.rangemode = RangeLineMode;
|
||||
}
|
||||
} else if (reWrite.indexIn(cmd) != -1) { // :w and :x
|
||||
bool noArgs = (beginLine == -1);
|
||||
if (beginLine == -1)
|
||||
@@ -1869,8 +1914,9 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
|
||||
} else if (file1.open(QIODevice::ReadWrite)) {
|
||||
file1.close();
|
||||
QTextCursor tc = m_tc;
|
||||
selectRange(beginLine, endLine);
|
||||
QString contents = selectedText();
|
||||
Range range(firstPositionInLine(beginLine),
|
||||
firstPositionInLine(endLine), RangeLineMode);
|
||||
QString contents = text(range);
|
||||
m_tc = tc;
|
||||
qDebug() << "LINES: " << beginLine << endLine;
|
||||
bool handled = false;
|
||||
@@ -1913,7 +1959,8 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
|
||||
} else if (cmd.startsWith(QLatin1Char('!'))) {
|
||||
selectRange(beginLine, endLine);
|
||||
QString command = cmd.mid(1).trimmed();
|
||||
QString text = removeSelectedText();
|
||||
QString text = selectedText();
|
||||
removeSelectedText();
|
||||
QProcess proc;
|
||||
proc.start(cmd.mid(1));
|
||||
proc.waitForStarted();
|
||||
@@ -2203,7 +2250,8 @@ void FakeVimHandler::Private::shiftRegionLeft(int repeat)
|
||||
break;
|
||||
}
|
||||
setPosition(pos + i);
|
||||
text = removeSelectedText();
|
||||
text = selectedText();
|
||||
removeSelectedText();
|
||||
setPosition(pos);
|
||||
}
|
||||
|
||||
@@ -2413,16 +2461,168 @@ QString FakeVimHandler::Private::lastSearchString() const
|
||||
return m_searchHistory.empty() ? QString() : m_searchHistory.back();
|
||||
}
|
||||
|
||||
QString FakeVimHandler::Private::selectedText(MoveType moveType) const
|
||||
QString FakeVimHandler::Private::text(const Range &range) const
|
||||
{
|
||||
if (range.rangemode == RangeCharMode) {
|
||||
QTextCursor tc = m_tc;
|
||||
tc.setPosition(range.beginPos, MoveAnchor);
|
||||
tc.setPosition(range.endPos, KeepAnchor);
|
||||
return tc.selection().toPlainText();
|
||||
}
|
||||
// FIXME: Performance?
|
||||
int beginLine = lineForPosition(range.beginPos);
|
||||
int endLine = lineForPosition(range.endPos);
|
||||
int beginColumn = 0;
|
||||
int endColumn = INT_MAX;
|
||||
if (range.rangemode == RangeBlockMode) {
|
||||
int column1 = range.beginPos - firstPositionInLine(beginLine);
|
||||
int column2 = range.endPos - firstPositionInLine(endLine);
|
||||
beginColumn = qMin(column1, column2);
|
||||
endColumn = qMax(column1, column2);
|
||||
qDebug() << "COLS: " << beginColumn << endColumn;
|
||||
}
|
||||
int len = endColumn - beginColumn + 1;
|
||||
QString contents;
|
||||
QTextBlock block = m_tc.document()->findBlockByNumber(beginLine - 1);
|
||||
for (int i = beginLine; i <= endLine && block.isValid(); ++i) {
|
||||
QString line = block.text();
|
||||
if (range.rangemode == RangeBlockMode) {
|
||||
line = line.mid(beginColumn, len);
|
||||
if (line.size() < len)
|
||||
line += QString(len - line.size(), QChar(' '));
|
||||
}
|
||||
contents += line;
|
||||
if (!contents.endsWith('\n'))
|
||||
contents += '\n';
|
||||
block = block.next();
|
||||
}
|
||||
//qDebug() << "SELECTED: " << contents;
|
||||
return contents;
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::yankSelectedText()
|
||||
{
|
||||
Range range(anchor(), position());
|
||||
range.rangemode = m_rangemode;
|
||||
yankText(range, m_register);
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::yankText(const Range &range, int toregister)
|
||||
{
|
||||
Register ® = m_registers[toregister];
|
||||
reg.contents = text(range);
|
||||
reg.rangemode = range.rangemode;
|
||||
//qDebug() << "YANKED: " << reg.contents;
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::removeSelectedText()
|
||||
{
|
||||
Range range(anchor(), position());
|
||||
range.rangemode = m_rangemode;
|
||||
removeText(range);
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::removeText(const Range &range)
|
||||
{
|
||||
int beginPos = qMin(position(), anchor());
|
||||
int endPos = qMax(position(), anchor());
|
||||
if (moveType == MoveInclusive)
|
||||
++endPos;
|
||||
QTextCursor tc = m_tc;
|
||||
tc.setPosition(beginPos, MoveAnchor);
|
||||
tc.setPosition(endPos, KeepAnchor);
|
||||
return tc.selection().toPlainText();
|
||||
switch (range.rangemode) {
|
||||
case RangeCharMode: {
|
||||
tc.setPosition(range.beginPos, MoveAnchor);
|
||||
tc.setPosition(range.endPos, KeepAnchor);
|
||||
tc.removeSelectedText();
|
||||
return;
|
||||
}
|
||||
case RangeLineMode: {
|
||||
tc.setPosition(range.beginPos, MoveAnchor);
|
||||
tc.movePosition(StartOfLine, MoveAnchor);
|
||||
tc.setPosition(range.endPos, KeepAnchor);
|
||||
tc.movePosition(EndOfLine, KeepAnchor);
|
||||
tc.movePosition(Right, KeepAnchor, 1);
|
||||
tc.removeSelectedText();
|
||||
return;
|
||||
}
|
||||
case RangeBlockMode: {
|
||||
int beginLine = lineForPosition(range.beginPos);
|
||||
int endLine = lineForPosition(range.endPos);
|
||||
int column1 = range.beginPos - firstPositionInLine(beginLine);
|
||||
int column2 = range.endPos - firstPositionInLine(endLine);
|
||||
int beginColumn = qMin(column1, column2);
|
||||
int endColumn = qMax(column1, column2);
|
||||
qDebug() << "COLS: " << beginColumn << endColumn;
|
||||
|
||||
QTextBlock block = m_tc.document()->findBlockByNumber(endLine - 1);
|
||||
beginEditBlock();
|
||||
for (int i = beginLine; i <= endLine && block.isValid(); ++i) {
|
||||
int bCol = qMin(beginColumn, block.length() - 1);
|
||||
int eCol = qMin(endColumn, block.length() - 1);
|
||||
tc.setPosition(block.position() + bCol, MoveAnchor);
|
||||
tc.setPosition(block.position() + eCol, KeepAnchor);
|
||||
tc.removeSelectedText();
|
||||
block = block.previous();
|
||||
}
|
||||
endEditBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::pasteText(bool afterCursor)
|
||||
{
|
||||
const QString text = m_registers[m_register].contents;
|
||||
const QStringList lines = text.split(QChar('\n'));
|
||||
switch (m_registers[m_register].rangemode) {
|
||||
case RangeCharMode: {
|
||||
m_targetColumn = 0;
|
||||
for (int i = count(); --i >= 0; ) {
|
||||
if (afterCursor && rightDist() > 0)
|
||||
moveRight();
|
||||
m_tc.insertText(text);
|
||||
moveLeft();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RangeLineMode: {
|
||||
moveToStartOfLine();
|
||||
m_targetColumn = 0;
|
||||
for (int i = count(); --i >= 0; ) {
|
||||
if (afterCursor)
|
||||
moveDown();
|
||||
m_tc.insertText(text);
|
||||
moveUp(lines.size() - 1);
|
||||
}
|
||||
moveToFirstNonBlankOnLine();
|
||||
break;
|
||||
}
|
||||
case RangeBlockMode: {
|
||||
beginEditBlock();
|
||||
QTextBlock block = m_tc.block();
|
||||
moveRight();
|
||||
QTextCursor tc = m_tc;
|
||||
const int col = tc.position() - block.position();
|
||||
//for (int i = lines.size(); --i >= 0; ) {
|
||||
for (int i = 0; i < lines.size(); ++i) {
|
||||
const QString line = lines.at(i);
|
||||
tc.movePosition(StartOfLine, MoveAnchor);
|
||||
if (col >= block.length()) {
|
||||
tc.movePosition(EndOfLine, MoveAnchor);
|
||||
tc.insertText(QString(col - line.size() + 1, QChar(' ')));
|
||||
} else {
|
||||
tc.movePosition(Right, MoveAnchor, col);
|
||||
}
|
||||
qDebug() << "INSERT " << line << " AT " << tc.position()
|
||||
<< "COL: " << col;
|
||||
tc.insertText(line);
|
||||
tc.movePosition(StartOfLine, MoveAnchor);
|
||||
tc.movePosition(Down, MoveAnchor, 1);
|
||||
if (tc.position() >= lastPositionInDocument() - 1) {
|
||||
tc.insertText(QString(QChar('\n')));
|
||||
tc.movePosition(Up, MoveAnchor, 1);
|
||||
}
|
||||
block = block.next();
|
||||
}
|
||||
endEditBlock();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int FakeVimHandler::Private::firstPositionInLine(int line) const
|
||||
@@ -2497,20 +2697,6 @@ void FakeVimHandler::Private::redo()
|
||||
m_tc.setPosition(m_undoCursorPosition[rev]);
|
||||
}
|
||||
|
||||
QString FakeVimHandler::Private::removeSelectedText()
|
||||
{
|
||||
//qDebug() << "POS: " << position() << " ANCHOR: " << anchor() << m_tc.anchor();
|
||||
int pos = m_tc.position();
|
||||
if (pos == anchor())
|
||||
return QString();
|
||||
m_tc.setPosition(anchor(), MoveAnchor);
|
||||
m_tc.setPosition(pos, KeepAnchor);
|
||||
QString from = m_tc.selection().toPlainText();
|
||||
m_tc.removeSelectedText();
|
||||
setAnchor();
|
||||
return from;
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::enterInsertMode()
|
||||
{
|
||||
EDITOR(setCursorWidth(m_cursorWidth));
|
||||
|
@@ -108,8 +108,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
QObject::connect(&handler, SIGNAL(commandBufferChanged(QString)),
|
||||
&proxy, SLOT(changeStatusMessage(QString)));
|
||||
QObject::connect(&handler, SIGNAL(quitRequested(bool)),
|
||||
&app, SLOT(quit()));
|
||||
//QObject::connect(&handler, SIGNAL(quitRequested(bool)),
|
||||
// &app, SLOT(quit()));
|
||||
QObject::connect(&handler,
|
||||
SIGNAL(selectionChanged(QList<QTextEdit::ExtraSelection>)),
|
||||
&proxy, SLOT(changeSelection(QList<QTextEdit::ExtraSelection>)));
|
||||
|
Reference in New Issue
Block a user