[gtksourceview/wip/chergert/snippets] start on some conversion to marks



commit d09f4e52537e63a5600d8b9964497a2484486278
Author: Christian Hergert <chergert redhat com>
Date:   Wed Jan 22 14:05:56 2020 -0800

    start on some conversion to marks

 data/styles/classic.xml                       |  2 +
 gtksourceview/gtksourcesnippet.c              | 15 ++++--
 gtksourceview/gtksourcesnippetchunk-private.h | 33 ++++++++++++
 gtksourceview/gtksourcesnippetchunk.c         | 46 +++++++++++++++--
 gtksourceview/gtksourceview-private.h         |  1 +
 gtksourceview/gtksourceview-snippets.c        | 73 ++++++++++++++++++++++++---
 6 files changed, 155 insertions(+), 15 deletions(-)
---
diff --git a/data/styles/classic.xml b/data/styles/classic.xml
index 379ede77..c0f2cda0 100644
--- a/data/styles/classic.xml
+++ b/data/styles/classic.xml
@@ -127,6 +127,8 @@
 
   <style name="sh:variable"                 foreground="#6A5ACD"/>
 
+  <style name="snippet:focus-position"      background="gray"/>
+
   <!-- legacy styles for old lang files -->
   <style name="Others"                      foreground="#2E8B57" bold="true"/>
   <style name="Others 2"                    foreground="#008B8B"/>
diff --git a/gtksourceview/gtksourcesnippet.c b/gtksourceview/gtksourcesnippet.c
index 3f87235d..1885537c 100644
--- a/gtksourceview/gtksourcesnippet.c
+++ b/gtksourceview/gtksourcesnippet.c
@@ -23,8 +23,7 @@
 
 #include "gtksourcebuffer-private.h"
 #include "gtksourcesnippet-private.h"
-#include "gtksourcesnippetchunk.h"
-#include "gtksourcesnippetcontext.h"
+#include "gtksourcesnippetchunk-private.h"
 #include "gtksourcesnippetcontext-private.h"
 
 struct _GtkSourceSnippet
