diff --git a/src/plugins/coreplugin/dialogs/shortcutsettings.cpp b/src/plugins/coreplugin/dialogs/shortcutsettings.cpp
index 0a76901f6284b356259bccf8e27f4885889dab8f..8393b2def6ab4a203af65f379f272b8ce90e9959 100644
--- a/src/plugins/coreplugin/dialogs/shortcutsettings.cpp
+++ b/src/plugins/coreplugin/dialogs/shortcutsettings.cpp
@@ -196,6 +196,12 @@ void ShortcutSettings::setKeySequence(const QKeySequence &key)
 
 bool ShortcutSettings::filter(const QString &f, const QTreeWidgetItem *item)
 {
+
+    if (QTreeWidgetItem *parent = item->parent()) {
+        if (parent->text(0).contains(f, Qt::CaseInsensitive))
+            return false;
+    }
+
     if (item->childCount() == 0) {
         if (f.isEmpty())
             return false;
@@ -285,6 +291,8 @@ void ShortcutSettings::initialize()
     m_am = ActionManagerPrivate::instance();
     UniqueIDManager *uidm = UniqueIDManager::instance();
 
+    QMap<QString, QTreeWidgetItem *> sections;
+
     foreach (Command *c, m_am->commands()) {
         if (c->hasAttribute(Command::CA_NonConfigureable))
             continue;
@@ -294,11 +302,25 @@ void ShortcutSettings::initialize()
         QTreeWidgetItem *item = 0;
         ShortcutItem *s = new ShortcutItem;
         m_scitems << s;
-        item = new QTreeWidgetItem(m_page->commandList);
+        item = new QTreeWidgetItem;
         s->m_cmd = c;
         s->m_item = item;
 
-        item->setText(0, uidm->stringForUniqueIdentifier(c->id()));
+        const QString identifier = uidm->stringForUniqueIdentifier(c->id());
+        int pos = identifier.indexOf(QLatin1Char('.'));
+        const QString section = identifier.left(pos);
+        const QString subId = identifier.mid(pos+1);
+        if (!sections.contains(section)) {
+            QTreeWidgetItem *categoryItem = new QTreeWidgetItem(m_page->commandList, QStringList() << section);
+            QFont f = categoryItem->font(0);
+            f.setBold(true);
+            categoryItem->setFont(0, f);
+            sections.insert(section, categoryItem);
+            m_page->commandList->expandItem(categoryItem);
+        }
+        sections[section]->addChild(item);
+
+        item->setText(0, subId);
 
         if (c->action()) {
             QString text = c->hasAttribute(Command::CA_UpdateText) && !c->defaultText().isNull() ? c->defaultText() : c->action()->text();
diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp
index f032200315755073d3294266284be08002dbd206..a32ccd39e03d105378f4d49b03ac6530deff97be 100644
--- a/src/plugins/fakevim/fakevimplugin.cpp
+++ b/src/plugins/fakevim/fakevimplugin.cpp
@@ -63,6 +63,7 @@
 
 #include <utils/qtcassert.h>
 #include <utils/savedaction.h>
+#include <utils/treewidgetcolumnstretcher.h>
 
 #include <cpptools/cpptoolsconstants.h>
 
@@ -333,6 +334,7 @@ QWidget *FakeVimExCommandsPage::createPage(QWidget *parent)
             << ' ' << m_ui.groupBox->title();
         m_searchKeywords.remove(QLatin1Char('&'));
     }
+    new Utils::TreeWidgetColumnStretcher(m_ui.commandList, 1);
 
     return w;
 }
@@ -344,18 +346,34 @@ void FakeVimExCommandsPage::initialize()
     UniqueIDManager *uidm = UniqueIDManager::instance();
     QTC_ASSERT(uidm, return);
 
+    QMap<QString, QTreeWidgetItem *> sections;
+
     foreach (Command *c, am->commands()) {
         if (c->action() && c->action()->isSeparator())
             continue;
 
         CommandItem *ci = new CommandItem;
-        QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.commandList);
+        QTreeWidgetItem *item = new QTreeWidgetItem;
         ci->m_cmd = c;
         ci->m_item = item;
         m_citems << ci;
 
         const QString name = uidm->stringForUniqueIdentifier(c->id());
-        item->setText(0, name);
+        const int pos = name.indexOf(QLatin1Char('.'));
+        const QString section = name.left(pos);
+        const QString subId = name.mid(pos+1);
+
+        if (!sections.contains(section)) {
+            QTreeWidgetItem *categoryItem = new QTreeWidgetItem(m_ui.commandList, QStringList() << section);
+            QFont f = categoryItem->font(0);
+            f.setBold(true);
+            categoryItem->setFont(0, f);
+            sections.insert(section, categoryItem);
+            m_ui.commandList->expandItem(categoryItem);
+        }
+        sections[section]->addChild(item);
+
+        item->setText(0, subId);
 
         if (c->action()) {
             QString text = c->hasAttribute(Command::CA_UpdateText) && !c->defaultText().isNull() ? c->defaultText() : c->action()->text();
@@ -416,6 +434,11 @@ void FakeVimExCommandsPage::setRegex(const QString &regex)
 
 bool FakeVimExCommandsPage::filter(const QString &f, const QTreeWidgetItem *item)
 {
+    if (QTreeWidgetItem *parent = item->parent()) {
+        if (parent->text(0).contains(f, Qt::CaseInsensitive))
+            return false;
+    }
+
     if (item->childCount() == 0) {
         if (f.isEmpty())
             return false;