[gtksourceview/wip/chergert/snippets] cancel snippet if edit covers multiple snippets



commit 915b0ce81be5685371e4d74516ea34320c2e0c3e
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jan 24 13:17:42 2020 -0800

    cancel snippet if edit covers multiple snippets

 gtksourceview/gtksourcesnippet-private.h | 70 +++++++++++++++++---------------
 gtksourceview/gtksourcesnippet.c         | 38 +++++++++++++++++
 gtksourceview/gtksourceview-private.h    |  1 +
 gtksourceview/gtksourceview-snippets.c   | 21 ++++++++++
 4 files changed, 97 insertions(+), 33 deletions(-)
---
diff --git a/gtksourceview/gtksourcesnippet-private.h b/gtksourceview/gtksourcesnippet-private.h
index 6338514a..58ca0956 100644
--- a/gtksourceview/gtksourcesnippet-private.h
+++ b/gtksourceview/gtksourcesnippet-private.h
@@ -24,52 +24,56 @@
  G_BEGIN_DECLS
 
 G_GNUC_INTERNAL
-void         _gtk_source_snippet_replace_current_chunk_text (GtkSourceSnippet *self,
-                                                             const gchar      *new_text);
+void         _gtk_source_snippet_replace_current_chunk_text (GtkSourceSnippet  *self,
+                                                             const gchar       *new_text);
 G_GNUC_INTERNAL
-gchar       *_gtk_source_snippet_get_edited_text            (GtkSourceSnippet *self);
+gchar       *_gtk_source_snippet_get_edited_text            (GtkSourceSnippet  *self);
 G_GNUC_INTERNAL
-void         _gtk_source_snippet_pause                      (GtkSourceSnippet *self);
+void         _gtk_source_snippet_pause                      (GtkSourceSnippet  *self);
 G_GNUC_INTERNAL
-void         _gtk_source_snippet_unpause                    (GtkSourceSnippet *self);
+void         _gtk_source_snippet_unpause                    (GtkSourceSnippet  *self);
 G_GNUC_INTERNAL
-gboolean     _gtk_source_snippet_begin                      (GtkSourceSnippet *self,
-                                                             GtkTextBuffer    *buffer,
-                                                             GtkTextIter      *iter);
+gboolean     _gtk_source_snippet_begin                      (GtkSourceSnippet  *self,
+                                                             GtkTextBuffer     *buffer,
+                                                             GtkTextIter       *iter);
 G_GNUC_INTERNAL
-void         _gtk_source_snippet_finish                     (GtkSourceSnippet *self);
+void         _gtk_source_snippet_finish                     (GtkSourceSnippet  *self);
 G_GNUC_INTERNAL
-gboolean     _gtk_source_snippet_move_next                  (GtkSourceSnippet *self);
+gboolean     _gtk_source_snippet_move_next                  (GtkSourceSnippet  *self);
 G_GNUC_INTERNAL
-gboolean     _gtk_source_snippet_move_previous              (GtkSourceSnippet *self);
+gboolean     _gtk_source_snippet_move_previous              (GtkSourceSnippet  *self);
 G_GNUC_INTERNAL
-void         _gtk_source_snippet_before_insert_text         (GtkSourceSnippet *self,
-                                                             GtkTextBuffer    *buffer,
-                                                             GtkTextIter      *iter,
-                                                             const gchar      *text,
-                                                             gint              len);
+void         _gtk_source_snippet_before_insert_text         (GtkSourceSnippet  *self,
+                                                             GtkTextBuffer     *buffer,
+                                                             GtkTextIter       *iter,
+                                                             const gchar       *text,
+                                                             gint               len);
 G_GNUC_INTERNAL
-void         _gtk_source_snippet_after_insert_text          (GtkSourceSnippet *self,
-                                                             GtkTextBuffer    *buffer,
-                                                             GtkTextIter      *iter,
-                                                             const gchar      *text,
-                                                             gint              len);
+void         _gtk_source_snippet_after_insert_text          (GtkSourceSnippet  *self,
+                                                             GtkTextBuffer     *buffer,
+                                                             GtkTextIter       *iter,
+                                                             const gchar       *text,
+                                                             gint               len);
 G_GNUC_INTERNAL
-void         _gtk_source_snippet_before_delete_range        (GtkSourceSnippet *self,
-                                                             GtkTextBuffer    *buffer,
-                                                             GtkTextIter      *begin,
-                                                             GtkTextIter      *end);
+void         _gtk_source_snippet_before_delete_range        (GtkSourceSnippet  *self,
+                                                             GtkTextBuffer     *buffer,
+                                                             GtkTextIter       *begin,
+                                                             GtkTextIter       *end);
 G_GNUC_INTERNAL
-void         _gtk_source_snippet_after_delete_range         (GtkSourceSnippet *self,
-                                                             GtkTextBuffer    *buffer,
-                                                             GtkTextIter      *begin,
-                                                             GtkTextIter      *end);
+void         _gtk_source_snippet_after_delete_range         (GtkSourceSnippet  *self,
+                                                             GtkTextBuffer     *buffer,
+                                                             GtkTextIter       *begin,
+                                                             GtkTextIter       *end);
 G_GNUC_INTERNAL
