diff --git a/moo.kdevelop b/moo.kdevelop
index 5f295e51..524817c3 100644
--- a/moo.kdevelop
+++ b/moo.kdevelop
@@ -103,7 +103,7 @@
- --enable-all-gcc-warnings=fatal --without-python
+ --enable-all-gcc-warnings=fatal
build/optimized
kdevgccoptions
kdevgppoptions
diff --git a/moo/mooedit/moohighlighter.c b/moo/mooedit/moohighlighter.c
index ba0c3f8b..44fcb91f 100644
--- a/moo/mooedit/moohighlighter.c
+++ b/moo/mooedit/moohighlighter.c
@@ -198,13 +198,9 @@ apply_tag (MooHighlighter *hl,
if (tag)
{
#if 0
- static int last_line_no = -1;
- int line_no = _moo_line_buffer_get_line_index (hl->line_buf, line);
- if (line_no != last_line_no)
- {
- last_line_no = line_no;
- g_message ("applying tag on line %d", line_no);
- }
+ g_print ("* applying tag '%s' on line %d\n",
+ rule ? rule->description : "NULL",
+ _moo_line_buffer_get_line_index (hl->line_buf, line));
#endif
line->hl_info->tags = g_slist_prepend (line->hl_info->tags, g_object_ref (tag));
hl->last_tag = tag;
@@ -627,7 +623,6 @@ hl_compute_range (MooHighlighter *hl,
if (timer)
g_timer_destroy (timer);
- check_last_tag (hl);
_moo_text_buffer_highlighting_changed (MOO_TEXT_BUFFER (hl->buffer),
lines->first, line_no);
// g_print ("changed %d to %d\n", lines->first, line_no);
@@ -787,11 +782,11 @@ _moo_highlighter_apply_tags (MooHighlighter *hl,
}
}
- check_last_tag (hl);
+// check_last_tag (hl);
if (first_changed >= 0)
- _moo_text_buffer_highlighting_changed (MOO_TEXT_BUFFER (hl->buffer),
- first_changed, last_changed);
+ _moo_text_buffer_tags_changed (MOO_TEXT_BUFFER (hl->buffer),
+ first_changed, last_changed);
}
diff --git a/moo/mooedit/mootext-private.h b/moo/mooedit/mootext-private.h
index b60cf41a..e1be3549 100644
--- a/moo/mooedit/mootext-private.h
+++ b/moo/mooedit/mootext-private.h
@@ -59,6 +59,9 @@ void _moo_text_buffer_apply_syntax_tag (MooTextBuffer *buffer,
void _moo_text_buffer_highlighting_changed (MooTextBuffer *buffer,
int first,
int last);
+void _moo_text_buffer_tags_changed (MooTextBuffer *buffer,
+ int first,
+ int last);
G_END_DECLS
diff --git a/moo/mooedit/mootextbuffer.c b/moo/mooedit/mootextbuffer.c
index 061d6604..170f9f46 100644
--- a/moo/mooedit/mootextbuffer.c
+++ b/moo/mooedit/mootextbuffer.c
@@ -123,6 +123,7 @@ enum {
CURSOR_MOVED,
SELECTION_CHANGED,
HIGHLIGHTING_CHANGED,
+ TAGS_CHANGED,
LINE_MARK_ADDED,
LINE_MARK_MOVED,
LINE_MARK_DELETED,
@@ -258,6 +259,16 @@ moo_text_buffer_class_init (MooTextBufferClass *klass)
GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE,
GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE);
+ signals[TAGS_CHANGED] =
+ moo_signal_new_cb ("tags-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ NULL, NULL, NULL,
+ _moo_marshal_VOID__BOXED_BOXED,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE,
+ GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE);
+
signals[LINE_MARK_ADDED] =
g_signal_new ("line-mark-added",
G_OBJECT_CLASS_TYPE (klass),
@@ -939,10 +950,11 @@ _moo_text_buffer_ensure_highlight (MooTextBuffer *buffer,
}
-void
-_moo_text_buffer_highlighting_changed (MooTextBuffer *buffer,
- int first,
- int last)
+static void
+something_changed (MooTextBuffer *buffer,
+ int first,
+ int last,
+ guint sig)
{
GtkTextIter start, end;
@@ -956,7 +968,25 @@ _moo_text_buffer_highlighting_changed (MooTextBuffer *buffer,
else
gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (buffer), &end, last);
- g_signal_emit (buffer, signals[HIGHLIGHTING_CHANGED], 0, &start, &end);
+ g_signal_emit (buffer, signals[sig], 0, &start, &end);
+}
+
+
+void
+_moo_text_buffer_highlighting_changed (MooTextBuffer *buffer,
+ int first,
+ int last)
+{
+ something_changed (buffer, first, last, HIGHLIGHTING_CHANGED);
+}
+
+
+void
+_moo_text_buffer_tags_changed (MooTextBuffer *buffer,
+ int first,
+ int last)
+{
+ something_changed (buffer, first, last, TAGS_CHANGED);
}
diff --git a/moo/mooedit/mootextview-private.h b/moo/mooedit/mootextview-private.h
index 13dcf674..fbe7a122 100644
--- a/moo/mooedit/mootextview-private.h
+++ b/moo/mooedit/mootextview-private.h
@@ -78,6 +78,10 @@ typedef enum {
struct _MooTextViewPrivate {
gboolean constructed;
+ GdkRectangle *update_rectangle;
+ gboolean in_expose;
+ guint update_idle;
+
/* Clipboard */
gboolean manage_clipboard;
diff --git a/moo/mooedit/mootextview.c b/moo/mooedit/mootextview.c
index ceb13027..da3bec19 100644
--- a/moo/mooedit/mootextview.c
+++ b/moo/mooedit/mootextview.c
@@ -124,6 +124,9 @@ static void selection_changed (MooTextView *view,
static void highlighting_changed (GtkTextView *view,
const GtkTextIter *start,
const GtkTextIter *end);
+static void tags_changed (GtkTextView *view,
+ const GtkTextIter *start,
+ const GtkTextIter *end);
static void moo_text_view_set_scheme_real (MooTextView *view,
MooTextStyleScheme *scheme);
@@ -673,6 +676,8 @@ moo_text_view_constructor (GType type,
G_CALLBACK (selection_changed), view);
g_signal_connect_swapped (get_buffer (view), "highlighting-changed",
G_CALLBACK (highlighting_changed), view);
+ g_signal_connect_swapped (get_buffer (view), "tags-changed",
+ G_CALLBACK (tags_changed), view);
g_signal_connect_swapped (get_buffer (view), "notify::has-selection",
G_CALLBACK (proxy_prop_notify), view);
g_signal_connect_swapped (get_buffer (view), "notify::has-text",
@@ -1957,6 +1962,13 @@ moo_text_view_unrealize (GtkWidget *widget)
g_object_set_data (G_OBJECT (widget), "moo-line-mark-icons", NULL);
g_object_set_data (G_OBJECT (widget), "moo-line-mark-colors", NULL);
+ if (view->priv->update_idle)
+ g_source_remove (view->priv->update_idle);
+ view->priv->update_idle = 0;
+
+ g_free (view->priv->update_rectangle);
+ view->priv->update_rectangle = NULL;
+
if (view->priv->current_line_gc)
g_object_unref (view->priv->current_line_gc);
view->priv->current_line_gc = NULL;
@@ -2226,6 +2238,8 @@ moo_text_view_expose (GtkWidget *widget,
GdkWindow *right_window = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_RIGHT);
GtkTextIter start, end;
+ view->priv->in_expose = TRUE;
+
if (view->priv->highlight_current_line &&
view->priv->current_line_gc &&
event->window == text_window && view->priv->current_line_gc)
@@ -2289,6 +2303,8 @@ moo_text_view_expose (GtkWidget *widget,
if (event->window == text_window && view->priv->cursor_visible)
moo_text_view_draw_cursor (text_view, event);
+ view->priv->in_expose = FALSE;
+
return handled;
}
@@ -2314,16 +2330,96 @@ highlighting_changed (GtkTextView *text_view,
if (gdk_rectangle_intersect (&changed, &visible, &update))
{
- GdkWindow *window = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT);
+ GtkTextIter update_start, update_end;
+ int first_line, last_line;
- gtk_text_view_buffer_to_window_coords (text_view,
- GTK_TEXT_WINDOW_TEXT,
- update.x,
- update.y,
- &update.x,
- &update.y);
+ gtk_text_view_get_line_at_y (text_view, &update_start, update.y, NULL);
+ gtk_text_view_get_line_at_y (text_view, &update_end, update.y + update.height - 1, NULL);
- gdk_window_invalidate_rect (window, &update, TRUE);
+ first_line = gtk_text_iter_get_line (&update_start);
+ last_line = gtk_text_iter_get_line (&update_end);
+
+ /* it reports bogus values sometimes, like on opening huge file */
+ if (last_line - first_line < 2000)
+ {
+// g_print ("asking to apply tags on lines %d-%d\n", first_line, last_line);
+ _moo_text_buffer_ensure_highlight (get_moo_buffer (MOO_TEXT_VIEW (text_view)),
+ first_line, last_line);
+ }
+ }
+}
+
+
+static gboolean
+invalidate_rectangle (MooTextView *view)
+{
+ GdkWindow *window;
+ GdkRectangle *rect = view->priv->update_rectangle;
+
+ view->priv->update_rectangle = NULL;
+ view->priv->update_idle = 0;
+
+ gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (view),
+ GTK_TEXT_WINDOW_TEXT,
+ rect->x, rect->y,
+ &rect->x, &rect->y);
+ window = gtk_text_view_get_window (GTK_TEXT_VIEW (view), GTK_TEXT_WINDOW_TEXT);
+ gdk_window_invalidate_rect (window, rect, FALSE);
+
+ g_free (rect);
+ return FALSE;
+}
+
+
+static void
+tags_changed (GtkTextView *text_view,
+ const GtkTextIter *start,
+ const GtkTextIter *end)
+{
+ GdkRectangle visible, changed, update;
+ int y, height;
+ MooTextView *view = MOO_TEXT_VIEW (text_view);
+
+ if (!GTK_WIDGET_DRAWABLE (text_view))
+ return;
+
+ gtk_text_view_get_visible_rect (text_view, &visible);
+
+ gtk_text_view_get_line_yrange (text_view, start, &changed.y, &height);
+ gtk_text_view_get_line_yrange (text_view, end, &y, &height);
+ changed.height = y - changed.y + height;
+ changed.x = visible.x;
+ changed.width = visible.width;
+
+ if (!gdk_rectangle_intersect (&changed, &visible, &update))
+ return;
+
+ if (view->priv->update_rectangle)
+ {
+ gdk_rectangle_union (view->priv->update_rectangle, &update,
+ view->priv->update_rectangle);
+ }
+ else
+ {
+ view->priv->update_rectangle = g_new (GdkRectangle, 1);
+ *view->priv->update_rectangle = update;
+ }
+
+ if (view->priv->in_expose)
+ {
+ if (!view->priv->update_idle)
+ view->priv->update_idle =
+ g_idle_add_full (G_PRIORITY_HIGH_IDLE,
+ (GSourceFunc) invalidate_rectangle,
+ view, NULL);
+ }
+ else
+ {
+ if (view->priv->update_idle)
+ g_source_remove (view->priv->update_idle);
+ view->priv->update_idle = 0;
+
+ invalidate_rectangle (view);
}
}
diff --git a/moo/mooedit/syntax/c.lang b/moo/mooedit/syntax/c.lang
index 710d68dc..09b34061 100644
--- a/moo/mooedit/syntax/c.lang
+++ b/moo/mooedit/syntax/c.lang
@@ -8,7 +8,7 @@
priority="5">
-
+
break
case
continue