[gnome-builder/wip/highlight] highlight: implement incremental, callback based, highlight engine
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/highlight] highlight: implement incremental, callback based, highlight engine
- Date: Thu, 26 Mar 2015 23:49:46 +0000 (UTC)
commit ceadec60177fd81c24423ccdf0062a18dca2337f
Author: Christian Hergert <christian hergert me>
Date: Thu Mar 26 16:49:40 2015 -0700
highlight: implement incremental, callback based, highlight engine
Now, the highlight engine will provide a callback to perform a style
update. That callback will return if the highlighter may continue or
if it has expired its quanta.
This helps reduce the overhead in highlighters that need to setup a bunch
of information to make forward progress in the buffer. It has the small
cost of a qdata lookup in the callback. (We could make this less by
enforcing the highlighter pass extra data back, but I don't like the API
much for that).
The index can now take arbitrary pointers as the values for words. The
clang index takes advantage of this to specify the direct tags it wants.
This will change in the future as we add more styling information to
builder.xml (and builder-dark.xml). Other style schemes will need to
do the same if they want extra-detailed coloring.
For example, we have plans for functions, macros, members, fields, and
other special types which may not map to the same generic coloring that
other languages will want to use.
Anyway, WIP
libide/clang/ide-clang-highlighter.c | 73 +++++++++--------
libide/clang/ide-clang-service.c | 6 +-
libide/ide-highlight-engine.c | 147 +++++++++++++++++-----------------
libide/ide-highlight-index.c | 24 ++++--
libide/ide-highlight-index.h | 6 +-
libide/ide-highlighter.c | 43 ++++++----
libide/ide-highlighter.h | 48 +++++++-----
7 files changed, 189 insertions(+), 158 deletions(-)
---
diff --git a/libide/clang/ide-clang-highlighter.c b/libide/clang/ide-clang-highlighter.c
index 32e45b8..c214160 100644
--- a/libide/clang/ide-clang-highlighter.c
+++ b/libide/clang/ide-clang-highlighter.c
@@ -58,12 +58,12 @@ select_next_word (GtkTextIter *begin,
return TRUE;
}
-static IdeHighlightKind
-ide_clang_highlighter_real_next (IdeHighlighter *highlighter,
- const GtkTextIter *range_begin,
- const GtkTextIter *range_end,
- GtkTextIter *begin,
- GtkTextIter *end)
+static void
+ide_clang_highlighter_real_update (IdeHighlighter *highlighter,
+ IdeHighlightCallback callback,
+ const GtkTextIter *range_begin,
+ const GtkTextIter *range_end,
+ GtkTextIter *location)
{
IdeClangHighlighter *self = (IdeClangHighlighter *)highlighter;
GtkTextBuffer *text_buffer;
@@ -74,18 +74,14 @@ ide_clang_highlighter_real_next (IdeHighlighter *highlighter,
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.
- */
+ GtkTextIter begin;
+ GtkTextIter end;
g_assert (IDE_IS_CLANG_HIGHLIGHTER (self));
+ g_assert (callback != NULL);
+ g_assert (range_begin != NULL);
+ g_assert (range_end != NULL);
+ g_assert (location != NULL);
if (!(text_buffer = gtk_text_iter_get_buffer (range_begin)) ||
!IDE_IS_BUFFER (text_buffer) ||
@@ -96,39 +92,46 @@ ide_clang_highlighter_real_next (IdeHighlighter *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;
+ return;
- *begin = *end = *range_begin;
+ begin = end = *location = *range_begin;
- while (gtk_text_iter_compare (begin, range_end) < 0)
+ while (gtk_text_iter_compare (&begin, range_end) < 0)
{
- if (!select_next_word (begin, end))
- return IDE_HIGHLIGHT_KIND_NONE;
+ if (!select_next_word (&begin, &end))
+ goto completed;
- if (gtk_text_iter_compare (begin, range_end) >= 0)
- return IDE_HIGHLIGHT_KIND_NONE;
+ if (gtk_text_iter_compare (&begin, range_end) >= 0)
+ goto completed;
- g_assert (!gtk_text_iter_equal (begin, end));
+ 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"))
+ 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;
+ const gchar *tag;
gchar *word;
- word = gtk_text_iter_get_slice (begin, end);
- ret = ide_highlight_index_lookup (index, word);
+ word = gtk_text_iter_get_slice (&begin, &end);
+ tag = ide_highlight_index_lookup (index, word);
g_free (word);
- if (ret != IDE_HIGHLIGHT_KIND_NONE)
- return ret;
+ if (tag != NULL)
+ {
+ if (callback (&begin, &end, tag) == IDE_HIGHLIGHT_STOP)
+ {
+ *location = end;
+ return;
+ }
+ }
}
- *begin = *end;
+ begin = end;
}
- return IDE_HIGHLIGHT_KIND_NONE;
+completed:
+ *location = *range_end;
}
static void
@@ -136,7 +139,7 @@ ide_clang_highlighter_class_init (IdeClangHighlighterClass *klass)
{
IdeHighlighterClass *highlighter_class = IDE_HIGHLIGHTER_CLASS (klass);
- highlighter_class->next = ide_clang_highlighter_real_next;
+ highlighter_class->update = ide_clang_highlighter_real_update;
}
static void
diff --git a/libide/clang/ide-clang-service.c b/libide/clang/ide-clang-service.c
index 1633ffc..700666d 100644
--- a/libide/clang/ide-clang-service.c
+++ b/libide/clang/ide-clang-service.c
@@ -93,20 +93,20 @@ ide_clang_service_build_index_visitor (CXCursor cursor,
case CXCursor_TypeAliasDecl:
cxstr = clang_getCursorSpelling (cursor);
word = clang_getCString (cxstr);
- ide_highlight_index_insert (request->index, word, IDE_HIGHLIGHT_KIND_TYPE_NAME);
+ ide_highlight_index_insert (request->index, word, "def:type");
break;
case CXCursor_FunctionDecl:
cxstr = clang_getCursorSpelling (cursor);
word = clang_getCString (cxstr);
- ide_highlight_index_insert (request->index, word, IDE_HIGHLIGHT_KIND_FUNCTION_NAME);
+ ide_highlight_index_insert (request->index, word, "def:function");
break;
case CXCursor_MacroDefinition:
case CXCursor_MacroExpansion:
cxstr = clang_getCursorSpelling (cursor);
word = clang_getCString (cxstr);
- ide_highlight_index_insert (request->index, word, IDE_HIGHLIGHT_KIND_MACRO_NAME);
+ ide_highlight_index_insert (request->index, word, "def:preprocessor");
break;
default:
diff --git a/libide/ide-highlight-engine.c b/libide/ide-highlight-engine.c
index b4a7160..0035e7a 100644
--- a/libide/ide-highlight-engine.c
+++ b/libide/ide-highlight-engine.c
@@ -34,11 +34,13 @@ struct _IdeHighlightEngine
IdeBuffer *buffer;
IdeHighlighter *highlighter;
- GtkTextTag *tags[IDE_HIGHLIGHT_KIND_LAST];
-
GtkTextMark *invalid_begin;
GtkTextMark *invalid_end;
+ GList *tags;
+
+ guint64 quanta_expiration;
+
guint work_timeout;
};
@@ -52,6 +54,7 @@ enum {
};
static GParamSpec *gParamSpecs [LAST_PROP];
+static GQuark gEngineQuark;
static GtkTextTag *
create_tag_from_style (IdeHighlightEngine *self,
@@ -75,7 +78,7 @@ create_tag_from_style (IdeHighlightEngine *self,
g_assert (self->buffer != NULL);
g_assert (IDE_IS_BUFFER (self->buffer));
- tag = gtk_text_buffer_create_tag (GTK_TEXT_BUFFER (self->buffer), NULL, NULL);
+ tag = gtk_text_buffer_create_tag (GTK_TEXT_BUFFER (self->buffer), style_name, NULL);
style_scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (self->buffer));
if (style_scheme == NULL)
@@ -117,38 +120,46 @@ create_tag_from_style (IdeHighlightEngine *self,
}
static GtkTextTag *
-get_kind_tag (IdeHighlightEngine *self,
- IdeHighlightKind kind)
+get_style_tag (IdeHighlightEngine *self,
+ const gchar *style_name)
{
- const gchar *name = NULL;
+ GtkTextTagTable *tag_table;
+ GtkTextTag *tag;
g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
+ g_assert (style_name != NULL);
+
+ tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (self->buffer));
+ tag = gtk_text_tag_table_lookup (tag_table, style_name);
- switch (kind)
+ if (tag == NULL)
{
- case IDE_HIGHLIGHT_KIND_TYPE_NAME:
- case IDE_HIGHLIGHT_KIND_CLASS_NAME:
- name = "def:type";
- break;
+ tag = create_tag_from_style (self, style_name);
+ self->tags = g_list_prepend (self->tags, tag);
+ }
- case IDE_HIGHLIGHT_KIND_FUNCTION_NAME:
- case IDE_HIGHLIGHT_KIND_MACRO_NAME:
- name = "def:function";
- break;
+ return tag;
+}
- case IDE_HIGHLIGHT_KIND_CONSTANT:
- name = "def:constant";
- break;
+static IdeHighlightResult
+ide_highlight_engine_apply_style (const GtkTextIter *begin,
+ const GtkTextIter *end,
+ const gchar *style_name)
+{
+ IdeHighlightEngine *self;
+ GtkTextBuffer *buffer;
+ GtkTextTag *tag;
- case IDE_HIGHLIGHT_KIND_NONE:
- default:
- return NULL;
- }
+ buffer = gtk_text_iter_get_buffer (begin);
+ self = g_object_get_qdata (G_OBJECT (buffer), gEngineQuark);
+ tag = get_style_tag (self, style_name);
+
+ gtk_text_buffer_apply_tag (buffer, tag, begin, end);
- if ((self->tags [kind] == NULL) && (name != NULL))
- self->tags [kind] = create_tag_from_style (self, name);
+ if (g_get_monotonic_time () >= self->quanta_expiration)
+ return IDE_HIGHLIGHT_STOP;
- return self->tags [kind];
+ return IDE_HIGHLIGHT_CONTINUE;
}
static gboolean
@@ -156,10 +167,8 @@ ide_highlight_engine_tick (IdeHighlightEngine *self)
{
GtkTextBuffer *buffer;
GtkTextIter iter;
- GtkTextIter begin;
- GtkTextIter end;
- guint64 quanta_expiration;
- IdeHighlightKind kind;
+ GtkTextIter invalid_begin;
+ GtkTextIter invalid_end;
IDE_PROBE;
@@ -169,50 +178,38 @@ ide_highlight_engine_tick (IdeHighlightEngine *self)
g_assert (self->invalid_begin != NULL);
g_assert (self->invalid_end != NULL);
- quanta_expiration = g_get_monotonic_time () + HIGHLIGHT_QUANTA_USEC;
+ self->quanta_expiration = g_get_monotonic_time () + HIGHLIGHT_QUANTA_USEC;
buffer = GTK_TEXT_BUFFER (self->buffer);
- do
- {
- GtkTextTag *tag;
- GtkTextIter invalid_begin;
- GtkTextIter invalid_end;
-
- gtk_text_buffer_get_iter_at_mark (buffer, &invalid_begin, self->invalid_begin);
- gtk_text_buffer_get_iter_at_mark (buffer, &invalid_end, self->invalid_end);
-
- IDE_TRACE_MSG ("Highlight Range (%u:%u <=> %u:%u)",
- gtk_text_iter_get_line (&invalid_begin),
- gtk_text_iter_get_line_offset (&invalid_begin),
- gtk_text_iter_get_line (&invalid_end),
- gtk_text_iter_get_line_offset (&invalid_end));
-
- if (gtk_text_iter_compare (&invalid_begin, &invalid_end) >= 0)
- IDE_GOTO (up_to_date);
+ gtk_text_buffer_get_iter_at_mark (buffer, &invalid_begin, self->invalid_begin);
+ gtk_text_buffer_get_iter_at_mark (buffer, &invalid_end, self->invalid_end);
- iter = invalid_begin;
+ IDE_TRACE_MSG ("Highlight Range (%u:%u <=> %u:%u)",
+ gtk_text_iter_get_line (&invalid_begin),
+ gtk_text_iter_get_line_offset (&invalid_begin),
+ gtk_text_iter_get_line (&invalid_end),
+ gtk_text_iter_get_line_offset (&invalid_end));
- kind = ide_highlighter_next (self->highlighter, &iter, &invalid_end, &begin, &end);
+ if (gtk_text_iter_compare (&invalid_begin, &invalid_end) >= 0)
+ IDE_GOTO (up_to_date);
- if (kind == IDE_HIGHLIGHT_KIND_NONE)
- IDE_GOTO (up_to_date);
+ iter = invalid_begin;
- IDE_TRACE_MSG ("Found tag of kind: %d", kind);
+ ide_highlighter_update (self->highlighter, ide_highlight_engine_apply_style,
+ &invalid_begin, &invalid_end, &iter);
- tag = get_kind_tag (self, kind);
+ if (gtk_text_iter_compare (&iter, &invalid_end) >= 0)
+ IDE_GOTO (up_to_date);
- gtk_text_buffer_apply_tag (buffer, tag, &begin, &end);
- gtk_text_buffer_move_mark (buffer, self->invalid_begin, &end);
- }
- while (g_get_monotonic_time () < quanta_expiration);
+ gtk_text_buffer_move_mark (buffer, self->invalid_begin, &iter);
return TRUE;
up_to_date:
- gtk_text_buffer_get_start_iter (buffer, &begin);
- gtk_text_buffer_move_mark (buffer, self->invalid_begin, &begin);
- gtk_text_buffer_move_mark (buffer, self->invalid_end, &begin);
+ gtk_text_buffer_get_start_iter (buffer, &iter);
+ gtk_text_buffer_move_mark (buffer, self->invalid_begin, &iter);
+ gtk_text_buffer_move_mark (buffer, self->invalid_end, &iter);
return FALSE;
}
@@ -251,7 +248,7 @@ ide_highlight_engine_reload (IdeHighlightEngine *self)
GtkTextBuffer *buffer;
GtkTextIter begin;
GtkTextIter end;
- gsize i;
+ GList *iter;
IDE_ENTRY;
@@ -279,9 +276,10 @@ ide_highlight_engine_reload (IdeHighlightEngine *self)
/*
* Remove our highlight tags from the buffer.
*/
- for (i = 0; i < G_N_ELEMENTS (self->tags); i++)
- if (self->tags [i] != NULL)
- gtk_text_buffer_remove_tag (buffer, self->tags [i], &begin, &end);
+ for (iter = self->tags; iter; iter = iter->next)
+ gtk_text_buffer_remove_tag (buffer, iter->data, &begin, &end);
+ g_list_free (self->tags);
+ self->tags = NULL;
if (self->highlighter == NULL)
IDE_EXIT;
@@ -393,6 +391,8 @@ ide_highlight_engine_connect_buffer (IdeHighlightEngine *self,
g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
g_assert (IDE_IS_BUFFER (buffer));
+ g_object_set_qdata (G_OBJECT (buffer), gEngineQuark, self);
+
gtk_text_buffer_get_bounds (text_buffer, &begin, &end);
self->invalid_begin = gtk_text_buffer_create_mark (text_buffer, NULL, &begin, TRUE);
@@ -423,7 +423,7 @@ ide_highlight_engine_disconnect_buffer (IdeHighlightEngine *self,
GtkTextTagTable *tag_table;
GtkTextIter begin;
GtkTextIter end;
- gsize i;
+ GList *iter;
IDE_ENTRY;
@@ -436,6 +436,8 @@ ide_highlight_engine_disconnect_buffer (IdeHighlightEngine *self,
self->work_timeout = 0;
}
+ g_object_set_qdata (G_OBJECT (buffer), gEngineQuark, NULL);
+
g_signal_handlers_disconnect_by_func (buffer,
G_CALLBACK (ide_highlight_engine__buffer_delete_range_cb),
self);
@@ -454,16 +456,15 @@ ide_highlight_engine_disconnect_buffer (IdeHighlightEngine *self,
gtk_text_buffer_get_bounds (text_buffer, &begin, &end);
- for (i = 0; i < G_N_ELEMENTS (self->tags); i++)
+ for (iter = self->tags; iter; iter= iter->next)
{
- if (self->tags [i] != NULL)
- {
- gtk_text_buffer_remove_tag (text_buffer, self->tags [i], &begin, &end);
- gtk_text_tag_table_remove (tag_table, self->tags [i]);
- self->tags [i] = NULL;
- }
+ gtk_text_buffer_remove_tag (text_buffer, iter->data, &begin, &end);
+ gtk_text_tag_table_remove (tag_table, iter->data);
}
+ g_list_free (self->tags);
+ self->tags = NULL;
+
IDE_EXIT;
}
@@ -584,6 +585,8 @@ ide_highlight_engine_class_init (IdeHighlightEngineClass *klass)
IDE_TYPE_HIGHLIGHTER,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_HIGHLIGHTER, gParamSpecs [PROP_HIGHLIGHTER]);
+
+ gEngineQuark = g_quark_from_string ("IDE_HIGHLIGHT_ENGINE");
}
static void
diff --git a/libide/ide-highlight-index.c b/libide/ide-highlight-index.c
index ee8b445..0d9d81b 100644
--- a/libide/ide-highlight-index.c
+++ b/libide/ide-highlight-index.c
@@ -52,12 +52,12 @@ ide_highlight_index_new (void)
void
ide_highlight_index_insert (IdeHighlightIndex *self,
const gchar *word,
- IdeHighlightKind kind)
+ gpointer tag)
{
gchar *key;
g_assert (self);
- g_assert (kind != IDE_HIGHLIGHT_KIND_NONE);
+ g_assert (tag != NULL);
if (word == NULL || word[0] == '\0')
return;
@@ -69,21 +69,27 @@ ide_highlight_index_insert (IdeHighlightIndex *self,
self->chunk_size += strlen (word) + 1;
key = g_string_chunk_insert (self->strings, word);
- g_hash_table_insert (self->index, key, GINT_TO_POINTER (kind));
+ g_hash_table_insert (self->index, key, tag);
}
-IdeHighlightKind
+/**
+ * ide_highlight_index_lookup:
+ * @self: An #IdeHighlightIndex.
+ *
+ * Gets the pointer tag that was registered for @word, or %NULL. This can be
+ * any arbitrary value. Some highlight engines might use it to point at
+ * internal structures or strings they know about to optimize later work.
+ *
+ * Returns: (transfer none) (nullable): Highlighter specific tag.
+ */
+gpointer
ide_highlight_index_lookup (IdeHighlightIndex *self,
const gchar *word)
{
- gpointer value;
-
g_assert (self);
g_assert (word);
- value = g_hash_table_lookup (self->index, word);
-
- return GPOINTER_TO_INT (value);
+ return g_hash_table_lookup (self->index, word);
}
IdeHighlightIndex *
diff --git a/libide/ide-highlight-index.h b/libide/ide-highlight-index.h
index ab95c00..8cf294d 100644
--- a/libide/ide-highlight-index.h
+++ b/libide/ide-highlight-index.h
@@ -19,7 +19,7 @@
#ifndef IDE_HIGHLIGHT_INDEX_H
#define IDE_HIGHLIGHT_INDEX_H
-#include "ide-highlighter.h"
+#include <glib-object.h>
G_BEGIN_DECLS
@@ -33,8 +33,8 @@ IdeHighlightIndex *ide_highlight_index_ref (IdeHighlightIndex *self);
void ide_highlight_index_unref (IdeHighlightIndex *self);
void ide_highlight_index_insert (IdeHighlightIndex *self,
const gchar *word,
- IdeHighlightKind kind);
-IdeHighlightKind ide_highlight_index_lookup (IdeHighlightIndex *self,
+ gpointer tag);
+gpointer ide_highlight_index_lookup (IdeHighlightIndex *self,
const gchar *word);
void ide_highlight_index_dump (IdeHighlightIndex *self);
diff --git a/libide/ide-highlighter.c b/libide/ide-highlighter.c
index 6b54162..9ccb0ed 100644
--- a/libide/ide-highlighter.c
+++ b/libide/ide-highlighter.c
@@ -30,23 +30,32 @@ ide_highlighter_init (IdeHighlighter *self)
{
}
-IdeHighlightKind
-ide_highlighter_next (IdeHighlighter *self,
- const GtkTextIter *range_begin,
- const GtkTextIter *range_end,
- GtkTextIter *match_begin,
- GtkTextIter *match_end)
+/**
+ * ide_highlighter_update:
+ * @self: A #IdeHighlighter.
+ * @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.
+ * @location: (out): How far the highlighter got in the update.
+ *
+ * Incrementally processes more of the buffer for highlighting. If @callback
+ * returns %IDE_HIGHLIGHT_STOP, then this vfunc should stop processing and
+ * return, having set @location to the current position of processing.
+ *
+ * If processing the entire range was successful, then @location should be set
+ * to @range_end.
+ */
+void
+ide_highlighter_update (IdeHighlighter *self,
+ IdeHighlightCallback callback,
+ const GtkTextIter *range_begin,
+ const GtkTextIter *range_end,
+ GtkTextIter *location)
{
- g_return_val_if_fail (IDE_IS_HIGHLIGHTER (self), 0);
- g_return_val_if_fail (range_begin, 0);
- g_return_val_if_fail (range_end, 0);
- g_return_val_if_fail (match_begin, 0);
- g_return_val_if_fail (match_end, 0);
-
- if (IDE_HIGHLIGHTER_GET_CLASS (self)->next)
- return IDE_HIGHLIGHTER_GET_CLASS (self)->next (self,
- range_begin, range_end,
- match_begin, match_end);
+ g_return_if_fail (IDE_IS_HIGHLIGHTER (self));
+ g_return_if_fail (range_begin);
+ g_return_if_fail (range_end);
- return IDE_HIGHLIGHT_KIND_NONE;
+ if (IDE_HIGHLIGHTER_GET_CLASS (self)->update)
+ IDE_HIGHLIGHTER_GET_CLASS (self)->update (self, callback, range_begin, range_end, location);
}
diff --git a/libide/ide-highlighter.h b/libide/ide-highlighter.h
index 4723f02..ed5932c 100644
--- a/libide/ide-highlighter.h
+++ b/libide/ide-highlighter.h
@@ -33,33 +33,43 @@ G_DECLARE_DERIVABLE_TYPE (IdeHighlighter, ide_highlighter, IDE, HIGHLIGHTER, Ide
typedef enum
{
- IDE_HIGHLIGHT_KIND_NONE,
+ IDE_HIGHLIGHT_STOP,
+ IDE_HIGHLIGHT_CONTINUE,
+} IdeHighlightResult;
- IDE_HIGHLIGHT_KIND_TYPE_NAME,
- IDE_HIGHLIGHT_KIND_CLASS_NAME,
- IDE_HIGHLIGHT_KIND_FUNCTION_NAME,
- IDE_HIGHLIGHT_KIND_MACRO_NAME,
- IDE_HIGHLIGHT_KIND_CONSTANT,
-
- IDE_HIGHLIGHT_KIND_LAST
-} IdeHighlightKind;
+typedef IdeHighlightResult (*IdeHighlightCallback) (const GtkTextIter *begin,
+ const GtkTextIter *end,
+ const gchar *style_name);
struct _IdeHighlighterClass
{
IdeObjectClass parent;
- IdeHighlightKind (*next) (IdeHighlighter *self,
- const GtkTextIter *range_begin,
- const GtkTextIter *range_end,
- GtkTextIter *match_begin,
- GtkTextIter *match_end);
+ /**
+ * IdeHighlighter::update:
+ *
+ * #IdeHighlighter should call callback() with the range and style-name of
+ * the style to apply. Callback will ensure that the style exists and style
+ * it appropriately based on the style scheme.
+ *
+ * If @callback returns %IDE_HIGHLIGHT_STOP, the caller has run out of its
+ * time slice and should yield back to the highlight engine.
+ *
+ * @location should be set to the position that the highlighter got to
+ * before yielding back to the engine.
+ */
+ void (*update) (IdeHighlighter *self,
+ IdeHighlightCallback callback,
+ const GtkTextIter *range_begin,
+ const GtkTextIter *range_end,
+ GtkTextIter *location);
};
-IdeHighlightKind ide_highlighter_next (IdeHighlighter *self,
- const GtkTextIter *range_begin,
- const GtkTextIter *range_end,
- GtkTextIter *match_begin,
- GtkTextIter *match_end);
+void ide_highlighter_update (IdeHighlighter *self,
+ IdeHighlightCallback callback,
+ const GtkTextIter *range_begin,
+ const GtkTextIter *range_end,
+ GtkTextIter *location);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]