-gboolean     _gtk_source_snippet_insert_set                 (GtkSourceSnippet *self,
-                                                             GtkTextMark      *mark);
+gboolean     _gtk_source_snippet_insert_set                 (GtkSourceSnippet  *self,
+                                                             GtkTextMark       *mark);
 G_GNUC_INTERNAL
-GtkTextMark *_gtk_source_snippet_get_mark_begin             (GtkSourceSnippet *self);
+GtkTextMark *_gtk_source_snippet_get_mark_begin             (GtkSourceSnippet  *self);
 G_GNUC_INTERNAL
-GtkTextMark *_gtk_source_snippet_get_mark_end               (GtkSourceSnippet *self);
+GtkTextMark *_gtk_source_snippet_get_mark_end               (GtkSourceSnippet  *self);
+G_GNUC_INTERNAL
+guint        _gtk_source_snippet_count_affected_chunks      (GtkSourceSnippet  *snippet,
+                                                             const GtkTextIter *begin,
+                                                             const GtkTextIter *end);
 
 G_END_DECLS
diff --git a/gtksourceview/gtksourcesnippet.c b/gtksourceview/gtksourcesnippet.c
index f97a8a9d..eebc5c27 100644
--- a/gtksourceview/gtksourcesnippet.c
+++ b/gtksourceview/gtksourcesnippet.c
@@ -1094,6 +1094,44 @@ _gtk_source_snippet_after_delete_range (GtkSourceSnippet *self,
        gtk_source_snippet_restore_insert (self);
 }
 
+guint
+_gtk_source_snippet_count_affected_chunks (GtkSourceSnippet  *snippet,
+                                           const GtkTextIter *begin,
+                                           const GtkTextIter *end)
+{
+       guint count = 0;
+
+       g_return_val_if_fail (GTK_SOURCE_IS_SNIPPET (snippet), FALSE);
+       g_return_val_if_fail (begin != NULL, FALSE);
+       g_return_val_if_fail (end != NULL, FALSE);
+
+       for (const GList *l = snippet->chunks.head; l; l = l->next)
+       {
+               GtkSourceSnippetChunk *chunk = l->data;
+               GtkTextIter chunk_begin;
+               GtkTextIter chunk_end;
+
+               if (_gtk_source_snippet_chunk_get_bounds (chunk, &chunk_begin, &chunk_end))
+               {
+                       /* We only care about this chunk if it's non-empty. As
+                        * we may have multiple "empty" chunks if they are right
+                        * next to each other. Those can be safely ignored unless
+                        * we have a chunk after them which is also overlapped.
+                        */
+                       if (!gtk_text_iter_equal (&chunk_begin, &chunk_end))
+                       {
+                               if (gtk_text_iter_compare (end, &chunk_begin) >= 0 &&
+                                   gtk_text_iter_compare (begin, &chunk_end) <= 0)
+                               {
+                                       count++;
+                               }
+                       }
+               }
+       }
+
+       return count;
+}
+
 GtkTextMark *
 _gtk_source_snippet_get_mark_begin (GtkSourceSnippet *self)
 {
diff --git a/gtksourceview/gtksourceview-private.h b/gtksourceview/gtksourceview-private.h
index 14891e12..c4521f7f 100644
--- a/gtksourceview/gtksourceview-private.h
+++ b/gtksourceview/gtksourceview-private.h
@@ -43,6 +43,7 @@ void     _gtk_source_view_snippets_push        (GtkSourceViewSnippets *snippets,
                                                 GtkSourceSnippet      *snippet,
                                                 GtkTextIter           *iter);
 void     _gtk_source_view_snippets_pop         (GtkSourceViewSnippets *snippets);
+void     _gtk_source_view_snippets_pop_all     (GtkSourceViewSnippets *snippets);
 gboolean _gtk_source_view_snippets_key_pressed (GtkSourceViewSnippets *snippets,
                                                 guint                  key,
                                                 guint                  keycode,
diff --git a/gtksourceview/gtksourceview-snippets.c b/gtksourceview/gtksourceview-snippets.c
index 05b6765b..58f28452 100644
--- a/gtksourceview/gtksourceview-snippets.c
+++ b/gtksourceview/gtksourceview-snippets.c
@@ -139,6 +139,16 @@ buffer_delete_range_cb (GtkTextBuffer         *buffer,
 
        if (snippet != NULL)
        {
+               /* If the deletion will affect multiple chunks in the snippet,
+                * then we want to cancel all active snippets and go back to
+                * regular editing.
+                */
+               if (_gtk_source_snippet_count_affected_chunks (snippet, begin, end) > 1)
+               {
+                       _gtk_source_view_snippets_pop_all (snippets);
+                       return;
+               }
+
                /* We'll complete the user action in the after phase */
                gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));
 
@@ -534,3 +544,14 @@ _gtk_source_view_snippets_pop (GtkSourceViewSnippets *snippets)
                g_object_unref (snippet);
        }
 }
+
+void
+_gtk_source_view_snippets_pop_all (GtkSourceViewSnippets *self)
+{
+       g_return_if_fail (self != NULL);
+
+       while (self->queue.length > 0)
+       {
+               _gtk_source_view_snippets_pop (self);
+       }
+}


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