FakeVim: Option 'passnewline' (not in Vim)

Option 'passnewline' ('pnl') passes new line in insert mode and on 'o'
and 'O' commands to editor widget. This way the editor widget can handle
the indentation or insert characters (e.g. asterisk if in C block
comment).

Change-Id: I06afab6b20b49e1b4d31447826c847d36d32806f
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
hluk
2013-03-16 13:32:32 +01:00
committed by hjk
parent bcb11829ba
commit 70adf53fbd
4 changed files with 63 additions and 16 deletions

View File

@@ -1646,6 +1646,7 @@ void FakeVimPlugin::test_vim_code_autoindent()
TestData data; TestData data;
setup(&data); setup(&data);
data.doCommand("set nopassnewline");
data.doCommand("set expandtab"); data.doCommand("set expandtab");
data.doCommand("set shiftwidth=3"); data.doCommand("set shiftwidth=3");

View File

@@ -180,6 +180,7 @@ FakeVimSettings *theFakeVimSettings()
#endif #endif
createAction(s, ConfigShowMarks, false, _("ShowMarks"), _("sm")); createAction(s, ConfigShowMarks, false, _("ShowMarks"), _("sm"));
createAction(s, ConfigPassControlKey, false, _("PassControlKey"), _("pck")); createAction(s, ConfigPassControlKey, false, _("PassControlKey"), _("pck"));
createAction(s, ConfigPassNewLine, false, _("PassNewLine"), _("pnl"));
// Emulated Vim setting // Emulated Vim setting
createAction(s, ConfigStartOfLine, true, _("StartOfLine"), _("sol")); createAction(s, ConfigStartOfLine, true, _("StartOfLine"), _("sol"));

View File

@@ -93,6 +93,7 @@ enum FakeVimSettingsCode
// other actions // other actions
ConfigShowMarks, ConfigShowMarks,
ConfigPassControlKey, ConfigPassControlKey,
ConfigPassNewLine,
ConfigClipboard, ConfigClipboard,
ConfigShowCmd, ConfigShowCmd,
ConfigScrollOff ConfigScrollOff

View File

@@ -1396,6 +1396,7 @@ public:
void handleExCommand(const QString &cmd); void handleExCommand(const QString &cmd);
void installEventFilter(); void installEventFilter();
void removeEventFilter();
void passShortcuts(bool enable); void passShortcuts(bool enable);
void setupWidget(); void setupWidget();
void restoreWidget(int tabSize); void restoreWidget(int tabSize);
@@ -1728,6 +1729,8 @@ public:
void joinLines(int count, bool preserveSpace = false); void joinLines(int count, bool preserveSpace = false);
void insertNewLine();
// undo handling // undo handling
int revision() const { return document()->availableUndoSteps(); } int revision() const { return document()->availableUndoSteps(); }
void undoRedo(bool undo); void undoRedo(bool undo);
@@ -2098,6 +2101,12 @@ void FakeVimHandler::Private::installEventFilter()
EDITOR(installEventFilter(q)); EDITOR(installEventFilter(q));
} }
void FakeVimHandler::Private::removeEventFilter()
{
EDITOR(viewport()->removeEventFilter(q));
EDITOR(removeEventFilter(q));
}
void FakeVimHandler::Private::setupWidget() void FakeVimHandler::Private::setupWidget()
{ {
m_mode = CommandMode; m_mode = CommandMode;
@@ -3661,26 +3670,38 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
bool insertAfter = input.is('o'); bool insertAfter = input.is('o');
setDotCommand(_(insertAfter ? "%1o" : "%1O"), count()); setDotCommand(_(insertAfter ? "%1o" : "%1O"), count());
setUndoPosition(); setUndoPosition();
enterInsertMode();
// Insert new line so that command can be repeated [count] times inserting new line // Prepend line only if on the first line and command is 'O'.
// each time without unfolding any lines. bool appendLine = true;
QTextBlock block = cursor().block(); if (!insertAfter) {
bool appendLine = false; if (block().blockNumber() == 0)
if (insertAfter) { appendLine = false;
const int line = lineNumber(block); else
appendLine = line >= document()->lineCount();
setPosition(appendLine ? lastPositionInLine(line) : firstPositionInLine(line + 1));
} else {
setPosition(block.position());
}
beginEditBlock();
insertText(QString::fromLatin1("\n"));
if (!appendLine)
moveUp(); moveUp();
insertAutomaticIndentation(insertAfter); }
const int line = lineNumber(block());
enterInsertMode();
beginEditBlock();
if (appendLine) {
setPosition(lastPositionInLine(line));
insertNewLine();
} else {
setPosition(firstPositionInLine(line));
insertNewLine();
moveUp();
}
recordInsertion(QString::fromLatin1("\n")); recordInsertion(QString::fromLatin1("\n"));
setTargetColumn(); setTargetColumn();
endEditBlock(); endEditBlock();
// Close accidentally opened block.
if (block().blockNumber() > 0) {
moveUp();
if (line != lineNumber(block()))
emit q->fold(1, true);
moveDown();
}
} else if (input.isControl('o')) { } else if (input.isControl('o')) {
jump(-count()); jump(-count());
} else if (input.is('p') || input.is('P') || input.isShift(Qt::Key_Insert)) { } else if (input.is('p') || input.is('P') || input.isShift(Qt::Key_Insert)) {
@@ -4266,9 +4287,8 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input)
} else if (input.isReturn() || input.isControl('j') || input.isControl('m')) { } else if (input.isReturn() || input.isControl('j') || input.isControl('m')) {
joinPreviousEditBlock(); joinPreviousEditBlock();
m_submode = NoSubMode; m_submode = NoSubMode;
insertText(QString::fromLatin1("\n")); insertNewLine();
insert = _("\n"); insert = _("\n");
insertAutomaticIndentation(true);
endEditBlock(); endEditBlock();
} else if (input.isBackspace()) { } else if (input.isBackspace()) {
joinPreviousEditBlock(); joinPreviousEditBlock();
@@ -6456,6 +6476,30 @@ void FakeVimHandler::Private::joinLines(int count, bool preserveSpace)
setPosition(pos); setPosition(pos);
} }
void FakeVimHandler::Private::insertNewLine()
{
if ( hasConfig(ConfigPassNewLine) ) {
QKeyEvent event(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, QLatin1String("\n"));
removeEventFilter();
QTextCursor tc = m_cursor;
tc.setPosition(tc.position());
EDITOR(setTextCursor(tc));
bool accepted = QApplication::sendEvent(editor(), &event);
installEventFilter();
if (accepted) {
setPosition(EDITOR(textCursor()).position());
return;
}
}
insertText(QString::fromLatin1("\n"));
insertAutomaticIndentation(true);
}
QString FakeVimHandler::Private::lineContents(int line) const QString FakeVimHandler::Private::lineContents(int line) const
{ {
return document()->findBlockByLineNumber(line - 1).text(); return document()->findBlockByLineNumber(line - 1).text();