forked from qt-creator/qt-creator
fakevim: Improved command line buffers
Command line history should be global. Keep last submitted command/search visible. Change-Id: I0fc60786d486eb07c849d016aa23f71875d2cede Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
@@ -871,7 +871,7 @@ const QString &History::move(const QStringRef &prefix, int skip)
|
|||||||
return current();
|
return current();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This wraps a string and a "cursor position".
|
// Command line buffer with prompt (i.e. :, / or ? characters), text contents and cursor position.
|
||||||
class CommandBuffer
|
class CommandBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -1364,10 +1364,7 @@ public:
|
|||||||
|
|
||||||
int m_gflag; // whether current command started with 'g'
|
int m_gflag; // whether current command started with 'g'
|
||||||
|
|
||||||
CommandBuffer m_commandBuffer;
|
|
||||||
CommandBuffer m_searchBuffer;
|
|
||||||
QString m_currentFileName;
|
QString m_currentFileName;
|
||||||
QString m_currentMessage;
|
|
||||||
|
|
||||||
bool m_lastSearchForward;
|
bool m_lastSearchForward;
|
||||||
bool m_findPending;
|
bool m_findPending;
|
||||||
@@ -1523,6 +1520,7 @@ public:
|
|||||||
{
|
{
|
||||||
// default mapping state - shouldn't be removed
|
// default mapping state - shouldn't be removed
|
||||||
mapStates << MappingState();
|
mapStates << MappingState();
|
||||||
|
commandBuffer.setPrompt(':');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repetition.
|
// Repetition.
|
||||||
@@ -1539,6 +1537,13 @@ public:
|
|||||||
int inputTimer;
|
int inputTimer;
|
||||||
int lastMapCode;
|
int lastMapCode;
|
||||||
QStack<MappingState> mapStates;
|
QStack<MappingState> mapStates;
|
||||||
|
|
||||||
|
// Command line buffers.
|
||||||
|
CommandBuffer commandBuffer;
|
||||||
|
CommandBuffer searchBuffer;
|
||||||
|
|
||||||
|
// Current mini buffer message.
|
||||||
|
QString currentMessage;
|
||||||
} g;
|
} g;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1586,7 +1591,6 @@ void FakeVimHandler::Private::init()
|
|||||||
m_breakEditBlock = false;
|
m_breakEditBlock = false;
|
||||||
m_searchStartPosition = 0;
|
m_searchStartPosition = 0;
|
||||||
m_searchFromScreenLine = 0;
|
m_searchFromScreenLine = 0;
|
||||||
m_commandBuffer.setPrompt(':');
|
|
||||||
|
|
||||||
setupCharClass();
|
setupCharClass();
|
||||||
}
|
}
|
||||||
@@ -1900,7 +1904,7 @@ EventResult FakeVimHandler::Private::handleKey(const Input &input)
|
|||||||
QTC_CHECK(!g.mapStates.empty());
|
QTC_CHECK(!g.mapStates.empty());
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
if (g.mapStates.size() == 1)
|
if (g.mapStates.size() == 1)
|
||||||
m_commandBuffer.setHistoryAutoSave(true);
|
g.commandBuffer.setHistoryAutoSave(true);
|
||||||
if (m_mode == ExMode || m_subsubmode == SearchSubSubMode)
|
if (m_mode == ExMode || m_subsubmode == SearchSubSubMode)
|
||||||
updateMiniBuffer(); // update cursor position on command line
|
updateMiniBuffer(); // update cursor position on command line
|
||||||
} else {
|
} else {
|
||||||
@@ -1972,7 +1976,7 @@ void FakeVimHandler::Private::handleMappedKeys()
|
|||||||
g.pendingInput.clear();
|
g.pendingInput.clear();
|
||||||
g.pendingInput << inputs << Input() << rest;
|
g.pendingInput << inputs << Input() << rest;
|
||||||
g.mapStates << MappingState(maxMapDepth, inputs.noremap(), inputs.silent());
|
g.mapStates << MappingState(maxMapDepth, inputs.noremap(), inputs.silent());
|
||||||
m_commandBuffer.setHistoryAutoSave(false);
|
g.commandBuffer.setHistoryAutoSave(false);
|
||||||
beginEditBlock();
|
beginEditBlock();
|
||||||
}
|
}
|
||||||
g.currentMap.reset();
|
g.currentMap.reset();
|
||||||
@@ -2127,8 +2131,8 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
|
|||||||
int endLine = lineForPosition(position());
|
int endLine = lineForPosition(position());
|
||||||
setPosition(qMin(anchor(), position()));
|
setPosition(qMin(anchor(), position()));
|
||||||
enterExMode();
|
enterExMode();
|
||||||
m_currentMessage.clear();
|
g.currentMessage.clear();
|
||||||
m_commandBuffer.setContents(QString(".,+%1!").arg(qAbs(endLine - beginLine)));
|
g.commandBuffer.setContents(QString(".,+%1!").arg(qAbs(endLine - beginLine)));
|
||||||
updateMiniBuffer();
|
updateMiniBuffer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2331,19 +2335,22 @@ void FakeVimHandler::Private::updateMiniBuffer()
|
|||||||
QString msg;
|
QString msg;
|
||||||
int cursorPos = -1;
|
int cursorPos = -1;
|
||||||
|
|
||||||
|
if (g.mapStates.last().silent)
|
||||||
|
g.currentMessage.clear();
|
||||||
|
|
||||||
if (m_passing) {
|
if (m_passing) {
|
||||||
msg = "-- PASSING -- ";
|
msg = "-- PASSING -- ";
|
||||||
} else if (m_subsubmode == SearchSubSubMode) {
|
} else if (m_subsubmode == SearchSubSubMode) {
|
||||||
msg = m_searchBuffer.display();
|
msg = g.searchBuffer.display();
|
||||||
if (g.mapStates.size() == 1)
|
if (g.mapStates.size() == 1)
|
||||||
cursorPos = m_searchBuffer.cursorPos() + 1;
|
cursorPos = g.searchBuffer.cursorPos() + 1;
|
||||||
} else if (m_mode == ExMode) {
|
} else if (m_mode == ExMode) {
|
||||||
msg = m_commandBuffer.display();
|
msg = g.commandBuffer.display();
|
||||||
if (g.mapStates.size() == 1)
|
if (g.mapStates.size() == 1)
|
||||||
cursorPos = m_commandBuffer.cursorPos() + 1;
|
cursorPos = g.commandBuffer.cursorPos() + 1;
|
||||||
} else if (!m_currentMessage.isEmpty()) {
|
} else if (!g.currentMessage.isEmpty()) {
|
||||||
msg = m_currentMessage;
|
msg = g.currentMessage;
|
||||||
m_currentMessage.clear();
|
g.currentMessage.clear();
|
||||||
} else if (g.mapStates.size() > 1 && !g.mapStates.last().silent) {
|
} else if (g.mapStates.size() > 1 && !g.mapStates.last().silent) {
|
||||||
// Do not reset previous message when after running a mapped command.
|
// Do not reset previous message when after running a mapped command.
|
||||||
return;
|
return;
|
||||||
@@ -2383,14 +2390,14 @@ void FakeVimHandler::Private::updateMiniBuffer()
|
|||||||
void FakeVimHandler::Private::showRedMessage(const QString &msg)
|
void FakeVimHandler::Private::showRedMessage(const QString &msg)
|
||||||
{
|
{
|
||||||
//qDebug() << "MSG: " << msg;
|
//qDebug() << "MSG: " << msg;
|
||||||
m_currentMessage = msg;
|
g.currentMessage = msg;
|
||||||
updateMiniBuffer();
|
updateMiniBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::showBlackMessage(const QString &msg)
|
void FakeVimHandler::Private::showBlackMessage(const QString &msg)
|
||||||
{
|
{
|
||||||
//qDebug() << "MSG: " << msg;
|
//qDebug() << "MSG: " << msg;
|
||||||
m_currentMessage = msg;
|
g.currentMessage = msg;
|
||||||
updateMiniBuffer();
|
updateMiniBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2706,10 +2713,10 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input)
|
|||||||
handleExCommand(m_gflag ? "%s//~/&" : "s");
|
handleExCommand(m_gflag ? "%s//~/&" : "s");
|
||||||
} else if (input.is(':')) {
|
} else if (input.is(':')) {
|
||||||
enterExMode();
|
enterExMode();
|
||||||
m_currentMessage.clear();
|
g.currentMessage.clear();
|
||||||
m_commandBuffer.clear();
|
g.commandBuffer.clear();
|
||||||
if (isVisualMode())
|
if (isVisualMode())
|
||||||
m_commandBuffer.setContents("'<,'>");
|
g.commandBuffer.setContents("'<,'>");
|
||||||
updateMiniBuffer();
|
updateMiniBuffer();
|
||||||
} else if (input.is('/') || input.is('?')) {
|
} else if (input.is('/') || input.is('?')) {
|
||||||
m_lastSearchForward = input.is('/');
|
m_lastSearchForward = input.is('/');
|
||||||
@@ -2723,13 +2730,13 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input)
|
|||||||
} else {
|
} else {
|
||||||
// FIXME: make core find dialog sufficiently flexible to
|
// FIXME: make core find dialog sufficiently flexible to
|
||||||
// produce the "default vi" behaviour too. For now, roll our own.
|
// produce the "default vi" behaviour too. For now, roll our own.
|
||||||
m_currentMessage.clear();
|
g.currentMessage.clear();
|
||||||
m_movetype = MoveExclusive;
|
m_movetype = MoveExclusive;
|
||||||
m_subsubmode = SearchSubSubMode;
|
m_subsubmode = SearchSubSubMode;
|
||||||
m_searchBuffer.setPrompt(m_lastSearchForward ? '/' : '?');
|
g.searchBuffer.setPrompt(m_lastSearchForward ? '/' : '?');
|
||||||
m_searchStartPosition = position();
|
m_searchStartPosition = position();
|
||||||
m_searchFromScreenLine = firstVisibleLine();
|
m_searchFromScreenLine = firstVisibleLine();
|
||||||
m_searchBuffer.clear();
|
g.searchBuffer.clear();
|
||||||
updateMiniBuffer();
|
updateMiniBuffer();
|
||||||
}
|
}
|
||||||
} else if (input.is('`')) {
|
} else if (input.is('`')) {
|
||||||
@@ -2743,7 +2750,7 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input)
|
|||||||
tc.select(QTextCursor::WordUnderCursor);
|
tc.select(QTextCursor::WordUnderCursor);
|
||||||
needle = "\\<" + tc.selection().toPlainText() + "\\>";
|
needle = "\\<" + tc.selection().toPlainText() + "\\>";
|
||||||
setAnchorAndPosition(tc.position(), tc.anchor());
|
setAnchorAndPosition(tc.position(), tc.anchor());
|
||||||
m_searchBuffer.historyPush(needle);
|
g.searchBuffer.historyPush(needle);
|
||||||
m_lastSearchForward = input.is('*');
|
m_lastSearchForward = input.is('*');
|
||||||
searchNext();
|
searchNext();
|
||||||
finishMovement();
|
finishMovement();
|
||||||
@@ -2760,8 +2767,8 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input)
|
|||||||
m_submode = FilterSubMode;
|
m_submode = FilterSubMode;
|
||||||
} else if (input.is('!') && isVisualMode()) {
|
} else if (input.is('!') && isVisualMode()) {
|
||||||
enterExMode();
|
enterExMode();
|
||||||
m_currentMessage.clear();
|
g.currentMessage.clear();
|
||||||
m_commandBuffer.setContents("'<,'>!");
|
g.commandBuffer.setContents("'<,'>!");
|
||||||
updateMiniBuffer();
|
updateMiniBuffer();
|
||||||
} else if (input.is('"')) {
|
} else if (input.is('"')) {
|
||||||
m_submode = RegisterSubMode;
|
m_submode = RegisterSubMode;
|
||||||
@@ -3708,38 +3715,40 @@ void FakeVimHandler::Private::insertInInsertMode(const QString &text)
|
|||||||
EventResult FakeVimHandler::Private::handleExMode(const Input &input)
|
EventResult FakeVimHandler::Private::handleExMode(const Input &input)
|
||||||
{
|
{
|
||||||
if (input.isEscape()) {
|
if (input.isEscape()) {
|
||||||
m_commandBuffer.clear();
|
g.commandBuffer.clear();
|
||||||
enterCommandMode();
|
enterCommandMode();
|
||||||
m_ctrlVActive = false;
|
m_ctrlVActive = false;
|
||||||
} else if (m_ctrlVActive) {
|
} else if (m_ctrlVActive) {
|
||||||
m_commandBuffer.insertChar(input.raw());
|
g.commandBuffer.insertChar(input.raw());
|
||||||
m_ctrlVActive = false;
|
m_ctrlVActive = false;
|
||||||
} else if (input.isControl('v')) {
|
} else if (input.isControl('v')) {
|
||||||
m_ctrlVActive = true;
|
m_ctrlVActive = true;
|
||||||
return EventHandled;
|
return EventHandled;
|
||||||
} else if (input.isBackspace()) {
|
} else if (input.isBackspace()) {
|
||||||
if (m_commandBuffer.isEmpty())
|
if (g.commandBuffer.isEmpty())
|
||||||
enterCommandMode();
|
enterCommandMode();
|
||||||
else
|
else
|
||||||
m_commandBuffer.deleteChar();
|
g.commandBuffer.deleteChar();
|
||||||
} else if (input.isKey(Key_Tab)) {
|
} else if (input.isKey(Key_Tab)) {
|
||||||
// FIXME: Complete actual commands.
|
// FIXME: Complete actual commands.
|
||||||
m_commandBuffer.historyUp();
|
g.commandBuffer.historyUp();
|
||||||
} else if (input.isKey(Key_Left)) {
|
} else if (input.isKey(Key_Left)) {
|
||||||
m_commandBuffer.moveLeft();
|
g.commandBuffer.moveLeft();
|
||||||
} else if (input.isReturn()) {
|
} else if (input.isReturn()) {
|
||||||
if (!m_commandBuffer.isEmpty()) {
|
if (!g.commandBuffer.isEmpty()) {
|
||||||
//g.commandHistory.takeLast();
|
//g.commandHistory.takeLast();
|
||||||
handleExCommand(m_commandBuffer.contents());
|
handleExCommand(g.commandBuffer.contents());
|
||||||
m_commandBuffer.clear();
|
if (g.currentMessage.isEmpty())
|
||||||
|
g.currentMessage = g.commandBuffer.display();
|
||||||
|
g.commandBuffer.clear();
|
||||||
if (m_textedit || m_plaintextedit)
|
if (m_textedit || m_plaintextedit)
|
||||||
leaveVisualMode();
|
leaveVisualMode();
|
||||||
}
|
}
|
||||||
} else if (input.isKey(Key_Up) || input.isKey(Key_PageUp)) {
|
} else if (input.isKey(Key_Up) || input.isKey(Key_PageUp)) {
|
||||||
m_commandBuffer.historyUp();
|
g.commandBuffer.historyUp();
|
||||||
} else if (input.isKey(Key_Down) || input.isKey(Key_PageDown)) {
|
} else if (input.isKey(Key_Down) || input.isKey(Key_PageDown)) {
|
||||||
m_commandBuffer.historyDown();
|
g.commandBuffer.historyDown();
|
||||||
} else if (!m_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;
|
||||||
}
|
}
|
||||||
@@ -3750,27 +3759,27 @@ EventResult FakeVimHandler::Private::handleExMode(const Input &input)
|
|||||||
EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input)
|
EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input)
|
||||||
{
|
{
|
||||||
if (input.isEscape()) {
|
if (input.isEscape()) {
|
||||||
m_currentMessage.clear();
|
g.currentMessage.clear();
|
||||||
m_searchBuffer.clear();
|
g.searchBuffer.clear();
|
||||||
m_searchCursor = QTextCursor();
|
m_searchCursor = QTextCursor();
|
||||||
setPosition(m_searchStartPosition);
|
setPosition(m_searchStartPosition);
|
||||||
scrollToLine(m_searchFromScreenLine);
|
scrollToLine(m_searchFromScreenLine);
|
||||||
updateSelection();
|
updateSelection();
|
||||||
enterCommandMode();
|
enterCommandMode();
|
||||||
} else if (input.isBackspace()) {
|
} else if (input.isBackspace()) {
|
||||||
if (m_searchBuffer.isEmpty()) {
|
if (g.searchBuffer.isEmpty()) {
|
||||||
m_searchCursor = QTextCursor();
|
m_searchCursor = QTextCursor();
|
||||||
enterCommandMode();
|
enterCommandMode();
|
||||||
} else {
|
} else {
|
||||||
m_searchBuffer.deleteChar();
|
g.searchBuffer.deleteChar();
|
||||||
}
|
}
|
||||||
} else if (input.isKey(Key_Left)) {
|
} else if (input.isKey(Key_Left)) {
|
||||||
m_searchBuffer.moveLeft();
|
g.searchBuffer.moveLeft();
|
||||||
} else if (input.isKey(Key_Right)) {
|
} else if (input.isKey(Key_Right)) {
|
||||||
m_searchBuffer.moveRight();
|
g.searchBuffer.moveRight();
|
||||||
} else if (input.isReturn()) {
|
} else if (input.isReturn()) {
|
||||||
m_searchCursor = QTextCursor();
|
m_searchCursor = QTextCursor();
|
||||||
const QString &needle = m_searchBuffer.contents();
|
const QString &needle = g.searchBuffer.contents();
|
||||||
if (!needle.isEmpty()) {
|
if (!needle.isEmpty()) {
|
||||||
if (!hasConfig(ConfigIncSearch)) {
|
if (!hasConfig(ConfigIncSearch)) {
|
||||||
SearchData sd;
|
SearchData sd;
|
||||||
@@ -3780,27 +3789,29 @@ EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input)
|
|||||||
sd.highlightMatches = true;
|
sd.highlightMatches = true;
|
||||||
search(sd);
|
search(sd);
|
||||||
}
|
}
|
||||||
finishMovement(m_searchBuffer.prompt() + needle + '\n');
|
finishMovement(g.searchBuffer.prompt() + needle + '\n');
|
||||||
} else {
|
} else {
|
||||||
finishMovement();
|
finishMovement();
|
||||||
}
|
}
|
||||||
|
if (g.currentMessage.isEmpty())
|
||||||
|
g.currentMessage = g.searchBuffer.display();
|
||||||
enterCommandMode();
|
enterCommandMode();
|
||||||
highlightMatches(needle);
|
highlightMatches(needle);
|
||||||
m_searchBuffer.clear();
|
g.searchBuffer.clear();
|
||||||
} else if (input.isKey(Key_Up) || input.isKey(Key_PageUp)) {
|
} else if (input.isKey(Key_Up) || input.isKey(Key_PageUp)) {
|
||||||
m_searchBuffer.historyUp();
|
g.searchBuffer.historyUp();
|
||||||
} else if (input.isKey(Key_Down) || input.isKey(Key_PageDown)) {
|
} else if (input.isKey(Key_Down) || input.isKey(Key_PageDown)) {
|
||||||
m_searchBuffer.historyDown();
|
g.searchBuffer.historyDown();
|
||||||
} else if (input.isKey(Key_Tab)) {
|
} else if (input.isKey(Key_Tab)) {
|
||||||
m_searchBuffer.insertChar(QChar(9));
|
g.searchBuffer.insertChar(QChar(9));
|
||||||
} else if (!m_searchBuffer.handleInput(input)) {
|
} else if (!g.searchBuffer.handleInput(input)) {
|
||||||
return EventUnhandled;
|
return EventUnhandled;
|
||||||
}
|
}
|
||||||
updateMiniBuffer();
|
updateMiniBuffer();
|
||||||
|
|
||||||
if (hasConfig(ConfigIncSearch) && !input.isReturn() && !input.isEscape()) {
|
if (hasConfig(ConfigIncSearch) && !input.isReturn() && !input.isEscape()) {
|
||||||
SearchData sd;
|
SearchData sd;
|
||||||
sd.needle = m_searchBuffer.contents();
|
sd.needle = g.searchBuffer.contents();
|
||||||
sd.forward = m_lastSearchForward;
|
sd.forward = m_lastSearchForward;
|
||||||
sd.highlightCursor = true;
|
sd.highlightCursor = true;
|
||||||
sd.highlightMatches = false;
|
sd.highlightMatches = false;
|
||||||
@@ -4133,7 +4144,7 @@ bool FakeVimHandler::Private::handleExHistoryCommand(const ExCommand &cmd)
|
|||||||
QString info;
|
QString info;
|
||||||
info += "# command history\n";
|
info += "# command history\n";
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (const QString &item, m_commandBuffer.historyItems()) {
|
foreach (const QString &item, g.commandBuffer.historyItems()) {
|
||||||
++i;
|
++i;
|
||||||
info += QString("%1 %2\n").arg(i, -8).arg(item);
|
info += QString("%1 %2\n").arg(i, -8).arg(item);
|
||||||
}
|
}
|
||||||
@@ -4468,7 +4479,7 @@ bool FakeVimHandler::Private::handleExEchoCommand(const ExCommand &cmd)
|
|||||||
// :echo
|
// :echo
|
||||||
if (cmd.cmd != "echo")
|
if (cmd.cmd != "echo")
|
||||||
return false;
|
return false;
|
||||||
m_currentMessage = cmd.args;
|
g.currentMessage = cmd.args;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4647,16 +4658,14 @@ void FakeVimHandler::Private::search(const SearchData &sd)
|
|||||||
void FakeVimHandler::Private::searchNext(bool forward)
|
void FakeVimHandler::Private::searchNext(bool forward)
|
||||||
{
|
{
|
||||||
SearchData sd;
|
SearchData sd;
|
||||||
sd.needle = m_searchBuffer.last();
|
sd.needle = g.searchBuffer.last();
|
||||||
sd.forward = forward ? m_lastSearchForward : !m_lastSearchForward;
|
sd.forward = forward ? m_lastSearchForward : !m_lastSearchForward;
|
||||||
sd.highlightCursor = false;
|
sd.highlightCursor = false;
|
||||||
sd.highlightMatches = true;
|
sd.highlightMatches = true;
|
||||||
m_searchStartPosition = position();
|
m_searchStartPosition = position();
|
||||||
m_currentMessage.clear();
|
g.currentMessage = (m_lastSearchForward ? '/' : '?') + sd.needle;
|
||||||
|
updateMiniBuffer();
|
||||||
search(sd);
|
search(sd);
|
||||||
|
|
||||||
m_searchBuffer.setPrompt(m_lastSearchForward ? '/' : '?');
|
|
||||||
m_searchBuffer.setContents(sd.needle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::highlightMatches(const QString &needle)
|
void FakeVimHandler::Private::highlightMatches(const QString &needle)
|
||||||
|
|||||||
Reference in New Issue
Block a user