fakevim: Appearance of command line widget.

Widget for Ex and search mode is QLineEdit.

Messages are displayed using QLabel widget with different style for
error, warnings etc.

Change-Id: I4d4f799bbe261febaf6c2c21c01f6b66e1beec6e
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
Lukas Holecek
2012-09-10 22:10:23 +02:00
committed by hjk
parent 3934b9b976
commit 1264d0ea5e
3 changed files with 241 additions and 143 deletions

View File

@@ -880,6 +880,8 @@ public:
void setPrompt(const QChar &prompt) { m_prompt = prompt; }
void setContents(const QString &s) { m_buffer = s; m_pos = s.size(); }
void setContents(const QString &s, int pos) { m_buffer = s; m_pos = m_userPos = pos; }
QStringRef userContents() const { return m_buffer.leftRef(m_userPos); }
const QChar &prompt() const { return m_prompt; }
const QString &contents() const { return m_buffer; }
@@ -1143,11 +1145,12 @@ public:
void finishMovement(const QString &dotCommand = QString());
void finishMovement(const QString &dotCommand, int count);
void resetCommandMode();
void search(const SearchData &sd);
void search(const SearchData &sd, bool showMessages = true);
void searchNext(bool forward = true);
void searchBalanced(bool forward, QChar needle, QChar other);
void highlightMatches(const QString &needle);
void stopIncrementalFind();
void updateFind(bool isComplete);
int mvCount() const { return m_mvcount.isEmpty() ? 1 : m_mvcount.toInt(); }
int opCount() const { return m_opcount.isEmpty() ? 1 : m_opcount.toInt(); }
@@ -1286,8 +1289,8 @@ public:
void enterReplaceMode();
void enterCommandMode();
void enterExMode();
void showRedMessage(const QString &msg);
void showBlackMessage(const QString &msg);
void showMessage(MessageLevel level, const QString &msg);
void clearMessage() { showMessage(MessageInfo, QString()); }
void notImplementedYet();
void updateMiniBuffer();
void updateSelection();
@@ -1514,9 +1517,12 @@ public:
signed char m_charClass[256];
bool m_ctrlVActive;
void miniBufferTextEdited(const QString &text, int cursorPos);
static struct GlobalData
{
GlobalData() : mappings(), currentMap(&mappings), inputTimer(-1)
GlobalData()
: mappings(), currentMap(&mappings), inputTimer(-1), currentMessageLevel(MessageInfo)
{
// default mapping state - shouldn't be removed
mapStates << MappingState();
@@ -1544,6 +1550,7 @@ public:
// Current mini buffer message.
QString currentMessage;
MessageLevel currentMessageLevel;
} g;
};
@@ -1847,7 +1854,7 @@ void FakeVimHandler::Private::updateEditor()
void FakeVimHandler::Private::restoreWidget(int tabSize)
{
//showBlackMessage(QString());
//clearMessage();
//updateMiniBuffer();
//EDITOR(removeEventFilter(q));
//EDITOR(setReadOnly(m_wasReadOnly));
@@ -1968,7 +1975,7 @@ void FakeVimHandler::Private::handleMappedKeys()
}
if (maxMapDepth <= 0) {
showRedMessage("recursive mapping");
showMessage(MessageError, "recursive mapping");
g.pendingInput.remove(0, g.currentMap.mapLength() + invalidCount);
} else {
const Inputs &inputs = g.currentMap.inputs();
@@ -2002,6 +2009,22 @@ void FakeVimHandler::Private::stopIncrementalFind()
}
}
void FakeVimHandler::Private::updateFind(bool isComplete)
{
if (!isComplete && !hasConfig(ConfigIncSearch))
return;
g.currentMessage.clear();
const QString &needle = g.searchBuffer.contents();
SearchData sd;
sd.needle = needle;
sd.forward = m_lastSearchForward;
sd.highlightCursor = !isComplete;
sd.highlightMatches = isComplete;
search(sd, isComplete);
}
bool FakeVimHandler::Private::atEmptyLine(const QTextCursor &tc) const
{
if (tc.isNull())
@@ -2245,7 +2268,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
setPosition(anchor());
}
if (la != lp)
showBlackMessage(QString("%1 lines yanked").arg(qAbs(la - lp) + 1));
showMessage(MessageInfo, QString("%1 lines yanked").arg(qAbs(la - lp) + 1));
} else if (m_submode == TransformSubMode) {
if (m_subsubmode == InvertCaseSubSubMode) {
invertCase(currentRange());
@@ -2334,12 +2357,13 @@ void FakeVimHandler::Private::updateMiniBuffer()
QString msg;
int cursorPos = -1;
MessageLevel messageLevel = MessageMode;
if (g.mapStates.last().silent)
if (g.mapStates.last().silent && g.currentMessageLevel < MessageInfo)
g.currentMessage.clear();
if (m_passing) {
msg = "-- PASSING -- ";
msg = "PASSING";
} else if (m_subsubmode == SearchSubSubMode) {
msg = g.searchBuffer.display();
if (g.mapStates.size() == 1)
@@ -2351,27 +2375,28 @@ void FakeVimHandler::Private::updateMiniBuffer()
} else if (!g.currentMessage.isEmpty()) {
msg = g.currentMessage;
g.currentMessage.clear();
messageLevel = g.currentMessageLevel;
} else if (g.mapStates.size() > 1 && !g.mapStates.last().silent) {
// Do not reset previous message when after running a mapped command.
return;
} else if (m_mode == CommandMode && isVisualMode()) {
if (isVisualCharMode()) {
msg = "-- VISUAL --";
msg = "VISUAL";
} else if (isVisualLineMode()) {
msg = "-- VISUAL LINE --";
msg = "VISUAL LINE";
} else if (isVisualBlockMode()) {
msg = "-- VISUAL BLOCK --";
msg = "VISUAL BLOCK";
}
} else if (m_mode == InsertMode) {
msg = "-- INSERT --";
msg = "INSERT";
} else if (m_mode == ReplaceMode) {
msg = "-- REPLACE --";
msg = "REPLACE";
} else {
QTC_CHECK(m_mode == CommandMode && m_subsubmode != SearchSubSubMode);
msg = "-- COMMAND --";
msg = "COMMAND";
}
emit q->commandBufferChanged(msg, cursorPos);
emit q->commandBufferChanged(msg, cursorPos, messageLevel, q);
int linesInDoc = linesInDocument();
int l = cursorLine();
@@ -2387,24 +2412,18 @@ void FakeVimHandler::Private::updateMiniBuffer()
emit q->statusDataChanged(status);
}
void FakeVimHandler::Private::showRedMessage(const QString &msg)
{
//qDebug() << "MSG: " << msg;
g.currentMessage = msg;
updateMiniBuffer();
}
void FakeVimHandler::Private::showBlackMessage(const QString &msg)
void FakeVimHandler::Private::showMessage(MessageLevel level, const QString &msg)
{
//qDebug() << "MSG: " << msg;
g.currentMessage = msg;
g.currentMessageLevel = level;
updateMiniBuffer();
}
void FakeVimHandler::Private::notImplementedYet()
{
qDebug() << "Not implemented in FakeVim";
showRedMessage(FakeVimHandler::tr("Not implemented in FakeVim"));
showMessage(MessageError, FakeVimHandler::tr("Not implemented in FakeVim"));
updateMiniBuffer();
}
@@ -2486,7 +2505,7 @@ EventResult FakeVimHandler::Private::handleCommandSubSubMode(const Input &input)
moveToFirstNonBlankOnLine();
finishMovement();
} else {
showRedMessage(msgMarkNotSet(input.text()));
showMessage(MessageError, msgMarkNotSet(input.text()));
}
m_subsubmode = NoSubSubMode;
} else {
@@ -2896,7 +2915,7 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input)
finishMovement();
} else if (input.isControl('c')) {
if (isNoVisualMode())
showBlackMessage("Type Alt-v,Alt-v to quit FakeVim mode");
showMessage(MessageInfo, "Type Alt-v,Alt-v to quit FakeVim mode");
else
leaveVisualMode();
} else if (input.is('d') && isNoVisualMode()) {
@@ -3460,6 +3479,7 @@ EventResult FakeVimHandler::Private::handleReplaceMode(const Input &input)
m_submode = NoSubMode;
m_mode = CommandMode;
finishMovement();
updateMiniBuffer();
} else if (input.isKey(Key_Left)) {
breakEditBlock();
moveLeft(1);
@@ -3735,15 +3755,11 @@ EventResult FakeVimHandler::Private::handleExMode(const Input &input)
} else if (input.isKey(Key_Left)) {
g.commandBuffer.moveLeft();
} else if (input.isReturn()) {
if (!g.commandBuffer.isEmpty()) {
//g.commandHistory.takeLast();
handleExCommand(g.commandBuffer.contents());
if (g.currentMessage.isEmpty())
g.currentMessage = g.commandBuffer.display();
g.commandBuffer.clear();
if (m_textedit || m_plaintextedit)
leaveVisualMode();
}
showMessage(MessageCommand, g.commandBuffer.display());
handleExCommand(g.commandBuffer.contents());
g.commandBuffer.clear();
if (m_textedit || m_plaintextedit)
leaveVisualMode();
} else if (input.isKey(Key_Up) || input.isKey(Key_PageUp)) {
g.commandBuffer.historyUp();
} else if (input.isKey(Key_Down) || input.isKey(Key_PageDown)) {
@@ -3781,20 +3797,13 @@ EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input)
m_searchCursor = QTextCursor();
const QString &needle = g.searchBuffer.contents();
if (!needle.isEmpty()) {
if (!hasConfig(ConfigIncSearch)) {
SearchData sd;
sd.needle = needle;
sd.forward = m_lastSearchForward;
sd.highlightCursor = false;
sd.highlightMatches = true;
search(sd);
}
updateFind(true);
finishMovement(g.searchBuffer.prompt() + needle + '\n');
} else {
finishMovement();
}
if (g.currentMessage.isEmpty())
g.currentMessage = g.searchBuffer.display();
showMessage(MessageCommand, g.searchBuffer.display());
enterCommandMode();
highlightMatches(needle);
g.searchBuffer.clear();
@@ -3805,23 +3814,15 @@ EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input)
} else if (input.isKey(Key_Tab)) {
g.searchBuffer.insertChar(QChar(9));
} else if (!g.searchBuffer.handleInput(input)) {
//qDebug() << "IGNORED IN SEARCH MODE: " << input.key() << input.text();
return EventUnhandled;
}
updateMiniBuffer();
if (hasConfig(ConfigIncSearch) && !input.isReturn() && !input.isEscape()) {
SearchData sd;
sd.needle = g.searchBuffer.contents();
sd.forward = m_lastSearchForward;
sd.highlightCursor = true;
sd.highlightMatches = false;
search(sd);
}
if (!input.isReturn() && !input.isEscape())
updateFind(false);
//else {
// qDebug() << "IGNORED IN SEARCH MODE: " << input.key() << input.text();
// return EventUnhandled;
//}
return EventHandled;
}
@@ -3848,12 +3849,12 @@ int FakeVimHandler::Private::readLineCode(QString &cmd)
return linesInDocument();
if (c == '\'' && !cmd.isEmpty()) {
if (cmd.isEmpty()) {
showRedMessage(msgMarkNotSet(QString()));
showMessage(MessageError, msgMarkNotSet(QString()));
return -1;
}
int m = mark(cmd.at(0).unicode());
if (m == -1) {
showRedMessage(msgMarkNotSet(cmd.at(0)));
showMessage(MessageError, msgMarkNotSet(cmd.at(0)));
cmd = cmd.mid(1);
return -1;
}
@@ -3871,7 +3872,7 @@ int FakeVimHandler::Private::readLineCode(QString &cmd)
if (c == '\'' && !cmd.isEmpty()) {
int pos = mark(cmd.at(0).unicode());
if (pos == -1) {
showRedMessage(msgMarkNotSet(cmd.at(0)));
showMessage(MessageError, msgMarkNotSet(cmd.at(0)));
cmd = cmd.mid(1);
return -1;
}
@@ -4189,7 +4190,7 @@ bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd)
if (!cmd.matches("se", "set"))
return false;
showBlackMessage(QString());
clearMessage();
SavedAction *act = theFakeVimSettings()->item(cmd.args);
QTC_CHECK(!cmd.args.isEmpty()); // Handled by plugin.
if (act && act->value().canConvert(QVariant::Bool)) {
@@ -4201,7 +4202,7 @@ bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd)
{} // nothing to do
} else if (act) {
// Non-boolean to show.
showBlackMessage(cmd.args + '=' + act->value().toString());
showMessage(MessageInfo, cmd.args + '=' + act->value().toString());
} else if (cmd.args.startsWith(_("no"))
&& (act = theFakeVimSettings()->item(cmd.args.mid(2)))) {
// Boolean config to be switched off.
@@ -4216,9 +4217,9 @@ bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd)
QString error = theFakeVimSettings()
->trySetValue(cmd.args.left(p), cmd.args.mid(p + 1));
if (!error.isEmpty())
showRedMessage(error);
showMessage(MessageError, error);
} else {
showRedMessage(FakeVimHandler::tr("Unknown option: ") + cmd.args);
showMessage(MessageError, FakeVimHandler::tr("Unknown option: ") + cmd.args);
}
updateMiniBuffer();
updateEditor();
@@ -4278,7 +4279,7 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd)
QFile file1(fileName);
const bool exists = file1.exists();
if (exists && !forced && !noArgs) {
showRedMessage(FakeVimHandler::tr
showMessage(MessageError, FakeVimHandler::tr
("File \"%1\" exists (add ! to override)").arg(fileName));
} else if (file1.open(QIODevice::ReadWrite)) {
// Nobody cared, so act ourselves.
@@ -4292,14 +4293,14 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd)
QTextStream ts(&file2);
ts << contents;
} else {
showRedMessage(FakeVimHandler::tr
showMessage(MessageError, FakeVimHandler::tr
("Cannot open file \"%1\" for writing").arg(fileName));
}
// Check result by reading back.
QFile file3(fileName);
file3.open(QIODevice::ReadOnly);
QByteArray ba = file3.readAll();
showBlackMessage(FakeVimHandler::tr("\"%1\" %2 %3L, %4C written")
showMessage(MessageInfo, FakeVimHandler::tr("\"%1\" %2 %3L, %4C written")
.arg(fileName).arg(exists ? " " : tr(" [New] "))
.arg(ba.count('\n')).arg(ba.size()));
//if (quitAll)
@@ -4307,7 +4308,7 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd)
//else if (quit)
// passUnknownExCommand(forced ? "q!" : "q");
} else {
showRedMessage(FakeVimHandler::tr
showMessage(MessageError, FakeVimHandler::tr
("Cannot open file \"%1\" for reading").arg(fileName));
}
return true;
@@ -4330,7 +4331,7 @@ bool FakeVimHandler::Private::handleExReadCommand(const ExCommand &cmd)
QString data = ts.readAll();
insertText(data);
endEditBlock();
showBlackMessage(FakeVimHandler::tr("\"%1\" %2L, %3C")
showMessage(MessageInfo, FakeVimHandler::tr("\"%1\" %2L, %3C")
.arg(m_currentFileName).arg(data.count('\n')).arg(data.size()));
return true;
}
@@ -4363,7 +4364,7 @@ bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :!
endEditBlock();
leaveVisualMode();
//qDebug() << "FILTER: " << command;
showBlackMessage(FakeVimHandler::tr("%n lines filtered", 0,
showMessage(MessageInfo, FakeVimHandler::tr("%n lines filtered", 0,
text.count('\n')));
}
return true;
@@ -4386,7 +4387,7 @@ bool FakeVimHandler::Private::handleExShiftCommand(const ExCommand &cmd)
leaveVisualMode();
const int beginLine = lineForPosition(range.beginPos);
const int endLine = lineForPosition(range.endPos);
showBlackMessage(FakeVimHandler::tr("%n lines %1ed %2 time", 0,
showMessage(MessageInfo, FakeVimHandler::tr("%n lines %1ed %2 time", 0,
(endLine - beginLine + 1)).arg(cmd.cmd).arg(count));
return true;
}
@@ -4432,7 +4433,7 @@ bool FakeVimHandler::Private::handleExGotoCommand(const ExCommand &cmd)
const int beginLine = lineForPosition(cmd.range.beginPos);
setPosition(firstPositionInLine(beginLine));
showBlackMessage(QString());
clearMessage();
return true;
}
@@ -4445,7 +4446,7 @@ bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd)
QString fileName = cmd.args;
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
showRedMessage(FakeVimHandler::tr("Cannot open file %1").arg(fileName));
showMessage(MessageError, FakeVimHandler::tr("Cannot open file %1").arg(fileName));
return true;
}
@@ -4479,7 +4480,7 @@ bool FakeVimHandler::Private::handleExEchoCommand(const ExCommand &cmd)
// :echo
if (cmd.cmd != "echo")
return false;
g.currentMessage = cmd.args;
showMessage(MessageInfo, cmd.args);
return true;
}
@@ -4491,7 +4492,7 @@ void FakeVimHandler::Private::handleExCommand(const QString &line0)
line.chop(1);
int percent = line.toInt();
setPosition(firstPositionInLine(percent * linesInDocument() / 100));
showBlackMessage(QString());
clearMessage();
return;
}
@@ -4517,9 +4518,8 @@ void FakeVimHandler::Private::handleExCommand(const QString &line0)
}
//qDebug() << "CMD: " << cmd;
showBlackMessage(QString());
if (!handleExCommandHelper(cmd))
showRedMessage(tr("Not an editor command: %1").arg(cmd.cmd));
showMessage(MessageError, tr("Not an editor command: %1").arg(cmd.cmd));
enterCommandMode();
}
@@ -4584,7 +4584,7 @@ void FakeVimHandler::Private::searchBalanced(bool forward, QChar needle, QChar o
}
}
void FakeVimHandler::Private::search(const SearchData &sd)
void FakeVimHandler::Private::search(const SearchData &sd, bool showMessages)
{
QTextDocument::FindFlags flags = QTextDocument::FindCaseSensitively;
if (!sd.forward)
@@ -4610,19 +4610,22 @@ void FakeVimHandler::Private::search(const SearchData &sd)
tc = document()->find(needleExp, tc, flags);
if (tc.isNull()) {
highlightMatches(QString());
showRedMessage(FakeVimHandler::tr("Pattern not found: %1").arg(sd.needle));
if (showMessages) {
showMessage(MessageError,
FakeVimHandler::tr("Pattern not found: %1").arg(sd.needle));
}
updateSelection();
} else {
} else if (showMessages) {
QString msg = sd.forward
? FakeVimHandler::tr("search hit BOTTOM, continuing at TOP")
: FakeVimHandler::tr("search hit TOP, continuing at BOTTOM");
showRedMessage(msg);
showMessage(MessageWarning, msg);
}
} else {
} else if (showMessages) {
QString msg = sd.forward
? FakeVimHandler::tr("search hit BOTTOM without match for: %1")
: FakeVimHandler::tr("search hit TOP without match for: %1");
showRedMessage(msg.arg(sd.needle));
showMessage(MessageError, msg.arg(sd.needle));
}
}
@@ -4663,8 +4666,7 @@ void FakeVimHandler::Private::searchNext(bool forward)
sd.highlightCursor = false;
sd.highlightMatches = true;
m_searchStartPosition = position();
g.currentMessage = (m_lastSearchForward ? '/' : '?') + sd.needle;
updateMiniBuffer();
showMessage(MessageCommand, (m_lastSearchForward ? '/' : '?') + sd.needle);
search(sd);
}
@@ -4683,7 +4685,7 @@ void FakeVimHandler::Private::highlightMatches(const QString &needle)
QRegExp needleExp = vimPatternToQtPattern(needle, hasConfig(ConfigSmartCase));
if (!needleExp.isValid()) {
QString error = needleExp.errorString();
showRedMessage(
showMessage(MessageError,
FakeVimHandler::tr("Invalid regular expression: %1").arg(error));
return;
}
@@ -4753,7 +4755,7 @@ void FakeVimHandler::Private::indentText(const Range &range, QChar typedChar)
// LineForPosition has returned 1-based line numbers.
emit q->indentRegion(beginLine - 1, endLine - 1, typedChar);
if (beginLine != endLine)
showBlackMessage("MARKS ARE OFF NOW");
showMessage(MessageError, "MARKS ARE OFF NOW");
}
bool FakeVimHandler::Private::isElectricCharacter(QChar c) const
@@ -4877,6 +4879,32 @@ int FakeVimHandler::Private::charClass(QChar c, bool simple) const
return c.isSpace() ? 0 : 1;
}
void FakeVimHandler::Private::miniBufferTextEdited(const QString &text, int cursorPos)
{
if (m_subsubmode != SearchSubSubMode && m_mode != ExMode) {
editor()->setFocus();
} else if (text.isEmpty()) {
// editing cancelled
handleDefaultKey(Input(Qt::Key_Escape, Qt::NoModifier, QString()));
editor()->setFocus();
updateCursorShape();
} else {
CommandBuffer &cmdBuf = (m_mode == ExMode) ? g.commandBuffer : g.searchBuffer;
// prepend prompt character if missing
if (!text.startsWith(cmdBuf.prompt())) {
emit q->commandBufferChanged(cmdBuf.prompt() + text, cmdBuf.cursorPos() + 1, 0, q);
cmdBuf.setContents(text, cursorPos - 1);
} else {
cmdBuf.setContents(text.mid(1), cursorPos - 1);
}
// update search expression
if (m_subsubmode == SearchSubSubMode) {
updateFind(false);
exportSelection();
}
}
}
// Helper to parse a-z,A-Z,48-57,_
static int someInt(const QString &str)
{
@@ -5657,10 +5685,10 @@ void FakeVimHandler::Private::undo()
m_undo.pop();
if (current == rev) {
showBlackMessage(FakeVimHandler::tr("Already at oldest change"));
showMessage(MessageInfo, FakeVimHandler::tr("Already at oldest change"));
return;
}
showBlackMessage(QString());
clearMessage();
if (!m_undo.empty()) {
State &state = m_undo.top();
@@ -5689,10 +5717,10 @@ void FakeVimHandler::Private::redo()
m_redo.pop();
if (rev == current) {
showBlackMessage(FakeVimHandler::tr("Already at newest change"));
showMessage(MessageInfo, FakeVimHandler::tr("Already at newest change"));
return;
}
showBlackMessage(QString());
clearMessage();
if (!m_redo.empty()) {
State &state = m_redo.top();
@@ -6224,7 +6252,7 @@ bool FakeVimHandler::eventFilter(QObject *ob, QEvent *ev)
return res == EventHandled;
}
if (active && ev->type() == QEvent::KeyPress && ob == d->editor()) {
if (active && ev->type() == QEvent::KeyPress) {
QKeyEvent *kev = static_cast<QKeyEvent *>(ev);
KEY_DEBUG("KEYPRESS" << kev->key() << kev->text() << QChar(kev->key()));
EventResult res = d->handleEvent(kev);
@@ -6300,14 +6328,9 @@ QString FakeVimHandler::currentFileName() const
return d->m_currentFileName;
}
void FakeVimHandler::showBlackMessage(const QString &msg)
void FakeVimHandler::showMessage(MessageLevel level, const QString &msg)
{
d->showBlackMessage(msg);
}
void FakeVimHandler::showRedMessage(const QString &msg)
{
d->showRedMessage(msg);
d->showMessage(level, msg);
}
QWidget *FakeVimHandler::widget()
@@ -6333,6 +6356,11 @@ QString FakeVimHandler::tabExpand(int n) const
return d->tabExpand(n);
}
void FakeVimHandler::miniBufferTextEdited(const QString &text, int cursorPos)
{
d->miniBufferTextEdited(text, cursorPos);
}
} // namespace Internal
} // namespace FakeVim

