[gnome-builder] libide/code: remove tags as part of higlighter update



commit ef24b7c60952de404f5fd198453f086f0bcdf519
Author: Christian Hergert <chergert redhat com>
Date:   Tue Sep 13 23:29:29 2022 -0700

    libide/code: remove tags as part of higlighter update
    
    Clearing the old tags in one fell swoop is very handy from a performance
    perspective, as it means we do less work. However, it is very jarring to
    the user because it means that the screen can flash as they are typing.
    
    Instead, clear the old tags as we are scanning words so that we more
    minimally damage the screen as highlight indexes are updated and/or
    words are typed.

 src/libide/code/ide-highlight-engine.c     |  9 +-------
 src/libide/code/ide-highlighter.c          |  5 ++++-
 src/libide/code/ide-highlighter.h          |  8 +++++--
 src/libide/lsp/ide-lsp-highlighter.c       | 36 +++++++++++++++++++++++++-----
 src/plugins/clang/ide-clang-highlighter.c  | 27 +++++++++++++++++++++-
 src/plugins/ctags/ide-ctags-highlighter.c  | 36 +++++++++++++++++++++++++-----
 src/plugins/xml-pack/ide-xml-highlighter.c |  1 +
 7 files changed, 99 insertions(+), 23 deletions(-)
---
diff --git a/src/libide/code/ide-highlight-engine.c b/src/libide/code/ide-highlight-engine.c
index 766a7880b..56cb47e68 100644
--- a/src/libide/code/ide-highlight-engine.c
+++ b/src/libide/code/ide-highlight-engine.c
@@ -324,7 +324,6 @@ ide_highlight_engine_tick (IdeHighlightEngine *self,
   GtkTextIter iter;
   GtkTextIter invalid_begin;
   GtkTextIter invalid_end;
-  GSList *tags_iter;
 
   IDE_PROBE;
 
@@ -349,13 +348,6 @@ again:
                  gtk_text_iter_get_line_offset (&invalid_end) + 1,
                  G_OBJECT_TYPE_NAME (self->highlighter));
 
-  /* Clear all our tags */
-  for (tags_iter = self->private_tags; tags_iter; tags_iter = tags_iter->next)
-    gtk_text_buffer_remove_tag (buffer,
-                                GTK_TEXT_TAG (tags_iter->data),
-                                &invalid_begin,
-                                &invalid_end);
-
   iter = invalid_begin;
 
   while (gtk_text_iter_ends_line (&iter))
