]> granicus.if.org Git - neomutt/commitdiff
There is a long-standing problem in Mutt, related to coloring the
authorThomas Roessler <roessler@does-not-exist.org>
Wed, 23 Sep 1998 06:03:55 +0000 (06:03 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Wed, 23 Sep 1998 06:03:55 +0000 (06:03 +0000)
various levels of quoting: if the attributions are missing, like
this:
        >>> blah blah from A
>> blah blah from B
> blah blah from C

then the "quoted" color object is associated with ">>>", "quoted1"
with ">>" and "quoted2" with ">" --- which is not what most people
expect. The reason is Mutt doesn't count the quote characters (since
there is no way to distinguish between a single quote ">> " and a
">" followed by a "> "), and it allocates colors as it finds new
types of quote prefixes. The attached patch fixes this problem still
without counting the quote characters.

pager.c

diff --git a/pager.c b/pager.c
index 5883790123b522c2334549363143e655ad32bf93..6d0e723caa25a35220fad4f6f0491ce14478ca89 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -76,6 +76,7 @@
 struct q_class_t
 {
   int length;
+  int index;
   int color;
   char *prefix;
   struct q_class_t *next, *prev;
@@ -302,6 +303,51 @@ append_line (struct line_t *lineInfo, int n, int cnt)
     cnt + (lineInfo[n].syntax)[0].last : cnt;
 }
 
+static void
+new_class_color (struct q_class_t *class, int *q_level)
+{
+  class->index = (*q_level)++;
+  class->color = ColorQuote[class->index % ColorQuoteUsed];
+}
+
+static void
+shift_class_colors (struct q_class_t *QuoteList, struct q_class_t *new_class,
+                     int index, int *q_level)
+{
+  struct q_class_t * q_list;
+
+  q_list = QuoteList;
+  new_class->index = -1;
+
+  while (q_list)
+  {
+    if (q_list->index >= index)
+    {
+      q_list->index++;
+      q_list->color = ColorQuote[q_list->index % ColorQuoteUsed];
+    }
+    if (q_list->down)
+      q_list = q_list->down;
+    else if (q_list->next)
+      q_list = q_list->next;
+    else
+    {
+      while (!q_list->next)
+      {
+       q_list = q_list->up;
+       if (q_list == NULL)
+         break;
+      }
+      if (q_list)
+       q_list = q_list->next;
+    }
+  }
+
+  new_class->index = index;
+  new_class->color = ColorQuote[index % ColorQuoteUsed];
+  (*q_level)++;
+}
+
 static void
 cleanup_quote (struct q_class_t **QuoteList)
 {
@@ -325,9 +371,10 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
                int length, int *force_redraw, int *q_level)
 {
   struct q_class_t *q_list = *QuoteList;
-  struct q_class_t *class = NULL, *tmp = NULL, *ptr;
+  struct q_class_t *class = NULL, *tmp = NULL, *ptr, *save;
   char *tail_qptr;
   int offset, tail_lng;
+  int index = -1;
 
   /* Did I mention how much I like emulating Lisp in C? */
 
@@ -336,13 +383,14 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
   {
     if (length <= q_list->length)
     {
+      /* case 1: check the top level nodes */
+
       if (strncmp (qptr, q_list->prefix, length) == 0)
       {
-       /* same prefix: return the current class */
        if (length == q_list->length)
-         return q_list;
+         return q_list;        /* same prefix: return the current class */
 
-       /* found shorter common prefix */
+       /* found shorter prefix */
        if (tmp == NULL)
        {
          /* add a node above q_list */
@@ -350,11 +398,6 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
          tmp->prefix = (char *) safe_calloc (1, length + 1);
          strncpy (tmp->prefix, qptr, length);
          tmp->length = length;
-         if (*q_level >= ColorQuoteUsed)
-           *q_level = 1;
-         else
-           (*q_level)++;
-         tmp->color = ColorQuote[(*q_level) - 1];
 
          /* replace q_list by tmp in the top level list */
          if (q_list->next)
@@ -372,7 +415,7 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
          tmp->down = q_list;
          q_list->up = tmp;
 
-         /* q_list has no siblings */
+         /* q_list has no siblings for now */
          q_list->next = NULL;
          q_list->prev = NULL;
 
@@ -380,16 +423,23 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
          if (q_list == *QuoteList)
            *QuoteList = tmp;
 
+         index = q_list->index;
+
          /* tmp should be the return class too */
          class = tmp;
 
-         /* next class to test */
+         /* next class to test; if tmp is a shorter prefix for another
+          * node, that node can only be in the top level list, so don't
+          * go down after this point
+          */
          q_list = tmp->next;
        }
        else
        {
+         /* found another branch for which tmp is a shorter prefix */
+
          /* save the next sibling for later */
-         ptr = q_list->next;
+         save = q_list->next;
 
          /* unlink q_list from the top level list */
          if (q_list->next)
@@ -398,17 +448,22 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
            q_list->prev->next = q_list->next;
 
          /* at this point, we have a tmp->down; link q_list to it */
-         q_list->next = tmp->down;
-         tmp->down->prev = q_list;
-         q_list->prev = NULL;
-         tmp->down = q_list;
+         ptr = tmp->down;
+         /* sibling order is important here, q_list should be linked last */
+         while (ptr->next)
+           ptr = ptr->next;
+         ptr->next = q_list;
+         q_list->next = NULL;
+         q_list->prev = ptr;
          q_list->up = tmp;
 
-         /* next class to test */
-         q_list = ptr;
+         index = q_list->index;
+
+         /* next class to test; as above, we shouldn't go down */
+         q_list = save;
        }
 
-       /* in both cases q_list points now to the next top-level node */
+       /* we found a shorter prefix, so certain quotes have changed classes */
        *force_redraw = 1;
        continue;
       }
@@ -421,10 +476,13 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
     }
     else
     {
-      /* longer than the top level prefix: try subclassing it */
+      /* case 2: try subclassing the current top level node */
+      
+      /* tmp != NULL means we already found a shorter prefix at case 1 */
       if (tmp == NULL && strncmp (qptr, q_list->prefix, q_list->length) == 0)
       {
-       /* ok, we may link it as a subclass */
+       /* ok, it's a subclass somewhere on this branch */
+
        ptr = q_list;
        offset = q_list->length;
 
@@ -451,11 +509,6 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
                tmp->prefix = (char *) safe_calloc (1, length + 1);
                strncpy (tmp->prefix, qptr, length);
                tmp->length = length;
-               if (*q_level >= ColorQuoteUsed)
-                 *q_level = 1;
-               else
-                 (*q_level)++;
-               tmp->color = ColorQuote[(*q_level) - 1];
                        
                /* replace q_list by tmp */
                if (q_list->next)
@@ -480,6 +533,8 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
                q_list->next = NULL;
                q_list->prev = NULL;
                               
+               index = q_list->index;
+
                /* tmp should be the return class too */
                class = tmp;
 
@@ -488,8 +543,10 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
              }
              else
              {
+               /* found another branch for which tmp is a shorter prefix */
+
                /* save the next sibling for later */
-               ptr = q_list->next;
+               save = q_list->next;
 
                /* unlink q_list from the top level list */
                if (q_list->next)
@@ -498,16 +555,21 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
                  q_list->prev->next = q_list->next;
 
                /* at this point, we have a tmp->down; link q_list to it */
-               q_list->next = tmp->down;
-               tmp->down->prev = q_list;
-               q_list->prev = NULL;
-               tmp->down = q_list;
+               ptr = tmp->down;
+               while (ptr->next)
+                 ptr = ptr->next;
+               ptr->next = q_list;
+               q_list->next = NULL;
+               q_list->prev = ptr;
                q_list->up = tmp;
 
+               index = q_list->index;
+
                /* next class to test */
-               q_list = ptr;
+               q_list = save;
              }
 
+             /* we found a shorter prefix, so we need a redraw */
              *force_redraw = 1;
              continue;
            }
@@ -542,18 +604,13 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
          }
        }
 
