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