diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 34c0080ca099c8140debccff7138c663da17f3d4..70d96bd1df06090a1659f82a03507e92bb88525d 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -260,7 +260,6 @@ public: // helper functions for indenting bool isElectricCharacter(QChar c) const { return c == '{' || c == '}' || c == '#'; } - int indentDist() const; void indentRegion(QChar lastTyped = QChar()); void shiftRegionLeft(int repeat = 1); void shiftRegionRight(int repeat = 1); @@ -386,6 +385,12 @@ public: int m_cursorWidth; + // auto-indent + void insertAutomaticIndentation(bool goingDown); + bool removeAutomaticIndentation(); // true if something removed + // number of autoindented characters + int m_justAutoIndented; + void recordJump(); void recordNewUndo(); QList<int> m_jumpListUndo; @@ -419,7 +424,7 @@ FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget) m_savedYankPosition = 0; m_cursorWidth = EDITOR(cursorWidth()); m_inReplay = false; - + m_justAutoIndented = 0; } bool FakeVimHandler::Private::wantsOverride(QKeyEvent *ev) @@ -492,7 +497,7 @@ EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev) key += 32; } - m_undoCursorPosition[EDITOR(document())->revision()] = m_tc.position(); + m_undoCursorPosition[m_tc.document()->revision()] = m_tc.position(); if (m_mode == InsertMode) m_tc.joinPreviousEditBlock(); else @@ -1218,16 +1223,11 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, m_dotCommand = QString("%1o").arg(count()); enterInsertMode(); moveToFirstNonBlankOnLine(); - int numSpaces = leftDist(); if (key == 'O') moveUp(); moveToEndOfLine(); m_tc.insertText("\n"); - moveToStartOfLine(); - if (0 && hasConfig(ConfigAutoIndent)) - m_tc.insertText(QString(indentDist(), ' ')); - else - m_tc.insertText(QString(numSpaces, ' ')); + insertAutomaticIndentation(key == 'o'); } else if (key == control('o')) { if (!m_jumpListUndo.isEmpty()) { m_jumpListRedo.append(position()); @@ -1423,10 +1423,12 @@ EventResult FakeVimHandler::Private::handleInsertMode(int key, int, moveLeft(count()); m_lastInsertion.clear(); } else if (key == Key_Down) { + removeAutomaticIndentation(); m_submode = NoSubMode; moveDown(count()); m_lastInsertion.clear(); } else if (key == Key_Up) { + removeAutomaticIndentation(); m_submode = NoSubMode; moveUp(count()); m_lastInsertion.clear(); @@ -1437,20 +1439,22 @@ EventResult FakeVimHandler::Private::handleInsertMode(int key, int, m_submode = NoSubMode; m_tc.insertBlock(); m_lastInsertion += "\n"; - if (0 && hasConfig(ConfigAutoIndent)) - indentRegion('\n'); + insertAutomaticIndentation(true); } else if (key == Key_Backspace || key == control('h')) { - if (!m_lastInsertion.isEmpty() || hasConfig(ConfigBackspace, "start")) { - m_tc.deletePreviousChar(); - m_lastInsertion = m_lastInsertion.left(m_lastInsertion.size() - 1); - } + if (!removeAutomaticIndentation()) + if (!m_lastInsertion.isEmpty() || hasConfig(ConfigBackspace, "start")) { + m_tc.deletePreviousChar(); + m_lastInsertion.chop(1); + } } else if (key == Key_Delete) { m_tc.deleteChar(); m_lastInsertion.clear(); } else if (key == Key_PageDown || key == control('f')) { + removeAutomaticIndentation(); moveDown(count() * (linesOnScreen() - 2)); m_lastInsertion.clear(); } else if (key == Key_PageUp || key == control('b')) { + removeAutomaticIndentation(); moveUp(count() * (linesOnScreen() - 2)); m_lastInsertion.clear(); } else if (key == Key_Tab && hasConfig(ConfigExpandTab)) { @@ -1914,14 +1918,6 @@ void FakeVimHandler::Private::moveToFirstNonBlankOnLine() } } -int FakeVimHandler::Private::indentDist() const -{ - int amount = 0; - int line = cursorLineInDocument(); - emit q->indentRegion(&amount, line, line, QChar(' ')); - return amount; -} - void FakeVimHandler::Private::indentRegion(QChar typedChar) { //int savedPos = anchor(); @@ -2153,7 +2149,7 @@ void FakeVimHandler::Private::scrollUp(int count) int FakeVimHandler::Private::lastPositionInDocument() const { - QTextBlock block = m_tc.block().document()->lastBlock(); + QTextBlock block = m_tc.document()->lastBlock(); return block.position() + block.length(); } @@ -2171,12 +2167,12 @@ QString FakeVimHandler::Private::selectedText() const int FakeVimHandler::Private::firstPositionInLine(int line) const { - return m_tc.block().document()->findBlockByNumber(line - 1).position(); + return m_tc.document()->findBlockByNumber(line - 1).position(); } int FakeVimHandler::Private::lastPositionInLine(int line) const { - QTextBlock block = m_tc.block().document()->findBlockByNumber(line - 1); + QTextBlock block = m_tc.document()->findBlockByNumber(line - 1); return block.position() + block.length() - 1; } @@ -2213,14 +2209,14 @@ QWidget *FakeVimHandler::Private::editor() const void FakeVimHandler::Private::undo() { - int current = EDITOR(document())->revision(); + int current = m_tc.document()->revision(); m_tc.endEditBlock(); m_needMoreUndo = false; EDITOR(undo()); if (m_needMoreUndo) EDITOR(undo()); m_tc.beginEditBlock(); - int rev = EDITOR(document())->revision(); + int rev = m_tc.document()->revision(); if (current == rev) showBlackMessage(tr("Already at oldest change")); else @@ -2231,14 +2227,14 @@ void FakeVimHandler::Private::undo() void FakeVimHandler::Private::redo() { - int current = EDITOR(document())->revision(); + int current = m_tc.document()->revision(); m_tc.endEditBlock(); m_needMoreUndo = false; EDITOR(redo()); if (m_needMoreUndo) EDITOR(redo()); m_tc.beginEditBlock(); - int rev = EDITOR(document())->revision(); + int rev = m_tc.document()->revision(); if (rev == current) showBlackMessage(tr("Already at newest change")); else @@ -2304,6 +2300,32 @@ void FakeVimHandler::Private::recordNewUndo() m_tc.beginEditBlock(); } +void FakeVimHandler::Private::insertAutomaticIndentation(bool goingDown) +{ + if (!hasConfig(ConfigAutoIndent)) + return; + QTextBlock block = goingDown ? m_tc.block().previous() : m_tc.block().next(); + QString text = block.text(); + int pos = 0, n = text.size(); + while (pos < n && text.at(pos).isSpace()) + ++pos; + text.truncate(pos); + // FIXME: handle 'smartindent' and 'cindent' + m_tc.insertText(text); + m_justAutoIndented = text.size(); +} + +bool FakeVimHandler::Private::removeAutomaticIndentation() +{ + if (!hasConfig(ConfigAutoIndent) || m_justAutoIndented == 0) + return false; + m_tc.movePosition(StartOfLine, KeepAnchor); + m_tc.removeSelectedText(); + m_lastInsertion.chop(m_justAutoIndented); + m_justAutoIndented = 0; + return true; +} + /////////////////////////////////////////////////////////////////////// // diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp index 666d4c9a7085d25dc82e401edf2319beb71d6c7a..9ff77312df2dd29bb552d4dcb70812147c50d45e 100644 --- a/tests/manual/gdbdebugger/simple/app.cpp +++ b/tests/manual/gdbdebugger/simple/app.cpp @@ -135,6 +135,14 @@ void testQByteArray() QByteArray ba = "Hello"; ba += '"'; ba += "World"; + + const char *str1 = "\356"; + const char *str2 = "\xee"; + const char *str3 = "\\ee"; + QByteArray buf1( str1 ); + QByteArray buf2( str2 ); + QByteArray buf3( str3 ); + ba += char(0); ba += 1; ba += 2;