-       /* if it's still not found so far we mai add it as a sibling */
+       /* still not found so far: add it as a sibling to the current node */
        if (class == NULL)
        {
          tmp = (struct q_class_t *) safe_calloc (1, sizeof (struct q_class_t));
          tmp->prefix = (char *) safe_calloc (1, length + 1);
          strncpy (tmp->prefix, qptr, length);
          tmp->length = length;
-         if (*q_level >= ColorQuoteUsed)
-           *q_level = 1;
-         else
-           (*q_level)++;
-         tmp->color = ColorQuote[(*q_level) - 1];
 
          if (ptr->down)
          {
@@ -562,7 +619,9 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
          }
          ptr->down = tmp;
          tmp->up = ptr;
-         
+
+         new_class_color (tmp, q_level);
+
          return tmp;
        }
        else
@@ -584,11 +643,7 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
     class->prefix = (char *) safe_calloc (1, length + 1);
     strncpy (class->prefix, qptr, length);
     class->length = length;
-    if (*q_level >= ColorQuoteUsed)
-      *q_level = 1;
-    else
-      (*q_level)++;
-    class->color = ColorQuote[(*q_level) - 1];
+    new_class_color (class, q_level);
 
     if (*QuoteList)
     {
@@ -598,6 +653,9 @@ classify_quote (struct q_class_t **QuoteList, const char *qptr,
     *QuoteList = class;
   }
 
+  if (index != -1)
+    shift_class_colors (*QuoteList, tmp, index, q_level);
+
   return class;
 }