FakeVim: Window movement with <C-W> and :only

Allow movement with <C-W> and h, j, k, l, plus capital alternatives to
focus furthest split.

Command <C-W>o or :only closes all splits except the current one.

Change-Id: I14ed57cff5d639c22d3eb325560922c10d0c92bf
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
hluk
2013-04-24 18:15:32 +02:00
committed by hjk
parent b563fc6db9
commit 016a926ab7
3 changed files with 73 additions and 67 deletions

View File

@@ -4196,8 +4196,7 @@ bool FakeVimHandler::Private::handleWindowSubMode(const Input &input)
if (handleCount(input)) if (handleCount(input))
return true; return true;
for (int i = 0, repeat = count(); i < repeat; ++i) emit q->windowCommandRequested(input.toString(), count());
emit q->windowCommandRequested(input.key());
m_submode = NoSubMode; m_submode = NoSubMode;
return true; return true;

View File

@@ -143,7 +143,7 @@ signals:
void indentRegion(int beginLine, int endLine, QChar typedChar); void indentRegion(int beginLine, int endLine, QChar typedChar);
void completionRequested(); void completionRequested();
void simpleCompletionRequested(const QString &needle, bool forward); void simpleCompletionRequested(const QString &needle, bool forward);
void windowCommandRequested(int key); void windowCommandRequested(const QString &key, int count);
void findRequested(bool reverse); void findRequested(bool reverse);
void findNextRequested(bool reverse); void findNextRequested(bool reverse);
void handleExCommandRequested(bool *handled, const ExCommand &cmd); void handleExCommandRequested(bool *handled, const ExCommand &cmd);

View File

