[gtksourceview/wip/chergert/snippets] cancel snippet if edit covers multiple snippets
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/snippets] cancel snippet if edit covers multiple snippets
- Date: Fri, 24 Jan 2020 21:17:39 +0000 (UTC)
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]