[gnome-builder] buffer: give IdeBuffer generic addins



commit bc659a41a0bc43782d4d0e3fab353f5fd1e276bb
Author: Christian Hergert <chergert redhat com>
Date:   Sat Jul 15 18:05:12 2017 -0700

    buffer: give IdeBuffer generic addins
    
    This adds the IdeBufferAddin interface which allows a simple
    form of plugins to hook into IdeBuffer. Doing this should allow
    us to move more features outside of IdeBuffer and into dedicated
    plugins that can access features provided by peer objects.

 libide/buffers/ide-buffer-addin.c   |  130 +++++++++++++++++++++++++++++++++++
 libide/buffers/ide-buffer-addin.h   |   46 ++++++++++++
 libide/buffers/ide-buffer-private.h |   45 ++++++++++++
 libide/buffers/ide-buffer.c         |   76 +++++++++++++++++++-
 libide/ide-internal.h               |   14 +----
 libide/ide.h                        |    1 +
 libide/meson.build                  |    3 +
 7 files changed, 299 insertions(+), 16 deletions(-)
---
diff --git a/libide/buffers/ide-buffer-addin.c b/libide/buffers/ide-buffer-addin.c
new file mode 100644
index 0000000..daaf141
--- /dev/null
+++ b/libide/buffers/ide-buffer-addin.c
@@ -0,0 +1,130 @@
+/* ide-buffer-addin.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * 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/>.
+ */
+
+#define G_LOG_DOMAIN "ide-buffer-addin"
+
+#include <libpeas/peas.h>
+
+#include "ide-buffer-addin.h"
+#include "ide-buffer-private.h"
+
+/**
+ * SECTION:ide-buffer-addin
+ * @title: IdeBufferAddin
+ * @short_description: addins for #IdeBuffer
+ *
+ * The #IdeBufferAddin allows a plugin to register an object that will be
+ * created with every #IdeBuffer. It can register extra features with the
+ * buffer or extend it as necessary.
+ *
+ * Once use of #IdeBufferAddin is to add a spellchecker to the buffer that
+ * may be used by views to show the misspelled words. This is preferrable
+ * to adding a spellchecker in each view because it allows for multiple
+ * views to share one spellcheker on the underlying buffer.
+ */
+
+G_DEFINE_INTERFACE (IdeBufferAddin, ide_buffer_addin, G_TYPE_OBJECT)
+
+static void
+ide_buffer_addin_default_init (IdeBufferAddinInterface *iface)
+{
+}
+
+/**
+ * ide_buffer_addin_load:
+ * @self: an #IdeBufferAddin
+ * @buffer: an #IdeBuffer
+ *
+ * This calls the load virtual function of #IdeBufferAddin to request
+ * that the addin load itself.
+ *
+ * Since: 3.26
+ */
+void
+ide_buffer_addin_load (IdeBufferAddin *self,
+                       IdeBuffer      *buffer)
+{
+  g_return_if_fail (IDE_IS_BUFFER_ADDIN (self));
+  g_return_if_fail (IDE_IS_BUFFER (buffer));
+
+  if (IDE_BUFFER_ADDIN_GET_IFACE (self)->load)
+    IDE_BUFFER_ADDIN_GET_IFACE (self)->load (self, buffer);
+}
+
+/**
+ * ide_buffer_addin_unload:
+ * @self: an #IdeBufferAddin
+ * @buffer: an #IdeBuffer
+ *
+ * This calls the unload virtual function of #IdeBufferAddin to request
+ * that the addin unload itself.
+ *
+ * The addin should cancel any in-flight operations and attempt to drop
+ * references to the buffer or any other machinery as soon as possible.
+ *
+ * Since: 3.26
+ */
+void
+ide_buffer_addin_unload (IdeBufferAddin *self,
+                         IdeBuffer      *buffer)
+{
+  g_return_if_fail (IDE_IS_BUFFER_ADDIN (self));
+  g_return_if_fail (IDE_IS_BUFFER (buffer));
+
+  if (IDE_BUFFER_ADDIN_GET_IFACE (self)->unload)
+    IDE_BUFFER_ADDIN_GET_IFACE (self)->unload (self, buffer);
+}
+
+/**
+ * ide_buffer_addin_find_by_module_name:
+ * @buffer: an #IdeBuffer
+ * @module_name: the module name of the addin
+ *
+ * Locates an addin attached to the #IdeBuffer by the name of the module
+ * that provides the addin.
+ *
+ * Returns: (transfer none) (nullable): An #IdeBufferAddin or %NULL
+ *
+ * Since: 3.26
+ */
+IdeBufferAddin *
+ide_buffer_addin_find_by_module_name (IdeBuffer   *buffer,
+                                      const gchar *module_name)
+{
+  PeasPluginInfo *plugin_info;
+  PeasExtensionSet *set;
+  PeasExtension *ret = NULL;
+
+  g_return_val_if_fail (IDE_IS_BUFFER (buffer), NULL);
+  g_return_val_if_fail (module_name != NULL, NULL);
+
+  set = _ide_buffer_get_addins (buffer);
+
+  /* Addins might not be loaded */
+  if (set == NULL)
+    return NULL;
+
+  plugin_info = peas_engine_get_plugin_info (peas_engine_get_default (), module_name);
+
+  if (plugin_info != NULL)
+    ret = peas_extension_set_get_extension (set, plugin_info);
+  else
+    g_warning ("Failed to locate addin named %s", module_name);
+
+  return ret ? IDE_BUFFER_ADDIN (ret) : NULL;
+}
diff --git a/libide/buffers/ide-buffer-addin.h b/libide/buffers/ide-buffer-addin.h
new file mode 100644
index 0000000..41c490a
--- /dev/null
+++ b/libide/buffers/ide-buffer-addin.h
@@ -0,0 +1,46 @@
+/* ide-buffer-addin.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * 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/>.
+ */
+
+#pragma once
+
+#include "buffers/ide-buffer.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_BUFFER_ADDIN (ide_buffer_addin_get_type())
+
+G_DECLARE_INTERFACE (IdeBufferAddin, ide_buffer_addin, IDE, BUFFER_ADDIN, GObject)
+
+struct _IdeBufferAddinInterface
+{
+  GTypeInterface parent_iface;
+
+  void (*load)   (IdeBufferAddin    *self,
+                  IdeBuffer         *buffer);
+  void (*unload) (IdeBufferAddin    *self,
+                  IdeBuffer         *buffer);
+};
+
+void            ide_buffer_addin_load                (IdeBufferAddin *self,
+                                                      IdeBuffer      *buffer);
+void            ide_buffer_addin_unload              (IdeBufferAddin *self,
+                                                      IdeBuffer      *buffer);
+IdeBufferAddin *ide_buffer_addin_find_by_module_name (IdeBuffer      *buffer,
+                                                      const gchar    *module_name);
+
+G_END_DECLS
diff --git a/libide/buffers/ide-buffer-private.h b/libide/buffers/ide-buffer-private.h
new file mode 100644
index 0000000..1bb5246
--- /dev/null
+++ b/libide/buffers/ide-buffer-private.h
@@ -0,0 +1,45 @@
+/* ide-buffer-private.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * 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/>.
+ */
+
+#pragma once
+
+#include <dazzle.h>
+#include <libpeas/peas.h>
+
+#include "buffers/ide-buffer.h"
+#include "buffers/ide-buffer-manager.h"
+
+G_BEGIN_DECLS
+
+PeasExtensionSet *_ide_buffer_get_addins            (IdeBuffer        *self);
+void              _ide_buffer_set_changed_on_volume (IdeBuffer        *self,
+                                                     gboolean          changed_on_volume);
+gboolean          _ide_buffer_get_loading           (IdeBuffer        *self);
+void              _ide_buffer_set_loading           (IdeBuffer        *self,
+                                                     gboolean          loading);
+void              _ide_buffer_cancel_cursor_restore (IdeBuffer        *self);
+gboolean          _ide_buffer_can_restore_cursor    (IdeBuffer        *self);
+void              _ide_buffer_set_mtime             (IdeBuffer        *self,
+                                                     const GTimeVal   *mtime);
+void              _ide_buffer_set_read_only         (IdeBuffer        *buffer,
+                                                     gboolean          read_only);
+
+void              _ide_buffer_manager_reclaim       (IdeBufferManager *self,
+                                                     IdeBuffer        *buffer);
+
+G_END_DECLS
diff --git a/libide/buffers/ide-buffer.c b/libide/buffers/ide-buffer.c
index 3889d83..d260b76 100644
--- a/libide/buffers/ide-buffer.c
+++ b/libide/buffers/ide-buffer.c
@@ -25,18 +25,20 @@
 #include "ide-debug.h"
 #include "ide-internal.h"
 
