]> granicus.if.org Git - neomutt/commitdiff
merge: status-color
authorRichard Russon <rich@flatcap.org>
Thu, 16 Jun 2016 14:43:12 +0000 (15:43 +0100)
committerRichard Russon <rich@flatcap.org>
Thu, 16 Jun 2016 14:43:12 +0000 (15:43 +0100)
 * rework mutt_draw_statusline()

1  2 
curs_main.c
protos.h

diff --cc curs_main.c
index 4967c9dac6becda67406d9710f549a9c48c75385,0d7783270b1db013fd4f36ba954c46643f222d06..3f8191aa889423fa9e4936e2c9edeee8d1d7276e
@@@ -533,152 -509,79 +525,159 @@@ mutt_draw_statusline (int cols, const c
                if (!buf[offset])
                        break;
  
-               while (color_line) {
-                       regmatch_t pmatch[color_line->match + 1];
-                       if (regexec (&color_line->rx, buf + offset, color_line->match + 1, pmatch, (offset ? REG_NOTBOL : 0)) == 0) {
-                               if (pmatch[color_line->match].rm_eo != pmatch[color_line->match].rm_so) {
-                                       if (!found) {
-                                               if (++(lineInfo.chunks) > 1) {
-                                                       safe_realloc (&(lineInfo.syntax), (lineInfo.chunks) * sizeof (struct syntax_t));
-                                               }
-                                       }
-                                       i = lineInfo.chunks - 1;
-                                       pmatch[color_line->match].rm_so += offset;
-                                       pmatch[color_line->match].rm_eo += offset;
-                                       if (!found ||
-                                               (pmatch[color_line->match].rm_so < (lineInfo.syntax)[i].first) ||
-                                               ((pmatch[color_line->match].rm_so == (lineInfo.syntax)[i].first) &&
-                                               (pmatch[color_line->match].rm_eo > (lineInfo.syntax)[i].last))) {
-                                               (lineInfo.syntax)[i].color = color_line->pair;
-                                               (lineInfo.syntax)[i].first = pmatch[color_line->match].rm_so;
-                                               (lineInfo.syntax)[i].last = pmatch[color_line->match].rm_eo;
-                                       }
-                                       found = 1;
-                                       null_rx = 0;
-                               } else {
-                                       null_rx = 1; /* empty regexp; don't add it, but keep looking */
-                               }
+               /* loop through each "color status regex" */
+               for (cl = ColorStatusList; cl; cl = cl->next) {
+                       regmatch_t pmatch[cl->match + 1];
+                       if (regexec (&cl->rx, buf + offset, cl->match + 1, pmatch, 0) != 0)
+                               continue;       /* regex doesn't match the status bar */
+                       int first = pmatch[cl->match].rm_so + offset;
+                       int last  = pmatch[cl->match].rm_eo + offset;
+                       if (first == last)
+                               continue;       /* ignore an empty regex */
+                       if (!found) {
+                               chunks++;
+                               safe_realloc (&syntax, chunks * sizeof (struct syntax_t));
                        }
-                       color_line = color_line->next;
-               }
  
-               if (null_rx)
-                       offset++; /* avoid degenerate cases */
-               else
-                       offset = (lineInfo.syntax)[i].last;
-       } while (found || null_rx);
-       for (cnt = 0; cnt < mutt_strlen (buf); cnt++) {
-               color = lineInfo.syntax[0].color;
-               for (i = 0; i < lineInfo.chunks; i++) {
-                       /* we assume the chunks are sorted */
-                       if (cnt > (lineInfo.syntax)[i].last)
-                               continue;
-                       if (cnt < (lineInfo.syntax)[i].first)
-                               break;
-                       if (cnt != (lineInfo.syntax)[i].last) {
-                               color = (lineInfo.syntax)[i].color;
-                               break;
+                       i = chunks - 1;
+                       if (!found || (first < syntax[i].first) || ((first == syntax[i].first) && (last > syntax[i].last))) {
+                               syntax[i].color = cl->pair;
+                               syntax[i].first = first;
+                               syntax[i].last  = last;
                        }
-                       /* don't break here, as cnt might be in the next chunk as well */
+                       found = 1;
                }
-               if (color != last_color) {
-                       attrset (color);
-                       last_color = color;
+               if (syntax) {
+                       offset = syntax[i].last;
                }
-               /* XXX more than one char at a time? */
-               addch ((unsigned char)buf[cnt]);
- #if 0
-               waddnstr (stdscr, tgbuf, 10);
-               SETCOLOR (MT_COLOR_NORMAL);
-               waddnstr (stdscr, tgbuf + 10, -1);
- #endif
+       } while (found);
+       int len = mutt_strlen (buf);
+       int base = 0;
+       if ((chunks > 0) && (syntax[0].first > 0)) {
+               /* Text before the first highlight */
+               addnstr (buf, syntax[0].first);
+               attrset (ColorDefs[MT_COLOR_STATUS]);
+               base = syntax[0].first;
+       }
+       for (i = 0; i < chunks; i++) {
+               /* Highlighted text */
+               attrset (syntax[i].color);
+               addnstr (buf + base, syntax[i].last - base);
+               if ((i + 1) == chunks) {
+                       base = len;
+               } else {
+                       base = syntax[i+1].first;
+               }
+               if (syntax[i].last < base) {
+                       /* Normal (un-highlighted) text */
+                       attrset (ColorDefs[MT_COLOR_STATUS]);
+                       addnstr (buf + syntax[i].last, base - syntax[i].last);
+               }
+       }
+       attrset (ColorDefs[MT_COLOR_STATUS]);
+       if (base < len) {
+               /* Text after the last highlight */
+               addnstr (buf + base, len - base);
+       }
+       int width = mutt_strwidth (buf);
+       if (width < cols) {
+               /* Pad the rest of the line with whitespace */
+               mutt_paddstr (cols - width, "");
        }
  
-       safe_free (&lineInfo.syntax);
+       safe_free (&syntax);
  }
  
 +static int main_change_folder(MUTTMENU *menu, int op, char *buf, size_t bufsz,
 +                        int *oldcount, int *index_hint, int flags)
 +{
 +#ifdef USE_NNTP
 +  if (option (OPTNEWS))
 +  {
 +    unset_option (OPTNEWS);
 +    nntp_expand_path (buf, bufsz, &CurrentNewsSrv->conn->account);
 +  }
 +  else
 +#endif
 +  mutt_expand_path (buf, bufsz);
 +#ifdef USE_SIDEBAR
 +  mutt_sb_set_open_buffy (buf);
 +#endif
 +  if (mx_get_magic (buf) <= 0)
 +  {
 +    mutt_error (_("%s is not a mailbox."), buf);
 +    return -1;
 +  }
 +  mutt_str_replace (&CurrentFolder, buf);
 +
 +  /* keepalive failure in mutt_enter_fname may kill connection. #3028 */
 +  if (Context && !Context->path)
 +    FREE (&Context);
 +
 +  if (Context)
 +  {
 +    int check;
 +
 +#ifdef USE_COMPRESSED
 +        if (Context->compress_info && Context->realpath)
 +          mutt_str_replace (&LastFolder, Context->realpath);
 +        else
 +#endif
 +    mutt_str_replace (&LastFolder, Context->path);
 +    *oldcount = Context ? Context->msgcount : 0;
 +
 +    if ((check = mx_close_mailbox (Context, index_hint)) != 0)
 +    {
 +      if (check == M_NEW_MAIL || check == M_REOPENED)
 +        update_index (menu, Context, check, *oldcount, *index_hint);
 +
 +      set_option (OPTSEARCHINVALID);
 +      menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
 +      return 0;
 +    }
 +    FREE (&Context);
 +  }
 +
 +  if (Labels)
 +    hash_destroy(&Labels, NULL);
 +
 +  mutt_sleep (0);
 +
 +  /* Set CurrentMenu to MENU_MAIN before executing any folder
 +   * hooks so that all the index menu functions are available to
 +   * the exec command.
 +   */
 +
 +  CurrentMenu = MENU_MAIN;
 +  mutt_folder_hook (buf);
 +
 +  if ((Context = mx_open_mailbox (buf, flags, NULL)) != NULL)
 +  {
 +    Labels = hash_create(131, 0);
 +    mutt_scan_labels(Context);
 +    menu->current = ci_first_message ();
 +  }
 +  else
 +    menu->current = 0;
 +
 +  mutt_clear_error ();
 +  mutt_buffy_check(1); /* force the buffy check after we have changed the folder */
 +  menu->redraw = REDRAW_FULL;
 +  set_option (OPTSEARCHINVALID);
 +
 +  return 0;
 +}
 +
  static const struct mapping_t IndexHelp[] = {
    { N_("Quit"),  OP_QUIT },
    { N_("Del"),   OP_DELETE },
diff --cc protos.h
Simple merge