forked from qt-creator/qt-creator
FakeVim: Fix searching in visual mode and with commands
Search in visual mode should select text up to matched position. Using commands should work with search movement; e.g. 'd2/needle<CR>'. Commands should be also properly canceled if search movement fails. Change-Id: Ic695dccaf3f36ccae2f2b1a93f888d5ba9805a78 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -1472,6 +1472,32 @@ void FakeVimPlugin::test_vim_search()
|
||||
KEYS("N", "abc" N X "def" N "ghi");
|
||||
KEYS("N", X "abc" N "def" N "ghi");
|
||||
KEYS("2n2N", X "abc" N "def" N "ghi");
|
||||
|
||||
// delete to match
|
||||
data.setText("abc" N "def" N "abc" N "ghi abc jkl" N "xyz");
|
||||
KEYS("2l" "d/ghi<CR>", "ab" X "ghi abc jkl" N "xyz");
|
||||
|
||||
data.setText("abc" N "def" N "abc" N "ghi abc jkl" N "xyz");
|
||||
KEYS("l" "d2/abc<CR>", "a" X "abc jkl" N "xyz");
|
||||
|
||||
data.setText("abc" N "def" N "abc" N "ghi abc jkl" N "xyz");
|
||||
KEYS("d/abc<CR>", X "abc" N "ghi abc jkl" N "xyz");
|
||||
KEYS(".", "abc jkl" N "xyz");
|
||||
|
||||
data.setText("abc" N "def" N "abc" N "ghi abc jkl" N "xyz");
|
||||
KEYS("/abc<CR>" "l" "dn", "abc" N "def" N "a" X "abc jkl" N "xyz");
|
||||
|
||||
data.setText("abc" N "def" N "abc" N "ghi abc jkl" N "xyz");
|
||||
KEYS("2/abc<CR>" "h" "dN", "abc" N "def" N X " abc jkl" N "xyz");
|
||||
KEYS("c/xxx<CR><ESC>" "h" "dN", "abc" N "def" N X " abc jkl" N "xyz");
|
||||
|
||||
data.setText("abc" N "def" N "abc" N "ghi abc jkl" N "xyz");
|
||||
KEYS("l" "v2/abc<CR>" "x", "abc jkl" N "xyz");
|
||||
|
||||
// don't leave visual mode after search failed or is cancelled
|
||||
data.setText("abc" N "def" N "abc" N "ghi abc jkl" N "xyz");
|
||||
KEYS("vj" "/abc<ESC>" "x", X "ef" N "abc" N "ghi abc jkl" N "xyz");
|
||||
KEYS("vj" "/xxx<CR>" "x", X "bc" N "ghi abc jkl" N "xyz");
|
||||
}
|
||||
|
||||
void FakeVimPlugin::test_vim_indent()
|
||||
|
||||
@@ -1524,12 +1524,13 @@ public:
|
||||
EventResult handleSearchSubSubMode(const Input &);
|
||||
bool handleCommandSubSubMode(const Input &);
|
||||
void fixSelection(); // Fix selection according to current range, move and command modes.
|
||||
bool finishSearch();
|
||||
void finishMovement(const QString &dotCommandMovement = QString());
|
||||
void resetCommandMode();
|
||||
void clearCommandMode();
|
||||
QTextCursor search(const SearchData &sd, int startPos, int count, bool showMessages);
|
||||
void search(const SearchData &sd, bool showMessages = true);
|
||||
void searchNext(bool forward = true);
|
||||
bool searchNext(bool forward = true);
|
||||
void searchBalanced(bool forward, QChar needle, QChar other);
|
||||
void highlightMatches(const QString &needle);
|
||||
void stopIncrementalFind();
|
||||
@@ -2096,15 +2097,32 @@ void FakeVimHandler::Private::init()
|
||||
|
||||
void FakeVimHandler::Private::focus()
|
||||
{
|
||||
if (g.inFakeVim)
|
||||
return;
|
||||
|
||||
enterFakeVim();
|
||||
|
||||
stopIncrementalFind();
|
||||
if (!isInsertMode()) {
|
||||
leaveVisualMode();
|
||||
if (g.subsubmode == SearchSubSubMode) {
|
||||
setPosition(m_searchStartPosition);
|
||||
scrollToLine(m_searchFromScreenLine);
|
||||
setTargetColumn();
|
||||
} else {
|
||||
leaveVisualMode();
|
||||
}
|
||||
|
||||
bool exitCommandLine = (g.subsubmode == SearchSubSubMode || g.mode == ExMode);
|
||||
resetCommandMode();
|
||||
if (exitCommandLine)
|
||||
updateMiniBuffer();
|
||||
}
|
||||
updateCursorShape();
|
||||
if (!g.inFakeVim || g.mode != CommandMode)
|
||||
if (g.mode != CommandMode)
|
||||
updateMiniBuffer();
|
||||
updateHighlights();
|
||||
|
||||
leaveFakeVim();
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::enterFakeVim()
|
||||
@@ -2726,14 +2744,16 @@ void FakeVimHandler::Private::updateFind(bool isComplete)
|
||||
g.currentMessage.clear();
|
||||
|
||||
const QString &needle = g.searchBuffer.contents();
|
||||
if (isComplete) {
|
||||
setPosition(m_searchStartPosition);
|
||||
if (!needle.isEmpty())
|
||||
recordJump();
|
||||
}
|
||||
|
||||
SearchData sd;
|
||||
sd.needle = needle;
|
||||
sd.forward = g.lastSearchForward;
|
||||
sd.highlightMatches = isComplete;
|
||||
if (isComplete) {
|
||||
setPosition(m_searchStartPosition);
|
||||
recordJump();
|
||||
}
|
||||
search(sd, isComplete);
|
||||
}
|
||||
|
||||
@@ -3018,6 +3038,17 @@ void FakeVimHandler::Private::fixSelection()
|
||||
}
|
||||
}
|
||||
|
||||
bool FakeVimHandler::Private::finishSearch()
|
||||
{
|
||||
if (g.lastSearch.isEmpty()
|
||||
|| (!g.currentMessage.isEmpty() && g.currentMessageLevel == MessageError)) {
|
||||
return false;
|
||||
}
|
||||
if (g.submode != NoSubMode)
|
||||
setAnchorAndPosition(m_searchStartPosition, position());
|
||||
return true;
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|
||||
{
|
||||
//dump("FINISH MOVEMENT");
|
||||
@@ -3488,7 +3519,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input)
|
||||
g.searchBuffer.historyPush(needle);
|
||||
g.lastSearch = needle;
|
||||
g.lastSearchForward = input.is('*');
|
||||
searchNext();
|
||||
handled = searchNext();
|
||||
} else if (input.is('\'')) {
|
||||
g.subsubmode = TickSubSubMode;
|
||||
if (g.submode != NoSubMode)
|
||||
@@ -3655,7 +3686,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input)
|
||||
}
|
||||
setPosition(m_cursor.selectionStart());
|
||||
} else {
|
||||
searchNext(input.is('n'));
|
||||
handled = searchNext(input.is('n'));
|
||||
}
|
||||
} else if (input.is('t')) {
|
||||
g.movetype = MoveInclusive;
|
||||
@@ -4378,6 +4409,7 @@ bool FakeVimHandler::Private::handleWindowSubMode(const Input &input)
|
||||
if (handleCount(input))
|
||||
return true;
|
||||
|
||||
leaveVisualMode();
|
||||
emit q->windowCommandRequested(input.toString(), count());
|
||||
|
||||
g.submode = NoSubMode;
|
||||
@@ -4811,7 +4843,6 @@ EventResult FakeVimHandler::Private::handleExMode(const Input &input)
|
||||
{
|
||||
if (input.isEscape()) {
|
||||
g.commandBuffer.clear();
|
||||
enterCommandMode(g.returnToMode);
|
||||
resetCommandMode();
|
||||
m_ctrlVActive = false;
|
||||
} else if (m_ctrlVActive) {
|
||||
@@ -4822,7 +4853,7 @@ EventResult FakeVimHandler::Private::handleExMode(const Input &input)
|
||||
return EventHandled;
|
||||
} else if (input.isBackspace()) {
|
||||
if (g.commandBuffer.isEmpty()) {
|
||||
enterCommandMode(g.returnToMode);
|
||||
leaveVisualMode();
|
||||
resetCommandMode();
|
||||
} else if (g.commandBuffer.hasSelection()) {
|
||||
g.commandBuffer.deleteSelected();
|
||||
@@ -4852,11 +4883,8 @@ EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input)
|
||||
|
||||
if (input.isEscape()) {
|
||||
g.currentMessage.clear();
|
||||
g.searchBuffer.clear();
|
||||
setAnchorAndPosition(m_searchStartPosition, m_searchStartPosition);
|
||||
setPosition(m_searchStartPosition);
|
||||
scrollToLine(m_searchFromScreenLine);
|
||||
enterCommandMode(g.returnToMode);
|
||||
resetCommandMode();
|
||||
} else if (input.isBackspace()) {
|
||||
if (g.searchBuffer.isEmpty())
|
||||
resetCommandMode();
|
||||
@@ -4868,19 +4896,17 @@ EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input)
|
||||
g.lastSearch = needle;
|
||||
else
|
||||
g.searchBuffer.setContents(g.lastSearch);
|
||||
if (!g.lastSearch.isEmpty()) {
|
||||
updateFind(true);
|
||||
finishMovement(g.searchBuffer.prompt() + g.lastSearch + QLatin1Char('\n'));
|
||||
|
||||
updateFind(true);
|
||||
|
||||
if (finishSearch()) {
|
||||
if (g.submode != NoSubMode)
|
||||
finishMovement(g.searchBuffer.prompt() + g.lastSearch + QLatin1Char('\n'));
|
||||
if (g.currentMessage.isEmpty())
|
||||
showMessage(MessageCommand, g.searchBuffer.display());
|
||||
} else {
|
||||
finishMovement();
|
||||
}
|
||||
if (g.currentMessage.isEmpty())
|
||||
showMessage(MessageCommand, g.searchBuffer.display());
|
||||
else if (g.currentMessageLevel == MessageError)
|
||||
handled = EventCancelled; // Not found so cancel mapping if any.
|
||||
enterCommandMode(g.returnToMode);
|
||||
resetCommandMode();
|
||||
g.searchBuffer.clear();
|
||||
}
|
||||
} else if (input.isKey(Key_Tab)) {
|
||||
g.searchBuffer.insertChar(QChar(9));
|
||||
} else if (!g.searchBuffer.handleInput(input)) {
|
||||
@@ -4888,10 +4914,14 @@ EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input)
|
||||
return EventUnhandled;
|
||||
}
|
||||
|
||||
updateMiniBuffer();
|
||||
|
||||
if (!input.isReturn() && !input.isEscape())
|
||||
if (input.isReturn() || input.isEscape()) {
|
||||
g.searchBuffer.clear();
|
||||
resetCommandMode();
|
||||
updateMiniBuffer();
|
||||
} else {
|
||||
updateMiniBuffer();
|
||||
updateFind(false);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
@@ -5963,7 +5993,7 @@ void FakeVimHandler::Private::search(const SearchData &sd, bool showMessages)
|
||||
setTargetColumn();
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::searchNext(bool forward)
|
||||
bool FakeVimHandler::Private::searchNext(bool forward)
|
||||
{
|
||||
SearchData sd;
|
||||
sd.needle = g.lastSearch;
|
||||
@@ -5973,6 +6003,7 @@ void FakeVimHandler::Private::searchNext(bool forward)
|
||||
showMessage(MessageCommand, QLatin1Char(g.lastSearchForward ? '/' : '?') + sd.needle);
|
||||
recordJump();
|
||||
search(sd);
|
||||
return finishSearch();
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::highlightMatches(const QString &needle)
|
||||
|
||||
@@ -122,7 +122,6 @@ class MiniBuffer : public QStackedWidget
|
||||
public:
|
||||
MiniBuffer() : m_label(new QLabel(this)), m_edit(new QLineEdit(this)), m_eventFilter(0)
|
||||
{
|
||||
m_edit->installEventFilter(this);
|
||||
connect(m_edit, SIGNAL(textEdited(QString)), SLOT(changed()));
|
||||
connect(m_edit, SIGNAL(cursorPositionChanged(int,int)), SLOT(changed()));
|
||||
connect(m_edit, SIGNAL(selectionChanged()), SLOT(changed()));
|
||||
@@ -206,18 +205,6 @@ private slots:
|
||||
emit edited(m_edit->text(), cursorPos, anchorPos);
|
||||
}
|
||||
|
||||
bool eventFilter(QObject *ob, QEvent *ev)
|
||||
{
|
||||
// cancel editing on escape
|
||||
if (m_eventFilter != 0 && ob == m_edit && ev->type() == QEvent::ShortcutOverride
|
||||
&& static_cast<QKeyEvent*>(ev)->key() == Qt::Key_Escape) {
|
||||
emit edited(QString(), -1, -1);
|
||||
ev->accept();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
QLabel *m_label;
|
||||
QLineEdit *m_edit;
|
||||
|
||||
Reference in New Issue
Block a user