[gnome-builder] libide/code: port highlight engine to CjhTextRegion
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] libide/code: port highlight engine to CjhTextRegion
- Date: Wed, 14 Sep 2022 06:32:53 +0000 (UTC)
commit 10bee55caeddab1b042076827f5f7e5d16c4c5e4
Author: Christian Hergert <chergert redhat com>
Date: Tue Sep 13 22:39:05 2022 -0700
libide/code: port highlight engine to CjhTextRegion
This tries to avoid using the ever growing textmark region to update and
instead tries to be finer grained with runs of invalid areas. It should
help speed up quite a bit how fast we can react to changes.
However, some additional work to only clear highlights from lines we are
about to process would make this feel a lot better.
src/libide/code/ide-highlight-engine.c | 517 ++++++++++++++++-----------------
1 file changed, 247 insertions(+), 270 deletions(-)
---
diff --git a/src/libide/code/ide-highlight-engine.c b/src/libide/code/ide-highlight-engine.c
index 5f7cb0df0..766a7880b 100644
--- a/src/libide/code/ide-highlight-engine.c
+++ b/src/libide/code/ide-highlight-engine.c
@@ -23,18 +23,25 @@
#include "config.h"
#include <glib/gi18n.h>
+
#include <gtksourceview/gtksource.h>
-#include <libide-plugins.h>
#include <string.h>
+#include <libide-plugins.h>
+
#include "ide-buffer.h"
#include "ide-buffer-private.h"
#include "ide-highlight-engine.h"
#include "ide-highlight-index.h"
#include "ide-highlighter.h"
+#include "cjhtextregionprivate.h"
+
#define PRIVATE_TAG_PREFIX "Builder"
+#define RUN_UNCHECKED GSIZE_TO_POINTER(0)
+#define RUN_CHECKED GSIZE_TO_POINTER(1)
+
struct _IdeHighlightEngine
{
IdeObject parent_instance;
@@ -47,8 +54,7 @@ struct _IdeHighlightEngine
IdeExtensionAdapter *extension;
- GtkTextMark *invalid_begin;
- GtkTextMark *invalid_end;
+ CjhTextRegion *region;
GSList *private_tags;
GSList *public_tags;
@@ -57,6 +63,8 @@ struct _IdeHighlightEngine
gsize work_scheduled;
+ guint commit_funcs_handler;
+
guint enabled : 1;
};
@@ -71,67 +79,6 @@ enum {
static GParamSpec *properties [LAST_PROP];
-static gboolean
-get_invalidation_area (GtkTextIter *begin,
- GtkTextIter *end)
-{
- GtkTextIter begin_tmp;
- GtkTextIter end_tmp;
-
- g_assert (begin != NULL);
- g_assert (end != NULL);
-
- /*
- * Move to the beginning of line.We dont use gtk_text_iter_backward_line
- * because if begin is at the beginning of the line we dont want to
- * move to the previous line
- */
- gtk_text_iter_set_line_offset (begin, 0);
-
- /* Move to the beginning of the next line. */
- gtk_text_iter_forward_line (end);
-
- /* Save the original locations. We will need them down the line. */
- begin_tmp = *begin;
- end_tmp = *end;
-
- /*
- * Fordward begin iter character by character until:
- * - We reach a non space character
- * - We reach end iter
- */
- while (g_unichar_isspace (gtk_text_iter_get_char (begin)) &&
- gtk_text_iter_compare (begin, &end_tmp) < 0)
- gtk_text_iter_forward_char (begin);
-
-
- /*
- * If after moving forward the begin iter, we reached the end iter,
- * there is no need to play with the end iter.
- */
- if (gtk_text_iter_compare (begin, end) < 0)
- {
- /*
- * Backward end iter character by character until:
- * - We reach a non space character
- * - We reach begin iter
- */
- while (g_unichar_isspace (gtk_text_iter_get_char (end)) &&
- gtk_text_iter_compare (end, &begin_tmp) > 0)
- gtk_text_iter_backward_char (end);
-
- /*
- * If we found the character we are looking for then move one
- * character forward in order to include it as the last
- * character of the begin - end range.
- */
- if (gtk_text_iter_compare (end, &end_tmp) < 0)
- gtk_text_iter_forward_char (end);
- }
-
- return gtk_text_iter_compare (begin, end) < 0;
-}
-
static void
sync_tag_style (GtkSourceStyleScheme *style_scheme,
GtkSourceLanguage *language,
@@ -317,6 +264,58 @@ ide_highlight_engine_apply_style (const GtkTextIter *begin,
return IDE_HIGHLIGHT_CONTINUE;
}
+typedef struct
+{
+ gsize offset;
+ gsize length;
+} GetUncheckedRange;
+
+static inline gboolean
+get_unchecked_start_cb (gsize offset,
+ const CjhTextRegionRun *run,
+ gpointer user_data)
+{
+ GetUncheckedRange *range = user_data;
+
+ if (range->offset == G_MAXSIZE)
+ {
+ if (run->data == RUN_UNCHECKED)
+ {
+ range->offset = offset;
+ range->length = run->length;
+ }
+
+ return FALSE;
+ }
+ else if (run->data == RUN_UNCHECKED &&
+ range->offset + range->length == offset)
+ {
+ range->length += run->length;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+get_next_range (CjhTextRegion *region,
+ GtkTextBuffer *buffer,
+ GtkTextIter *begin,
+ GtkTextIter *end)
+{
+ GetUncheckedRange range = {G_MAXSIZE, G_MAXSIZE};
+
+ _cjh_text_region_foreach (region, get_unchecked_start_cb, &range);
+
+ if (range.offset == G_MAXSIZE)
+ return FALSE;
+
+ gtk_text_buffer_get_iter_at_offset (buffer, begin, range.offset);
+ gtk_text_buffer_get_iter_at_offset (buffer, end, range.offset + range.length);
+
+ return TRUE;
+}
+
static gboolean
ide_highlight_engine_tick (IdeHighlightEngine *self,
gint64 deadline)
@@ -331,28 +330,25 @@ ide_highlight_engine_tick (IdeHighlightEngine *self,
g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
g_assert (self->highlighter != NULL);
- g_assert (self->invalid_begin != NULL);
- g_assert (self->invalid_end != NULL);
- buffer = g_weak_ref_get (&self->buffer_wref);
- if (buffer == NULL)
+ if (!(buffer = g_weak_ref_get (&self->buffer_wref)))
return G_SOURCE_REMOVE;
self->quanta_expiration = deadline;
- 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);
+ if (!get_next_range (self->region, buffer, &invalid_begin, &invalid_end))
+ return G_SOURCE_REMOVE;
+
+again:
+ g_assert (gtk_text_iter_compare (&invalid_begin, &invalid_end) <= 0);
IDE_TRACE_MSG ("Highlight Range [%u:%u,%u:%u] (%s)",
- 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),
+ gtk_text_iter_get_line (&invalid_begin) + 1,
+ gtk_text_iter_get_line_offset (&invalid_begin) + 1,
+ gtk_text_iter_get_line (&invalid_end) + 1,
+ gtk_text_iter_get_line_offset (&invalid_end) + 1,
G_OBJECT_TYPE_NAME (self->highlighter));
- if (gtk_text_iter_compare (&invalid_begin, &invalid_end) >= 0)
- IDE_GOTO (up_to_date);
-
/* Clear all our tags */
for (tags_iter = self->private_tags; tags_iter; tags_iter = tags_iter->next)
gtk_text_buffer_remove_tag (buffer,
@@ -362,26 +358,36 @@ ide_highlight_engine_tick (IdeHighlightEngine *self,
iter = invalid_begin;
- ide_highlighter_update (self->highlighter, ide_highlight_engine_apply_style,
- &invalid_begin, &invalid_end, &iter);
+ while (gtk_text_iter_ends_line (&iter))
+ {
+ if (!gtk_text_iter_forward_char (&iter))
+ break;
+ }
+
+ if (gtk_text_iter_compare (&iter, &invalid_end) < 0)
+ ide_highlighter_update (self->highlighter,
+ ide_highlight_engine_apply_style,
+ &invalid_begin,
+ &invalid_end,
+ &iter);
+
+ if (!gtk_text_iter_equal (&iter, &invalid_begin))
+ _cjh_text_region_replace (self->region,
+ gtk_text_iter_get_offset (&invalid_begin),
+ gtk_text_iter_get_offset (&iter) - gtk_text_iter_get_offset (&invalid_begin),
+ RUN_CHECKED);
if (gtk_text_iter_compare (&iter, &invalid_end) >= 0)
- IDE_GOTO (up_to_date);
+ {
+ if (get_next_range (self->region, buffer, &invalid_begin, &invalid_end))
+ IDE_GOTO (again);
+ }
/* Stop processing until further instruction if no movement was made */
if (gtk_text_iter_equal (&iter, &invalid_begin))
return G_SOURCE_REMOVE;
- gtk_text_buffer_move_mark (buffer, self->invalid_begin, &iter);
-
return G_SOURCE_CONTINUE;
-
-up_to_date:
- 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 G_SOURCE_REMOVE;
}
static gboolean
@@ -410,8 +416,10 @@ ide_highlight_engine_queue_work (IdeHighlightEngine *self)
g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
- buffer = g_weak_ref_get (&self->buffer_wref);
- if (self->highlighter == NULL || buffer == NULL || self->work_scheduled != 0)
+ if (self->work_scheduled != 0 || self->highlighter == NULL)
+ return;
+
+ if (!(buffer = g_weak_ref_get (&self->buffer_wref)))
return;
self->work_scheduled = gtk_source_scheduler_add (ide_highlight_engine_worker, self);
@@ -435,51 +443,6 @@ ide_highlight_engine_advance (IdeHighlightEngine *self)
ide_highlight_engine_queue_work (self);
}
-static gboolean
-invalidate_and_highlight (IdeHighlightEngine *self,
- GtkTextIter *begin,
- GtkTextIter *end)
-{
- GtkTextBuffer *text_buffer;
-
- g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
- g_assert (begin != NULL);
- g_assert (end != NULL);
-
- if (!self->enabled)
- return FALSE;
-
- text_buffer = gtk_text_iter_get_buffer (begin);
-
- if (get_invalidation_area (begin, end))
- {
- GtkTextIter begin_tmp;
- GtkTextIter end_tmp;
-
- gtk_text_buffer_get_iter_at_mark (text_buffer, &begin_tmp, self->invalid_begin);
- gtk_text_buffer_get_iter_at_mark (text_buffer, &end_tmp, self->invalid_end);
-
- if (gtk_text_iter_equal (&begin_tmp, &end_tmp))
- {
- gtk_text_buffer_move_mark (text_buffer, self->invalid_begin, begin);
- gtk_text_buffer_move_mark (text_buffer, self->invalid_end, end);
- }
- else
- {
- if (gtk_text_iter_compare (begin, &begin_tmp) < 0)
- gtk_text_buffer_move_mark (text_buffer, self->invalid_begin, begin);
- if (gtk_text_iter_compare (end, &end_tmp) > 0)
- gtk_text_buffer_move_mark (text_buffer, self->invalid_end, end);
- }
-
- ide_highlight_engine_queue_work (self);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
static void
ide_highlight_engine_reload (IdeHighlightEngine *self)
{
@@ -494,21 +457,13 @@ ide_highlight_engine_reload (IdeHighlightEngine *self)
gtk_source_scheduler_clear (&self->work_scheduled);
- buffer = g_weak_ref_get (&self->buffer_wref);
- if (buffer == NULL)
+ if (!(buffer = g_weak_ref_get (&self->buffer_wref)))
IDE_EXIT;
gtk_text_buffer_get_bounds (buffer, &begin, &end);
+ ide_highlight_engine_invalidate (self, &begin, &end);
- /*
- * Invalidate the whole buffer.
- */
- gtk_text_buffer_move_mark (buffer, self->invalid_begin, &begin);
- gtk_text_buffer_move_mark (buffer, self->invalid_end, &end);
-
- /*
- * Remove our highlight tags from the buffer.
- */
+ /* Remove our highlight tags from the buffer. */
for (iter = self->private_tags; iter; iter = iter->next)
gtk_text_buffer_remove_tag (buffer, iter->data, &begin, &end);
g_clear_pointer (&self->private_tags, g_slist_free);
@@ -545,71 +500,6 @@ ide_highlight_engine_set_highlighter (IdeHighlightEngine *self,
}
}
-static void
-ide_highlight_engine__buffer_insert_text_cb (IdeHighlightEngine *self,
- GtkTextIter *location,
- gchar *text,
- gint len,
- IdeBuffer *buffer)
-{
- GtkTextIter begin;
- GtkTextIter end;
-
- IDE_ENTRY;
-
- g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
- g_assert (location);
- g_assert (text);
- g_assert (IDE_IS_BUFFER (buffer));
-
- if (!self->enabled)
- IDE_EXIT;
-
- /*
- * Backward the begin iter len characters from location
- * (location points to the end of the string) in order to get
- * the iter position where our inserted text was started.
- */
- begin = *location;
- gtk_text_iter_backward_chars (&begin, g_utf8_strlen (text, len));
-
- end = *location;
-
- invalidate_and_highlight (self, &begin, &end);
-
- IDE_EXIT;
-}
-
-static void
-ide_highlight_engine__buffer_delete_range_cb (IdeHighlightEngine *self,
- GtkTextIter *range_begin,
- GtkTextIter *range_end,
- IdeBuffer *buffer)
-{
- GtkTextIter begin;
- GtkTextIter end;
-
- IDE_ENTRY;
-
- g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
- g_assert (range_begin);
- g_assert (IDE_IS_BUFFER (buffer));
-
- if (!self->enabled)
- IDE_EXIT;
-
- /*
- * No need to use the range_end since everything that
- * was after range_end will now be after range_begin
- */
- begin = *range_begin;
- end = *range_begin;
-
- invalidate_and_highlight (self, &begin, &end);
-
- IDE_EXIT;
-}
-
static void
ide_highlight_engine__notify_language_cb (IdeHighlightEngine *self,
GParamSpec *pspec,
@@ -674,36 +564,126 @@ ide_highlight_engine_clear (IdeHighlightEngine *self)
}
}
+static void
+mark_unchecked (IdeHighlightEngine *self,
+ IdeBuffer *buffer,
+ guint offset,
+ guint length)
+{
+ GtkTextIter begin, end;
+
+ g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
+
+ gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (buffer), &begin, offset);
+ gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (buffer), &end, offset + length);
+
+ while (!gtk_text_iter_starts_line (&begin))
+ {
+ gunichar ch;
+
+ if (!gtk_text_iter_backward_char (&begin))
+ break;
+
+ ch = gtk_text_iter_get_char (&begin);
+
+ if (ch != '_' && !g_unichar_isalnum (ch))
+ break;
+ }
+
+ while (!gtk_text_iter_ends_line (&end))
+ {
+ gunichar ch;
+
+ if (!gtk_text_iter_forward_char (&end))
+ break;
+
+ ch = gtk_text_iter_get_char (&end);
+
+ if (ch != '_' && !g_unichar_isalnum (ch))
+ break;
+ }
+
+ ide_highlight_engine_invalidate (self, &begin, &end);
+}
+
+static void
+ide_highlight_engine_insert_before_cb (IdeBuffer *buffer,
+ guint offset,
+ guint length,
+ gpointer user_data)
+{
+ IdeHighlightEngine *self = user_data;
+
+ g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
+
+ if (self->enabled)
+ _cjh_text_region_insert (self->region, offset, length, RUN_UNCHECKED);
+}
+
+static void
+ide_highlight_engine_insert_after_cb (IdeBuffer *buffer,
+ guint offset,
+ guint length,
+ gpointer user_data)
+{
+ IdeHighlightEngine *self = user_data;
+
+ g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
+
+ if (self->enabled)
+ mark_unchecked (self, buffer, offset, length);
+}
+
+static void
+ide_highlight_engine_delete_before_cb (IdeBuffer *buffer,
+ guint offset,
+ guint length,
+ gpointer user_data)
+{
+ IdeHighlightEngine *self = user_data;
+
+ g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
+
+ if (self->enabled)
+ _cjh_text_region_remove (self->region, offset, length);
+}
+
+static void
+ide_highlight_engine_delete_after_cb (IdeBuffer *buffer,
+ guint offset,
+ guint length,
+ gpointer user_data)
+{
+ IdeHighlightEngine *self = user_data;
+
+ g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
+
+ if (self->enabled)
+ mark_unchecked (self, buffer, offset, 0);
+}
+
static void
ide_highlight_engine__bind_buffer_cb (IdeHighlightEngine *self,
IdeBuffer *buffer,
IdeSignalGroup *group)
{
GtkTextBuffer *text_buffer = (GtkTextBuffer *)buffer;
- GtkTextIter begin;
- GtkTextIter end;
IDE_ENTRY;
g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
g_assert (IDE_IS_BUFFER (buffer));
g_assert (IDE_IS_SIGNAL_GROUP (group));
- g_assert (self->invalid_begin == NULL);
- g_assert (self->invalid_end == NULL);
g_weak_ref_set (&self->buffer_wref, buffer);
- gtk_text_buffer_get_bounds (text_buffer, &begin, &end);
-
- self->invalid_begin = gtk_text_buffer_create_mark (text_buffer, NULL, &begin, TRUE);
- self->invalid_end = gtk_text_buffer_create_mark (text_buffer, NULL, &end, FALSE);
-
- /* We can hold a full reference to the text marks, without
- * taking a reference to the buffer. We want to avoid a reference
- * to the buffer for cyclic reasons.
- */
- g_object_ref (self->invalid_begin);
- g_object_ref (self->invalid_end);
+ self->commit_funcs_handler =
+ ide_buffer_add_commit_funcs (IDE_BUFFER (text_buffer),
+ ide_highlight_engine_insert_before_cb,
+ ide_highlight_engine_insert_after_cb,
+ ide_highlight_engine_delete_before_cb,
+ ide_highlight_engine_delete_after_cb,
+ self, NULL);
ide_highlight_engine__notify_style_scheme_cb (self, NULL, buffer);
ide_highlight_engine__notify_language_cb (self, NULL, buffer);
@@ -718,6 +698,7 @@ ide_highlight_engine__unbind_buffer_cb (IdeHighlightEngine *self,
IdeSignalGroup *group)
{
g_autoptr(GtkTextBuffer) text_buffer = NULL;
+ gsize length;
IDE_ENTRY;
@@ -728,6 +709,9 @@ ide_highlight_engine__unbind_buffer_cb (IdeHighlightEngine *self,
gtk_source_scheduler_clear (&self->work_scheduled);
+ length = _cjh_text_region_get_length (self->region);
+ _cjh_text_region_remove (self->region, 0, length - 1);
+
if (text_buffer != NULL)
{
g_autoptr(GSList) private_tags = NULL;
@@ -736,10 +720,14 @@ ide_highlight_engine__unbind_buffer_cb (IdeHighlightEngine *self,
GtkTextIter begin;
GtkTextIter end;
- tag_table = gtk_text_buffer_get_tag_table (text_buffer);
+ if (self->commit_funcs_handler)
+ {
+ ide_buffer_remove_commit_funcs (IDE_BUFFER (text_buffer),
+ self->commit_funcs_handler);
+ self->commit_funcs_handler = 0;
+ }
- gtk_text_buffer_delete_mark (text_buffer, self->invalid_begin);
- gtk_text_buffer_delete_mark (text_buffer, self->invalid_end);
+ tag_table = gtk_text_buffer_get_tag_table (text_buffer);
gtk_text_buffer_get_bounds (text_buffer, &begin, &end);
@@ -762,9 +750,6 @@ ide_highlight_engine__unbind_buffer_cb (IdeHighlightEngine *self,
g_clear_pointer (&self->public_tags, g_slist_free);
g_clear_pointer (&self->private_tags, g_slist_free);
- g_clear_object (&self->invalid_begin);
- g_clear_object (&self->invalid_end);
-
IDE_EXIT;
}
@@ -856,6 +841,7 @@ ide_highlight_engine_dispose (GObject *object)
g_clear_object (&self->extension);
g_clear_object (&self->highlighter);
g_clear_object (&self->settings);
+ g_clear_pointer (&self->region, _cjh_text_region_free);
G_OBJECT_CLASS (ide_highlight_engine_parent_class)->dispose (object);
}
@@ -951,17 +937,7 @@ ide_highlight_engine_init (IdeHighlightEngine *self)
self->enabled = g_settings_get_boolean (self->settings, "semantic-highlighting");
self->signal_group = ide_signal_group_new (IDE_TYPE_BUFFER);
- ide_signal_group_connect_object (self->signal_group,
- "insert-text",
- G_CALLBACK (ide_highlight_engine__buffer_insert_text_cb),
- self,
- G_CONNECT_SWAPPED | G_CONNECT_AFTER);
-
- ide_signal_group_connect_object (self->signal_group,
- "delete-range",
- G_CALLBACK (ide_highlight_engine__buffer_delete_range_cb),
- self,
- G_CONNECT_SWAPPED | G_CONNECT_AFTER);
+ self->region = _cjh_text_region_new (NULL, NULL);
ide_signal_group_connect_object (self->signal_group,
"notify::language",
@@ -1055,25 +1031,37 @@ void
ide_highlight_engine_rebuild (IdeHighlightEngine *self)
{
g_autoptr(GtkTextBuffer) buffer = NULL;
+ GtkTextIter begin, end;
+ gsize length;
IDE_ENTRY;
g_return_if_fail (IDE_IS_HIGHLIGHT_ENGINE (self));
- buffer = g_weak_ref_get (&self->buffer_wref);
+ if (!self->enabled)
+ IDE_EXIT;
- if (buffer != NULL)
+ if ((buffer = g_weak_ref_get (&self->buffer_wref)))
{
- GtkTextIter begin;
- GtkTextIter end;
+ /* We remove using the known length from the region */
+ if ((length = _cjh_text_region_get_length (self->region)) > 0)
+ _cjh_text_region_remove (self->region, 0, length - 1);
+ /* We add using the length from the buffer because if we were not
+ * enabled previously, the textregion would be empty.
+ */
gtk_text_buffer_get_bounds (buffer, &begin, &end);
- gtk_text_buffer_move_mark (buffer, self->invalid_begin, &begin);
- gtk_text_buffer_move_mark (buffer, self->invalid_end, &end);
+ if (!gtk_text_iter_equal (&begin, &end))
+ {
+ length = gtk_text_iter_get_offset (&end) - gtk_text_iter_get_offset (&begin);
- ide_highlight_engine_queue_work (self);
+ if (length > 0)
+ _cjh_text_region_insert (self->region, 0, length, RUN_UNCHECKED);
+ }
}
+ ide_highlight_engine_queue_work (self);
+
IDE_EXIT;
}
@@ -1098,32 +1086,21 @@ ide_highlight_engine_invalidate (IdeHighlightEngine *self,
const GtkTextIter *begin,
const GtkTextIter *end)
{
- GtkTextBuffer *buffer;
- GtkTextIter mark_begin;
- GtkTextIter mark_end;
+ guint offset;
+ guint length;
IDE_ENTRY;
g_return_if_fail (IDE_IS_HIGHLIGHT_ENGINE (self));
- g_return_if_fail (begin != NULL);
- g_return_if_fail (end != NULL);
-
- buffer = gtk_text_iter_get_buffer (begin);
+ g_return_if_fail (gtk_text_iter_compare (begin, end) <= 0);
- gtk_text_buffer_get_iter_at_mark (buffer, &mark_begin, self->invalid_begin);
- gtk_text_buffer_get_iter_at_mark (buffer, &mark_end, self->invalid_end);
+ offset = gtk_text_iter_get_offset (begin);
+ length = gtk_text_iter_get_offset (end) - gtk_text_iter_get_offset (begin);
- if (gtk_text_iter_equal (&mark_begin, &mark_end))
- {
- gtk_text_buffer_move_mark (buffer, self->invalid_begin, begin);
- gtk_text_buffer_move_mark (buffer, self->invalid_end, end);
- }
- else
+ if (length > 0)
{
- if (gtk_text_iter_compare (begin, &mark_begin) < 0)
- gtk_text_buffer_move_mark (buffer, self->invalid_begin, begin);
- if (gtk_text_iter_compare (end, &mark_end) > 0)
- gtk_text_buffer_move_mark (buffer, self->invalid_end, end);
+ _cjh_text_region_remove (self->region, offset, length);
+ _cjh_text_region_insert (self->region, offset, length, RUN_UNCHECKED);
}
ide_highlight_engine_queue_work (self);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]