@@ -897,7 +897,7 @@ private slots:
void quitFakeVim(); void quitFakeVim();
void triggerCompletions(); void triggerCompletions();
void triggerSimpleCompletions(const QString &needle, bool forward); void triggerSimpleCompletions(const QString &needle, bool forward);
void windowCommand(int key); void windowCommand(const QString &key, int count);
void find(bool reverse); void find(bool reverse);
void findNext(bool reverse); void findNext(bool reverse);
void foldToggle(int depth); void foldToggle(int depth);
@@ -946,7 +946,9 @@ private:
void setActionChecked(const Id &id, bool check); void setActionChecked(const Id &id, bool check);
typedef int (*DistFunction)(const QRect &cursor, const QRect &other); typedef int (*DistFunction)(const QRect &cursor, const QRect &other);
void moveSomewhere(DistFunction f); void moveSomewhere(DistFunction f, int count);
void keepOnlyWindow(); // :only
ExCommandMap &exCommandMap() { return m_exCommandMap; } ExCommandMap &exCommandMap() { return m_exCommandMap; }
ExCommandMap &defaultExCommandMap() { return m_defaultExCommandMap; } ExCommandMap &defaultExCommandMap() { return m_defaultExCommandMap; }
@@ -1268,7 +1270,7 @@ void FakeVimPluginPrivate::setActionChecked(const Id &id, bool check)
static int moveRightWeight(const QRect &cursor, const QRect &other) static int moveRightWeight(const QRect &cursor, const QRect &other)
{ {
if (!cursor.adjusted(other.right(), 0, 0, 0).intersects(other)) if (!cursor.adjusted(999999, 0, 0, 0).intersects(other))
return -1; return -1;
const int dx = other.left() - cursor.right(); const int dx = other.left() - cursor.right();
const int dy = qAbs(cursor.center().y() - other.center().y()); const int dy = qAbs(cursor.center().y() - other.center().y());
@@ -1278,7 +1280,7 @@ static int moveRightWeight(const QRect &cursor, const QRect &other)
static int moveLeftWeight(const QRect &cursor, const QRect &other) static int moveLeftWeight(const QRect &cursor, const QRect &other)
{ {
if (!cursor.adjusted(-other.right(), 0, 0, 0).intersects(other)) if (!cursor.adjusted(-999999, 0, 0, 0).intersects(other))
return -1; return -1;
const int dx = cursor.left() - other.right(); const int dx = cursor.left() - other.right();
const int dy = qAbs(cursor.center().y() -other.center().y()); const int dy = qAbs(cursor.center().y() -other.center().y());
@@ -1288,7 +1290,7 @@ static int moveLeftWeight(const QRect &cursor, const QRect &other)
static int moveUpWeight(const QRect &cursor, const QRect &other) static int moveUpWeight(const QRect &cursor, const QRect &other)
{ {
if (!cursor.adjusted(0, 0, 0, -other.bottom()).intersects(other)) if (!cursor.adjusted(0, 0, 0, -999999).intersects(other))
return -1; return -1;
const int dy = cursor.top() - other.bottom(); const int dy = cursor.top() - other.bottom();
const int dx = qAbs(cursor.center().x() - other.center().x()); const int dx = qAbs(cursor.center().x() - other.center().x());
@@ -1298,7 +1300,7 @@ static int moveUpWeight(const QRect &cursor, const QRect &other)
static int moveDownWeight(const QRect &cursor, const QRect &other) static int moveDownWeight(const QRect &cursor, const QRect &other)
{ {
if (!cursor.adjusted(0, 0, 0, other.bottom()).intersects(other)) if (!cursor.adjusted(0, 0, 0, 999999).intersects(other))
return -1; return -1;
const int dy = other.top() - cursor.bottom(); const int dy = other.top() - cursor.bottom();
const int dx = qAbs(cursor.center().x() - other.center().x()); const int dx = qAbs(cursor.center().x() - other.center().x());
@@ -1306,49 +1308,36 @@ static int moveDownWeight(const QRect &cursor, const QRect &other)
return w; return w;
} }
void FakeVimPluginPrivate::windowCommand(int key) void FakeVimPluginPrivate::windowCommand(const QString &map, int count)
{ {
# define control(n) (256 + n) // normalize mapping
switch (key) { const QString key = map.toUpper();
case 'c': case 'C': case control('c'):
triggerAction(Core::Constants::CLOSE); if (key == _("C") || key == _("<C-C>"))
break; triggerAction(Core::Constants::REMOVE_CURRENT_SPLIT);
case 'n': case 'N': case control('n'): else if (key == _("N") || key == _("<C-N>"))
triggerAction(Core::Constants::GOTONEXT); triggerAction(Core::Constants::GOTONEXT);
break; else if (key == _("O") || key == _("<C-O>"))
case 'o': case 'O': case control('o'): keepOnlyWindow();
//triggerAction(Core::Constants::REMOVE_ALL_SPLITS); else if (key == _("P") || key == _("<C-P>"))
triggerAction(Core::Constants::REMOVE_CURRENT_SPLIT); triggerAction(Core::Constants::GOTOPREV);
break; else if (key == _("S") || key == _("<C-S>"))
case 'p': case 'P': case control('p'): triggerAction(Core::Constants::SPLIT);
triggerAction(Core::Constants::GOTOPREV); else if (key == _("W") || key == _("<C-W>"))
break; triggerAction(Core::Constants::GOTO_OTHER_SPLIT);
case 's': case 'S': case control('s'): else if (key.contains(_("RIGHT")) || key == _("L") || key == _("<S-L>"))
triggerAction(Core::Constants::SPLIT); moveSomewhere(&moveRightWeight, key == _("<S-L>") ? -1 : count);
break; else if (key.contains(_("LEFT")) || key == _("H") || key == _("<S-H>"))
case 'w': case 'W': case control('w'): moveSomewhere(&moveLeftWeight, key == _("<S-H>") ? -1 : count);
triggerAction(Core::Constants::GOTO_OTHER_SPLIT); else if (key.contains(_("UP")) || key == _("K") || key == _("<S-K>"))
break; moveSomewhere(&moveUpWeight, key == _("<S-K>") ? -1 : count);
case Qt::Key_Right: else if (key.contains(_("DOWN")) || key == _("J") || key == _("<S-J>"))
moveSomewhere(&moveRightWeight); moveSomewhere(&moveDownWeight, key == _("<S-J>") ? -1 : count);
break; else
case Qt::Key_Left: qDebug() << "UNKNOWN WINDOW COMMAND: <C-W>" << map;
moveSomewhere(&moveLeftWeight);
break;
case Qt::Key_Up:
moveSomewhere(&moveUpWeight);
break;
case Qt::Key_Down:
moveSomewhere(&moveDownWeight);
break;
default:
qDebug() << "UNKNOWN WINDOWS COMMAND: " << key;
break;
}
# undef control
} }
void FakeVimPluginPrivate::moveSomewhere(DistFunction f) void FakeVimPluginPrivate::moveSomewhere(DistFunction f, int count)
{ {
IEditor *currentEditor = EditorManager::currentEditor(); IEditor *currentEditor = EditorManager::currentEditor();
QWidget *w = currentEditor->widget(); QWidget *w = currentEditor->widget();
@@ -1360,24 +1349,31 @@ void FakeVimPluginPrivate::moveSomewhere(DistFunction f)
//qDebug() << "\nCURSOR: " << cursorRect; //qDebug() << "\nCURSOR: " << cursorRect;
IEditor *bestEditor = 0; IEditor *bestEditor = 0;
int bestValue = 1 << 30; int repeat = count;
foreach (IEditor *editor, EditorManager::instance()->visibleEditors()) { QList<IEditor *> editors = EditorManager::instance()->visibleEditors();
if (editor == currentEditor) while (repeat < 0 || repeat-- > 0) {
continue; editors.removeOne(currentEditor);
QWidget *w = editor->widget(); int bestValue = -1;
QRect editorRect(w->mapToGlobal(w->geometry().topLeft()), foreach (IEditor *editor, editors) {
w->mapToGlobal(w->geometry().bottomRight())); QWidget *w = editor->widget();
//qDebug() << " EDITOR: " << editorRect << editor; QRect editorRect(w->mapToGlobal(w->geometry().topLeft()),
w->mapToGlobal(w->geometry().bottomRight()));
//qDebug() << " EDITOR: " << editorRect << editor;
int value = f(cursorRect, editorRect); int value = f(cursorRect, editorRect);
if (value != -1 && value < bestValue) { if (value != -1 && (bestValue == -1 || value < bestValue)) {
bestValue = value; bestValue = value;
bestEditor = editor; bestEditor = editor;
//qDebug() << " BEST SO FAR: " << bestValue << bestEditor; //qDebug() << " BEST SO FAR: " << bestValue << bestEditor;
}
} }
if (bestValue == -1)
break;
currentEditor = bestEditor;
//qDebug() << " BEST: " << bestValue << bestEditor;
} }
//qDebug() << " BEST: " << bestValue << bestEditor;
// FIME: This is know to fail as the EditorManager will fall back to // FIME: This is know to fail as the EditorManager will fall back to
// the current editor's view. Needs additional public API there. // the current editor's view. Needs additional public API there.
@@ -1385,6 +1381,18 @@ void FakeVimPluginPrivate::moveSomewhere(DistFunction f)
EditorManager::activateEditor(bestEditor); EditorManager::activateEditor(bestEditor);
} }
void FakeVimPluginPrivate::keepOnlyWindow()
{
IEditor *currentEditor = EditorManager::currentEditor();
QList<IEditor *> editors = EditorManager::instance()->visibleEditors();
editors.removeOne(currentEditor);
foreach (IEditor *editor, editors) {
EditorManager::activateEditor(editor);
triggerAction(Core::Constants::REMOVE_CURRENT_SPLIT);
}
}
void FakeVimPluginPrivate::find(bool reverse) void FakeVimPluginPrivate::find(bool reverse)
{ {
if (Find::FindPlugin *plugin = Find::FindPlugin::instance()) { if (Find::FindPlugin *plugin = Find::FindPlugin::instance()) {
@@ -1629,8 +1637,8 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
SLOT(triggerCompletions())); SLOT(triggerCompletions()));
connect(handler, SIGNAL(simpleCompletionRequested(QString,bool)), connect(handler, SIGNAL(simpleCompletionRequested(QString,bool)),
SLOT(triggerSimpleCompletions(QString,bool))); SLOT(triggerSimpleCompletions(QString,bool)));
connect(handler, SIGNAL(windowCommandRequested(int)), connect(handler, SIGNAL(windowCommandRequested(QString,int)),
SLOT(windowCommand(int))); SLOT(windowCommand(QString,int)));
connect(handler, SIGNAL(findRequested(bool)), connect(handler, SIGNAL(findRequested(bool)),
SLOT(find(bool))); SLOT(find(bool)));
connect(handler, SIGNAL(findNextRequested(bool)), connect(handler, SIGNAL(findNextRequested(bool)),
@@ -1823,8 +1831,7 @@ void FakeVimPluginPrivate::handleExCommand(bool *handled, const ExCommand &cmd)
switchToFile(currentFile() - cmd.count); switchToFile(currentFile() - cmd.count);
} else if (cmd.matches(_("on"), _("only"))) { } else if (cmd.matches(_("on"), _("only"))) {
// :on[ly] // :on[ly]
//triggerAction(Core::Constants::REMOVE_ALL_SPLITS); keepOnlyWindow();
triggerAction(Core::Constants::REMOVE_CURRENT_SPLIT);
} else if (cmd.cmd == _("AS")) { } else if (cmd.cmd == _("AS")) {
triggerAction(Core::Constants::SPLIT); triggerAction(Core::Constants::SPLIT);
triggerAction(CppTools::Constants::SWITCH_HEADER_SOURCE); triggerAction(CppTools::Constants::SWITCH_HEADER_SOURCE);