[gnome-builder] highlight: add very crude, not even vaguely optimize highlight



commit f8fc4456c924ead2c9c539374f08a87f338c6026
Author: Christian Hergert <christian hergert me>
Date:   Thu Mar 26 15:13:45 2015 -0700

    highlight: add very crude, not even vaguely optimize highlight
    
    This does tons of things wrong that need to be changed, but i dont want
    to lose a snapshot of something "working".
    
    We should change this to use a callback design, so we can amortize the
    overhead cost of walking through the buffer and fetching the translation
    unit.
    
    We should also probably drop the intermediate IdeHighlightKind and allow
    the highlighter to set the style type directly. Otherwise, we might lock
    ourselves into only being able to highlight things that are "generic"
    amongst all the languages.
    
    For example, we might want "c:function" or "cpp:method" instead of
    "def:function".
    
    Also, the index is currently oversized, (about 350k on my current
    working set). We can still find some tricks to prune this down.
    
    Anyway, step 1!

 libide/clang/ide-clang-highlighter.c |  107 ++++++++++++++++++++++++++++++++++
 1 files changed, 107 insertions(+), 0 deletions(-)
---
diff --git a/libide/clang/ide-clang-highlighter.c b/libide/clang/ide-clang-highlighter.c
index 12bcad1..32e45b8 100644
--- a/libide/clang/ide-clang-highlighter.c
+++ b/libide/clang/ide-clang-highlighter.c
@@ -19,6 +19,9 @@
 #include <glib/gi18n.h>
 
 #include "ide-clang-highlighter.h"
+#include "ide-clang-service.h"
+#include "ide-clang-translation-unit.h"
+#include "ide-context.h"
 
 struct _IdeClangHighlighter
 {
@@ -27,9 +30,113 @@ struct _IdeClangHighlighter
 
 G_DEFINE_TYPE (IdeClangHighlighter, ide_clang_highlighter, IDE_TYPE_HIGHLIGHTER)
 
+static inline gboolean
+accepts_char (gunichar ch)
+{
+  return (ch == '_' || g_unichar_isalnum (ch));
+}
+
+static gboolean
+select_next_word (GtkTextIter *begin,
+                  GtkTextIter *end)
+{
+  g_assert (begin);
+  g_assert (end);
+
+  *end = *begin;
+
+  while (!accepts_char (gtk_text_iter_get_char (begin)))
+    if (!gtk_text_iter_forward_char (begin))
+      return FALSE;
+
+  *end = *begin;
+
+  while (accepts_char (gtk_text_iter_get_char (end)))
+    if (!gtk_text_iter_forward_char (end))
+      return !gtk_text_iter_equal (begin, end);
+
+  return TRUE;
+}
+
+static IdeHighlightKind
+ide_clang_highlighter_real_next (IdeHighlighter    *highlighter,
+                                 const GtkTextIter *range_begin,
+                                 const GtkTextIter *range_end,
+                                 GtkTextIter       *begin,
+                                 GtkTextIter       *end)
+{
+  IdeClangHighlighter *self = (IdeClangHighlighter *)highlighter;
+  GtkTextBuffer *text_buffer;
+  GtkSourceBuffer *source_buffer;
+  IdeHighlightIndex *index;
+  IdeClangTranslationUnit *unit;
+  IdeContext *context;
+  IdeClangService *service;
+  IdeBuffer *buffer;
+  IdeFile *file;
+
+  /*
+   * TODO:
+   *
+   * This API has a decent bit of overhead. Instead, we should move to an API
+   * design that allows us to walk through the entire buffer, and then call a
+   * callback (back into the engine) to set the style name for the region.
+   * This would allow us to amortize the overhead cost of getting the
+   * information we need.
+   */
+
+  g_assert (IDE_IS_CLANG_HIGHLIGHTER (self));
+
+  if (!(text_buffer = gtk_text_iter_get_buffer (range_begin)) ||
+      !IDE_IS_BUFFER (text_buffer) ||
+      !(source_buffer = GTK_SOURCE_BUFFER (text_buffer)) ||
+      !(buffer = IDE_BUFFER (text_buffer)) ||
+      !(file = ide_buffer_get_file (buffer)) ||
+      !(context = ide_object_get_context (IDE_OBJECT (highlighter))) ||
+      !(service = ide_context_get_service_typed (context, IDE_TYPE_CLANG_SERVICE)) ||
+      !(unit = ide_clang_service_get_cached_translation_unit (service, file)) ||
+      !(index = ide_clang_translation_unit_get_index (unit)))
+    return IDE_HIGHLIGHT_KIND_NONE;
+
+  *begin = *end = *range_begin;
+
+  while (gtk_text_iter_compare (begin, range_end) < 0)
+    {
+      if (!select_next_word (begin, end))
+        return IDE_HIGHLIGHT_KIND_NONE;
+
+      if (gtk_text_iter_compare (begin, range_end) >= 0)
+        return IDE_HIGHLIGHT_KIND_NONE;
+
+      g_assert (!gtk_text_iter_equal (begin, end));
+
+      if (!gtk_source_buffer_iter_has_context_class (source_buffer, begin, "string") &&
+          !gtk_source_buffer_iter_has_context_class (source_buffer, begin, "path") &&
+          !gtk_source_buffer_iter_has_context_class (source_buffer, begin, "comment"))
+        {
+          IdeHighlightKind ret;
+          gchar *word;
+
+          word = gtk_text_iter_get_slice (begin, end);
+          ret = ide_highlight_index_lookup (index, word);
+          g_free (word);
+
+          if (ret != IDE_HIGHLIGHT_KIND_NONE)
+            return ret;
+        }
+
+      *begin = *end;
+    }
+
+  return IDE_HIGHLIGHT_KIND_NONE;
+}
+
 static void
 ide_clang_highlighter_class_init (IdeClangHighlighterClass *klass)
 {
+  IdeHighlighterClass *highlighter_class = IDE_HIGHLIGHTER_CLASS (klass);
+
+  highlighter_class->next = ide_clang_highlighter_real_next;
 }
 
 static void


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