@@ -80,8 +79,6 @@ GtkSourceSnippet *
 gtk_source_snippet_new (const gchar *trigger,
                         const gchar *language_id)
 {
-       g_return_val_if_fail (trigger != NULL, NULL);
-
        return g_object_new (GTK_SOURCE_TYPE_SNIPPET,
                             "trigger", trigger,
                             "language-id", language_id,
@@ -177,7 +174,7 @@ gtk_source_snippet_get_n_chunks (GtkSourceSnippet *self)
  */
 GtkSourceSnippetChunk *
 gtk_source_snippet_get_nth_chunk (GtkSourceSnippet *self,
-                           guint             nth)
+                                  guint             nth)
 {
        g_return_val_if_fail (GTK_SOURCE_IS_SNIPPET (self), 0);
 
@@ -714,11 +711,16 @@ _gtk_source_snippet_begin (GtkSourceSnippet *self,
        for (guint i = 0; i < self->chunks->len; i++)
        {
                GtkSourceSnippetChunk *chunk;
+               GtkTextMark *begin;
+               GtkTextMark *end;
                const gchar *text;
 
                chunk = g_ptr_array_index (self->chunks, i);
                text = gtk_source_snippet_chunk_get_text (chunk);
 
+               begin = gtk_text_buffer_create_mark (buffer, NULL, iter, TRUE);
+               _gtk_source_snippet_chunk_set_begin_mark (chunk, begin);
+
                if (text != NULL)
                {
                        gint len;
@@ -727,6 +729,9 @@ _gtk_source_snippet_begin (GtkSourceSnippet *self,
                        g_array_append_val (self->runs, len);
                        gtk_text_buffer_insert (buffer, iter, text, -1);
                }
+
+               end = gtk_text_buffer_create_mark (buffer, NULL, iter, FALSE);
+               _gtk_source_snippet_chunk_set_end_mark (chunk, end);
        }
 
        mark = gtk_text_buffer_create_mark (buffer, NULL, iter, FALSE);
diff --git a/gtksourceview/gtksourcesnippetchunk-private.h b/gtksourceview/gtksourcesnippetchunk-private.h
new file mode 100644
index 00000000..f5f9aa29
--- /dev/null
+++ b/gtksourceview/gtksourcesnippetchunk-private.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2014-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 "gtksourcesnippetchunk.h"
+
+G_BEGIN_DECLS
+
+GtkTextMark *_gtk_source_snippet_chunk_get_begin_mark (GtkSourceSnippetChunk *chunk);
+void         _gtk_source_snippet_chunk_set_begin_mark (GtkSourceSnippetChunk *chunk,
+                                                       GtkTextMark           *end_mark);
+GtkTextMark *_gtk_source_snippet_chunk_get_end_mark   (GtkSourceSnippetChunk *chunk);
+void         _gtk_source_snippet_chunk_set_end_mark   (GtkSourceSnippetChunk *chunk,
+                                                       GtkTextMark           *end_mark);
+
+G_END_DECLS
diff --git a/gtksourceview/gtksourcesnippetchunk.c b/gtksourceview/gtksourcesnippetchunk.c
index 738f7a69..96f0bfdd 100644
--- a/gtksourceview/gtksourcesnippetchunk.c
+++ b/gtksourceview/gtksourcesnippetchunk.c
@@ -1,7 +1,7 @@
 /*
  * This file is part of GtkSourceView
  *
- * Copyright 2020 Christian Hergert <chergert redhat com>
+ * Copyright 2014-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
@@ -19,7 +19,7 @@
 
 #include "config.h"
 
-#include "gtksourcesnippetchunk.h"
+#include "gtksourcesnippetchunk-private.h"
 #include "gtksourcesnippetcontext.h"
 
 /**
@@ -42,6 +42,8 @@ struct _GtkSourceSnippetChunk
        GtkSourceSnippetContext *context;
        gchar                   *spec;
        gchar                   *text;
+       GtkTextMark             *begin_mark;
+       GtkTextMark             *end_mark;
 
        gulong                   context_changed_handler;
 
@@ -102,13 +104,13 @@ static void
 on_context_changed (GtkSourceSnippetContext *context,
                     GtkSourceSnippetChunk   *chunk)
 {
-       gchar *text;
-
        g_assert (GTK_SOURCE_IS_SNIPPET_CHUNK (chunk));
        g_assert (GTK_SOURCE_IS_SNIPPET_CONTEXT (context));
 
        if (!chunk->text_set)
        {
+               gchar *text;
+
                text = gtk_source_snippet_context_expand (context, chunk->spec);
                gtk_source_snippet_chunk_set_text (chunk, text);
                g_free (text);
@@ -402,3 +404,39 @@ gtk_source_snippet_chunk_init (GtkSourceSnippetChunk *chunk)
        chunk->focus_position = -1;
        chunk->spec = g_strdup ("");
 }
+
+GtkTextMark *
+_gtk_source_snippet_chunk_get_begin_mark (GtkSourceSnippetChunk *chunk)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_SNIPPET_CHUNK (chunk), NULL);
+
+       return chunk->begin_mark;
+}
+
+GtkTextMark *
+_gtk_source_snippet_chunk_get_end_mark (GtkSourceSnippetChunk *chunk)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_SNIPPET_CHUNK (chunk), NULL);
+
+       return chunk->begin_mark;
+}
+
+void
+_gtk_source_snippet_chunk_set_begin_mark (GtkSourceSnippetChunk *chunk,
+                                          GtkTextMark           *begin_mark)
+{
+       g_return_if_fail (GTK_SOURCE_IS_SNIPPET_CHUNK (chunk));
+       g_return_if_fail (!begin_mark || GTK_IS_TEXT_MARK (begin_mark));
+
+       g_set_object (&chunk->begin_mark, begin_mark);
+}
+
+void
+_gtk_source_snippet_chunk_set_end_mark (GtkSourceSnippetChunk *chunk,
+                                        GtkTextMark           *end_mark)
+{
+       g_return_if_fail (GTK_SOURCE_IS_SNIPPET_CHUNK (chunk));
+       g_return_if_fail (!end_mark || GTK_IS_TEXT_MARK (end_mark));
+
+       g_set_object (&chunk->end_mark, end_mark);
+}
diff --git a/gtksourceview/gtksourceview-private.h b/gtksourceview/gtksourceview-private.h
index 920ea02e..14891e12 100644
--- a/gtksourceview/gtksourceview-private.h
+++ b/gtksourceview/gtksourceview-private.h
@@ -33,6 +33,7 @@ typedef struct _GtkSourceViewSnippets
        gulong         buffer_insert_text_after_handler;
        gulong         buffer_delete_range_handler;
        gulong         buffer_delete_range_after_handler;
+       gulong         buffer_cursor_moved_handler;
 } GtkSourceViewSnippets;
 
 void     _gtk_source_view_snippets_init        (GtkSourceViewSnippets *snippets,
diff --git a/gtksourceview/gtksourceview-snippets.c b/gtksourceview/gtksourceview-snippets.c
index e2dd6975..76664e3a 100644
--- a/gtksourceview/gtksourceview-snippets.c
+++ b/gtksourceview/gtksourceview-snippets.c
@@ -21,6 +21,7 @@
 
 #include <string.h>
 
+#include "gtksourcebuffer.h"
 #include "gtksourceiter-private.h"
 #include "gtksourcesnippet-private.h"
 #include "gtksourcesnippetchunk.h"
@@ -39,6 +40,8 @@ gtk_source_view_snippets_block (GtkSourceViewSnippets *snippets)
                                snippets->buffer_delete_range_handler);
        g_signal_handler_block (snippets->buffer,
                                snippets->buffer_delete_range_after_handler);
+       g_signal_handler_block (snippets->buffer,
+                               snippets->buffer_cursor_moved_handler);
 }
 
 static void
@@ -54,6 +57,8 @@ gtk_source_view_snippets_unblock (GtkSourceViewSnippets *snippets)
                                  snippets->buffer_delete_range_handler);
        g_signal_handler_unblock (snippets->buffer,
                                  snippets->buffer_delete_range_after_handler);
+       g_signal_handler_unblock (snippets->buffer,
+                                 snippets->buffer_cursor_moved_handler);
 }
 
 static void
@@ -174,11 +179,40 @@ buffer_delete_range_after_cb (GtkTextBuffer         *buffer,
        }
 }
 
+static void
+buffer_cursor_moved_cb (GtkSourceBuffer       *buffer,
+                        GtkSourceViewSnippets *snippets)
+{
+       GtkSourceSnippet *snippet;
+
+       g_assert (GTK_SOURCE_IS_BUFFER (buffer));
+       g_assert (snippets != NULL);
+
+       snippet = g_queue_peek_head (&snippets->queue);
+
+       if (snippet != NULL)
+       {
+               GtkTextMark *insert;
+
+               insert = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (buffer));
+
+               while (snippet != NULL &&
+                      !_gtk_source_snippet_insert_set (snippet, insert))
+               {
+                       g_object_unref (g_queue_pop_head (&snippets->queue));
+                       snippet = g_queue_peek_head (&snippets->queue);
+               }
+       }
+
+}
+
 static void
 view_notify_buffer_cb (GtkSourceView         *view,
                        GParamSpec            *pspec,
                        GtkSourceViewSnippets *snippets)
 {
+       GtkTextBuffer *buffer;
+
        g_assert (view != NULL);
        g_assert (snippets != NULL);
        g_assert (snippets->view == view);
@@ -193,11 +227,16 @@ view_notify_buffer_cb (GtkSourceView         *view,
                                snippets->buffer);
        g_clear_signal_handler (&snippets->buffer_delete_range_after_handler,
                                snippets->buffer);
+       g_clear_signal_handler (&snippets->buffer_cursor_moved_handler,
+                               snippets->buffer);
+
+       snippets->buffer = NULL;
 
-       snippets->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
 
-       if (snippets->buffer != NULL)
+       if (GTK_SOURCE_IS_BUFFER (buffer))
        {
+               snippets->buffer = buffer;
                snippets->buffer_insert_text_handler =
                        g_signal_connect (snippets->buffer,
                                          "insert-text",
@@ -218,6 +257,11 @@ view_notify_buffer_cb (GtkSourceView         *view,
                                                "delete-range",
                                                G_CALLBACK (buffer_delete_range_after_cb),
                                                snippets);
+               snippets->buffer_cursor_moved_handler =
+                       g_signal_connect_after (snippets->buffer,
+                                               "cursor-moved",
+                                               G_CALLBACK (buffer_cursor_moved_cb),
+                                               snippets);
        }
 }
 
@@ -257,6 +301,8 @@ _gtk_source_view_snippets_shutdown (GtkSourceViewSnippets *snippets)
                                snippets->buffer);
        g_clear_signal_handler (&snippets->buffer_delete_range_after_handler,
                                snippets->buffer);
+       g_clear_signal_handler (&snippets->buffer_cursor_moved_handler,
+                               snippets->buffer);
 
        snippets->buffer = NULL;
        snippets->view = NULL;
@@ -353,6 +399,11 @@ _gtk_source_view_snippets_key_pressed (GtkSourceViewSnippets *snippets,
        g_return_val_if_fail (snippets != NULL, FALSE);
        g_return_val_if_fail (snippets->view != NULL, FALSE);
 
+       if (snippets->buffer == NULL)
+       {
+               return FALSE;
+       }
+
        /* Be careful when testing for modifier state equality:
         * caps lock, num lock,etc need to be taken into account */
        modifiers = gtk_accelerator_get_default_mod_mask ();
@@ -418,9 +469,14 @@ _gtk_source_view_snippets_push (GtkSourceViewSnippets *snippets,
        GtkSourceSnippet *previous_snippet;
        gboolean more_to_focus;
 
-       g_assert (snippets != NULL);
-       g_assert (GTK_SOURCE_IS_SNIPPET (snippet));
-       g_assert (iter != NULL);
+       g_return_if_fail (snippets != NULL);
+       g_return_if_fail (GTK_SOURCE_IS_SNIPPET (snippet));
+       g_return_if_fail (iter != NULL);
+
+       if (snippets->buffer == NULL)
+       {
+               return;
+       }
 
        previous_snippet = g_queue_peek_head (&snippets->queue);
 
@@ -452,7 +508,12 @@ _gtk_source_view_snippets_pop (GtkSourceViewSnippets *snippets)
        GtkSourceSnippet *next_snippet;
        GtkSourceSnippet *snippet;
 
-       g_assert (snippets != NULL);
+       g_return_if_fail (snippets != NULL);
+
+       if (snippets->buffer == NULL)
+       {
+               return;
+       }
 
        snippet = g_queue_pop_head (&snippets->queue);
 


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