diff -r 91d92ba286a1 gtksourceview/gtksourcecontextengine.c --- a/gtksourceview/gtksourcecontextengine.c Fri May 26 07:23:33 2006 +++ b/gtksourceview/gtksourcecontextengine.c Fri May 26 18:33:58 2006 @@ -377,8 +377,8 @@ Context *root_context; /* Modifications that need to be done asynchronously. The - * elements in the queue are pointers to Modify. */ - GQueue *modifications; + * elements in the list are pointers to Modify. */ + GSList *modifications; gint worker_last_offset; gint worker_batch_size; @@ -418,7 +418,11 @@ static void text_modified (GtkSourceContextEngine *ce, gint offset, gint delta); -static gboolean async_modify (GtkSourceContextEngine *ce); +static void push_modification (GtkSourceContextEngine *ce, + Modify *m); +static Modify *pop_modification (GtkSourceContextEngine *ce); +static void clear_modifications (GtkSourceContextEngine *ce); +static gboolean async_modify (GtkSourceContextEngine *ce); static void update_syntax (GtkSourceContextEngine *ce, const GtkTextIter *needed_end, gint modification_offset, @@ -475,7 +479,7 @@ g_free, (GDestroyNotify)definition_free); ce->priv->root_context = NULL; ce->priv->buffer = NULL; - ce->priv->modifications = g_queue_new (); + ce->priv->modifications = NULL; } static void @@ -498,7 +502,8 @@ context_destroy (ce->priv->root_context); g_hash_table_destroy (ce->priv->definitions); - g_queue_free (ce->priv->modifications); + + clear_modifications (ce); g_free (ce->priv->id); @@ -778,8 +783,6 @@ /* Detach previous buffer if there is one. */ if (ce->priv->buffer != NULL) { - gpointer modify; - enable_highlight (ce, FALSE); /* Disconnect signals. */ @@ -807,21 +810,20 @@ ce->priv->refresh_region = NULL; ce->priv->highlight_requests = NULL; - while ((modify = g_queue_pop_head (ce->priv->modifications))) - g_free (modify); + clear_modifications (ce); } ce->priv->buffer = buffer; if (buffer != NULL) { + gchar *root_id; ContextDefinition *main_definition; /* Retrieve references to all text tags. */ sync_with_tag_table (ce); /* Create the root context. */ - gchar *root_id; root_id = g_strdup_printf ("%s:%s", ce->priv->id, ce->priv->id); main_definition = g_hash_table_lookup (ce->priv->definitions, root_id); @@ -884,9 +886,8 @@ static Regex * regex_ref (Regex *regex) { - if (regex == NULL) - return NULL; - regex->ref_count++; + if (regex != NULL) + regex->ref_count++; return regex; } @@ -1660,14 +1661,15 @@ * * @context: a #Context. * - * Removes @context from the contexts' tree containing it. After the tree - * has been removed it can be deleted with context_destroy(). + * Removes @context from the contexts' tree containing it. + * If @destroy is true the context and his children are destroyed + * and NULL si returned, otherwise the detached subtree is returned. */ -static void -context_remove (Context *context) -{ - if (context->parent == NULL) - return; +static Context * +context_remove (Context *context, gboolean destroy) +{ + /* can't remove the root */ + g_assert (context->parent != NULL); if (context->prev != NULL) context->prev->next = context->next; @@ -1677,9 +1679,18 @@ if (context->next != NULL) context->next->prev = context->prev; - context_set_last_sibling (context, NULL); - context->prev = context->next = NULL; - context->parent = NULL; + if (!destroy) + { + context_set_last_sibling (context, NULL); + context->prev = context->next = NULL; + context->parent = NULL; + return context; + } + else + { + context_destroy (context); + return NULL; + } } /** @@ -1715,7 +1726,7 @@ g_return_val_if_fail (ce->priv->buffer != NULL, FALSE); - if (!g_queue_is_empty (ce->priv->modifications)) + if (ce->priv->modifications != NULL) /* Do asynchronous modifications. */ async_modify (ce); else if (ce->priv->worker_last_offset >= 0) @@ -1767,7 +1778,7 @@ } if (ce->priv->worker_last_offset < 0 && - g_queue_is_empty (ce->priv->modifications)) + ce->priv->modifications == NULL) { /* Idle handler will be removed. */ ce->priv->worker_handler = 0; @@ -1972,37 +1983,119 @@ gint offset, gint delta) { - if (ABS (delta) == 1 && g_queue_is_empty (ce->priv->modifications)) + if (ABS (delta) == 1 && ce->priv->modifications == NULL) { update_syntax (ce, NULL, offset, delta); } else { - Modify *modify = g_queue_peek_tail (ce->priv->modifications); - if (modify != NULL && - SIGN (modify->delta) == SIGN (delta) && - ((delta > 0 && modify->offset + modify->delta == offset) || - (delta < 0 && modify->offset + delta == offset))) - { - /* The two modifications can be joined in a - * single one. */ - modify->offset = MIN (modify->offset, offset); - modify->delta += delta; - } - else - { - modify = g_new0 (Modify, 1); - modify->delta = delta; - modify->offset = offset; - g_queue_push_tail (ce->priv->modifications, modify); - install_idle_worker (ce); - } - } + Modify *modify; + modify = g_new0 (Modify, 1); + modify->delta = delta; + modify->offset = offset; + push_modification (ce, modify); + install_idle_worker (ce); + } +} + +static void +print_modifications (GtkSourceContextEngine *ce) +{ + GSList *l; + + if (ce->priv->modifications == NULL) + { + g_print ("mods list empty\n"); + return; + } + + for (l = ce->priv->modifications; l; l = l->next) + g_print ("(%d, %d)", ((Modify *) l->data)->offset, ((Modify *) l->data)->delta); + + g_print ("\n"); +} + +static void +push_modification (GtkSourceContextEngine *ce, Modify *m) +{ + GSList *l; + GSList *tmp = NULL; + + g_print ("pre push:"); print_modifications (ce); + + /* the modifications list should always be ordered by offset. + * note that offsets of modifications following the inserted + * one need to be updated. TODO: merge overlapping mods??. + */ + + if (ce->priv->modifications == NULL) + { + ce->priv->modifications = g_slist_append (ce->priv->modifications, + m); + return; + } + + /* find the right spot */ + for (l = ce->priv->modifications; l != NULL; l = l->next) + { + Modify *m2 = l->data; + + if (m->offset > m2->offset + m2->delta) + { + tmp = l; + break; + } + } + + /* insert */ + if (tmp != NULL) + ce->priv->modifications = g_slist_insert_before (ce->priv->modifications, + tmp, + m); + else + ce->priv->modifications = g_slist_prepend (ce->priv->modifications, + m); + + /* update the following modifications */ + for (l = tmp; l != NULL; l = l->next) + { + Modify *m2 = l->data; + m2->offset += m2->delta; + } + + g_print ("post push:"); print_modifications (ce); +} + +static Modify * +pop_modification (GtkSourceContextEngine *ce) +{ + g_print ("pre pop:"); print_modifications (ce); + + if (ce->priv->modifications) + { + Modify *m = ce->priv->modifications->data; + ce->priv->modifications = g_slist_delete_link (ce->priv->modifications, + ce->priv->modifications); + + g_print ("post pop:"); print_modifications (ce); + return m; + } + + g_print ("post pop:"); print_modifications (ce); + + return NULL; +} + +static void +clear_modifications (GtkSourceContextEngine *ce) +{ + g_slist_foreach (ce->priv->modifications, (GFunc) g_free, NULL); + g_slist_free (ce->priv->modifications); + ce->priv->modifications = NULL; } /** * async_modify: - * * @ce: a #GtkSourceContextEngine. * * Does a single asynchronous modification. @@ -2016,12 +2109,19 @@ Modify *modify; gboolean clean_updates; - modify = g_queue_pop_head (ce->priv->modifications); + g_print ("async modify\n"); + + modify = pop_modification (ce); if (modify == NULL) return FALSE; update_syntax (ce, NULL, modify->offset, modify->delta); + g_free (modify); + +// What the fuck does this??? + +#if 0 /* If we have not updated all the tree in a single step, the * modifications after ce->priv->worker_last_offset are no more * needed. */ @@ -2029,6 +2129,7 @@ ce->priv->worker_last_offset < modify->offset + MAX (modify->delta, 0); g_free (modify); + if (clean_updates) { gint n_del = 0; @@ -2060,6 +2161,7 @@ ce->priv->modifications->length -= n_del; ce->priv->modifications->tail = g_list_last (ce->priv->modifications->head); } +#endif return TRUE; } @@ -2378,8 +2480,7 @@ } else { - context_remove (new_context); - context_destroy (new_context); + context_remove (new_context, TRUE); return FALSE; } } @@ -2416,8 +2517,7 @@ } else { - context_remove (new_context); - context_destroy (new_context); + context_remove (new_context, TRUE); return FALSE; } } @@ -3531,15 +3631,10 @@ { Context *wrong_context = get_next_context (current_state, text_starts_at); - if (wrong_context != NULL) - { - context_remove (wrong_context); - context_destroy (wrong_context); - } - else - { + if (wrong_context == NULL) break; - } + + context_remove (wrong_context, TRUE); } /* MAIN LOOP: build the tree. */