@@ -366,6 +358,7 @@ again:
 
   if (gtk_text_iter_compare (&iter, &invalid_end) < 0)
     ide_highlighter_update (self->highlighter,
+                            self->private_tags,
                             ide_highlight_engine_apply_style,
                             &invalid_begin,
                             &invalid_end,
diff --git a/src/libide/code/ide-highlighter.c b/src/libide/code/ide-highlighter.c
index 8a1438b0f..79eb0c975 100644
--- a/src/libide/code/ide-highlighter.c
+++ b/src/libide/code/ide-highlighter.c
@@ -30,6 +30,7 @@ G_DEFINE_INTERFACE (IdeHighlighter, ide_highlighter, IDE_TYPE_OBJECT)
 
 static void
 ide_highlighter_real_update (IdeHighlighter       *self,
+                             const GSList         *tags_to_remove,
                              IdeHighlightCallback  callback,
                              const GtkTextIter    *range_begin,
                              const GtkTextIter    *range_end,
@@ -53,6 +54,7 @@ ide_highlighter_default_init (IdeHighlighterInterface *iface)
 /**
  * ide_highlighter_update:
  * @self: an #IdeHighlighter.
+ * @tags_to_remove: (element-type GtkTextTag): a #GSList of tags to be removed
  * @callback: (scope call): A callback to apply a given style.
  * @range_begin: The beginning of the range to update.
  * @range_end: The end of the range to update.
@@ -67,6 +69,7 @@ ide_highlighter_default_init (IdeHighlighterInterface *iface)
  */
 void
 ide_highlighter_update (IdeHighlighter       *self,
+                        const GSList         *tags_to_remove,
                         IdeHighlightCallback  callback,
                         const GtkTextIter    *range_begin,
                         const GtkTextIter    *range_end,
@@ -78,7 +81,7 @@ ide_highlighter_update (IdeHighlighter       *self,
   g_return_if_fail (range_end != NULL);
   g_return_if_fail (location != NULL);
 
-  IDE_HIGHLIGHTER_GET_IFACE (self)->update (self, callback, range_begin, range_end, location);
+  IDE_HIGHLIGHTER_GET_IFACE (self)->update (self, tags_to_remove, callback, range_begin, range_end, 
location);
 }
 
 void
diff --git a/src/libide/code/ide-highlighter.h b/src/libide/code/ide-highlighter.h
index e5c6a972c..6bd8a86b6 100644
--- a/src/libide/code/ide-highlighter.h
+++ b/src/libide/code/ide-highlighter.h
@@ -62,8 +62,13 @@ struct _IdeHighlighterInterface
    *
    * @location should be set to the position that the highlighter got to
    * before yielding back to the engine.
+   *
+   * @tags_to_remove are the #GtkTextTag that should be removed for the region
+   * and it is left up to the highlighter to do so (generally on a line by
+   * line basis).
    */
   void (*update)     (IdeHighlighter       *self,
+                      const GSList         *tags_to_remove,
                       IdeHighlightCallback  callback,
                       const GtkTextIter    *range_begin,
                       const GtkTextIter    *range_end,
@@ -79,11 +84,10 @@ IDE_AVAILABLE_IN_ALL
 void ide_highlighter_load   (IdeHighlighter       *self);
 IDE_AVAILABLE_IN_ALL
 void ide_highlighter_update (IdeHighlighter       *self,
+                             const GSList         *tags_to_remove,
                              IdeHighlightCallback  callback,
                              const GtkTextIter    *range_begin,
                              const GtkTextIter    *range_end,
                              GtkTextIter          *location);
-void _ide_highlighter_set_highlighter_engine (IdeHighlighter       *self,
-                                              IdeHighlightEngine   *highlight_engine) G_GNUC_INTERNAL;
 
 G_END_DECLS
diff --git a/src/libide/lsp/ide-lsp-highlighter.c b/src/libide/lsp/ide-lsp-highlighter.c
index 962cdce23..31c85ab1b 100644
--- a/src/libide/lsp/ide-lsp-highlighter.c
+++ b/src/libide/lsp/ide-lsp-highlighter.c
@@ -254,11 +254,9 @@ ide_lsp_highlighter_queue_update (IdeLspHighlighter *self)
    */
 
   if (priv->queued_update == 0 && priv->active == FALSE)
-    {
-      priv->queued_update = g_timeout_add (DELAY_TIMEOUT_MSEC,
-                                           ide_lsp_highlighter_update_symbols,
-                                           self);
-    }
+    priv->queued_update = g_timeout_add (DELAY_TIMEOUT_MSEC,
+                                         ide_lsp_highlighter_update_symbols,
+                                         self);
 
   IDE_EXIT;
 }
@@ -429,8 +427,27 @@ select_next_word (GtkTextIter *begin,
   return TRUE;
 }
 
+static void
+remove_tags (const GtkTextIter *begin,
+             const GtkTextIter *end,
+             const GSList      *tags_to_remove)
+{
+  GtkTextBuffer *buffer;
+
+  g_assert (begin != NULL);
+  g_assert (end != NULL);
+
+  if (tags_to_remove == NULL)
+    return;
+
+  buffer = gtk_text_iter_get_buffer (begin);
+  for (const GSList *iter = tags_to_remove; iter; iter = iter->next)
+    gtk_text_buffer_remove_tag (buffer, iter->data, begin, end);
+}
+
 static void
 ide_lsp_highlighter_update (IdeHighlighter       *highlighter,
+                            const GSList         *tags_to_remove,
                             IdeHighlightCallback  callback,
                             const GtkTextIter    *range_begin,
                             const GtkTextIter    *range_end,
@@ -457,8 +474,15 @@ ide_lsp_highlighter_update (IdeHighlighter       *highlighter,
 
   while (gtk_text_iter_compare (&begin, range_end) < 0)
     {
+      GtkTextIter last = begin;
+
       if (!select_next_word (&begin, &end))
-        goto completed;
+        {
+          remove_tags (&last, range_end, tags_to_remove);
+          goto completed;
+        }
+
+      remove_tags (&last, &end, tags_to_remove);
 
       if (gtk_text_iter_compare (&begin, range_end) >= 0)
         goto completed;
diff --git a/src/plugins/clang/ide-clang-highlighter.c b/src/plugins/clang/ide-clang-highlighter.c
index bf689fb21..5f5e72afa 100644
--- a/src/plugins/clang/ide-clang-highlighter.c
+++ b/src/plugins/clang/ide-clang-highlighter.c
@@ -204,9 +204,27 @@ finish:
   return g_steal_pointer (&index);
 }
 
+static void
+remove_tags (const GtkTextIter *begin,
+             const GtkTextIter *end,
+             const GSList      *tags_to_remove)
+{
+  GtkTextBuffer *buffer;
+
+  g_assert (begin != NULL);
+  g_assert (end != NULL);
+
+  if (tags_to_remove == NULL)
+    return;
+
+  buffer = gtk_text_iter_get_buffer (begin);
+  for (const GSList *iter = tags_to_remove; iter; iter = iter->next)
+    gtk_text_buffer_remove_tag (buffer, iter->data, begin, end);
+}
 
 static void
 ide_clang_highlighter_real_update (IdeHighlighter       *highlighter,
+                                   const GSList         *tags_to_remove,
                                    IdeHighlightCallback  callback,
                                    const GtkTextIter    *range_begin,
                                    const GtkTextIter    *range_end,
@@ -239,8 +257,15 @@ ide_clang_highlighter_real_update (IdeHighlighter       *highlighter,
 
   while (gtk_text_iter_compare (&begin, range_end) < 0)
     {
+      GtkTextIter last = begin;
+
       if (!select_next_word (&begin, &end))
-        goto completed;
+        {
+          remove_tags (&last, range_end, tags_to_remove);
+          goto completed;
+        }
+
+      remove_tags (&last, &end, tags_to_remove);
 
       if (gtk_text_iter_compare (&begin, range_end) >= 0)
         goto completed;
diff --git a/src/plugins/ctags/ide-ctags-highlighter.c b/src/plugins/ctags/ide-ctags-highlighter.c
index ca3311794..d624553ec 100644
--- a/src/plugins/ctags/ide-ctags-highlighter.c
+++ b/src/plugins/ctags/ide-ctags-highlighter.c
@@ -39,10 +39,10 @@ struct _IdeCtagsHighlighter
 static void highlighter_iface_init (IdeHighlighterInterface *iface);
 
 G_DEFINE_FINAL_TYPE_WITH_CODE (IdeCtagsHighlighter,
-                         ide_ctags_highlighter,
-                         IDE_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (IDE_TYPE_HIGHLIGHTER,
-                                                highlighter_iface_init))
+                               ide_ctags_highlighter,
+                               IDE_TYPE_OBJECT,
+                               G_IMPLEMENT_INTERFACE (IDE_TYPE_HIGHLIGHTER,
+                                                      highlighter_iface_init))
 
 static inline gboolean
 accepts_char (gunichar ch)
@@ -134,8 +134,27 @@ get_tag (IdeCtagsHighlighter *self,
   return NULL;
 }
 
+static void
+remove_tags (const GtkTextIter *begin,
+             const GtkTextIter *end,
+             const GSList      *tags_to_remove)
+{
+  GtkTextBuffer *buffer;
+
+  g_assert (begin != NULL);
+  g_assert (end != NULL);
+
+  if (tags_to_remove == NULL)
+    return;
+
+  buffer = gtk_text_iter_get_buffer (begin);
+  for (const GSList *iter = tags_to_remove; iter; iter = iter->next)
+    gtk_text_buffer_remove_tag (buffer, iter->data, begin, end);
+}
+
 static void
 ide_ctags_highlighter_real_update (IdeHighlighter       *highlighter,
+                                   const GSList         *tags_to_remove,
                                    IdeHighlightCallback  callback,
                                    const GtkTextIter    *range_begin,
                                    const GtkTextIter    *range_end,
@@ -165,8 +184,15 @@ ide_ctags_highlighter_real_update (IdeHighlighter       *highlighter,
 
   while (gtk_text_iter_compare (&begin, range_end) < 0)
     {
+      GtkTextIter last = begin;
+
       if (!select_next_word (&begin, &end))
-        goto completed;
+        {
+          remove_tags (&last, range_end, tags_to_remove);
+          goto completed;
+        }
+
+      remove_tags (&last, &end, tags_to_remove);
 
       if (gtk_text_iter_compare (&begin, range_end) >= 0)
         goto completed;
diff --git a/src/plugins/xml-pack/ide-xml-highlighter.c b/src/plugins/xml-pack/ide-xml-highlighter.c
index 99d1111ba..b2a71a156 100644
--- a/src/plugins/xml-pack/ide-xml-highlighter.c
+++ b/src/plugins/xml-pack/ide-xml-highlighter.c
@@ -190,6 +190,7 @@ ide_xml_highlighter_real_set_engine (IdeHighlighter     *highlighter,
 
 static void
 ide_xml_highlighter_real_update (IdeHighlighter       *highlighter,
+                                 const GSList         *tags_to_remove,
                                  IdeHighlightCallback  callback,
                                  const GtkTextIter    *range_begin,
                                  const GtkTextIter    *range_end,


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