View File

@@ -77,6 +77,16 @@ struct ExCommand
int count;
};
// message levels sorted by severity
enum MessageLevel
{
MessageMode, // show current mode (format "-- %1 --")
MessageCommand, // show last Ex command or search
MessageInfo, // result of a command
MessageWarning, // warning
MessageError // error
};
class FakeVimHandler : public QObject
{
Q_OBJECT
@@ -94,8 +104,7 @@ public slots:
void setCurrentFileName(const QString &fileName);
QString currentFileName() const;
void showBlackMessage(const QString &msg);
void showRedMessage(const QString &msg);
void showMessage(MessageLevel level, const QString &msg);
// This executes an "ex" style command taking context
// information from the current widget.
@@ -114,8 +123,10 @@ public slots:
int logicalIndentation(const QString &line) const;
QString tabExpand(int n) const;
void miniBufferTextEdited(const QString &text, int cursorPos);
signals:
void commandBufferChanged(const QString &msg, int pos);
void commandBufferChanged(const QString &msg, int pos, int messageLevel, QObject *eventFilter);
void statusDataChanged(const QString &msg);
void extraInformationChanged(const QString &msg);
void selectionChanged(const QList<QTextEdit::ExtraSelection> &selection);

View File

@@ -86,6 +86,7 @@
#include <QtPlugin>
#include <QObject>
#include <QSettings>
#include <QStackedWidget>
#include <QTextStream>
#include <QDesktopServices>
@@ -111,49 +112,99 @@ const char SETTINGS_ID[] = "A.General";
const char SETTINGS_EX_CMDS_ID[] = "B.ExCommands";
const char SETTINGS_USER_CMDS_ID[] = "C.UserCommands";
class MiniBuffer : public QLabel
class MiniBuffer : public QStackedWidget
{
Q_OBJECT
public:
void setContents(const QString &contents, int cursorPos)
MiniBuffer() : m_label(new QLabel(this)), m_edit(new QLineEdit(this)), m_eventFilter(0)
{
QString msg = contents;
if (cursorPos != -1)
msg = contents.left(cursorPos) + QChar(10073) + contents.mid(cursorPos);
setText(" " + msg);
}
};
m_edit->installEventFilter(this);
connect(m_edit, SIGNAL(textEdited(QString)), SLOT(changed()));
connect(m_edit, SIGNAL(cursorPositionChanged(int,int)), SLOT(changed()));
m_label->setTextInteractionFlags(Qt::TextSelectableByMouse);
class MiniBuffer1 : public QLineEdit
{
Q_OBJECT
addWidget(m_label);
addWidget(m_edit);
}
public:
MiniBuffer1()
void setContents(const QString &contents, int cursorPos, int messageLevel, QObject *eventFilter)
{
setFrame(false);
if (cursorPos != -1) {
m_edit->blockSignals(true);
m_label->clear();
m_edit->setText(contents);
m_edit->setCursorPosition(cursorPos);
m_edit->blockSignals(false);
setCurrentWidget(m_edit);
m_edit->setFocus();
} else {
m_label->setText(messageLevel == MessageMode ? "-- " + contents + " --" : contents);
QString css;
if (messageLevel == MessageError) {
css = QString("border:1px solid rgba(255,255,255,150);"
"background-color:rgba(255,0,0,100);");
} else if (messageLevel == MessageWarning) {
css = QString("border:1px solid rgba(255,255,255,120);"
"background-color:rgba(255,255,0,20);");
}
m_label->setStyleSheet(QString(
"*{border-radius:2px;padding-left:4px;padding-right:4px;%1}").arg(css));
if (m_edit->hasFocus())
emit edited(QString(), -1);
setCurrentWidget(m_label);
}
if (m_eventFilter != eventFilter) {
if (m_eventFilter != 0) {
m_edit->removeEventFilter(m_eventFilter);
disconnect(SIGNAL(edited(QString,int)));
}
if (eventFilter != 0) {
m_edit->installEventFilter(eventFilter);
connect(this, SIGNAL(edited(QString,int)),
eventFilter, SLOT(miniBufferTextEdited(QString,int)));
}
m_eventFilter = eventFilter;
}
}
void showEvent(QShowEvent *ev)
QSize sizeHint() const
{
QLineEdit::showEvent(ev);
QColor color = Qt::black;
QPalette pal = parentWidget()->palette();
pal.setBrush(QPalette::All, QPalette::WindowText, color);
pal.setBrush(QPalette::All, QPalette::ButtonText, color);
pal.setBrush(QPalette::All, QPalette::Foreground, color);
pal.setBrush(QPalette::All, QPalette::Background, color);
//color.setAlpha(100);
//pal.setBrush(QPalette::Disabled, QPalette::WindowText, color);
//pal.setBrush(QPalette::Disabled, QPalette::ButtonText, color);
//pal.setBrush(QPalette::Disabled, QPalette::Foreground, color);
setPalette(pal);
QSize size = QWidget::sizeHint();
// reserve maximal width for line edit widget
return currentWidget() == m_edit ? QSize(maximumWidth(), size.height()) : size;
}
void setContents(const QString &contents, int cursorPos)
signals:
void edited(const QString &text, int cursorPos);
private slots:
void changed()
{
setText(contents);
setCursorPosition(cursorPos);
emit edited(m_edit->text(), m_edit->cursorPosition());
}
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);
ev->accept();
return true;
}
return false;
}
private:
QLabel *m_label;
QLineEdit *m_edit;
QObject *m_eventFilter;
};
///////////////////////////////////////////////////////////////////////
@@ -797,7 +848,9 @@ private slots:
void setBlockSelection(bool);
void hasBlockSelection(bool*);
void showCommandBuffer(const QString &contents, int cursorPos);
void resetCommandBuffer();
void showCommandBuffer(const QString &contents, int cursorPos, int messageLevel,
QObject *eventFilter);
void showExtraInformation(const QString &msg);
void changeSelection(const QList<QTextEdit::ExtraSelection> &selections);
void moveToMatchingParenthesis(bool *moved, bool *forward, QTextCursor *cursor);
@@ -1340,8 +1393,8 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
connect(handler, SIGNAL(extraInformationChanged(QString)),
SLOT(showExtraInformation(QString)));
connect(handler, SIGNAL(commandBufferChanged(QString,int)),
SLOT(showCommandBuffer(QString,int)));
connect(handler, SIGNAL(commandBufferChanged(QString,int,int,QObject*)),
SLOT(showCommandBuffer(QString,int,int,QObject*)));
connect(handler, SIGNAL(selectionChanged(QList<QTextEdit::ExtraSelection>)),
SLOT(changeSelection(QList<QTextEdit::ExtraSelection>)));
connect(handler, SIGNAL(moveToMatchingParenthesis(bool*,bool*,QTextCursor*)),
@@ -1376,7 +1429,7 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
// pop up the bar
if (theFakeVimSetting(ConfigUseFakeVim)->value().toBool()) {
showCommandBuffer(QString(), -1);
resetCommandBuffer();
handler->setupWidget();
}
}
@@ -1408,7 +1461,7 @@ void FakeVimPluginPrivate::setUseFakeVimInternal(bool on)
//ICore *core = ICore::instance();
//core->updateAdditionalContexts(Context(),
// Context(FAKEVIM_CONTEXT));
showCommandBuffer(QString(), -1);
resetCommandBuffer();
foreach (IEditor *editor, m_editorToHandler.keys()) {
if (BaseTextEditorWidget *textEditor =
qobject_cast<BaseTextEditorWidget *>(editor->widget())) {
@@ -1485,22 +1538,22 @@ void FakeVimPluginPrivate::handleExCommand(bool *handled, const ExCommand &cmd)
QFile file3(fileName);
file3.open(QIODevice::ReadOnly);
QByteArray ba = file3.readAll();
handler->showBlackMessage(FakeVimHandler::tr("\"%1\" %2 %3L, %4C written")
handler->showMessage(MessageInfo, FakeVimHandler::tr("\"%1\" %2 %3L, %4C written")
.arg(fileName).arg(" ")
.arg(ba.count('\n')).arg(ba.size()));
if (cmd.cmd == "wq")
delayedQuitRequested(cmd.hasBang, m_editorToHandler.key(handler));
} else {
handler->showRedMessage(tr("File not saved"));
handler->showMessage(MessageError, tr("File not saved"));
}
} else if (cmd.matches("wa", "wall")) {
// :w[all]
QList<IDocument *> toSave = DocumentManager::modifiedDocuments();
QList<IDocument *> failed = DocumentManager::saveModifiedDocumentsSilently(toSave);
if (failed.isEmpty())
handler->showBlackMessage(tr("Saving succeeded"));
handler->showMessage(MessageInfo, tr("Saving succeeded"));
else
handler->showRedMessage(tr("%n files not saved", 0, failed.size()));
handler->showMessage(MessageError, tr("%n files not saved", 0, failed.size()));
} else if (cmd.matches("q", "quit")) {
// :q[uit]
emit delayedQuitRequested(cmd.hasBang, m_editorToHandler.key(handler));
@@ -1666,11 +1719,17 @@ void FakeVimPluginPrivate::quitFakeVim()
theFakeVimSetting(ConfigUseFakeVim)->setValue(false);
}
void FakeVimPluginPrivate::showCommandBuffer(const QString &contents, int cursorPos)
void FakeVimPluginPrivate::resetCommandBuffer()
{
showCommandBuffer(QString(), -1, 0, 0);
}
void FakeVimPluginPrivate::showCommandBuffer(const QString &contents, int cursorPos,
int messageLevel, QObject *eventFilter)
{
//qDebug() << "SHOW COMMAND BUFFER" << contents;
if (MiniBuffer *w = qobject_cast<MiniBuffer *>(m_statusBar->widget()))
w->setContents(contents, cursorPos);
w->setContents(contents, cursorPos, messageLevel, eventFilter);
}
void FakeVimPluginPrivate::showExtraInformation(const QString &text)