[gtksourceview/wip/chergert/snippets: 3/3] wip: snippet manager



commit 356f2d7a492aa81b18c4150a67b67e6b9ebd4a00
Author: Christian Hergert <chergert redhat com>
Date:   Mon Jan 27 17:16:15 2020 -0800

    wip: snippet manager

 gtksourceview/gtksource.h                       |   1 +
 gtksourceview/gtksourceinit.c                   |   5 +
 gtksourceview/gtksourcesnippetmanager-private.h |  29 ++
 gtksourceview/gtksourcesnippetmanager.c         | 337 ++++++++++++++++++++++++
 gtksourceview/gtksourcesnippetmanager.h         |  48 ++++
 gtksourceview/gtksourcetypes.h                  |   1 +
 gtksourceview/meson.build                       |   2 +
 7 files changed, 423 insertions(+)
---
diff --git a/gtksourceview/gtksource.h b/gtksourceview/gtksource.h
index bea7c201..2656d70b 100644
--- a/gtksourceview/gtksource.h
+++ b/gtksourceview/gtksource.h
@@ -50,6 +50,7 @@
 #include "gtksourcesnippet.h"
 #include "gtksourcesnippetchunk.h"
 #include "gtksourcesnippetcontext.h"
+#include "gtksourcesnippetmanager.h"
 #include "gtksourcespacedrawer.h"
 #include "gtksourcestyle.h"
 #include "gtksourcestylescheme.h"
diff --git a/gtksourceview/gtksourceinit.c b/gtksourceview/gtksourceinit.c
index 0e10b047..9de2a811 100644
--- a/gtksourceview/gtksourceinit.c
+++ b/gtksourceview/gtksourceinit.c
@@ -32,6 +32,7 @@
 #include "gtksourceinit.h"
 #include "gtksourcelanguagemanager-private.h"
 #include "gtksourcemap.h"
+#include "gtksourcesnippetmanager-private.h"
 #include "gtksourcestyleschemechooser.h"
 #include "gtksourcestyleschemechooserbutton.h"
 #include "gtksourcestyleschemechooserwidget.h"
@@ -233,6 +234,7 @@ gtk_source_finalize (void)
        {
                GtkSourceLanguageManager *language_manager;
                GtkSourceStyleSchemeManager *style_scheme_manager;
+               GtkSourceSnippetManager *snippet_manager;
 
                language_manager = _gtk_source_language_manager_peek_default ();
                g_clear_object (&language_manager);
@@ -240,6 +242,9 @@ gtk_source_finalize (void)
                style_scheme_manager = _gtk_source_style_scheme_manager_peek_default ();
                g_clear_object (&style_scheme_manager);
 
+               snippet_manager = _gtk_source_snippet_manager_peek_default ();
+               g_clear_object (&snippet_manager);
+
                done = TRUE;
        }
 }
