From bf3c4a15626ae50ea9258f505ef2b356a242f2bb Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Mon, 9 Feb 2009 08:45:02 +0100 Subject: [PATCH 01/11] fakevim: use QTextDocument's undo/redo operations this has several advantages compared to an undo/redo stack private to fakevim: - change marks in document correspond to actual changes - mouse pasting does not invalidate the fakevim undo/redo stack - menu commands (such as undo/redo from the Edit menu) do not invalidate the fakevim undo/redo stack - possible other changes not caused by fakevim do not invalidate fakevim undo/redo stack it is pretty bad if the fakevim undo/redo stack becomes invalid, as applying these invalid undo/redo operations corrupts the document --- src/plugins/fakevim/fakevimhandler.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 11b4cc86cc3..52b8ffd4d33 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -312,6 +312,7 @@ public: QStack m_undoStack; QStack m_redoStack; QStack m_undoGroupStack; + QMap m_undoCursorPosition; // extra data for '.' QString m_dotCommand; @@ -416,7 +417,14 @@ bool FakeVimHandler::Private::handleEvent(QKeyEvent *ev) && (ev->modifiers() & Qt::ShiftModifier) == 0) { key += 32; } + + m_undoCursorPosition[EDITOR(document())->revision()] = m_tc.position(); + if (m_mode == InsertMode) + m_tc.joinPreviousEditBlock(); + else + m_tc.beginEditBlock(); bool handled = handleKey(key, um, ev->text()); + m_tc.endEditBlock(); // We fake vi-style end-of-line behaviour m_fakeEnd = (atEndOfLine() && m_mode == CommandMode); @@ -2012,6 +2020,11 @@ QWidget *FakeVimHandler::Private::editor() const void FakeVimHandler::Private::undo() { + EDITOR(undo()); + int rev = EDITOR(document())->revision(); + if (m_undoCursorPosition.contains(rev)) + m_tc.setPosition(m_undoCursorPosition[rev]); +#if 0 if (m_undoStack.isEmpty()) { showBlackMessage(tr("Already at oldest change")); } else { @@ -2033,10 +2046,22 @@ void FakeVimHandler::Private::undo() m_redoStack.push(op); showBlackMessage(QString()); } +#endif } void FakeVimHandler::Private::redo() { + int current = EDITOR(document())->revision(); + EDITOR(redo()); + int rev = EDITOR(document())->revision(); + if (rev == current) { + showBlackMessage(tr("Already at newest change")); + } else { + showBlackMessage(QString()); + if (m_undoCursorPosition.contains(rev)) + m_tc.setPosition(m_undoCursorPosition[rev]); + } +#if 0 if (m_redoStack.isEmpty()) { showBlackMessage(tr("Already at newest change")); } else { @@ -2058,6 +2083,7 @@ void FakeVimHandler::Private::redo() m_undoStack.push(op); showBlackMessage(QString()); } +#endif } void FakeVimHandler::Private::recordBeginGroup() From 5dc2f8ed0a3ca9240f266742b3fecf1f2220872c Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Mon, 16 Feb 2009 02:13:33 +0100 Subject: [PATCH 02/11] fakevim: d$ and D would delete newline --- src/plugins/fakevim/fakevimhandler.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 52b8ffd4d33..b3aaea7cd2a 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -872,6 +872,7 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, } else if (key == '$' || key == Key_End) { int submode = m_submode; moveToEndOfLine(); + m_moveType = MoveExclusive; finishMovement(); if (submode == NoSubMode) m_desiredColumn = -1; @@ -939,7 +940,8 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, recordBeginGroup(); m_submode = DeleteSubMode; moveDown(qMax(count() - 1, 0)); - moveRight(rightDist()); + m_moveType = MoveExclusive; + moveToEndOfLine(); finishMovement(); } else if (key == control('d')) { int sline = cursorLineOnScreen(); From d5f3c585ba8b3ecc79b6ee710b3aa8a9a093f27d Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Mon, 16 Feb 2009 22:43:19 +0100 Subject: [PATCH 03/11] fakevim: also repeat insertion with '.' --- src/plugins/fakevim/fakevimhandler.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index b3aaea7cd2a..a14072374be 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -882,9 +882,13 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, updateMiniBuffer(); } else if (key == '.') { qDebug() << "REPEATING" << m_dotCommand; + QString savedCommand = m_dotCommand; + m_dotCommand.clear(); for (int i = count(); --i >= 0; ) - foreach (QChar c, m_dotCommand) + foreach (QChar c, savedCommand) handleKey(c.unicode(), c.unicode(), QString(c)); + enterCommandMode(); + m_dotCommand = savedCommand; } else if (key == '=') { m_submode = IndentSubMode; } else if (key == '%') { @@ -1269,6 +1273,7 @@ bool FakeVimHandler::Private::handleInsertMode(int key, int, const QString &text recordEndGroup(); //qDebug() << "UNDO: " << m_undoStack; moveLeft(qMin(1, leftDist())); + m_dotCommand += m_lastInsertion; enterCommandMode(); } else if (key == Key_Left) { moveLeft(count()); From bd29664c8c714c71d545aaa2c387190599f484a1 Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Mon, 16 Feb 2009 22:44:27 +0100 Subject: [PATCH 04/11] fakevim: make 'c$' repeatable with '.' --- src/plugins/fakevim/fakevimhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index a14072374be..a8b484cc557 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -873,7 +873,7 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, int submode = m_submode; moveToEndOfLine(); m_moveType = MoveExclusive; - finishMovement(); + finishMovement("$"); if (submode == NoSubMode) m_desiredColumn = -1; } else if (key == ',') { From 5f5dfaaae88f3e32514b9fee8eddaec5cdaf0b72 Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Mon, 16 Feb 2009 22:45:40 +0100 Subject: [PATCH 05/11] fakevim: remove dead code --- src/plugins/fakevim/fakevimhandler.cpp | 73 -------------------------- 1 file changed, 73 deletions(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index a8b484cc557..a4bf23d1a15 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -1717,23 +1717,6 @@ void FakeVimHandler::Private::moveToFirstNonBlankOnLine() int FakeVimHandler::Private::indentDist() const { -#if 0 - // FIXME: Make independent of TextEditor - if (!m_texteditor) - return 0; - - TextEditor::TabSettings ts = m_texteditor->tabSettings(); - typedef SharedTools::Indenter Indenter; - Indenter &indenter = Indenter::instance(); - indenter.setIndentSize(ts.m_indentSize); - indenter.setTabSize(ts.m_tabSize); - - QTextDocument *doc = EDITOR(document()); - const TextEditor::TextBlockIterator current(m_tc.block()); - const TextEditor::TextBlockIterator begin(doc->begin()); - const TextEditor::TextBlockIterator end(m_tc.block().next()); - return indenter.indentForBottomLine(current, begin, end, QChar(' ')); -#endif int amount = 0; emit q->indentRegion(&amount, m_tc.block(), m_tc.block(), QChar(' ')); return amount; @@ -1743,33 +1726,6 @@ void FakeVimHandler::Private::indentRegion(QTextBlock begin, QTextBlock end, QCh { int amount = 0; emit q->indentRegion(&amount, begin, end, typedChar); -#if 0 - // FIXME: Make independent of TextEditor - if (!m_texteditor) - return 0; - typedef SharedTools::Indenter Indenter; - Indenter &indenter = Indenter::instance(); - indenter.setIndentSize(m_config[ConfigShiftWidth].toInt()); - indenter.setTabSize(m_config[ConfigTabStop].toInt()); - - QTextDocument *doc = EDITOR(document()); - const TextEditor::TextBlockIterator docStart(doc->begin()); - for(QTextBlock cur = begin; cur != end; cur = cur.next()) { - if (typedChar != 0 && cur.text().simplified().isEmpty()) { - m_tc.setPosition(cur.position(), KeepAnchor); - while (!m_tc.atBlockEnd()) - m_tc.deleteChar(); - } else { - const TextEditor::TextBlockIterator current(cur); - const TextEditor::TextBlockIterator next(cur.next()); - const int indent = indenter.indentForBottomLine(current, docStart, next, typedChar); - ts.indentLine(cur, indent); - } - } -#endif - Q_UNUSED(begin); - Q_UNUSED(end); - Q_UNUSED(typedChar); } void FakeVimHandler::Private::indentCurrentLine(QChar typedChar) @@ -1887,35 +1843,6 @@ void FakeVimHandler::Private::moveToMatchingParanthesis() if (m_submode == NoSubMode || m_submode == ZSubMode || m_submode == RegisterSubMode) m_tc.movePosition(Left, KeepAnchor, 1); } - -#if 0 - // FIXME: remove TextEditor dependency - bool undoFakeEOL = false; - if (atEndOfLine()) { - m_tc.movePosition(Left, KeepAnchor, 1); - undoFakeEOL = true; - } - TextEditor::TextBlockUserData::MatchType match - = TextEditor::TextBlockUserData::matchCursorForward(&m_tc); - if (match == TextEditor::TextBlockUserData::Match) { - if (m_submode == NoSubMode || m_submode == ZSubMode || m_submode == RegisterSubMode) - m_tc.movePosition(Left, KeepAnchor, 1); - } else { - if (undoFakeEOL) - m_tc.movePosition(Right, KeepAnchor, 1); - if (match == TextEditor::TextBlockUserData::NoMatch) { - // backward matching is according to the character before the cursor - bool undoMove = false; - if (!m_tc.atBlockEnd()) { - m_tc.movePosition(Right, KeepAnchor, 1); - undoMove = true; - } - match = TextEditor::TextBlockUserData::matchCursorBackward(&m_tc); - if (match != TextEditor::TextBlockUserData::Match && undoMove) - m_tc.movePosition(Left, KeepAnchor, 1); - } - } -#endif } int FakeVimHandler::Private::cursorLineOnScreen() const From 694f34a4f1237d86eaffdcc7d3a4dc1e97ca103e Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Mon, 16 Feb 2009 22:58:31 +0100 Subject: [PATCH 06/11] fakevim: indent correctly after return key --- src/plugins/fakevim/fakevimhandler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index a4bf23d1a15..4ed45053990 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -1293,7 +1293,8 @@ bool FakeVimHandler::Private::handleInsertMode(int key, int, const QString &text m_submode = NoSubMode; m_tc.insertBlock(); m_lastInsertion += "\n"; - indentRegion(m_tc.block(), m_tc.block().next()); + if(m_config[ConfigAutoIndent] == ConfigOn) + indentRegion(m_tc.block(), m_tc.block().next(), '\n'); } else if (key == Key_Backspace || key == control('h')) { m_tc.deletePreviousChar(); m_lastInsertion = m_lastInsertion.left(m_lastInsertion.size() - 1); From cc850f6f5b84225a222f5acd61a365cf9d00e80b Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Mon, 16 Feb 2009 23:29:07 +0100 Subject: [PATCH 07/11] fakevim: let Esc correctly cancel not yet complete commands --- src/plugins/fakevim/fakevimhandler.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 4ed45053990..b4f74a5be58 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -1246,10 +1246,15 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, moveRight(qMin(1, rightDist())); recordRemoveSelectedText(); } else if (key == Key_Escape) { - if (m_visualMode != NoVisualMode) + if (m_visualMode != NoVisualMode) { leaveVisualMode(); - else + } else if (m_submode != NoSubMode) { + m_submode = NoSubMode; + m_subsubmode = NoSubSubMode; + finishMovement(); + } else { handled = false; + } } else { qDebug() << "IGNORED IN COMMAND MODE: " << key << text; if (text.isEmpty()) From b1e73ff272c8aa629e7d9dab23f0b22793eac41c Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Mon, 16 Feb 2009 23:39:39 +0100 Subject: [PATCH 08/11] fakevim: 'I' would replace text between current position and first non-blank on line --- src/plugins/fakevim/fakevimhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index b4f74a5be58..1d9dd4faaae 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -1001,12 +1001,12 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, moveLeft(); } else if (key == 'I') { recordBeginGroup(); - setAnchor(); enterInsertMode(); if (m_gflag) moveToStartOfLine(); else moveToFirstNonBlankOnLine(); + m_tc.clearSelection(); } else if (key == control('i')) { if (!m_jumpListRedo.isEmpty()) { m_jumpListUndo.append(position()); From d8e675db9ad5f690235c393f2058114d99537c8f Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Tue, 17 Feb 2009 00:48:15 +0100 Subject: [PATCH 09/11] fakevim: fix backward deletion/change --- src/plugins/fakevim/fakevimhandler.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 1d9dd4faaae..fab1902f25e 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -528,6 +528,8 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) if (m_submode == ChangeSubMode) { if (m_moveType == MoveInclusive) moveRight(); // correction + if (anchor() >= position()) + m_anchor++; if (!dotCommand.isEmpty()) m_dotCommand = "c" + dotCommand; QString text = recordRemoveSelectedText(); @@ -538,6 +540,8 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) } else if (m_submode == DeleteSubMode) { if (m_moveType == MoveInclusive) moveRight(); // correction + if (anchor() >= position()) + m_anchor++; if (!dotCommand.isEmpty()) m_dotCommand = "d" + dotCommand; m_registers[m_register] = recordRemoveSelectedText(); @@ -892,6 +896,7 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, } else if (key == '=') { m_submode = IndentSubMode; } else if (key == '%') { + m_moveType = MoveExclusive; moveToMatchingParanthesis(); finishMovement(); } else if (key == 'a') { From 6b782811934f3e15f521e40c042e748115126561 Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Tue, 17 Feb 2009 00:50:05 +0100 Subject: [PATCH 10/11] fakevim: fix repetition for dh/j/k/l --- src/plugins/fakevim/fakevimhandler.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index fab1902f25e..5dc0eefcf0a 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -992,7 +992,7 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, if (m_fakeEnd && m_tc.block().length() > 1) ++n; moveLeft(n); - finishMovement(); + finishMovement("h"); } else if (key == 'H') { m_tc = EDITOR(cursorForPosition(QPoint(0, 0))); moveDown(qMax(count() - 1, 0)); @@ -1029,7 +1029,7 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, setAnchor(); moveDown(count() + 1); } - finishMovement(); + finishMovement("j"); m_desiredColumn = savedColumn; } else if (key == 'J') { recordBeginGroup(); @@ -1057,12 +1057,12 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, setAnchor(); moveUp(count() + 1); } - finishMovement(); + finishMovement("k"); m_desiredColumn = savedColumn; } else if (key == 'l' || key == Key_Right || key == ' ') { m_moveType = MoveExclusive; moveRight(qMin(count(), rightDist())); - finishMovement(); + finishMovement("l"); } else if (key == 'L') { m_tc = EDITOR(cursorForPosition(QPoint(0, EDITOR(height())))); moveUp(qMax(count(), 1)); From 81a4518127d623f441e6a21238e9beea9d8ec725 Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Fri, 13 Feb 2009 19:51:36 +0100 Subject: [PATCH 11/11] Revert "Fixes: Workaround a bug in kde 4.2.0." This reverts commit e08f1763b7534173fcb540c6ac981aae74d902c6. --- src/plugins/designer/formeditorplugin.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/plugins/designer/formeditorplugin.cpp b/src/plugins/designer/formeditorplugin.cpp index 862b29cb46e..823efb590d1 100644 --- a/src/plugins/designer/formeditorplugin.cpp +++ b/src/plugins/designer/formeditorplugin.cpp @@ -108,11 +108,7 @@ bool FormEditorPlugin::initialize(const QStringList &arguments, QString *error) addObject(m_factory); // Make sure settings pages and action shortcuts are registered - // TODO we don't want to do a full initialization here, - // we actually want to call ensureInitStage(FormEditorW::RegisterPlugins) - // But due to a bug in kde 4.2.0 this crashes then when opening the file dialog - // This should be removed after 4.2.1 is out - FormEditorW::ensureInitStage(FormEditorW::FullyInitialized); + FormEditorW::ensureInitStage(FormEditorW::RegisterPlugins); error->clear(); return true;