[gnome-builder/wip/plugins] wip



commit f2c9b2ae199c088ece3ee4bc77d89f8259816d85
Author: Christian Hergert <christian hergert me>
Date:   Sun Jun 7 15:01:05 2015 -0700

    wip
    
    Note: this branch requires custom patches to libpeas.
    
    See github.com/chergert/libpeas embedded-plugin-support branch.

 Makefile.am                                        |    2 +-
 configure.ac                                       |    4 +
 data/keybindings/default.css                       |    4 +-
 data/keybindings/emacs.css                         |    2 +-
 data/keybindings/shared.css                        |    4 +-
 data/keybindings/vim.css                           |    8 +-
 data/ui/gb-workbench.ui                            |    6 -
 plugins/Makefile.am                                |    6 +
 plugins/command-bar/Makefile.am                    |   62 +++++++
 .../command-bar}/gb-command-bar.c                  |  172 ++++++++++++------
 plugins/command-bar/gb-command-bar.gresource.xml   |    7 +
 .../command-bar}/gb-command-bar.h                  |    0
 plugins/command-bar/gb-command-bar.plugin          |    6 +
 {data/ui => plugins/command-bar}/gb-command-bar.ui |    1 +
 .../command-bar}/gb-command-gaction-provider.c     |    0
 .../command-bar}/gb-command-gaction-provider.h     |    0
 .../command-bar}/gb-command-gaction.c              |    0
 .../command-bar}/gb-command-gaction.h              |    0
 .../command-bar}/gb-command-manager.c              |    0
 .../command-bar}/gb-command-manager.h              |    0
 .../command-bar}/gb-command-provider.c             |    0
 .../command-bar}/gb-command-provider.h             |    0
 .../command-bar}/gb-command-result.c               |    0
 .../command-bar}/gb-command-result.h               |    0
 .../command-bar}/gb-command-vim-provider.c         |    0
 .../command-bar}/gb-command-vim-provider.h         |    0
 .../command-bar}/gb-command-vim.c                  |    0
 .../command-bar}/gb-command-vim.h                  |    0
 {src/commands => plugins/command-bar}/gb-command.c |    0
 {src/commands => plugins/command-bar}/gb-command.h |    0
 plugins/symbol-tree/Makefile.am                    |   46 +++++
 plugins/symbol-tree/symbol-tree.c                  |  164 +++++++++++++++++
 plugins/symbol-tree/symbol-tree.gresource.xml      |    7 +
 .../symbol-tree/symbol-tree.h                      |   19 +-
 plugins/symbol-tree/symbol-tree.plugin             |    6 +
 plugins/symbol-tree/symbol-tree.ui                 |   20 ++
 src/Makefile.am                                    |   42 +++---
 src/commands/gb-command-bar-item.c                 |  191 --------------------
 src/commands/gb-command-bar-item.h                 |   38 ----
 src/gb-plugins.c                                   |   90 +++++++++
 src/gb-plugins.h                                   |   57 ++++++
 src/main.c                                         |    3 +
 src/resources/gnome-builder.gresource.xml          |    1 -
 src/workbench/gb-workbench-actions.c               |   13 --
 src/workbench/gb-workbench-private.h               |    4 -
 src/workbench/gb-workbench.c                       |   61 +------
 src/workbench/gb-workbench.h                       |    3 -
 src/workspace/gb-workspace-pane.c                  |   12 ++
 src/workspace/gb-workspace.c                       |    9 +
 49 files changed, 664 insertions(+), 406 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index df06140..3c23f85 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = . build contrib libide src data po tools tests doc