+#include "buffers/ide-buffer-addin.h"
 #include "buffers/ide-buffer-change-monitor.h"
-#include "buffers/ide-buffer.h"
+#include "buffers/ide-buffer-manager.h"
+#include "buffers/ide-buffer-private.h"
 #include "buffers/ide-unsaved-files.h"
 #include "diagnostics/ide-diagnostic.h"
-#include "diagnostics/ide-diagnostics.h"
 #include "diagnostics/ide-diagnostics-manager.h"
+#include "diagnostics/ide-diagnostics.h"
 #include "diagnostics/ide-source-location.h"
 #include "diagnostics/ide-source-range.h"
 #include "files/ide-file-settings.h"
 #include "files/ide-file.h"
-#include "formatting/ide-formatter.h"
 #include "formatting/ide-formatter-options.h"
+#include "formatting/ide-formatter.h"
 #include "highlighting/ide-highlight-engine.h"
 #include "highlighting/ide-highlighter.h"
 #include "plugins/ide-extension-adapter.h"
@@ -80,6 +82,7 @@ typedef struct
   IdeExtensionAdapter    *formatter_adapter;
   IdeExtensionAdapter    *rename_provider_adapter;
   IdeExtensionAdapter    *symbol_resolver_adapter;
+  PeasExtensionSet       *addins;
   gchar                  *title;
 
   DzlSignalGroup         *file_signals;
