forked from qt-creator/qt-creator
FakeVim: Update internal cursor if it changes externally
Change-Id: I8c335e5a79699d9ae1eefdb2cd60840eea1bb300 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -1827,8 +1827,6 @@ public:
|
|||||||
void movePageUp(int count = 1) { movePageDown(-count); }
|
void movePageUp(int count = 1) { movePageDown(-count); }
|
||||||
void dump(const char *msg) const {
|
void dump(const char *msg) const {
|
||||||
qDebug() << msg << "POS: " << anchor() << position()
|
qDebug() << msg << "POS: " << anchor() << position()
|
||||||
<< "EXT: " << m_oldExternalAnchor << m_oldExternalPosition
|
|
||||||
<< "INT: " << m_oldInternalAnchor << m_oldInternalPosition
|
|
||||||
<< "VISUAL: " << g.visualMode;
|
<< "VISUAL: " << g.visualMode;
|
||||||
}
|
}
|
||||||
void moveRight(int n = 1) {
|
void moveRight(int n = 1) {
|
||||||
@@ -1871,31 +1869,19 @@ public:
|
|||||||
m_cursor.setPosition(anchor, MoveAnchor);
|
m_cursor.setPosition(anchor, MoveAnchor);
|
||||||
m_cursor.setPosition(position, KeepAnchor);
|
m_cursor.setPosition(position, KeepAnchor);
|
||||||
}
|
}
|
||||||
// Set cursor in text editor widget.
|
|
||||||
void commitCursor() {
|
|
||||||
if (isVisualBlockMode()) {
|
|
||||||
emit q->requestSetBlockSelection(m_cursor);
|
|
||||||
} else {
|
|
||||||
emit q->requestDisableBlockSelection();
|
|
||||||
if (editor())
|
|
||||||
EDITOR(setTextCursor(m_cursor));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Restore cursor from editor widget.
|
|
||||||
void pullCursor() {
|
|
||||||
if (isVisualBlockMode())
|
|
||||||
q->requestBlockSelection(&m_cursor);
|
|
||||||
else if (editor())
|
|
||||||
m_cursor = EDITOR(textCursor());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Set cursor in text editor widget.
|
||||||
|
void commitCursor();
|
||||||
|
|
||||||
|
// Restore cursor from editor widget.
|
||||||
// Update selection, record jump and target column if cursor position
|
// Update selection, record jump and target column if cursor position
|
||||||
// changes externally (e.g. by code completion).
|
// changes externally (e.g. by code completion).
|
||||||
void updateCursorPosition();
|
void pullCursor();
|
||||||
|
|
||||||
// Values to save when starting FakeVim processing.
|
// Values to save when starting FakeVim processing.
|
||||||
int m_firstVisibleLine;
|
int m_firstVisibleLine;
|
||||||
QTextCursor m_cursor;
|
QTextCursor m_cursor;
|
||||||
|
bool m_cursorNeedsUpdate;
|
||||||
|
|
||||||
bool moveToPreviousParagraph(int count) { return moveToNextParagraph(-count); }
|
bool moveToPreviousParagraph(int count) { return moveToNextParagraph(-count); }
|
||||||
bool moveToNextParagraph(int count);
|
bool moveToNextParagraph(int count);
|
||||||
@@ -1927,6 +1913,7 @@ public:
|
|||||||
void breakEditBlock() { m_buffer->breakEditBlock = true; }
|
void breakEditBlock() { m_buffer->breakEditBlock = true; }
|
||||||
|
|
||||||
Q_SLOT void onContentsChanged(int position, int charsRemoved, int charsAdded);
|
Q_SLOT void onContentsChanged(int position, int charsRemoved, int charsAdded);
|
||||||
|
Q_SLOT void onCursorPositionChanged();
|
||||||
Q_SLOT void onUndoCommandAdded();
|
Q_SLOT void onUndoCommandAdded();
|
||||||
|
|
||||||
bool isCommandLineMode() const { return g.mode == ExMode || g.subsubmode == SearchSubSubMode; }
|
bool isCommandLineMode() const { return g.mode == ExMode || g.subsubmode == SearchSubSubMode; }
|
||||||
@@ -1962,8 +1949,6 @@ public:
|
|||||||
bool selectBlockTextObject(bool inner, char left, char right);
|
bool selectBlockTextObject(bool inner, char left, char right);
|
||||||
bool selectQuotedStringTextObject(bool inner, const QString "e);
|
bool selectQuotedStringTextObject(bool inner, const QString "e);
|
||||||
|
|
||||||
Q_SLOT void importSelection();
|
|
||||||
void exportSelection();
|
|
||||||
void commitInsertState();
|
void commitInsertState();
|
||||||
void invalidateInsertState();
|
void invalidateInsertState();
|
||||||
bool isInsertStateValid() const;
|
bool isInsertStateValid() const;
|
||||||
@@ -1988,10 +1973,6 @@ public:
|
|||||||
bool m_inFakeVim; // true if currently processing a key press or a command
|
bool m_inFakeVim; // true if currently processing a key press or a command
|
||||||
|
|
||||||
FakeVimHandler *q;
|
FakeVimHandler *q;
|
||||||
int m_oldExternalPosition; // copy from last event to check for external changes
|
|
||||||
int m_oldExternalAnchor;
|
|
||||||
int m_oldInternalPosition; // copy from last event to check for external changes
|
|
||||||
int m_oldInternalAnchor;
|
|
||||||
int m_register;
|
int m_register;
|
||||||
BlockInsertMode m_visualBlockInsert;
|
BlockInsertMode m_visualBlockInsert;
|
||||||
|
|
||||||
@@ -2051,7 +2032,7 @@ public:
|
|||||||
void insertNewLine();
|
void insertNewLine();
|
||||||
|
|
||||||
bool handleInsertInEditor(const Input &input);
|
bool handleInsertInEditor(const Input &input);
|
||||||
bool passEventToEditor(QEvent &event); // Pass event to editor widget without filtering. Returns true if event was processed.
|
bool passEventToEditor(QEvent &event, QTextCursor &tc); // Pass event to editor widget without filtering. Returns true if event was processed.
|
||||||
|
|
||||||
// undo handling
|
// undo handling
|
||||||
int revision() const { return document()->availableUndoSteps(); }
|
int revision() const { return document()->availableUndoSteps(); }
|
||||||
@@ -2069,6 +2050,7 @@ public:
|
|||||||
// visual modes
|
// visual modes
|
||||||
void toggleVisualMode(VisualMode visualMode);
|
void toggleVisualMode(VisualMode visualMode);
|
||||||
void leaveVisualMode();
|
void leaveVisualMode();
|
||||||
|
void saveLastVisualMode();
|
||||||
|
|
||||||
// marks
|
// marks
|
||||||
Mark mark(QChar code) const;
|
Mark mark(QChar code) const;
|
||||||
@@ -2308,12 +2290,15 @@ FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget)
|
|||||||
connect(EDITOR(document()), SIGNAL(contentsChange(int,int,int)),
|
connect(EDITOR(document()), SIGNAL(contentsChange(int,int,int)),
|
||||||
SLOT(onContentsChanged(int,int,int)));
|
SLOT(onContentsChanged(int,int,int)));
|
||||||
connect(EDITOR(document()), SIGNAL(undoCommandAdded()), SLOT(onUndoCommandAdded()));
|
connect(EDITOR(document()), SIGNAL(undoCommandAdded()), SLOT(onUndoCommandAdded()));
|
||||||
|
connect(editor(), SIGNAL(cursorPositionChanged()), SLOT(onCursorPositionChanged()));
|
||||||
m_buffer->lastRevision = revision();
|
m_buffer->lastRevision = revision();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::init()
|
void FakeVimHandler::Private::init()
|
||||||
{
|
{
|
||||||
|
m_cursor = QTextCursor(document());
|
||||||
|
m_cursorNeedsUpdate = true;
|
||||||
m_inFakeVim = false;
|
m_inFakeVim = false;
|
||||||
m_findStartPosition = -1;
|
m_findStartPosition = -1;
|
||||||
m_visualBlockInsert = NoneBlockInsertMode;
|
m_visualBlockInsert = NoneBlockInsertMode;
|
||||||
@@ -2324,10 +2309,6 @@ void FakeVimHandler::Private::init()
|
|||||||
m_targetColumn = 0;
|
m_targetColumn = 0;
|
||||||
m_visualTargetColumn = 0;
|
m_visualTargetColumn = 0;
|
||||||
m_targetColumnWrapped = 0;
|
m_targetColumnWrapped = 0;
|
||||||
m_oldInternalAnchor = -1;
|
|
||||||
m_oldInternalPosition = -1;
|
|
||||||
m_oldExternalAnchor = -1;
|
|
||||||
m_oldExternalPosition = -1;
|
|
||||||
m_searchStartPosition = 0;
|
m_searchStartPosition = 0;
|
||||||
m_searchFromScreenLine = 0;
|
m_searchFromScreenLine = 0;
|
||||||
m_firstVisibleLine = 0;
|
m_firstVisibleLine = 0;
|
||||||
@@ -2336,6 +2317,7 @@ void FakeVimHandler::Private::init()
|
|||||||
m_ctrlVBase = 0;
|
m_ctrlVBase = 0;
|
||||||
|
|
||||||
pullOrCreateBufferData();
|
pullOrCreateBufferData();
|
||||||
|
pullCursor();
|
||||||
setupCharClass();
|
setupCharClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2377,17 +2359,13 @@ void FakeVimHandler::Private::enterFakeVim()
|
|||||||
|
|
||||||
pullOrCreateBufferData();
|
pullOrCreateBufferData();
|
||||||
|
|
||||||
pullCursor();
|
|
||||||
if (m_cursor.isNull())
|
|
||||||
m_cursor = QTextCursor(document());
|
|
||||||
|
|
||||||
m_inFakeVim = true;
|
m_inFakeVim = true;
|
||||||
|
|
||||||
removeEventFilter();
|
removeEventFilter();
|
||||||
|
|
||||||
updateFirstVisibleLine();
|
pullCursor();
|
||||||
|
|
||||||
updateCursorPosition();
|
updateFirstVisibleLine();
|
||||||
|
|
||||||
if (m_fakeEnd)
|
if (m_fakeEnd)
|
||||||
moveRight();
|
moveRight();
|
||||||
@@ -2412,12 +2390,7 @@ void FakeVimHandler::Private::leaveFakeVim(bool needUpdate)
|
|||||||
if (hasConfig(ConfigShowMarks))
|
if (hasConfig(ConfigShowMarks))
|
||||||
updateSelection();
|
updateSelection();
|
||||||
|
|
||||||
exportSelection();
|
|
||||||
updateCursorShape();
|
|
||||||
|
|
||||||
if (needUpdate) {
|
if (needUpdate) {
|
||||||
commitCursor();
|
|
||||||
|
|
||||||
// Move cursor line to middle of screen if it's not visible.
|
// Move cursor line to middle of screen if it's not visible.
|
||||||
const int line = cursorLine();
|
const int line = cursorLine();
|
||||||
if (line < firstVisibleLine() || line > firstVisibleLine() + linesOnScreen())
|
if (line < firstVisibleLine() || line > firstVisibleLine() + linesOnScreen())
|
||||||
@@ -2425,6 +2398,9 @@ void FakeVimHandler::Private::leaveFakeVim(bool needUpdate)
|
|||||||
else
|
else
|
||||||
scrollToLine(firstVisibleLine());
|
scrollToLine(firstVisibleLine());
|
||||||
updateScrollOffset();
|
updateScrollOffset();
|
||||||
|
|
||||||
|
commitCursor();
|
||||||
|
updateCursorShape();
|
||||||
}
|
}
|
||||||
|
|
||||||
installEventFilter();
|
installEventFilter();
|
||||||
@@ -2538,13 +2514,11 @@ EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev)
|
|||||||
|
|
||||||
void FakeVimHandler::Private::installEventFilter()
|
void FakeVimHandler::Private::installEventFilter()
|
||||||
{
|
{
|
||||||
EDITOR(viewport()->installEventFilter(q));
|
|
||||||
EDITOR(installEventFilter(q));
|
EDITOR(installEventFilter(q));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::removeEventFilter()
|
void FakeVimHandler::Private::removeEventFilter()
|
||||||
{
|
{
|
||||||
EDITOR(viewport()->removeEventFilter(q));
|
|
||||||
EDITOR(removeEventFilter(q));
|
EDITOR(removeEventFilter(q));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2559,66 +2533,9 @@ void FakeVimHandler::Private::setupWidget()
|
|||||||
updateMiniBuffer();
|
updateMiniBuffer();
|
||||||
updateCursorShape();
|
updateCursorShape();
|
||||||
|
|
||||||
updateCursorPosition();
|
|
||||||
|
|
||||||
leaveFakeVim();
|
leaveFakeVim();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::exportSelection()
|
|
||||||
{
|
|
||||||
int pos = position();
|
|
||||||
int anc = isVisualMode() ? anchor() : position();
|
|
||||||
|
|
||||||
m_oldInternalPosition = pos;
|
|
||||||
m_oldInternalAnchor = anc;
|
|
||||||
|
|
||||||
if (isVisualMode()) {
|
|
||||||
if (g.visualMode == VisualBlockMode) {
|
|
||||||
const int col1 = columnAt(anc);
|
|
||||||
const int col2 = columnAt(pos);
|
|
||||||
if (col1 > col2)
|
|
||||||
++anc;
|
|
||||||
else if (!atBlockEnd())
|
|
||||||
++pos;
|
|
||||||
// FIXME: After '$' command (i.e. m_visualTargetColumn == -1), end of selected lines
|
|
||||||
// should be selected.
|
|
||||||
setAnchorAndPosition(anc, pos);
|
|
||||||
commitCursor();
|
|
||||||
} else if (g.visualMode == VisualLineMode) {
|
|
||||||
const int posLine = lineForPosition(pos);
|
|
||||||
const int ancLine = lineForPosition(anc);
|
|
||||||
if (anc < pos) {
|
|
||||||
pos = lastPositionInLine(posLine);
|
|
||||||
anc = firstPositionInLine(ancLine);
|
|
||||||
} else {
|
|
||||||
pos = firstPositionInLine(posLine);
|
|
||||||
anc = lastPositionInLine(ancLine) + 1;
|
|
||||||
}
|
|
||||||
// putting cursor on folded line will unfold the line, so move the cursor a bit
|
|
||||||
if (!blockAt(pos).isVisible())
|
|
||||||
++pos;
|
|
||||||
setAnchorAndPosition(anc, pos);
|
|
||||||
} else if (g.visualMode == VisualCharMode) {
|
|
||||||
if (anc > pos)
|
|
||||||
++anc;
|
|
||||||
} else {
|
|
||||||
QTC_CHECK(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
setAnchorAndPosition(anc, pos);
|
|
||||||
|
|
||||||
setMark(QLatin1Char('<'), markLessPosition());
|
|
||||||
setMark(QLatin1Char('>'), markGreaterPosition());
|
|
||||||
} else {
|
|
||||||
if (g.subsubmode == SearchSubSubMode && !m_searchCursor.isNull())
|
|
||||||
m_cursor = m_searchCursor;
|
|
||||||
else
|
|
||||||
setAnchorAndPosition(pos, pos);
|
|
||||||
}
|
|
||||||
m_oldExternalPosition = position();
|
|
||||||
m_oldExternalAnchor = anchor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FakeVimHandler::Private::commitInsertState()
|
void FakeVimHandler::Private::commitInsertState()
|
||||||
{
|
{
|
||||||
if (!isInsertStateValid())
|
if (!isInsertStateValid())
|
||||||
@@ -2655,16 +2572,14 @@ void FakeVimHandler::Private::commitInsertState()
|
|||||||
|
|
||||||
void FakeVimHandler::Private::invalidateInsertState()
|
void FakeVimHandler::Private::invalidateInsertState()
|
||||||
{
|
{
|
||||||
m_oldInternalPosition = position();
|
|
||||||
BufferData::InsertState &insertState = m_buffer->insertState;
|
BufferData::InsertState &insertState = m_buffer->insertState;
|
||||||
insertState.pos1 = -1;
|
insertState.pos1 = -1;
|
||||||
insertState.pos2 = m_oldInternalPosition;
|
insertState.pos2 = position();
|
||||||
insertState.backspaces = 0;
|
insertState.backspaces = 0;
|
||||||
insertState.deletes = 0;
|
insertState.deletes = 0;
|
||||||
insertState.spaces.clear();
|
insertState.spaces.clear();
|
||||||
insertState.insertingSpaces = false;
|
insertState.insertingSpaces = false;
|
||||||
insertState.textBeforeCursor = textAt(blockAt(m_oldInternalPosition).position(),
|
insertState.textBeforeCursor = textAt(block().position(), position());
|
||||||
m_oldInternalPosition);
|
|
||||||
insertState.newLineBefore = false;
|
insertState.newLineBefore = false;
|
||||||
insertState.newLineAfter = false;
|
insertState.newLineAfter = false;
|
||||||
}
|
}
|
||||||
@@ -2716,31 +2631,6 @@ void FakeVimHandler::Private::ensureCursorVisible()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::importSelection()
|
|
||||||
{
|
|
||||||
if (position() == m_oldExternalPosition
|
|
||||||
&& anchor() == m_oldExternalAnchor) {
|
|
||||||
// Undo drawing correction.
|
|
||||||
setAnchorAndPosition(m_oldInternalAnchor, m_oldInternalPosition);
|
|
||||||
} else {
|
|
||||||
// Import new selection.
|
|
||||||
Qt::KeyboardModifiers mods = QApplication::keyboardModifiers();
|
|
||||||
if (m_cursor.hasSelection()) {
|
|
||||||
if (mods & HostOsInfo::controlModifier())
|
|
||||||
g.visualMode = VisualBlockMode;
|
|
||||||
else if (mods & Qt::AltModifier)
|
|
||||||
g.visualMode = VisualBlockMode;
|
|
||||||
else if (mods & Qt::ShiftModifier)
|
|
||||||
g.visualMode = VisualLineMode;
|
|
||||||
else
|
|
||||||
g.visualMode = VisualCharMode;
|
|
||||||
m_buffer->lastVisualMode = g.visualMode;
|
|
||||||
} else {
|
|
||||||
g.visualMode = NoVisualMode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FakeVimHandler::Private::updateEditor()
|
void FakeVimHandler::Private::updateEditor()
|
||||||
{
|
{
|
||||||
const int charWidth = QFontMetrics(EDITOR(font())).width(QLatin1Char(' '));
|
const int charWidth = QFontMetrics(EDITOR(font())).width(QLatin1Char(' '));
|
||||||
@@ -3095,10 +2985,6 @@ void FakeVimHandler::Private::pushUndoState(bool overwrite)
|
|||||||
|
|
||||||
m_buffer->redo.clear();
|
m_buffer->redo.clear();
|
||||||
m_buffer->lastChangePosition = CursorPosition(document(), pos);
|
m_buffer->lastChangePosition = CursorPosition(document(), pos);
|
||||||
if (isVisualMode()) {
|
|
||||||
setMark(QLatin1Char('<'), markLessPosition());
|
|
||||||
setMark(QLatin1Char('>'), markGreaterPosition());
|
|
||||||
}
|
|
||||||
m_buffer->undoState = State(revision(), m_buffer->lastChangePosition, m_buffer->marks,
|
m_buffer->undoState = State(revision(), m_buffer->lastChangePosition, m_buffer->marks,
|
||||||
m_buffer->lastVisualMode, m_buffer->lastVisualModeInverted);
|
m_buffer->lastVisualMode, m_buffer->lastVisualModeInverted);
|
||||||
}
|
}
|
||||||
@@ -3179,19 +3065,97 @@ void FakeVimHandler::Private::movePageDown(int count)
|
|||||||
scrollToLine(qMax(0, cursorLine() - screenLines + 1));
|
scrollToLine(qMax(0, cursorLine() - screenLines + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::updateCursorPosition()
|
void FakeVimHandler::Private::commitCursor()
|
||||||
{
|
{
|
||||||
importSelection();
|
QTextCursor tc = m_cursor;
|
||||||
|
|
||||||
if (position() != m_oldInternalPosition) {
|
if (isVisualMode()) {
|
||||||
// record external jump to different line
|
int pos = tc.position();
|
||||||
if (m_oldInternalPosition != -1 && lineForPosition(m_oldInternalPosition) != lineForPosition(position()))
|
int anc = tc.anchor();
|
||||||
recordJump(m_oldInternalPosition);
|
|
||||||
|
|
||||||
setTargetColumn();
|
if (isVisualBlockMode()) {
|
||||||
if (atEndOfLine() && !isVisualMode() && !isInsertMode())
|
const int col1 = columnAt(anc);
|
||||||
moveLeft();
|
const int col2 = columnAt(pos);
|
||||||
|
if (col1 > col2)
|
||||||
|
++anc;
|
||||||
|
else if (!tc.atBlockEnd())
|
||||||
|
++pos;
|
||||||
|
// FIXME: After '$' command (i.e. m_visualTargetColumn == -1), end of selected lines
|
||||||
|
// should be selected.
|
||||||
|
} else if (isVisualLineMode()) {
|
||||||
|
const int posLine = lineForPosition(pos);
|
||||||
|
const int ancLine = lineForPosition(anc);
|
||||||
|
if (anc < pos) {
|
||||||
|
pos = lastPositionInLine(posLine);
|
||||||
|
anc = firstPositionInLine(ancLine);
|
||||||
|
} else {
|
||||||
|
pos = firstPositionInLine(posLine);
|
||||||
|
anc = lastPositionInLine(ancLine) + 1;
|
||||||
|
}
|
||||||
|
// putting cursor on folded line will unfold the line, so move the cursor a bit
|
||||||
|
if (!blockAt(pos).isVisible())
|
||||||
|
++pos;
|
||||||
|
} else if (isVisualCharMode()) {
|
||||||
|
if (anc > pos)
|
||||||
|
++anc;
|
||||||
|
} else {
|
||||||
|
QTC_CHECK(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
tc.setPosition(anc);
|
||||||
|
tc.setPosition(pos, KeepAnchor);
|
||||||
|
} else if (g.subsubmode == SearchSubSubMode && !m_searchCursor.isNull()) {
|
||||||
|
tc = m_searchCursor;
|
||||||
|
} else {
|
||||||
|
tc.clearSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isVisualBlockMode()) {
|
||||||
|
emit q->requestSetBlockSelection(tc);
|
||||||
|
} else {
|
||||||
|
emit q->requestDisableBlockSelection();
|
||||||
|
if (editor())
|
||||||
|
EDITOR(setTextCursor(tc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeVimHandler::Private::pullCursor()
|
||||||
|
{
|
||||||
|
if (!m_cursorNeedsUpdate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_cursorNeedsUpdate = false;
|
||||||
|
|
||||||
|
QTextCursor oldCursor = m_cursor;
|
||||||
|
|
||||||
|
bool visualBlockMode = false;
|
||||||
|
emit q->requestHasBlockSelection(&visualBlockMode);
|
||||||
|
|
||||||
|
if (visualBlockMode)
|
||||||
|
q->requestBlockSelection(&m_cursor);
|
||||||
|
else if (editor())
|
||||||
|
m_cursor = EDITOR(textCursor());
|
||||||
|
|
||||||
|
// Cursor should be always valid.
|
||||||
|
if (m_cursor.isNull())
|
||||||
|
m_cursor = QTextCursor(document());
|
||||||
|
|
||||||
|
if (visualBlockMode)
|
||||||
|
g.visualMode = VisualBlockMode;
|
||||||
|
else if (m_cursor.hasSelection())
|
||||||
|
g.visualMode = VisualCharMode;
|
||||||
|
else
|
||||||
|
g.visualMode = NoVisualMode;
|
||||||
|
|
||||||
|
// Cursor position can be after the end of line only in some modes.
|
||||||
|
if (atEndOfLine() && !isVisualMode() && !isInsertMode())
|
||||||
|
moveLeft();
|
||||||
|
|
||||||
|
// Record external jump to different line.
|
||||||
|
if (lineForPosition(position()) != lineForPosition(oldCursor.position()))
|
||||||
|
recordJump(oldCursor.position());
|
||||||
|
|
||||||
|
setTargetColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FakeVimHandler::Private::moveToNextParagraph(int count)
|
bool FakeVimHandler::Private::moveToNextParagraph(int count)
|
||||||
@@ -4105,6 +4069,8 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input)
|
|||||||
else
|
else
|
||||||
g.currentCommand.append(input.toString());
|
g.currentCommand.append(input.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveLastVisualMode();
|
||||||
} else {
|
} else {
|
||||||
leaveCurrentMode();
|
leaveCurrentMode();
|
||||||
//qDebug() << "IGNORED IN COMMAND MODE: " << key << text
|
//qDebug() << "IGNORED IN COMMAND MODE: " << key << text
|
||||||
@@ -4305,8 +4271,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
|
|||||||
m_buffer->insertState.newLineBefore = true;
|
m_buffer->insertState.newLineBefore = true;
|
||||||
} else {
|
} else {
|
||||||
moveUp();
|
moveUp();
|
||||||
m_oldInternalPosition = position();
|
m_buffer->insertState.pos1 = position();
|
||||||
m_buffer->insertState.pos1 = m_oldInternalPosition;
|
|
||||||
m_buffer->insertState.newLineAfter = true;
|
m_buffer->insertState.newLineAfter = true;
|
||||||
}
|
}
|
||||||
setTargetColumn();
|
setTargetColumn();
|
||||||
@@ -4367,13 +4332,15 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
|
|||||||
handleStartOfLine();
|
handleStartOfLine();
|
||||||
scrollToLine(cursorLine() - sline);
|
scrollToLine(cursorLine() - sline);
|
||||||
} else if (g.gflag && input.is('v')) {
|
} else if (g.gflag && input.is('v')) {
|
||||||
if (m_buffer->lastVisualMode != NoVisualMode) {
|
if (isNoVisualMode()) {
|
||||||
CursorPosition from = markLessPosition();
|
CursorPosition from = markLessPosition();
|
||||||
CursorPosition to = markGreaterPosition();
|
CursorPosition to = markGreaterPosition();
|
||||||
|
if (m_buffer->lastVisualModeInverted)
|
||||||
|
std::swap(from, to);
|
||||||
toggleVisualMode(m_buffer->lastVisualMode);
|
toggleVisualMode(m_buffer->lastVisualMode);
|
||||||
setCursorPosition(m_buffer->lastVisualModeInverted ? to : from);
|
setCursorPosition(from);
|
||||||
setAnchor();
|
setAnchor();
|
||||||
setCursorPosition(m_buffer->lastVisualModeInverted ? from : to);
|
setCursorPosition(to);
|
||||||
setTargetColumn();
|
setTargetColumn();
|
||||||
}
|
}
|
||||||
} else if (input.is('v')) {
|
} else if (input.is('v')) {
|
||||||
@@ -4688,8 +4655,6 @@ EventResult FakeVimHandler::Private::handleInsertOrReplaceMode(const Input &inpu
|
|||||||
invalidateInsertState();
|
invalidateInsertState();
|
||||||
breakEditBlock();
|
breakEditBlock();
|
||||||
m_visualBlockInsert = NoneBlockInsertMode;
|
m_visualBlockInsert = NoneBlockInsertMode;
|
||||||
} else if (m_oldInternalPosition == position()) {
|
|
||||||
setTargetColumn();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMiniBuffer();
|
updateMiniBuffer();
|
||||||
@@ -4727,6 +4692,7 @@ void FakeVimHandler::Private::handleReplaceMode(const Input &input)
|
|||||||
const QString text = input.text();
|
const QString text = input.text();
|
||||||
setAnchor();
|
setAnchor();
|
||||||
insertText(text);
|
insertText(text);
|
||||||
|
setTargetColumn();
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4810,6 +4776,7 @@ void FakeVimHandler::Private::finishInsertMode()
|
|||||||
m_buffer->lastInsertion.remove(0, m_buffer->lastInsertion.indexOf(QLatin1Char('\n')) + 1);
|
m_buffer->lastInsertion.remove(0, m_buffer->lastInsertion.indexOf(QLatin1Char('\n')) + 1);
|
||||||
g.dotCommand.append(m_buffer->lastInsertion + _("<ESC>"));
|
g.dotCommand.append(m_buffer->lastInsertion + _("<ESC>"));
|
||||||
|
|
||||||
|
setTargetColumn();
|
||||||
enterCommandMode();
|
enterCommandMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5118,8 +5085,6 @@ EventResult FakeVimHandler::Private::handleExMode(const Input &input)
|
|||||||
showMessage(MessageCommand, g.commandBuffer.display());
|
showMessage(MessageCommand, g.commandBuffer.display());
|
||||||
handleExCommand(g.commandBuffer.contents());
|
handleExCommand(g.commandBuffer.contents());
|
||||||
g.commandBuffer.clear();
|
g.commandBuffer.clear();
|
||||||
if (m_textedit || m_plaintextedit)
|
|
||||||
leaveVisualMode();
|
|
||||||
} else if (!g.commandBuffer.handleInput(input)) {
|
} else if (!g.commandBuffer.handleInput(input)) {
|
||||||
qDebug() << "IGNORED IN EX-MODE: " << input.key() << input.text();
|
qDebug() << "IGNORED IN EX-MODE: " << input.key() << input.text();
|
||||||
return EventUnhandled;
|
return EventUnhandled;
|
||||||
@@ -5769,8 +5734,6 @@ bool FakeVimHandler::Private::handleExMoveCommand(const ExCommand &cmd)
|
|||||||
if (hasConfig(ConfigStartOfLine))
|
if (hasConfig(ConfigStartOfLine))
|
||||||
moveToFirstNonBlankOnLine();
|
moveToFirstNonBlankOnLine();
|
||||||
|
|
||||||
// correct last selection
|
|
||||||
leaveVisualMode();
|
|
||||||
if (lastAnchor.line >= startLine && lastAnchor.line <= endLine)
|
if (lastAnchor.line >= startLine && lastAnchor.line <= endLine)
|
||||||
lastAnchor.line += targetLine - startLine + 1;
|
lastAnchor.line += targetLine - startLine + 1;
|
||||||
if (lastPosition.line >= startLine && lastPosition.line <= endLine)
|
if (lastPosition.line >= startLine && lastPosition.line <= endLine)
|
||||||
@@ -6096,6 +6059,8 @@ void FakeVimHandler::Private::handleExCommand(const QString &line0)
|
|||||||
|
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
|
|
||||||
|
if (isVisualMode())
|
||||||
|
leaveVisualMode();
|
||||||
leaveCurrentMode();
|
leaveCurrentMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6480,7 +6445,7 @@ void FakeVimHandler::Private::miniBufferTextEdited(const QString &text, int curs
|
|||||||
// update search expression
|
// update search expression
|
||||||
if (g.subsubmode == SearchSubSubMode) {
|
if (g.subsubmode == SearchSubSubMode) {
|
||||||
updateFind(false);
|
updateFind(false);
|
||||||
exportSelection();
|
commitCursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7050,21 +7015,15 @@ void FakeVimHandler::Private::transformText(const Range &range,
|
|||||||
void FakeVimHandler::Private::insertText(QTextCursor &tc, const QString &text)
|
void FakeVimHandler::Private::insertText(QTextCursor &tc, const QString &text)
|
||||||
{
|
{
|
||||||
if (hasConfig(ConfigPassKeys)) {
|
if (hasConfig(ConfigPassKeys)) {
|
||||||
QTextCursor oldTc = m_cursor;
|
|
||||||
m_cursor = tc;
|
|
||||||
|
|
||||||
if (tc.hasSelection() && text.isEmpty()) {
|
if (tc.hasSelection() && text.isEmpty()) {
|
||||||
QKeyEvent event(QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier, QString());
|
QKeyEvent event(QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier, QString());
|
||||||
passEventToEditor(event);
|
passEventToEditor(event, tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (QChar c, text) {
|
foreach (QChar c, text) {
|
||||||
QKeyEvent event(QEvent::KeyPress, -1, Qt::NoModifier, QString(c));
|
QKeyEvent event(QEvent::KeyPress, -1, Qt::NoModifier, QString(c));
|
||||||
passEventToEditor(event);
|
passEventToEditor(event, tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
tc = m_cursor;
|
|
||||||
m_cursor = oldTc;
|
|
||||||
} else {
|
} else {
|
||||||
tc.insertText(text);
|
tc.insertText(text);
|
||||||
}
|
}
|
||||||
@@ -7279,7 +7238,7 @@ void FakeVimHandler::Private::insertNewLine()
|
|||||||
{
|
{
|
||||||
if ( m_buffer->editBlockLevel <= 1 && hasConfig(ConfigPassKeys) ) {
|
if ( m_buffer->editBlockLevel <= 1 && hasConfig(ConfigPassKeys) ) {
|
||||||
QKeyEvent event(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, QLatin1String("\n"));
|
QKeyEvent event(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, QLatin1String("\n"));
|
||||||
if (passEventToEditor(event))
|
if (passEventToEditor(event, m_cursor))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7296,27 +7255,32 @@ bool FakeVimHandler::Private::handleInsertInEditor(const Input &input)
|
|||||||
|
|
||||||
QKeyEvent event(QEvent::KeyPress, input.key(), input.modifiers(), input.text());
|
QKeyEvent event(QEvent::KeyPress, input.key(), input.modifiers(), input.text());
|
||||||
setAnchor();
|
setAnchor();
|
||||||
if (!passEventToEditor(event))
|
if (!passEventToEditor(event, m_cursor))
|
||||||
return !m_textedit && !m_plaintextedit; // Mark event as handled if it has destroyed editor.
|
return !m_textedit && !m_plaintextedit; // Mark event as handled if it has destroyed editor.
|
||||||
|
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
|
|
||||||
|
setTargetColumn();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FakeVimHandler::Private::passEventToEditor(QEvent &event)
|
bool FakeVimHandler::Private::passEventToEditor(QEvent &event, QTextCursor &tc)
|
||||||
{
|
{
|
||||||
removeEventFilter();
|
removeEventFilter();
|
||||||
|
emit q->requestDisableBlockSelection();
|
||||||
|
|
||||||
EDITOR(setOverwriteMode(false));
|
EDITOR(setOverwriteMode(false));
|
||||||
commitCursor();
|
EDITOR(setTextCursor(tc));
|
||||||
|
|
||||||
bool accepted = QApplication::sendEvent(editor(), &event);
|
bool accepted = QApplication::sendEvent(editor(), &event);
|
||||||
if (!m_textedit && !m_plaintextedit)
|
if (!m_textedit && !m_plaintextedit)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
updateCursorShape();
|
updateCursorShape();
|
||||||
|
|
||||||
if (accepted)
|
if (accepted)
|
||||||
pullCursor();
|
tc = EDITOR(textCursor());
|
||||||
|
|
||||||
return accepted;
|
return accepted;
|
||||||
}
|
}
|
||||||
@@ -7506,9 +7470,6 @@ void FakeVimHandler::Private::leaveVisualMode()
|
|||||||
if (!isVisualMode())
|
if (!isVisualMode())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setMark(QLatin1Char('<'), markLessPosition());
|
|
||||||
setMark(QLatin1Char('>'), markGreaterPosition());
|
|
||||||
m_buffer->lastVisualModeInverted = anchor() > position();
|
|
||||||
if (isVisualLineMode()) {
|
if (isVisualLineMode()) {
|
||||||
g.rangemode = RangeLineMode;
|
g.rangemode = RangeLineMode;
|
||||||
g.movetype = MoveLineWise;
|
g.movetype = MoveLineWise;
|
||||||
@@ -7524,6 +7485,16 @@ void FakeVimHandler::Private::leaveVisualMode()
|
|||||||
updateMiniBuffer();
|
updateMiniBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeVimHandler::Private::saveLastVisualMode()
|
||||||
|
{
|
||||||
|
if (isVisualMode() && g.mode == CommandMode && g.submode == NoSubMode) {
|
||||||
|
setMark(QLatin1Char('<'), markLessPosition());
|
||||||
|
setMark(QLatin1Char('>'), markGreaterPosition());
|
||||||
|
m_buffer->lastVisualModeInverted = anchor() > position();
|
||||||
|
m_buffer->lastVisualMode = g.visualMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QWidget *FakeVimHandler::Private::editor() const
|
QWidget *FakeVimHandler::Private::editor() const
|
||||||
{
|
{
|
||||||
return m_textedit
|
return m_textedit
|
||||||
@@ -7579,8 +7550,9 @@ void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved,
|
|||||||
// Record inserted and deleted text in insert mode.
|
// Record inserted and deleted text in insert mode.
|
||||||
if (isInsertMode() && (charsAdded > 0 || charsRemoved > 0)) {
|
if (isInsertMode() && (charsAdded > 0 || charsRemoved > 0)) {
|
||||||
BufferData::InsertState &insertState = m_buffer->insertState;
|
BufferData::InsertState &insertState = m_buffer->insertState;
|
||||||
|
const int oldPosition = insertState.pos2;
|
||||||
if (!isInsertStateValid()) {
|
if (!isInsertStateValid()) {
|
||||||
insertState.pos1 = m_oldInternalPosition;
|
insertState.pos1 = oldPosition;
|
||||||
g.dotCommand = _("i");
|
g.dotCommand = _("i");
|
||||||
resetCount();
|
resetCount();
|
||||||
}
|
}
|
||||||
@@ -7591,7 +7563,7 @@ void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved,
|
|||||||
if (position < insertState.pos1) {
|
if (position < insertState.pos1) {
|
||||||
// backspaces
|
// backspaces
|
||||||
const int bs = insertState.pos1 - position;
|
const int bs = insertState.pos1 - position;
|
||||||
const QString inserted = textAt(position, m_oldInternalPosition);
|
const QString inserted = textAt(position, oldPosition);
|
||||||
const QString removed = insertState.textBeforeCursor.right(bs);
|
const QString removed = insertState.textBeforeCursor.right(bs);
|
||||||
// Ignore backspaces if same text was just inserted.
|
// Ignore backspaces if same text was just inserted.
|
||||||
if ( !inserted.endsWith(removed) ) {
|
if ( !inserted.endsWith(removed) ) {
|
||||||
@@ -7611,11 +7583,9 @@ void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
insertState.pos2 = qMax(insertState.pos2 + charsAdded - charsRemoved,
|
const int newPosition = position + charsAdded;
|
||||||
position + charsAdded);
|
insertState.pos2 = qMax(insertState.pos2 + charsAdded - charsRemoved, newPosition);
|
||||||
m_oldInternalPosition = position + charsAdded;
|
insertState.textBeforeCursor = textAt(block().position(), newPosition);
|
||||||
insertState.textBeforeCursor = textAt(blockAt(m_oldInternalPosition).position(),
|
|
||||||
m_oldInternalPosition);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7623,6 +7593,12 @@ void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved,
|
|||||||
emit q->highlightMatches(m_highlighted);
|
emit q->highlightMatches(m_highlighted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeVimHandler::Private::onCursorPositionChanged()
|
||||||
|
{
|
||||||
|
if (!m_inFakeVim)
|
||||||
|
m_cursorNeedsUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::onUndoCommandAdded()
|
void FakeVimHandler::Private::onUndoCommandAdded()
|
||||||
{
|
{
|
||||||
// Undo commands removed?
|
// Undo commands removed?
|
||||||
@@ -7844,10 +7820,13 @@ void FakeVimHandler::Private::enterCommandMode(Mode returnToMode)
|
|||||||
if (g.isRecording && isCommandLineMode())
|
if (g.isRecording && isCommandLineMode())
|
||||||
record(Input(Key_Escape, NoModifier));
|
record(Input(Key_Escape, NoModifier));
|
||||||
|
|
||||||
if (isNoVisualMode() && atEndOfLine()) {
|
if (isNoVisualMode()) {
|
||||||
m_cursor.movePosition(Left, KeepAnchor);
|
if (atEndOfLine()) {
|
||||||
if (m_targetColumn != -1)
|
m_cursor.movePosition(Left, KeepAnchor);
|
||||||
setTargetColumn();
|
if (m_targetColumn != -1)
|
||||||
|
setTargetColumn();
|
||||||
|
}
|
||||||
|
setAnchor();
|
||||||
}
|
}
|
||||||
|
|
||||||
g.mode = CommandMode;
|
g.mode = CommandMode;
|
||||||
@@ -8423,28 +8402,6 @@ bool FakeVimHandler::eventFilter(QObject *ob, QEvent *ev)
|
|||||||
return QObject::eventFilter(ob, ev);
|
return QObject::eventFilter(ob, ev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Catch mouse events on the viewport.
|
|
||||||
QWidget *viewport = 0;
|
|
||||||
if (d->m_plaintextedit)
|
|
||||||
viewport = d->m_plaintextedit->viewport();
|
|
||||||
else if (d->m_textedit)
|
|
||||||
viewport = d->m_textedit->viewport();
|
|
||||||
if (ob == viewport) {
|
|
||||||
if (ev->type() == QEvent::MouseButtonRelease) {
|
|
||||||
QMouseEvent *mev = static_cast<QMouseEvent *>(ev);
|
|
||||||
if (mev->button() == Qt::LeftButton) {
|
|
||||||
d->importSelection();
|
|
||||||
//return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev->type() == QEvent::MouseButtonPress) {
|
|
||||||
QMouseEvent *mev = static_cast<QMouseEvent *>(ev);
|
|
||||||
if (mev->button() == Qt::LeftButton)
|
|
||||||
Private::g.visualMode = NoVisualMode;
|
|
||||||
}
|
|
||||||
return QObject::eventFilter(ob, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ev->type() == QEvent::Shortcut) {
|
if (ev->type() == QEvent::Shortcut) {
|
||||||
d->passShortcuts(false);
|
d->passShortcuts(false);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user