diff --git a/gtksourceview/gtksourcesnippetmanager-private.h b/gtksourceview/gtksourcesnippetmanager-private.h
new file mode 100644
index 00000000..7a0f86d3
--- /dev/null
+++ b/gtksourceview/gtksourcesnippetmanager-private.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2020 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "gtksourcesnippetmanager.h"
+
+G_BEGIN_DECLS
+
+G_GNUC_INTERNAL
+GtkSourceSnippetManager *_gtk_source_snippet_manager_peek_default (void);
+
+G_END_DECLS
diff --git a/gtksourceview/gtksourcesnippetmanager.c b/gtksourceview/gtksourcesnippetmanager.c
new file mode 100644
index 00000000..1975e578
--- /dev/null
+++ b/gtksourceview/gtksourcesnippetmanager.c
@@ -0,0 +1,337 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2020 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtksourcesnippet-private.h"
+#include "gtksourcesnippetmanager-private.h"
+#include "gtksourceutils-private.h"
+
+/**
+ * SECTION:snippetmanager
+ * @title: GtkSourceSnippetManager
+ * @short_description: Provides access to #GtkSourceSnippet
+ * @see_also: #GtkSourceSnippet
+ *
+ * #GtkSourceSnippetManager is an object which processes snippet description
+ * files and creates #GtkSourceSnippet objects.
+ *
+ * Use gtk_source_snippet_manager_get_default() to retrieve the default
+ * instance of #GtkSourceSnippetManager.
+ *
+ * Use gtk_source_snippet_manager_get_snippets() to retrieve snippets for
+ * a given snippets.
+ *
+ * Since: 5.0
+ */
+
+#define SNIPPET_DIR         "snippets"
+#define SNIPPET_FILE_SUFFIX ".snippets"
+
+struct _GtkSourceSnippetManager
+{
+       GObject parent_instance;
+
+       gchar **snippet_dirs;
+};
+
+enum {
+       PROP_0,
+       PROP_SEARCH_PATH,
+       N_PROPS
+};
+
+static GtkSourceSnippetManager *default_instance;
+static GParamSpec *properties[N_PROPS];
+
+G_DEFINE_TYPE (GtkSourceSnippetManager, gtk_source_snippet_manager, G_TYPE_OBJECT)
+
+static void
+gtk_source_snippet_manager_finalize (GObject *object)
+{
+       GtkSourceSnippetManager *self = GTK_SOURCE_SNIPPET_MANAGER (object);
+
+       g_clear_pointer (&self->snippet_dirs, g_strfreev);
+
+       G_OBJECT_CLASS (gtk_source_snippet_manager_parent_class)->finalize (object);
+}
+
+static void
+gtk_source_snippet_manager_set_property (GObject      *object,
+                                         guint         prop_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec)
+{
+       GtkSourceSnippetManager *self = GTK_SOURCE_SNIPPET_MANAGER (object);
+
+       switch (prop_id)
+       {
+       case PROP_SEARCH_PATH:
+               gtk_source_snippet_manager_set_search_path (self, g_value_get_boxed (value));
+               break;
+
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+gtk_source_snippet_manager_get_property (GObject    *object,
+                                         guint       prop_id,
+                                         GValue     *value,
+                                         GParamSpec *pspec)
+{
+       GtkSourceSnippetManager *self = GTK_SOURCE_SNIPPET_MANAGER (object);
+
+       switch (prop_id)
+       {
+       case PROP_SEARCH_PATH:
+               g_value_set_boxed (value, gtk_source_snippet_manager_get_search_path (self));
+               break;
+
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+gtk_source_snippet_manager_class_init (GtkSourceSnippetManagerClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->finalize  = gtk_source_snippet_manager_finalize;
+       object_class->set_property = gtk_source_snippet_manager_set_property;
+       object_class->get_property = gtk_source_snippet_manager_get_property;
+
+       /**
+        * GtkSourceSnippetManager:search-path:
+        *
+        * The "search-path" property contains a list of directories to search
+        * for files containing snippets (*.snippets).
+        *
+        * Since: 5.0
+        */
+       properties[PROP_SEARCH_PATH] =
+               g_param_spec_boxed ("search-path",
+                                   "Snippet directories",
+                                   "List of directories with snippet definitions (*.snippets)",
+                                   G_TYPE_STRV,
+                                   (G_PARAM_READWRITE |
+                                    G_PARAM_EXPLICIT_NOTIFY |
+                                    G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+gtk_source_snippet_manager_init (GtkSourceSnippetManager *self)
+{
+}
+
+/**
+ * gtk_source_snippet_manager_get_default:
+ *
+ * Returns the default #GtkSourceSnippetManager instance.
+ *
+ * Returns: (transfer none) (not nullable): a #GtkSourceSnippetManager which
+ *   is owned by GtkSourceView library and must not be unref'd.
+ *
+ * Since: 5.0
+ */
+GtkSourceSnippetManager *
+gtk_source_snippet_manager_get_default (void)
+{
+       if (default_instance == NULL)
+       {
+               GtkSourceSnippetManager *self;
+
+               self = g_object_new (GTK_SOURCE_TYPE_SNIPPET_MANAGER, NULL);
+               g_set_weak_pointer (&default_instance, self);
+       }
+
+       return default_instance;
+}
+
+GtkSourceSnippetManager *
+_gtk_source_snippet_manager_peek_default (void)
+{
+       return default_instance;
+}
+
+/**
+ * gtk_source_snippet_manager_set_search_path:
+ * @self: a #GtkSourceSnippetManager
+ * @dirs: (nullable) (array zero-terminated=1): a %NULL-terminated array of
+ *   strings or %NULL.
+ *
+ * Sets the list of directories in which the #GtkSourceSnippetManagerlooks for
+ * snippet files.  If @dirs is %NULL, the search path is reset to default.
+ *
+ * <note>
+ *   <para>
+ *     At the moment this function can be called only before the
+ *     snippet files are loaded for the first time. In practice
+ *     to set a custom search path for a #GtkSourceSnippetManager,
+ *     you have to call this function right after creating it.
+ *   </para>
+ * </note>
+ *
+ * Since: 5.0
+ */
+void
+gtk_source_snippet_manager_set_search_path (GtkSourceSnippetManager *self,
+                                           const gchar * const     *dirs)
+{
+       gchar **tmp;
+
+       g_return_if_fail (GTK_SOURCE_IS_SNIPPET_MANAGER (self));
+
+       tmp = self->snippet_dirs;
+
+       if (dirs == NULL)
+               self->snippet_dirs = _gtk_source_utils_get_default_dirs (SNIPPET_DIR);
+       else
+               self->snippet_dirs = g_strdupv ((gchar **)dirs);
+
+       g_strfreev (tmp);
+
+       g_object_notify_by_pspec (G_OBJECT (self),
+                                 properties [PROP_SEARCH_PATH]);
+}
+
+/**
+ * gtk_source_snippet_manager_get_search_path:
+ * @self: a #GtkSourceSnippetManager.
+ *
+ * Gets the list directories where @self looks for snippet files.
+ *
+ * Returns: (array zero-terminated=1) (transfer none): %NULL-terminated array
+ *   containg a list of snippet files directories.
+ *   The array is owned by @lm and must not be modified.
+ *
+ * Since: 5.0
+ */
+const gchar * const *
+gtk_source_snippet_manager_get_search_path (GtkSourceSnippetManager *self)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_SNIPPET_MANAGER (self), NULL);
+
+       if (self->snippet_dirs == NULL)
+               self->snippet_dirs = _gtk_source_utils_get_default_dirs (SNIPPET_DIR);
+
+       return (const gchar * const *)self->snippet_dirs;
+}
+
+static void
+ensure_snippets (GtkSourceSnippetManager *self)
+{
+#if 0
+       GSList *filenames, *l;
+       GPtrArray *ids_array = NULL;
+
+       if (self->snippet_ids != NULL)
+       {
+               return;
+       }
+
+       filenames = _gtk_source_utils_get_file_list (
+               (gchar **)gtk_source_snippet_manager_get_search_path (self),
+               SNIPPET_FILE_SUFFIX,
+               TRUE);
+
+       for (l = filenames; l != NULL; l = l->next)
+       {
+               GtkSourceSnippet *lang;
+               const gchar *id;
+               gchar *filename;
+
+               filename = l->data;
+
+               lang = _gtk_source_snippet_new_from_file (filename, self);
+
+               if (lang == NULL)
+               {
+                       g_warning ("Error reading snippet specification file '%s'", filename);
+                       continue;
+               }
+
+               id = gtk_source_snippet_get_id (lang);
+
+               if (g_hash_table_lookup (self->snippet_ids, id) == NULL)
+               {
+                       g_hash_table_insert (self->snippet_ids,
+                                            g_strdup (id),
+                                            lang);
+
+                       if (ids_array == NULL)
+                               ids_array = g_ptr_array_new ();
+
+                       g_ptr_array_add (ids_array, g_strdup (id));
+               }
+               else
+               {
+                       g_object_unref (lang);
+               }
+       }
+
+       if (ids_array != NULL)
+       {
+               /* Sort the array alphabetically so that it
+                * is ready to use in a list of a GUI */
+               g_ptr_array_sort_with_data (ids_array,
+                                           (GCompareDataFunc)snippet_compare,
+                                           self->snippet_ids);
+
+               /* Ensure the array is NULL terminated */
+               g_ptr_array_add (ids_array, NULL);
+
+               self->ids = (gchar **)g_ptr_array_free (ids_array, FALSE);
+       }
+
+       g_slist_free_full (filenames, g_free);
+#endif
+}
+
+/**
+ * gtk_source_snippet_manager_get_snippets:
+ * @self: a #GtkSourceSnippetManager
+ * @language_id: (nullable): the language identifier for the snippets or %NULL
+ *   for only global snippets
+ *
+ * Gets the snippets for a specific language.
+ *
+ * The resulting list also contains global snippets that apply to
+ * any language, if any.
+ *
+ * Returns: (transfer full) (nullable): a #GListModel, or %NULL
+ *
+ * Since: 5.0
+ */
+GListModel *
+gtk_source_snippet_manager_get_snippets (GtkSourceSnippetManager *self,
+                                         const gchar             *language_id)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_SNIPPET_MANAGER (self), NULL);
+
+       ensure_snippets (self);
+
+       return NULL;
+}
diff --git a/gtksourceview/gtksourcesnippetmanager.h b/gtksourceview/gtksourcesnippetmanager.h
new file mode 100644
index 00000000..9d922a36
--- /dev/null
+++ b/gtksourceview/gtksourcesnippetmanager.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2020 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#if !defined (GTK_SOURCE_H_INSIDE) && !defined (GTK_SOURCE_COMPILATION)
+#error "Only <gtksourceview/gtksource.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+
+#include "gtksourcetypes.h"
+
+G_BEGIN_DECLS
+
+#define GTK_SOURCE_TYPE_SNIPPET_MANAGER (gtk_source_snippet_manager_get_type())
+
+GTK_SOURCE_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (GtkSourceSnippetManager, gtk_source_snippet_manager, GTK_SOURCE, SNIPPET_MANAGER, 
GObject)
+
+GTK_SOURCE_AVAILABLE_IN_5_0
+GtkSourceSnippetManager *gtk_source_snippet_manager_get_default      (void);
+GTK_SOURCE_AVAILABLE_IN_5_0
+const gchar * const      *gtk_source_snippet_manager_get_search_path (GtkSourceSnippetManager  *self);
+GTK_SOURCE_AVAILABLE_IN_5_0
+void                      gtk_source_snippet_manager_set_search_path (GtkSourceSnippetManager  *self,
+                                                                      const gchar * const      *dirs);
+GTK_SOURCE_AVAILABLE_IN_5_0
+GListModel               *gtk_source_snippet_manager_get_snippets    (GtkSourceSnippetManager  *self,
+                                                                      const gchar              *language_id);
+
+G_END_DECLS
diff --git a/gtksourceview/gtksourcetypes.h b/gtksourceview/gtksourcetypes.h
index 8cf43b47..2348964b 100644
--- a/gtksourceview/gtksourcetypes.h
+++ b/gtksourceview/gtksourcetypes.h
@@ -62,6 +62,7 @@ typedef struct _GtkSourceSearchSettings            GtkSourceSearchSettings;
 typedef struct _GtkSourceSnippet                   GtkSourceSnippet;
 typedef struct _GtkSourceSnippetChunk              GtkSourceSnippetChunk;
 typedef struct _GtkSourceSnippetContext            GtkSourceSnippetContext;
+typedef struct _GtkSourceSnippetManager            GtkSourceSnippetManager;
 typedef struct _GtkSourceSpaceDrawer               GtkSourceSpaceDrawer;
 typedef struct _GtkSourceStyle                     GtkSourceStyle;
 typedef struct _GtkSourceStyleSchemeChooserButton  GtkSourceStyleSchemeChooserButton;
diff --git a/gtksourceview/meson.build b/gtksourceview/meson.build
index 5073577a..bedfebb9 100644
--- a/gtksourceview/meson.build
+++ b/gtksourceview/meson.build
@@ -36,6 +36,7 @@ core_public_h = files([
   'gtksourcesnippet.h',
   'gtksourcesnippetchunk.h',
   'gtksourcesnippetcontext.h',
+  'gtksourcesnippetmanager.h',
   'gtksourcespacedrawer.h',
   'gtksourcestyle.h',
   'gtksourcestylescheme.h',
@@ -79,6 +80,7 @@ core_public_c = files([
   'gtksourcesnippet.c',
   'gtksourcesnippetchunk.c',
   'gtksourcesnippetcontext.c',
+  'gtksourcesnippetmanager.c',
   'gtksourcespacedrawer.c',
   'gtksourcestyle.c',
   'gtksourcestylescheme.c',


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