@@ -1135,6 +1138,46 @@ ide_buffer_load_symbol_resolver (IdeBuffer           *self,
 }
 
 static void
+ide_buffer_addin_added (PeasExtensionSet *set,
+                        PeasPluginInfo   *plugin_info,
+                        PeasExtension    *exten,
+                        gpointer          user_data)
+{
+  IdeBufferAddin *addin = (IdeBufferAddin *)exten;
+  IdeBuffer *self = user_data;
+
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (IDE_IS_BUFFER_ADDIN (addin));
+  g_assert (IDE_IS_BUFFER (self));
+
+  g_debug ("loading IdeBufferAddin from %s",
+           peas_plugin_info_get_module_name (plugin_info));
+
+  ide_buffer_addin_load (addin, self);
+}
+
+static void
+ide_buffer_addin_removed (PeasExtensionSet *set,
+                          PeasPluginInfo   *plugin_info,
+                          PeasExtension    *exten,
+                          gpointer          user_data)
+{
+  IdeBufferAddin *addin = (IdeBufferAddin *)exten;
+  IdeBuffer *self = user_data;
+
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (IDE_IS_BUFFER_ADDIN (addin));
+  g_assert (IDE_IS_BUFFER (self));
+
+  g_debug ("unloading IdeBufferAddin from %s",
+           peas_plugin_info_get_module_name (plugin_info));
+
+  ide_buffer_addin_unload (addin, self);
+}
+
+static void
 ide_buffer_constructed (GObject *object)
 {
   IdeBuffer *self = (IdeBuffer *)object;
@@ -1219,6 +1262,22 @@ ide_buffer_constructed (GObject *object)
   priv->highlight_engine = ide_highlight_engine_new (self);
   ide_highlight_engine_pause (priv->highlight_engine);
 
+  priv->addins = peas_extension_set_new (peas_engine_get_default (),
+                                         IDE_TYPE_BUFFER_ADDIN,
+                                         NULL);
+
+  g_signal_connect (priv->addins,
+                    "extension-added",
+                    G_CALLBACK (ide_buffer_addin_added),
+                    self);
+
+  g_signal_connect (priv->addins,
+                    "extension-removed",
+                    G_CALLBACK (ide_buffer_addin_removed),
+                    self);
+
+  peas_extension_set_foreach (priv->addins, ide_buffer_addin_added, self);
+
   priv->formatter_adapter = ide_extension_adapter_new (priv->context,
                                                        NULL,
                                                        IDE_TYPE_FORMATTER,
@@ -1311,6 +1370,7 @@ ide_buffer_dispose (GObject *object)
   g_clear_pointer (&priv->content, g_bytes_unref);
   g_clear_pointer (&priv->title, g_free);
   g_clear_object (&priv->file);
+  g_clear_object (&priv->addins);
   g_clear_object (&priv->highlight_engine);
   g_clear_object (&priv->rename_provider_adapter);
   g_clear_object (&priv->symbol_resolver_adapter);
@@ -2953,3 +3013,13 @@ _ide_buffer_can_restore_cursor (IdeBuffer *self)
   g_return_val_if_fail (IDE_IS_BUFFER (self), FALSE);
   return !priv->cancel_cursor_restore;
 }
+
+PeasExtensionSet *
+_ide_buffer_get_addins (IdeBuffer *self)
+{
+  IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_BUFFER (self), NULL);
+
+  return priv->addins;
+}
diff --git a/libide/ide-internal.h b/libide/ide-internal.h
index e2b991e..92c464c 100644
--- a/libide/ide-internal.h
+++ b/libide/ide-internal.h
@@ -23,6 +23,7 @@
 
 #include "ide-types.h"
 
