[gtksourceview] snippet: add gtk_source_snippet_new_parsed()



commit 374352ec10d1cd71bf42da364c0b574cd4ca3b2c
Author: Christian Hergert <chergert redhat com>
Date:   Sun Apr 3 10:41:53 2022 -0700

    snippet: add gtk_source_snippet_new_parsed()
    
    This is a function that can create a new snippet by parsing the snippet
    format used in bundles. It happens to be able to parse a decent amount of
    language-server-protocol snippets as well, which should be what we aim
    for long-term to maximize re-use in IDE tooling such as Builder.

 gtksourceview/gtksourcesnippet.c | 52 ++++++++++++++++++++++++++++++++++++++++
 gtksourceview/gtksourcesnippet.h |  3 +++
 tests/test-snippets.c            | 39 ++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+)
---
diff --git a/gtksourceview/gtksourcesnippet.c b/gtksourceview/gtksourcesnippet.c
index 73ab98c6..5a780f3f 100644
--- a/gtksourceview/gtksourcesnippet.c
+++ b/gtksourceview/gtksourcesnippet.c
@@ -24,6 +24,7 @@
 #include "gtksourcebuffer-private.h"
 #include "gtksourcelanguage.h"
 #include "gtksourcesnippet-private.h"
+#include "gtksourcesnippetbundle-private.h"
 #include "gtksourcesnippetchunk-private.h"
 #include "gtksourcesnippetcontext-private.h"
 
@@ -1413,3 +1414,54 @@ _gtk_source_snippet_replace_current_chunk_text (GtkSourceSnippet *snippet,
                gtk_source_snippet_chunk_set_text_set (snippet->current_chunk, TRUE);
        }
 }
+
+/**
+ * gtk_source_snippet_new_parsed:
+ * @text: the formatted snippet text to parse
+ * @error: a location for a #GError or %NULL
+ *
+ * Parses the snippet formatted @text into a series of chunks and adds them
+ * to a new #GtkSourceSnippet.
+ *
+ * Returns: (transfer full): the newly parsed #GtkSourceSnippet, or %NULL upon
+ *   failure and @error is set.
+ *
+ * Since: 5.6
+ */
+GtkSourceSnippet *
+gtk_source_snippet_new_parsed (const char  *text,
+                               GError     **error)
+{
+       GtkSourceSnippet *snippet;
+       GPtrArray *chunks;
+
+       g_return_val_if_fail (text != NULL, NULL);
+
+       chunks = _gtk_source_snippet_bundle_parse_text (text, error);
+
+       if (chunks == NULL)
+       {
+               return NULL;
+       }
+
+       if (chunks->len == 0)
+       {
+               g_set_error (error,
+                            G_IO_ERROR,
+                            G_IO_ERROR_INVALID_DATA,
+                            "Failed to parse any content from snippet text");
+               g_ptr_array_unref (chunks);
+               return NULL;
+       }
+
+       snippet = gtk_source_snippet_new (NULL, NULL);
+
+       for (guint i = 0; i < chunks->len; i++)
+       {
+               gtk_source_snippet_add_chunk (snippet, g_ptr_array_index (chunks, i));
+       }
+
+       g_ptr_array_unref (chunks);
+
+       return g_steal_pointer (&snippet);
+}
diff --git a/gtksourceview/gtksourcesnippet.h b/gtksourceview/gtksourcesnippet.h
index 379864e2..71e64a31 100644
--- a/gtksourceview/gtksourcesnippet.h
+++ b/gtksourceview/gtksourcesnippet.h
@@ -37,6 +37,9 @@ G_DECLARE_FINAL_TYPE (GtkSourceSnippet, gtk_source_snippet, GTK_SOURCE, SNIPPET,
 GTK_SOURCE_AVAILABLE_IN_ALL
 GtkSourceSnippet        *gtk_source_snippet_new                        (const gchar           *trigger,
                                                                         const gchar           *language_id);
+GTK_SOURCE_AVAILABLE_IN_5_6
+GtkSourceSnippet        *gtk_source_snippet_new_parsed                 (const char            *text,
+                                                                        GError               **error);
 GTK_SOURCE_AVAILABLE_IN_ALL
 GtkSourceSnippet        *gtk_source_snippet_copy                       (GtkSourceSnippet      *snippet);
 GTK_SOURCE_AVAILABLE_IN_ALL
diff --git a/tests/test-snippets.c b/tests/test-snippets.c
index a37febc1..07c839c4 100644
--- a/tests/test-snippets.c
+++ b/tests/test-snippets.c
@@ -51,6 +51,44 @@ test_simple (void)
        g_assert_finalize_object (mgr);
 }
 
+static void
+test_snippet_parse (void)
+{
+       GtkSourceSnippet *snippet;
+       GtkSourceSnippetChunk *chunk;
+       GError *error = NULL;
+
+       snippet = gtk_source_snippet_new_parsed ("${1:test} ${2:$1}$0", &error);
+       g_assert_no_error (error);
+       g_assert_nonnull (snippet);
+
+       g_assert_cmpint (4, ==, gtk_source_snippet_get_n_chunks (snippet));
+
+       chunk = gtk_source_snippet_get_nth_chunk (snippet, 0);
+       g_assert_cmpint (1, ==, gtk_source_snippet_chunk_get_focus_position (chunk));
+       g_assert_cmpstr ("test", ==, gtk_source_snippet_chunk_get_spec (chunk));
+       g_assert_nonnull (chunk);
+
+       chunk = gtk_source_snippet_get_nth_chunk (snippet, 1);
+       g_assert_cmpint (-1, ==, gtk_source_snippet_chunk_get_focus_position (chunk));
+       g_assert_cmpstr (" ", ==, gtk_source_snippet_chunk_get_spec (chunk));
+       g_assert_nonnull (chunk);
+
+       chunk = gtk_source_snippet_get_nth_chunk (snippet, 2);
+       g_assert_cmpint (2, ==, gtk_source_snippet_chunk_get_focus_position (chunk));
+       g_assert_cmpstr ("$1", ==, gtk_source_snippet_chunk_get_spec (chunk));
+       /* Unset until user types */
+       g_assert_cmpstr ("", ==, gtk_source_snippet_chunk_get_text (chunk));
+       g_assert_nonnull (chunk);
+
+       chunk = gtk_source_snippet_get_nth_chunk (snippet, 3);
+       g_assert_cmpint (0, ==, gtk_source_snippet_chunk_get_focus_position (chunk));
+       g_assert_cmpstr ("", ==, gtk_source_snippet_chunk_get_spec (chunk));
+       g_assert_nonnull (chunk);
+
+       g_assert_finalize_object (snippet);
+}
+
 gint
 main (gint argc,
       gchar *argv[])
@@ -62,6 +100,7 @@ main (gint argc,
        g_test_init (&argc, &argv, NULL);
 
        g_test_add_func ("/SourceView/Snippets/parse-bundle", test_simple);
+       g_test_add_func ("/SourceView/Snippets/new-parsed", test_snippet_parse);
        ret = g_test_run ();
 
        gtk_source_finalize ();


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