[gnome-builder] highlight: add very crude, not even vaguely optimize highlight
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] highlight: add very crude, not even vaguely optimize highlight
- Date: Fri, 27 Mar 2015 00:39:25 +0000 (UTC)
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]