+#include "buffers/ide-buffer-private.h"
 #include "highlighting/ide-highlight-engine.h"
 #include "history/ide-back-forward-item.h"
 #include "history/ide-back-forward-list.h"
@@ -35,19 +36,6 @@ G_BEGIN_DECLS
 
 void                _ide_battery_monitor_init               (void);
 void                _ide_battery_monitor_shutdown           (void);
-void                _ide_buffer_set_changed_on_volume       (IdeBuffer             *self,
-                                                             gboolean               changed_on_volume);
-gboolean            _ide_buffer_get_loading                 (IdeBuffer             *self);
-void                _ide_buffer_set_loading                 (IdeBuffer             *self,
-                                                             gboolean               loading);
-void                _ide_buffer_cancel_cursor_restore       (IdeBuffer             *self);
-gboolean            _ide_buffer_can_restore_cursor          (IdeBuffer             *self);
-void                _ide_buffer_set_mtime                   (IdeBuffer             *self,
-                                                             const GTimeVal        *mtime);
-void                _ide_buffer_set_read_only               (IdeBuffer             *buffer,
-                                                             gboolean               read_only);
-void                _ide_buffer_manager_reclaim             (IdeBufferManager      *self,
-                                                             IdeBuffer             *buffer);
 void                _ide_build_system_set_project_file      (IdeBuildSystem        *self,
                                                              GFile                 *project_file);
 void                _ide_configuration_set_prebuild         (IdeConfiguration      *self,
diff --git a/libide/ide.h b/libide/ide.h
index b6ca24a..ec7d96c 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -39,6 +39,7 @@ G_BEGIN_DECLS
 #include "application/ide-application-addin.h"
 #include "application/ide-application-tool.h"
 #include "application/ide-application.h"
+#include "buffers/ide-buffer-addin.h"
 #include "buffers/ide-buffer-change-monitor.h"
 #include "buffers/ide-buffer-manager.h"
 #include "buffers/ide-buffer.h"
diff --git a/libide/meson.build b/libide/meson.build
index c4e1355..2e3f812 100644
--- a/libide/meson.build
+++ b/libide/meson.build
@@ -60,6 +60,7 @@ libide_public_headers = [
   'application/ide-application-credits.h',
   'application/ide-application-tool.h',
   'application/ide-application.h',
+  'buffers/ide-buffer-addin.h',
   'buffers/ide-buffer-change-monitor.h',
   'buffers/ide-buffer-manager.h',
   'buffers/ide-buffer.h',
@@ -257,6 +258,7 @@ libide_public_sources = [
   'application/ide-application-tool.c',
   'application/ide-application.c',
   'application/ide-application-open.c',
+  'buffers/ide-buffer-addin.c',
   'buffers/ide-buffer-change-monitor.c',
   'buffers/ide-buffer-manager.c',
   'buffers/ide-buffer.c',
@@ -443,6 +445,7 @@ libide_sources = libide_generated_headers + libide_public_sources + [
   'application/ide-application-private.h',
   'application/ide-application-tests.c',
   'application/ide-application-tests.h',
+  'buffers/ide-buffer-private.h',
   'buildconfig/ide-buildconfig-plugin.c',
   'buildconfig/ide-buildconfig-pipeline-addin.c',
   'buildconfig/ide-buildconfig-pipeline-addin.h',


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