+SUBDIRS = . build contrib libide plugins src data po tools tests doc
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = $(top_builddir)/data/libide-1.0.pc
diff --git a/configure.ac b/configure.ac
index 6aa7fa4..0b4fc18 100644
--- a/configure.ac
+++ b/configure.ac
@@ -377,6 +377,10 @@ AC_CONFIG_FILES([
        libide/ide-debug.h
        libide/Makefile
 
+       plugins/Makefile
+       plugins/command-bar/Makefile
+       plugins/symbol-tree/Makefile
+
        data/Makefile
        data/gsettings/Makefile
        data/icons/Makefile
diff --git a/data/keybindings/default.css b/data/keybindings/default.css
index 839a1f3..2d23efd 100644
--- a/data/keybindings/default.css
+++ b/data/keybindings/default.css
@@ -36,8 +36,8 @@
   bind "<alt>n" { "move-error" (down) };
   bind "<alt>p" { "move-error" (up) };
 
-  bind "<ctrl>Return" { "action" ("workbench", "show-command-bar", "") };
-  bind "<ctrl>KP_Enter" { "action" ("workbench", "show-command-bar", "") };
+  bind "<ctrl>Return" { "action" ("win", "show-command-bar", "") };
+  bind "<ctrl>KP_Enter" { "action" ("win", "show-command-bar", "") };
 
   bind "<ctrl>g" { "move-search" (down, 0, 1, 1, 1, 1) };
   bind "<ctrl><shift>g" { "move-search" (up, 0, 1, 0, 1, 1) };
diff --git a/data/keybindings/emacs.css b/data/keybindings/emacs.css
index fd6a5a6..396048b 100644
--- a/data/keybindings/emacs.css
+++ b/data/keybindings/emacs.css
@@ -50,7 +50,7 @@
 {
   bind "<ctrl>x" { "set-mode" ("emacs-x", transient) };
   bind "<ctrl>underscore" { "undo" () };
-  bind "<alt>x" { "action" ("workbench", "show-command-bar", "") };
+  bind "<alt>x" { "action" ("win", "show-command-bar", "") };
   bind "<ctrl>s" { "action" ("frame", "find", "") };
   bind "<ctrl>period" { "action" ("workbench", "global-search", "") };
   bind "<alt>period" { "goto-definition" () };
diff --git a/data/keybindings/shared.css b/data/keybindings/shared.css
index 8bf9989..88bc1bb 100644
--- a/data/keybindings/shared.css
+++ b/data/keybindings/shared.css
@@ -3,7 +3,7 @@
   bind "Delete" { "action" ("project-tree", "move-to-trash", "") };
   bind "F2" { "action" ("project-tree", "rename-file", "") };
 
-  bind "<ctrl>Return" { "action" ("workbench", "show-command-bar", "") };
-  bind "<ctrl>KP_Enter" { "action" ("workbench", "show-command-bar", "") };
+  bind "<ctrl>Return" { "action" ("win", "show-command-bar", "") };
+  bind "<ctrl>KP_Enter" { "action" ("win", "show-command-bar", "") };
 }
 
diff --git a/data/keybindings/vim.css b/data/keybindings/vim.css
index 7ed21aa..53d5110 100644
--- a/data/keybindings/vim.css
+++ b/data/keybindings/vim.css
@@ -134,7 +134,7 @@
   bind "9" { "append-to-count" (9)
              "set-mode" ("vim-normal-with-count", transient) };
 
-  bind "colon" { "action" ("workbench", "show-command-bar", "") };
+  bind "colon" { "action" ("win", "show-command-bar", "") };
 
   /* cycle "tabs" */
   bind "<ctrl>Page_Up" { "action" ("view-stack", "previous-view", "") };
@@ -1047,7 +1047,7 @@
 
 @binding-set builder-vim-source-view-visual
 {
-  bind "colon" { "action" ("workbench", "show-command-bar", "") };
+  bind "colon" { "action" ("win", "show-command-bar", "") };
 
   bind "percent" { "move-to-matching-bracket" (1) };
 
@@ -1211,7 +1211,7 @@
 
 @binding-set builder-vim-source-view-visual-line
 {
-  bind "colon" { "action" ("workbench", "show-command-bar", "") };
+  bind "colon" { "action" ("win", "show-command-bar", "") };
 
   bind "1" { "append-to-count" (1)
              "set-mode" ("vim-visual-line-with-count", transient) };
@@ -1364,7 +1364,7 @@
 
 @binding-set builder-gb-project-tree-vim
 {
-  bind "colon" { "action" ("workbench", "show-command-bar", "") };
+  bind "colon" { "action" ("win", "show-command-bar", "") };
 }
 
 /*
diff --git a/data/ui/gb-workbench.ui b/data/ui/gb-workbench.ui
index b2c935f..997dfbe 100644
--- a/data/ui/gb-workbench.ui
+++ b/data/ui/gb-workbench.ui
@@ -135,12 +135,6 @@
             </child>
           </object>
         </child>
-        <child>
-          <object class="GbCommandBar" id="command_bar">
-            <property name="transition-type">slide-up</property>
-            <property name="visible">true</property>
-          </object>
-        </child>
       </object>
     </child>
   </template>
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
new file mode 100644
index 0000000..d74a9bc
--- /dev/null
+++ b/plugins/Makefile.am
@@ -0,0 +1,6 @@
+SUBDIRS = \
+       command-bar \
+       symbol-tree \
+       $(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/command-bar/Makefile.am b/plugins/command-bar/Makefile.am
new file mode 100644
index 0000000..e31cbcd
--- /dev/null
+++ b/plugins/command-bar/Makefile.am
@@ -0,0 +1,62 @@
+DISTCLEANFILES =
+BUILT_SOURCES =
+CLEANFILES =
+EXTRA_DIST =
+
+noinst_LTLIBRARIES = libcommand-bar.la
+
+libcommand_bar_la_SOURCES = \
+       gb-command-bar-resources.c \
+       gb-command-bar-resources.h \
+       gb-command-bar.c \
+       gb-command-bar.h \
+       gb-command-gaction-provider.c \
+       gb-command-gaction-provider.h \
+       gb-command-gaction.c \
+       gb-command-gaction.h \
+       gb-command-manager.c \
+       gb-command-manager.h \
+       gb-command-provider.c \
+       gb-command-provider.h \
+       gb-command-result.c \
+       gb-command-result.h \
+       gb-command-vim-provider.c \
+       gb-command-vim-provider.h \
+       gb-command-vim.c \
+       gb-command-vim.h \
+       gb-command.c \
+       gb-command.h \
+       $(NULL)
+
+libcommand_bar_la_CFLAGS = \
+       -I$(top_srcdir)/libide \
+       -I$(top_srcdir)/src/workspace \
+       -I$(top_srcdir)/src/workbench \
+       -I$(top_srcdir)/src/views \
+       -I$(top_srcdir)/src/documents \
+       -I$(top_srcdir)/src/gd \
+       -I$(top_srcdir)/src/editor \
+       -I$(top_srcdir)/src/vim \
+       -I$(top_srcdir)/src/util \
+       -I$(top_srcdir)/src \
+       -I$(top_srcdir)/contrib/nautilus \
+       $(BUILDER_CFLAGS) \
+       $(DEBUG_CFLAGS) \
+       $(OPTIMIZE_CFLAGS) \
+       $(NULL)
+
+libcommand_bar_la_LIBADD = \
+       $(BUILDER_LIBS) \
+       $(NULL)
+
+libcommand_bar_la_LDFLAGS = \
+       $(OPTIMIZE_LDFLAGS) \
+       $(NULL)
+
+glib_resources_c = gb-command-bar-resources.c
+glib_resources_h = gb-command-bar-resources.h
+glib_resources_xml = gb-command-bar.gresource.xml
+glib_resources_namespace = gb_command_bar
+include $(top_srcdir)/build/autotools/Makefile.am.gresources
+
+-include $(top_srcdir)/git.mk
diff --git a/src/commands/gb-command-bar.c b/plugins/command-bar/gb-command-bar.c
similarity index 82%
rename from src/commands/gb-command-bar.c
rename to plugins/command-bar/gb-command-bar.c
index ebca621..bba9b5a 100644
--- a/src/commands/gb-command-bar.c
+++ b/plugins/command-bar/gb-command-bar.c
@@ -21,18 +21,25 @@
 
 #include "gb-command.h"
 #include "gb-command-bar.h"
-#include "gb-command-bar-item.h"
+#include "gb-command-bar-resources.h"
 #include "gb-command-manager.h"
 #include "gb-glib.h"
 #include "gb-string.h"
 #include "gb-view-stack.h"
 #include "gb-widget.h"
 #include "gb-workbench.h"
+#include "gb-workbench-addin.h"
+#include "gb-plugins.h"
 
 struct _GbCommandBar
 {
   GtkRevealer        parent_instance;
 
+  GbWorkbench       *workbench;
+  GbCommandManager  *command_manager;
+
+  GSimpleAction     *show_action;
+
   GtkSizeGroup      *result_size_group;
   GtkEntry          *entry;
   GtkListBox        *list_box;
@@ -50,7 +57,10 @@ struct _GbCommandBar
   gboolean           saved_position_valid;
 };
 
-G_DEFINE_TYPE (GbCommandBar, gb_command_bar, GTK_TYPE_REVEALER)
+static void workbench_addin_init (GbWorkbenchAddinInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GbCommandBar, gb_command_bar, GTK_TYPE_REVEALER,
+                         G_IMPLEMENT_INTERFACE (GB_TYPE_WORKBENCH_ADDIN, workbench_addin_init))
 
 #define HISTORY_LENGTH 30
 
@@ -60,8 +70,45 @@ enum {
   LAST_SIGNAL
 };
 
+enum {
+  PROP_0,
+  PROP_WORKBENCH,
+  LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
 static guint gSignals [LAST_SIGNAL];
 
+static void
+gb_command_bar_load (GbWorkbenchAddin *addin)
+{
+  GbCommandBar *self = (GbCommandBar *)addin;
+  GtkWidget *child;
+
+  g_assert (GB_IS_COMMAND_BAR (self));
+
+  child = gtk_bin_get_child (GTK_BIN (self->workbench));
+  gtk_box_pack_end (GTK_BOX (child), GTK_WIDGET (self), FALSE, FALSE, 0);
+
+  g_action_map_add_action (G_ACTION_MAP (self->workbench), G_ACTION (self->show_action));
+}
+
+static void
+gb_command_bar_unload (GbWorkbenchAddin *addin)
+{
+  GbCommandBar *self = (GbCommandBar *)addin;
+  GtkWidget *parent;
+
+  g_assert (GB_IS_COMMAND_BAR (self));
+
+  ide_clear_weak_pointer (&self->workbench);
+
+  parent = gtk_widget_get_parent (GTK_WIDGET (self));
+  gtk_container_remove (GTK_CONTAINER (parent), GTK_WIDGET (self));
+
+  g_action_map_remove_action (G_ACTION_MAP (self->workbench), "show-command-bar");
+}
+
 GtkWidget *
 gb_command_bar_new (void)
 {
@@ -107,7 +154,7 @@ find_alternate_focus (GtkWidget *focus)
 void
 gb_command_bar_hide (GbCommandBar *self)
 {
-  GbWorkbench *workbench;
+  GtkWidget *toplevel;
   GtkWidget *focus;
 
   g_return_if_fail (GB_IS_COMMAND_BAR (self));
@@ -117,14 +164,14 @@ gb_command_bar_hide (GbCommandBar *self)
 
   gtk_revealer_set_reveal_child (GTK_REVEALER (self), FALSE);
 
-  workbench = gb_widget_get_workbench (GTK_WIDGET (self));
-  if ((workbench == NULL) || gb_workbench_get_closing (workbench))
+  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
+  if ((toplevel == NULL) || gtk_widget_in_destruction (toplevel))
     return;
 
   if (self->last_focus)
     focus = find_alternate_focus (self->last_focus);
   else
-    focus = GTK_WIDGET (workbench);
+    focus = toplevel;
 
   gtk_widget_grab_focus (focus);
 }
@@ -175,41 +222,15 @@ static void
 gb_command_bar_push_result (GbCommandBar    *self,
                             GbCommandResult *result)
 {
-  GtkAdjustment *vadj;
-  GdkFrameClock *frame_clock;
-  GtkWidget *item;
-  GtkWidget *result_widget;
-  gdouble upper;
-
-  g_return_if_fail (GB_IS_COMMAND_BAR (self));
-  g_return_if_fail (GB_IS_COMMAND_RESULT (result));
-
-  item = g_object_new (GB_TYPE_COMMAND_BAR_ITEM,
-                       "result", result,
-                       "visible", TRUE,
-                       NULL);
-  gtk_container_add (GTK_CONTAINER (self->list_box), item);
-
-  result_widget = gb_command_bar_item_get_result (GB_COMMAND_BAR_ITEM (item));
-  gtk_size_group_add_widget (self->result_size_group, result_widget);
-
-  vadj = gtk_list_box_get_adjustment (self->list_box);
-  upper = gtk_adjustment_get_upper (vadj);
-  frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self->list_box));
-
-  ide_object_animate (vadj,
-                      IDE_ANIMATION_EASE_IN_CUBIC,
-                      250,
-                      frame_clock,
-                      "value", upper,
-                      NULL);
+  /*
+   * TODO: if we decide to keep results visible, add them to list here.
+   */
 }
 
 static void
 gb_command_bar_on_entry_activate (GbCommandBar *self,
                                   GtkEntry     *entry)
 {
-  GbWorkbench *workbench = NULL;
   const gchar *text;
 
   g_assert (GB_IS_COMMAND_BAR (self));
@@ -217,23 +238,17 @@ gb_command_bar_on_entry_activate (GbCommandBar *self,
 
   text = gtk_entry_get_text (entry);
 
-  workbench = GB_WORKBENCH (gtk_widget_get_toplevel (GTK_WIDGET (self)));
-  if (!workbench)
-    return;
-
   gtk_widget_hide (GTK_WIDGET (self->completion_scroller));
 
   if (!gb_str_empty0 (text))
     {
-      GbCommandManager *manager;
       GbCommandResult *result = NULL;
       GbCommand *command = NULL;
 
       g_queue_push_head (self->history, g_strdup (text));
       g_free (g_queue_pop_nth (self->history, HISTORY_LENGTH));
 
-      manager = gb_workbench_get_command_manager (workbench);
-      command = gb_command_manager_lookup (manager, text);
+      command = gb_command_manager_lookup (self->command_manager, text);
 
       if (command)
         {
@@ -339,16 +354,10 @@ gb_command_bar_complete (GbCommandBar *self)
 {
   GtkEditable *editable = GTK_EDITABLE (self->entry);
   GtkWidget *viewport = gtk_bin_get_child (GTK_BIN (self->completion_scroller));
-  GbWorkbench *workbench;
-  GbCommandManager *manager;
   gchar **completions;
   int pos, i;
   gchar *current_prefix, *expanded_prefix;
 
-  workbench = GB_WORKBENCH (gtk_widget_get_toplevel (GTK_WIDGET (self)));
-  if (!workbench)
-    return;
-
   pos = gtk_editable_get_position (editable);
   current_prefix = gtk_editable_get_chars (editable, 0, pos);
 
@@ -372,8 +381,7 @@ gb_command_bar_complete (GbCommandBar *self)
     {
       g_clear_pointer (&self->last_completion, g_free);
 
-      manager = gb_workbench_get_command_manager (workbench);
-      completions = gb_command_manager_complete (manager, current_prefix);
+      completions = gb_command_manager_complete (self->command_manager, current_prefix);
 
       expanded_prefix = find_longest_common_prefix (completions);
 
@@ -510,6 +518,15 @@ gb_command_bar_on_entry_cursor_changed (GbCommandBar *self)
   self->saved_position_valid = FALSE;
 }
 
+static void
+show_command_bar (GSimpleAction *action,
+                  GVariant      *param,
+                  GbCommandBar  *self)
+{
+  gtk_revealer_set_reveal_child (GTK_REVEALER (self), TRUE);
+  gtk_widget_grab_focus (GTK_WIDGET (self->entry));
+}
+
 static gboolean
 gb_command_bar_on_entry_key_press_event (GbCommandBar *bar,
                                          GdkEventKey  *event,
@@ -594,6 +611,8 @@ gb_command_bar_finalize (GObject *object)
 {
   GbCommandBar *self = (GbCommandBar *)object;
 
+  ide_clear_weak_pointer (&self->workbench);
+
   g_clear_pointer (&self->last_completion, g_free);
   g_clear_pointer (&self->saved_text, g_free);
   g_queue_free_full (self->history, g_free);
@@ -603,6 +622,25 @@ gb_command_bar_finalize (GObject *object)
 }
 
 static void
+gb_command_bar_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+  GbCommandBar *self = (GbCommandBar *)object;
+
+  switch (prop_id)
+    {
+    case PROP_WORKBENCH:
+      ide_set_weak_pointer (&self->workbench, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
 gb_command_bar_class_init (GbCommandBarClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -611,9 +649,19 @@ gb_command_bar_class_init (GbCommandBarClass *klass)
 
   object_class->constructed = gb_command_bar_constructed;
   object_class->finalize = gb_command_bar_finalize;
+  object_class->set_property = gb_command_bar_set_property;
 
   widget_class->grab_focus = gb_command_bar_grab_focus;
 
+  gParamSpecs [PROP_WORKBENCH] =
+    g_param_spec_object ("workbench",
+                         _("Workbench"),
+                         _("Workbench"),
+                         GB_TYPE_WORKBENCH,
+                         (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+
   /**
    * GbCommandBar::complete:
    * @bar: the object which received the signal.
@@ -658,7 +706,7 @@ gb_command_bar_class_init (GbCommandBarClass *klass)
                                 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_DOWN);
 
   gtk_widget_class_set_template_from_resource (widget_class,
-                                               "/org/gnome/builder/ui/gb-command-bar.ui");
+                                               "/org/gnome/builder/plugins/command-bar/gb-command-bar.ui");
 
   gtk_widget_class_bind_template_child (widget_class, GbCommandBar, entry);
   gtk_widget_class_bind_template_child (widget_class, GbCommandBar, list_box);
@@ -671,7 +719,27 @@ gb_command_bar_class_init (GbCommandBarClass *klass)
 static void
 gb_command_bar_init (GbCommandBar *self)
 {
+  self->history = g_queue_new ();
+  self->command_manager = gb_command_manager_new ();
+
+  self->show_action = g_simple_action_new ("show-command-bar", NULL);
+  g_signal_connect_object (self->show_action,
+                           "activate",
+                           G_CALLBACK (show_command_bar),
+                           self,
+                           0);
+
   gtk_widget_init_template (GTK_WIDGET (self));
+}
 
-  self->history = g_queue_new ();
+static void
+workbench_addin_init (GbWorkbenchAddinInterface *iface)
+{
+  iface->load = gb_command_bar_load;
+  iface->unload = gb_command_bar_unload;
 }
+
+GB_DEFINE_EMBEDDED_PLUGIN (gb_command_bar,
+                           gb_command_bar_get_resource (),
+                           "resource:///org/gnome/builder/plugins/command-bar/gb-command-bar.plugin",
+                           GB_DEFINE_PLUGIN_TYPE (GB_TYPE_WORKBENCH_ADDIN, GB_TYPE_COMMAND_BAR))
diff --git a/plugins/command-bar/gb-command-bar.gresource.xml 
b/plugins/command-bar/gb-command-bar.gresource.xml
new file mode 100644
index 0000000..1e9f9cc
--- /dev/null
+++ b/plugins/command-bar/gb-command-bar.gresource.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/org/gnome/builder/plugins/command-bar">
+    <file>gb-command-bar.plugin</file>
+    <file>gb-command-bar.ui</file>
+  </gresource>
+</gresources>
diff --git a/src/commands/gb-command-bar.h b/plugins/command-bar/gb-command-bar.h
similarity index 100%
rename from src/commands/gb-command-bar.h
rename to plugins/command-bar/gb-command-bar.h
diff --git a/plugins/command-bar/gb-command-bar.plugin b/plugins/command-bar/gb-command-bar.plugin
new file mode 100644
index 0000000..3d2f0ba
--- /dev/null
+++ b/plugins/command-bar/gb-command-bar.plugin
@@ -0,0 +1,6 @@
+[Plugin]
+Module=command-bar
+Name=Command Bar
+Description=Provides a command bar at the bottom of the workbench window.
+Authors=Christian Hergert <christian hergert me>
+Copyright=Copyright © 2015 Christian Hergert
diff --git a/data/ui/gb-command-bar.ui b/plugins/command-bar/gb-command-bar.ui
similarity index 98%
rename from data/ui/gb-command-bar.ui
rename to plugins/command-bar/gb-command-bar.ui
index 7a33c4e..86e7851 100644
--- a/data/ui/gb-command-bar.ui
+++ b/plugins/command-bar/gb-command-bar.ui
@@ -5,6 +5,7 @@
     <property name="visible">True</property>
     <property name="reveal-child">False</property>
     <property name="can-focus">False</property>
+    <property name="transition-type">slide-up</property>
     <child>
       <object class="GtkBox" id="vbox1">
         <property name="visible">True</property>
diff --git a/src/commands/gb-command-gaction-provider.c b/plugins/command-bar/gb-command-gaction-provider.c
similarity index 100%
rename from src/commands/gb-command-gaction-provider.c
rename to plugins/command-bar/gb-command-gaction-provider.c
diff --git a/src/commands/gb-command-gaction-provider.h b/plugins/command-bar/gb-command-gaction-provider.h
similarity index 100%
rename from src/commands/gb-command-gaction-provider.h
rename to plugins/command-bar/gb-command-gaction-provider.h
diff --git a/src/commands/gb-command-gaction.c b/plugins/command-bar/gb-command-gaction.c
similarity index 100%
rename from src/commands/gb-command-gaction.c
rename to plugins/command-bar/gb-command-gaction.c
diff --git a/src/commands/gb-command-gaction.h b/plugins/command-bar/gb-command-gaction.h
similarity index 100%
rename from src/commands/gb-command-gaction.h
rename to plugins/command-bar/gb-command-gaction.h
diff --git a/src/commands/gb-command-manager.c b/plugins/command-bar/gb-command-manager.c
similarity index 100%
rename from src/commands/gb-command-manager.c
rename to plugins/command-bar/gb-command-manager.c
diff --git a/src/commands/gb-command-manager.h b/plugins/command-bar/gb-command-manager.h
similarity index 100%
rename from src/commands/gb-command-manager.h
rename to plugins/command-bar/gb-command-manager.h
diff --git a/src/commands/gb-command-provider.c b/plugins/command-bar/gb-command-provider.c
similarity index 100%
rename from src/commands/gb-command-provider.c
rename to plugins/command-bar/gb-command-provider.c
diff --git a/src/commands/gb-command-provider.h b/plugins/command-bar/gb-command-provider.h
similarity index 100%
rename from src/commands/gb-command-provider.h
rename to plugins/command-bar/gb-command-provider.h
diff --git a/src/commands/gb-command-result.c b/plugins/command-bar/gb-command-result.c
similarity index 100%
rename from src/commands/gb-command-result.c
rename to plugins/command-bar/gb-command-result.c
diff --git a/src/commands/gb-command-result.h b/plugins/command-bar/gb-command-result.h
similarity index 100%
rename from src/commands/gb-command-result.h
rename to plugins/command-bar/gb-command-result.h
diff --git a/src/commands/gb-command-vim-provider.c b/plugins/command-bar/gb-command-vim-provider.c
similarity index 100%
rename from src/commands/gb-command-vim-provider.c
rename to plugins/command-bar/gb-command-vim-provider.c
diff --git a/src/commands/gb-command-vim-provider.h b/plugins/command-bar/gb-command-vim-provider.h
similarity index 100%
rename from src/commands/gb-command-vim-provider.h
rename to plugins/command-bar/gb-command-vim-provider.h
diff --git a/src/commands/gb-command-vim.c b/plugins/command-bar/gb-command-vim.c
similarity index 100%
rename from src/commands/gb-command-vim.c
rename to plugins/command-bar/gb-command-vim.c
diff --git a/src/commands/gb-command-vim.h b/plugins/command-bar/gb-command-vim.h
similarity index 100%
copy from src/commands/gb-command-vim.h
copy to plugins/command-bar/gb-command-vim.h
diff --git a/src/commands/gb-command.c b/plugins/command-bar/gb-command.c
similarity index 100%
rename from src/commands/gb-command.c
rename to plugins/command-bar/gb-command.c
diff --git a/src/commands/gb-command.h b/plugins/command-bar/gb-command.h
similarity index 100%
rename from src/commands/gb-command.h
rename to plugins/command-bar/gb-command.h
diff --git a/plugins/symbol-tree/Makefile.am b/plugins/symbol-tree/Makefile.am
new file mode 100644
index 0000000..e41a912
--- /dev/null
+++ b/plugins/symbol-tree/Makefile.am
@@ -0,0 +1,46 @@
+DISTCLEANFILES =
+BUILT_SOURCES =
+CLEANFILES =
+EXTRA_DIST =
+
+noinst_LTLIBRARIES = libsymbol-tree.la
+
+libsymbol_tree_la_SOURCES = \
+       symbol-tree-resources.c \
+       symbol-tree-resources.h \
+       symbol-tree.c \
+       symbol-tree.h \
+       $(NULL)
+
+# XXX: temporary, since we need to extract lots of src/ into plugins
+libsymbol_tree_la_CFLAGS = \
+       $(LIBIDE_CFLAGS) \
+       -I$(top_srcdir)/src \
+       -I$(top_srcdir)/src/commands \
+       -I$(top_srcdir)/src/documents \
+       -I$(top_srcdir)/src/views \
+       -I$(top_srcdir)/src/tree \
+       -I$(top_srcdir)/src/workbench \
+       -I$(top_srcdir)/src/workspace \
+       -I$(top_srcdir)/libide \
+       $(NULL)
+
+libsymbol_tree_la_LIBADD = \
+       $(LIBIDE_LIBS) \
+       $(top_builddir)/libide/libide-1.0.la \
+       $(NULL)
+
+libsymbol_tree_la_LDFLAGS = \
+       -avoid-version \
+       -module \
+       $(NULL)
+
+
+glib_resources_c = symbol-tree-resources.c
+glib_resources_h = symbol-tree-resources.h
+glib_resources_xml = symbol-tree.gresource.xml
+glib_resources_namespace = symbol_tree
+include $(top_srcdir)/build/autotools/Makefile.am.gresources
+
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/symbol-tree/symbol-tree.c b/plugins/symbol-tree/symbol-tree.c
new file mode 100644
index 0000000..2629d19
--- /dev/null
+++ b/plugins/symbol-tree/symbol-tree.c
@@ -0,0 +1,164 @@
+/* symbol-tree.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+#include <libpeas/peas.h>
+
+
+#include "gb-plugins.h"
+#include "gb-tree.h"
+#include "gb-workspace.h"
+
+#include "symbol-tree.h"
+#include "symbol-tree-resources.h"
+
+struct _SymbolTree
+{
+  GtkBox       parent_instance;
+
+  GbWorkbench *workbench;
+
+  GbTree      *tree;
+};
+
+enum {
+  PROP_0,
+  PROP_WORKBENCH,
+  LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+static void workbench_addin_init (GbWorkbenchAddinInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (SymbolTree, symbol_tree, GTK_TYPE_BOX,
+                         G_IMPLEMENT_INTERFACE (GB_TYPE_WORKBENCH_ADDIN, workbench_addin_init))
+
+static void
+symbol_tree_load (GbWorkbenchAddin *addin)
+{
+  SymbolTree *self = (SymbolTree *)addin;
+  GbWorkspace *workspace;
+  GtkWidget *right_pane;
+
+  g_assert (SYMBOL_IS_TREE (self));
+  g_assert (GB_IS_WORKBENCH (self->workbench));
+
+  workspace = GB_WORKSPACE (gb_workbench_get_workspace (self->workbench));
+  right_pane = gb_workspace_get_right_pane (workspace);
+  gb_workspace_pane_add_page (GB_WORKSPACE_PANE (right_pane),
+                              GTK_WIDGET (self),
+                              _("Symbol Tree"),
+                              "flag-symbolic");
+}
+
+static void
+symbol_tree_unload (GbWorkbenchAddin *addin)
+{
+  SymbolTree *self = (SymbolTree *)addin;
+  GbWorkspace *workspace;
+  GtkWidget *right_pane;
+
+  g_assert (SYMBOL_IS_TREE (self));
+  g_assert (GB_IS_WORKBENCH (self->workbench));
+
+  workspace = GB_WORKSPACE (gb_workbench_get_workspace (self->workbench));
+  right_pane = gb_workspace_get_right_pane (workspace);
+  gb_workspace_pane_remove_page (GB_WORKSPACE_PANE (right_pane), GTK_WIDGET (self));
+}
+
+static void
+symbol_tree_set_workbench (SymbolTree  *self,
+                           GbWorkbench *workbench)
+{
+  g_assert (SYMBOL_IS_TREE (self));
+  g_assert (GB_IS_WORKBENCH (workbench));
+
+  ide_set_weak_pointer (&self->workbench, workbench);
+}
+
+static void
+symbol_tree_set_property (GObject      *object,
+                          guint         prop_id,
+                          const GValue *value,
+                          GParamSpec   *pspec)
+{
+  SymbolTree *self = (SymbolTree *)object;
+
+  switch (prop_id)
+    {
+    case PROP_WORKBENCH:
+      symbol_tree_set_workbench (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+symbol_tree_finalize (GObject *object)
+{
+  SymbolTree *self = (SymbolTree *)object;
+
+  ide_clear_weak_pointer (&self->workbench);
+
+  G_OBJECT_CLASS (symbol_tree_parent_class)->finalize (object);
+}
+
+static void
+workbench_addin_init (GbWorkbenchAddinInterface *iface)
+{
+  iface->load = symbol_tree_load;
+  iface->unload = symbol_tree_unload;
+}
+
+static void
+symbol_tree_class_init (SymbolTreeClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = symbol_tree_finalize;
+  object_class->set_property = symbol_tree_set_property;
+
+  gParamSpecs [PROP_WORKBENCH] =
+    g_param_spec_object ("workbench",
+                         _("Workbench"),
+                         _("Workbench"),
+                         GB_TYPE_WORKBENCH,
+                         (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
+
+  gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/builder/plugins/symbol-tree/symbol-tree.ui");
+  gtk_widget_class_bind_template_child (widget_class, SymbolTree, tree);
+
+  g_type_ensure (GB_TYPE_TREE);
+}
+
+static void
+symbol_tree_init (SymbolTree *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+GB_DEFINE_EMBEDDED_PLUGIN (symbol_tree,
+                           symbol_tree_get_resource (),
+                           "resource:///org/gnome/builder/plugins/symbol-tree/symbol-tree.plugin",
+                           GB_DEFINE_PLUGIN_TYPE (GB_TYPE_WORKBENCH_ADDIN, SYMBOL_TYPE_TREE))
diff --git a/plugins/symbol-tree/symbol-tree.gresource.xml b/plugins/symbol-tree/symbol-tree.gresource.xml
new file mode 100644
index 0000000..a848fe0
--- /dev/null
+++ b/plugins/symbol-tree/symbol-tree.gresource.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/org/gnome/builder/plugins/symbol-tree">
+    <file>symbol-tree.plugin</file>
+    <file>symbol-tree.ui</file>
+  </gresource>
+</gresources>
diff --git a/src/commands/gb-command-vim.h b/plugins/symbol-tree/symbol-tree.h
similarity index 68%
rename from src/commands/gb-command-vim.h
rename to plugins/symbol-tree/symbol-tree.h
index 03a919c..cb7ccee 100644
--- a/src/commands/gb-command-vim.h
+++ b/plugins/symbol-tree/symbol-tree.h
@@ -1,6 +1,6 @@
-/* gb-command-vim.h
+/* symbol-tree.h
  *
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,18 +16,19 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef GB_COMMAND_VIM_H
-#define GB_COMMAND_VIM_H
+#ifndef SYMBOL_TREE_H
+#define SYMBOL_TREE_H
 
-#include "gb-command.h"
+#include <gtk/gtk.h>
 
-G_BEGIN_DECLS
+#include "gb-workbench-addin.h"
 
-#define GB_TYPE_COMMAND_VIM (gb_command_vim_get_type())
+G_BEGIN_DECLS
 
-G_DECLARE_FINAL_TYPE (GbCommandVim, gb_command_vim, GB, COMMAND_VIM, GbCommand)
+#define SYMBOL_TYPE_TREE (symbol_tree_get_type())
 
+G_DECLARE_FINAL_TYPE (SymbolTree, symbol_tree, SYMBOL, TREE, GtkBox)
 
 G_END_DECLS
 
-#endif /* GB_COMMAND_VIM_H */
+#endif /* SYMBOL_TREE_H */
diff --git a/plugins/symbol-tree/symbol-tree.plugin b/plugins/symbol-tree/symbol-tree.plugin
new file mode 100644
index 0000000..036ed04
--- /dev/null
+++ b/plugins/symbol-tree/symbol-tree.plugin
@@ -0,0 +1,6 @@
+[Plugin]
+Module=symbol-tree
+Name=Symbol Tree
+Description=Provides a Symbol Tree for the currently focused document.
+Authors=Christian Hergert <christian hergert me>
+Copyright=Copyright © 2015 Christian Hergert
diff --git a/plugins/symbol-tree/symbol-tree.ui b/plugins/symbol-tree/symbol-tree.ui
new file mode 100644
index 0000000..82316b4
--- /dev/null
+++ b/plugins/symbol-tree/symbol-tree.ui
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.16 -->
+  <template class="SymbolTree" parent="GtkBox">
+    <property name="vexpand">true</property>
+    <property name="visible">true</property>
+    <child>
+      <object class="GtkScrolledWindow">
+        <property name="expand">true</property>
+        <property name="visible">true</property>
+        <child>
+          <object class="GbTree" id="tree">
+            <property name="headers-visible">false</property>
+            <property name="visible">true</property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/Makefile.am b/src/Makefile.am
index fbec396..121af8e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,26 +15,6 @@ libgnome_builder_la_SOURCES = \
        app/gb-application-private.h \
        app/gb-application.c \
        app/gb-application.h \
-       commands/gb-command-bar-item.c \
-       commands/gb-command-bar-item.h \
-       commands/gb-command-bar.c \
-       commands/gb-command-bar.h \
-       commands/gb-command-gaction-provider.c \
-       commands/gb-command-gaction-provider.h \
-       commands/gb-command-gaction.c \
-       commands/gb-command-gaction.h \
-       commands/gb-command-manager.c \
-       commands/gb-command-manager.h \
-       commands/gb-command-provider.c \
-       commands/gb-command-provider.h \
-       commands/gb-command-result.c \
-       commands/gb-command-result.h \
-       commands/gb-command-vim-provider.c \
-       commands/gb-command-vim-provider.h \
-       commands/gb-command-vim.c \
-       commands/gb-command-vim.h \
-       commands/gb-command.c \
-       commands/gb-command.h \
        devhelp/gb-devhelp-document.c \
        devhelp/gb-devhelp-document.h \
        devhelp/gb-devhelp-view.c \
@@ -232,13 +212,33 @@ libgnome_builder_la_CFLAGS = \
        -I$(top_srcdir)/contrib/rg \
        $(NULL)
 
-gnome_builder_SOURCES = main.c
+define_plugin = -Wl,--whole-archive,$(top_builddir)/plugins/$1/.libs/lib$1.a,--no-whole-archive
+
+gnome_builder_PLUGINS = \
+       command-bar \
+       symbol-tree \
+       $(NULL)
+
+gnome_builder_SOURCES = \
+       gb-plugins.c \
+       gb-plugins.h \
+       main.c
+
 gnome_builder_CFLAGS = $(libgnome_builder_la_CFLAGS)
+
 gnome_builder_LDADD = \
        $(top_builddir)/libide/libide-1.0.la \
+       $(foreach plugin,$(gnome_builder_PLUGINS),$(top_builddir)/plugins/$(plugin)/lib$(plugin).la) \
        libgnome-builder.la \
        $(NULL)
 
+
+gnome_builder_LDFLAGS = \
+       -export-dynamic \
+       $(foreach plugin,$(gnome_builder_PLUGINS),$(call define_plugin,$(plugin))) \
+       $(NULL)
+
+
 glib_resources_c = resources/gb-resources.c
 glib_resources_h = resources/gb-resources.h
 glib_resources_xml = resources/gnome-builder.gresource.xml
diff --git a/src/gb-plugins.c b/src/gb-plugins.c
new file mode 100644
index 0000000..e489487
--- /dev/null
+++ b/src/gb-plugins.c
@@ -0,0 +1,90 @@
+/* gb-plugin.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gmodule.h>
+
+#include "gb-plugins.h"
+
+PeasPluginInfo **peas_register_types (void);
+
+static GPtrArray *embedded_plugins;
+
+void
+gb_plugins_register (PeasPluginInfo *plugin_info)
+{
+  g_assert (plugin_info != NULL);
+
+  g_print ("Registering plugin \"%s\"\n", peas_plugin_info_get_module_name (plugin_info));
+
+  if (embedded_plugins == NULL)
+    embedded_plugins = g_ptr_array_new ();
+
+  g_ptr_array_add (embedded_plugins, plugin_info);
+}
+
+PeasPluginInfo **
+peas_register_types (void)
+{
+  GPtrArray *copy;
+
+  g_print ("peas_register_types called ...\n");
+
+  copy = g_ptr_array_new ();
+
+  if (embedded_plugins != NULL)
+    {
+      gsize i;
+
+      for (i = 0; i < embedded_plugins->len; i++)
+        g_ptr_array_add (copy, g_ptr_array_index (embedded_plugins, i));
+    }
+
+  g_ptr_array_add (copy, NULL);
+
+  return (PeasPluginInfo **)g_ptr_array_free (copy, FALSE);
+}
+
+void
+gb_plugins_load (void)
+{
+  PeasEngine *engine;
+  GModule *module;
+  gpointer symbol = NULL;
+  gsize i;
+
+  g_print ("Loading plugins...\n");
+
+  module = g_module_open (NULL, G_MODULE_BIND_LAZY);
+  if (g_module_symbol (module, "peas_register_types", &symbol))
+    g_print ("Found\n");
+  else
+    g_print ("Not Found\n");
+
+  g_print ("func at %p (%p)\n", symbol, (void *)peas_register_types);
+
+  engine = peas_engine_get_default ();
+  peas_engine_add_search_path (engine, "plugins", "plugins");
+  peas_engine_rescan_plugins (engine);
+
+  for (i = 0; i < embedded_plugins->len; i++)
+    {
+      PeasPluginInfo *info = g_ptr_array_index (embedded_plugins, i);
+      g_print ("Loading %s\n", peas_plugin_info_get_name (info));
+      peas_engine_load_plugin (engine, info);
+    }
+}
diff --git a/src/gb-plugins.h b/src/gb-plugins.h
new file mode 100644
index 0000000..05eeee9
--- /dev/null
+++ b/src/gb-plugins.h
@@ -0,0 +1,57 @@
+/* gb-plugin.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_PLUGIN_H
+#define GB_PLUGIN_H
+
+#include <libpeas/peas.h>
+
+#include "gconstructor.h"
+
+G_BEGIN_DECLS
+
+#define GB_DEFINE_EMBEDDED_PLUGIN(name, resource, plugin_path, ...)    \
+  G_DEFINE_CONSTRUCTOR(name##_plugin);                                 \
+  static void                                                          \
+  name##_plugin (void)                                                 \
+  {                                                                    \
+    g_autoptr(PeasObjectModule) module = NULL;                         \
+    PeasPluginInfo *plugin_info = NULL;                                \
+                                                                       \
+    if (resource != NULL)                                              \
+      g_resources_register (resource);                                 \
+                                                                       \
+    module = peas_object_module_new_embedded ();                       \
+                                                                       \
+    __VA_ARGS__                                                        \
+                                                                       \
+    plugin_info = peas_plugin_info_new_embedded (module, plugin_path); \
+    gb_plugins_register (plugin_info);                                 \
+  }
+
+#define GB_DEFINE_PLUGIN_TYPE(PLUGIN, IMPL)                            \
+  G_STMT_START {                                                       \
+    peas_object_module_register_extension_type (module, PLUGIN, IMPL); \
+  } G_STMT_END;
+
+void gb_plugins_register (PeasPluginInfo *plugin_info);
+void gb_plugins_load     (void);
+
+G_END_DECLS
+
+#endif /* GB_PLUGIN_H */
diff --git a/src/main.c b/src/main.c
index faf03c3..2be702d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -29,6 +29,7 @@
 #include <locale.h>
 
 #include "gb-application.h"
+#include "gb-plugins.h"
 
 int
 main (int   argc,
@@ -55,6 +56,8 @@ main (int   argc,
              gtk_get_minor_version (),
              gtk_get_micro_version ());
 
+  gb_plugins_load ();
+
   app = g_object_new (GB_TYPE_APPLICATION,
                       "application-id", "org.gnome.Builder",
                       "flags", G_APPLICATION_HANDLES_OPEN,
diff --git a/src/resources/gnome-builder.gresource.xml b/src/resources/gnome-builder.gresource.xml
index d1c25e8..2eb26f8 100644
--- a/src/resources/gnome-builder.gresource.xml
+++ b/src/resources/gnome-builder.gresource.xml
@@ -42,7 +42,6 @@
     <file alias="theme/Adwaita-shared.css">../../data/theme/Adwaita-shared.css</file>
     <file alias="theme/shared.css">../../data/theme/shared.css</file>
 
-    <file alias="ui/gb-command-bar.ui">../../data/ui/gb-command-bar.ui</file>
     <file alias="ui/gb-devhelp-view.ui">../../data/ui/gb-devhelp-view.ui</file>
     <file alias="ui/gb-editor-frame.ui">../../data/ui/gb-editor-frame.ui</file>
     <file alias="ui/gb-editor-settings-widget.ui">../../data/ui/gb-editor-settings-widget.ui</file>
diff --git a/src/workbench/gb-workbench-actions.c b/src/workbench/gb-workbench-actions.c
index fcfdca8..0673501 100644
--- a/src/workbench/gb-workbench-actions.c
+++ b/src/workbench/gb-workbench-actions.c
@@ -232,18 +232,6 @@ gb_workbench_actions_save_all_quit (GSimpleAction *action,
 }
 
 static void
-gb_workbench_actions_show_command_bar (GSimpleAction *action,
-                                       GVariant      *parameter,
-                                       gpointer       user_data)
-{
-  GbWorkbench *self = user_data;
-
-  g_assert (GB_IS_WORKBENCH (self));
-
-  gb_command_bar_show (self->command_bar);
-}
-
-static void
 gb_workbench_actions_nighthack (GSimpleAction *action,
                                 GVariant      *parameter,
                                 gpointer       user_data)
@@ -390,7 +378,6 @@ static const GActionEntry GbWorkbenchActions[] = {
   { "save-all",         gb_workbench_actions_save_all },
   { "save-all-quit",    gb_workbench_actions_save_all_quit },
   { "search-docs",      gb_workbench_actions_search_docs, "s" },
-  { "show-command-bar", gb_workbench_actions_show_command_bar },
   { "show-gear-menu",   gb_workbench_actions_show_gear_menu },
   { "show-left-pane",   gb_workbench_actions_show_left_pane, NULL, "true" },
   { "show-right-pane",  gb_workbench_actions_show_right_pane, NULL, "false" },
diff --git a/src/workbench/gb-workbench-private.h b/src/workbench/gb-workbench-private.h
index de83f43..a3efaa3 100644
--- a/src/workbench/gb-workbench-private.h
+++ b/src/workbench/gb-workbench-private.h
@@ -23,8 +23,6 @@
 #include <libpeas/peas.h>
 #include <ide.h>
 
-#include "gb-command-bar.h"
-#include "gb-command-manager.h"
 #include "gb-editor-workspace.h"
 #include "gb-project-tree.h"
 #include "gb-search-box.h"
@@ -39,14 +37,12 @@ struct _GbWorkbench
   GtkApplicationWindow    parent_instance;
 
   /* Owned reference */
-  GbCommandManager       *command_manager;
   IdeContext             *context;
   GCancellable           *unload_cancellable;
   gchar                  *current_folder_uri;
   PeasExtensionSet       *extensions;
 
   /* Template references */
-  GbCommandBar           *command_bar;
   GeditMenuStackSwitcher *gear_menu_button;
   GbProjectTree          *project_tree;
   GbSearchBox            *search_box;
diff --git a/src/workbench/gb-workbench.c b/src/workbench/gb-workbench.c
index 9862fdf..9979263 100644
--- a/src/workbench/gb-workbench.c
+++ b/src/workbench/gb-workbench.c
@@ -21,8 +21,6 @@
 #include <glib/gi18n.h>
 #include <ide.h>
 
-#include "gb-command-gaction-provider.h"
-#include "gb-command-vim-provider.h"
 #include "gb-dnd.h"
 #include "gb-editor-document.h"
 #include "gb-settings.h"
@@ -40,9 +38,7 @@ G_DEFINE_TYPE (GbWorkbench, gb_workbench, GTK_TYPE_APPLICATION_WINDOW)
 
 enum {
   PROP_0,
-  PROP_ACTIVE_WORKSPACE,
   PROP_BUILDING,
-  PROP_COMMAND_MANAGER,
   PROP_CONTEXT,
   LAST_PROP
 };
@@ -412,7 +408,6 @@ gb_workbench_dispose (GObject *object)
 
   self->disposing++;
 
-  g_clear_object (&self->command_manager);
   g_clear_object (&self->unload_cancellable);
 
   G_OBJECT_CLASS (gb_workbench_parent_class)->dispose (object);
@@ -452,10 +447,6 @@ gb_workbench_get_property (GObject    *object,
       g_value_set_boolean (value, self->building);
       break;
 
-    case PROP_COMMAND_MANAGER:
-      g_value_set_object (value, gb_workbench_get_command_manager (self));
-      break;
-
     case PROP_CONTEXT:
       g_value_set_object (value, gb_workbench_get_context (self));
       break;
@@ -502,13 +493,6 @@ gb_workbench_class_init (GbWorkbenchClass *klass)
   widget_class->grab_focus = gb_workbench_grab_focus;
   widget_class->realize = gb_workbench_realize;
 
-  gParamSpecs [PROP_ACTIVE_WORKSPACE] =
-    g_param_spec_object ("active-workspace",
-                         _("Active Workspace"),
-                         _("The active workspace."),
-                         GB_TYPE_WORKSPACE,
-                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
   gParamSpecs [PROP_BUILDING] =
     g_param_spec_boolean ("building",
                           _("Building"),
@@ -516,13 +500,6 @@ gb_workbench_class_init (GbWorkbenchClass *klass)
                           FALSE,
                           (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
-  gParamSpecs [PROP_COMMAND_MANAGER] =
-    g_param_spec_object ("command-manager",
-                         _("Command Manager"),
-                         _("The command manager for the workbench."),
-                         GB_TYPE_COMMAND_MANAGER,
-                         (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
   /**
    * GbWorkbench:context:
    *
@@ -551,14 +528,12 @@ gb_workbench_class_init (GbWorkbenchClass *klass)
                   IDE_TYPE_CONTEXT);
 
   GB_WIDGET_CLASS_TEMPLATE (klass, "gb-workbench.ui");
-  GB_WIDGET_CLASS_BIND (klass, GbWorkbench, command_bar);
   GB_WIDGET_CLASS_BIND (klass, GbWorkbench, gear_menu_button);
   GB_WIDGET_CLASS_BIND (klass, GbWorkbench, search_box);
   GB_WIDGET_CLASS_BIND (klass, GbWorkbench, workspace);
   GB_WIDGET_CLASS_BIND (klass, GbWorkbench, project_tree);
   GB_WIDGET_CLASS_BIND (klass, GbWorkbench, view_grid);
 
-  g_type_ensure (GB_TYPE_COMMAND_BAR);
   g_type_ensure (GB_TYPE_PROJECT_TREE);
   g_type_ensure (GB_TYPE_SEARCH_BOX);
   g_type_ensure (GB_TYPE_VIEW_GRID);
@@ -572,6 +547,8 @@ gb_workbench__extension_added (PeasExtensionSet *set,
                                PeasPluginInfo   *plugin_info,
                                GbWorkbenchAddin *addin)
 {
+  g_print ("EXTENSION ADDED!!!!!\n");
+
   gb_workbench_addin_load (addin);
 }
 
@@ -586,25 +563,10 @@ gb_workbench__extension_removed (PeasExtensionSet *set,
 static void
 gb_workbench_init (GbWorkbench *self)
 {
-  PeasEngine *engine;
-  g_autoptr(GbCommandProvider) gaction_provider = NULL;
-  g_autoptr(GbCommandProvider) vim_provider = NULL;
-
   IDE_ENTRY;
 
   gtk_widget_init_template (GTK_WIDGET (self));
 
-  self->command_manager = gb_command_manager_new ();
-
-  gaction_provider = g_object_new (GB_TYPE_COMMAND_GACTION_PROVIDER,
-                                   "workbench", self,
-                                   NULL);
-  vim_provider = g_object_new (GB_TYPE_COMMAND_VIM_PROVIDER,
-                               "workbench", self,
-                               NULL);
-  gb_command_manager_add_provider (self->command_manager, gaction_provider);
-  gb_command_manager_add_provider (self->command_manager, vim_provider);
-
   /* Drag and drop support*/
   gtk_drag_dest_set (GTK_WIDGET (self),
                      (GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP),
@@ -612,8 +574,7 @@ gb_workbench_init (GbWorkbench *self)
 
   gb_settings_init_window (GTK_WINDOW (self));
 
-  engine = peas_engine_get_default ();
-  self->extensions = peas_extension_set_new (engine,
+  self->extensions = peas_extension_set_new (peas_engine_get_default (),
                                              GB_TYPE_WORKBENCH_ADDIN,
                                              "workbench", self,
                                              NULL);
@@ -770,22 +731,6 @@ gb_workbench_open_with_editor (GbWorkbench *self,
   ide_buffer_manager_load_file_async (buffer_manager, idefile, FALSE, NULL, NULL, NULL, NULL);
 }
 
-/**
- * gb_workbench_get_command_manager:
- * @self: A #GbWorkbench.
- *
- * Gets the command manager for the workbench. This may be moved into libide.
- *
- * Returns: (transfer none): A #GbCommandManager.
- */
-GbCommandManager *
-gb_workbench_get_command_manager (GbWorkbench *self)
-{
-  g_return_val_if_fail (GB_IS_WORKBENCH (self), NULL);
-
-  return self->command_manager;
-}
-
 void
 gb_workbench_open_uri_list (GbWorkbench         *self,
                             const gchar * const *uri_list)
diff --git a/src/workbench/gb-workbench.h b/src/workbench/gb-workbench.h
index 2b6ff7d..6e03939 100644
--- a/src/workbench/gb-workbench.h
+++ b/src/workbench/gb-workbench.h
@@ -22,8 +22,6 @@
 #include <gtk/gtk.h>
 #include <ide.h>
 
-#include "gb-command-manager.h"
-
 G_BEGIN_DECLS
 
 #define GB_TYPE_WORKBENCH (gb_workbench_get_type())
@@ -46,7 +44,6 @@ void              gb_workbench_open_with_editor     (GbWorkbench         *self,
                                                      GFile               *file);
 void              gb_workbench_open_uri_list        (GbWorkbench         *self,
                                                      const gchar * const *uri_list);
-GbCommandManager *gb_workbench_get_command_manager  (GbWorkbench         *self);
 gboolean          gb_workbench_get_closing          (GbWorkbench         *self);
 void              gb_workbench_views_foreach        (GbWorkbench         *self,
                                                      GtkCallback          callback,
diff --git a/src/workspace/gb-workspace-pane.c b/src/workspace/gb-workspace-pane.c
index 115d49a..e7b26dd 100644
--- a/src/workspace/gb-workspace-pane.c
+++ b/src/workspace/gb-workspace-pane.c
@@ -141,6 +141,17 @@ gb_workspace_pane_size_allocate (GtkWidget     *widget,
 }
 
 static void
+gb_workspace_pane_grab_focus (GtkWidget *widget)
+{
+  GbWorkspacePane *self= (GbWorkspacePane *)widget;
+  GtkWidget *child;
+
+  child = gtk_stack_get_visible_child (self->stack);
+  if (child != NULL)
+    gtk_widget_grab_focus (child);
+}
+
+static void
 gb_workspace_pane_finalize (GObject *object)
 {
   GbWorkspacePane *self = (GbWorkspacePane *)object;
@@ -200,6 +211,7 @@ gb_workspace_pane_class_init (GbWorkspacePaneClass *klass)
   object_class->set_property = gb_workspace_pane_set_property;
 
   widget_class->draw = gb_workspace_pane_draw;
+  widget_class->grab_focus = gb_workspace_pane_grab_focus;
   widget_class->size_allocate = gb_workspace_pane_size_allocate;
 
   /**
diff --git a/src/workspace/gb-workspace.c b/src/workspace/gb-workspace.c
index 675fa9c..f43092b 100644
--- a/src/workspace/gb-workspace.c
+++ b/src/workspace/gb-workspace.c
@@ -943,6 +943,14 @@ gb_workspace_get_internal_child (GtkBuildable *buildable,
 }
 
 static void
+gb_workspace_grab_focus (GtkWidget *widget)
+{
+  GbWorkspace *self = (GbWorkspace *)widget;
+
+  gtk_widget_grab_focus (self->children [GTK_POS_TOP].widget);
+}
+
+static void
 gb_workspace_finalize (GObject *object)
 {
   GbWorkspace *self = (GbWorkspace *)object;
@@ -1033,6 +1041,7 @@ gb_workspace_class_init (GbWorkspaceClass *klass)
   widget_class->realize = gb_workspace_realize;
   widget_class->unrealize = gb_workspace_unrealize;
   widget_class->size_allocate = gb_workspace_size_allocate;
+  widget_class->grab_focus = gb_workspace_grab_focus;
 
   container_class->get_child_property = gb_workspace_get_child_property;
   container_class->set_child_property = gb_workspace_set_child_property;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]