]> mj.ucw.cz Git - checkmail.git/commitdiff
Implemented incremental search
authorMartin Mares <mj@ucw.cz>
Sun, 18 Jul 2010 11:07:49 +0000 (13:07 +0200)
committerMartin Mares <mj@ucw.cz>
Sun, 18 Jul 2010 11:07:49 +0000 (13:07 +0200)
cm.c

diff --git a/cm.c b/cm.c
index 12ff25e9ecc1e9125614badb7e66f2755493f465..2d8c6ce1395d6abb7c3b75ad274875a0ce56b109 100644 (file)
--- a/cm.c
+++ b/cm.c
@@ -744,15 +744,19 @@ static void x11_cleanup(void) { }
 
 static int cursor_at, cursor_max;
 
+static unsigned is_active, is_pos;     // incremental search
+static char is_buf[64];
+
 enum {
   M_IDLE,
   M_SCAN,
   M_NEW,
   M_FLAG,
   M_BAD,
+  M_INCSEARCH,
   M_MAX
 };
-static int attrs[2][2][M_MAX];         // active, hilite, status
+static int attrs[3][2][M_MAX];         // active (2=incsearch), hilite, status
 
 static void
 redraw_line(int i)
@@ -761,8 +765,10 @@ redraw_line(int i)
   if (i < cursor_max)
     {
       struct mbox *b = mbox_array[i];
-      int cc = (cursor_at == i);
+      int cc = (cursor_at == i ? (is_active ? 2 : 1) : 0);
       int hi = b->o.highlight;
+      unsigned namepos = 0;
+      unsigned namelen = strlen(b->name);
 
       attrset(attrs[cc][hi][M_IDLE]);
       if (b->o.hotkey)
@@ -771,11 +777,22 @@ redraw_line(int i)
        printw("> ");
       else
        printw("  ");
+      if (cc == 2)
+       {
+         attrset(attrs[cc][hi][M_INCSEARCH]);
+         for (namepos=0; namepos < is_pos && namepos < 20; namepos++)
+           addch(is_buf[namepos]);
+       }
       if (b->new)
        attrset(attrs[cc][hi][M_NEW]);
       else if (b->flagged && b->o.show_flagged)
        attrset(attrs[cc][hi][M_FLAG]);
-      printw("%-20s ", b->name);
+      else
+       attrset(attrs[cc][hi][M_IDLE]);
+      while (namepos < namelen)
+       addch(b->name[namepos++]);
+      while (namepos++ < 20)
+       addch(' ');
       if (b->scanning < 0)
        ;
       else if (b->scanning)
@@ -915,20 +932,31 @@ term_init(void)
   curs_set(0);
 
   static const int attrs_mono[2][M_MAX] = {
-    [0] = { [M_IDLE] = 0, [M_SCAN] = A_BOLD, [M_NEW] = A_BOLD, [M_FLAG] = 0, [M_BAD] = A_DIM },
-    [1] = { [M_IDLE] = 0, [M_SCAN] = A_BOLD, [M_NEW] = A_REVERSE | A_BOLD, [M_FLAG] = A_REVERSE, [M_BAD] = A_DIM },
+       [0] = { [M_IDLE] = 0,
+               [M_SCAN] = A_BOLD,
+               [M_NEW] = A_BOLD,
+               [M_FLAG] = 0,
+               [M_BAD] = A_DIM,
+               [M_INCSEARCH] = A_REVERSE },
+       [1] = { [M_IDLE] = 0,
+               [M_SCAN] = A_BOLD,
+               [M_NEW] = A_REVERSE | A_BOLD,
+               [M_FLAG] = A_REVERSE,
+               [M_BAD] = A_DIM,
+               [M_INCSEARCH] = A_REVERSE },
   };
   for (int i=0; i<2; i++)
     for (int j=0; j<M_MAX; j++)
       {
        attrs[0][i][j] = attrs_mono[i][j];
        attrs[1][i][j] = attrs_mono[i][j] | A_UNDERLINE;
+       attrs[2][i][j] = attrs_mono[i][j] | A_UNDERLINE;
       }
 
   if (has_colors())
     {
       start_color();
-      if (COLOR_PAIRS >= 5)
+      if (COLOR_PAIRS >= 12)
        {
          init_pair(1, COLOR_YELLOW, COLOR_BLACK);
          init_pair(2, COLOR_RED, COLOR_BLACK);
@@ -937,11 +965,44 @@ term_init(void)
          init_pair(5, COLOR_RED, COLOR_BLUE);
          init_pair(6, COLOR_GREEN, COLOR_BLACK);
          init_pair(7, COLOR_GREEN, COLOR_BLUE);
-         static const int attrs_color[2][2][M_MAX] = {
-           [0][0] = { [M_IDLE] = 0, [M_SCAN] = COLOR_PAIR(1), [M_NEW] = COLOR_PAIR(1), [M_FLAG] = COLOR_PAIR(6), [M_BAD] = COLOR_PAIR(2) },
-           [0][1] = { [M_IDLE] = A_BOLD, [M_SCAN] = COLOR_PAIR(1), [M_NEW] = COLOR_PAIR(1) | A_BOLD, [M_FLAG] = COLOR_PAIR(6) | A_BOLD, [M_BAD] = COLOR_PAIR(2) | A_BOLD },
-           [1][0] = { [M_IDLE] = COLOR_PAIR(3), [M_SCAN] = COLOR_PAIR(4), [M_NEW] = COLOR_PAIR(4), [M_FLAG] = COLOR_PAIR(7), [M_BAD] = COLOR_PAIR(5) },
-           [1][1] = { [M_IDLE] = COLOR_PAIR(3) | A_BOLD, [M_SCAN] = COLOR_PAIR(4), [M_NEW] = COLOR_PAIR(4) | A_BOLD, [M_FLAG] = COLOR_PAIR(7) | A_BOLD, [M_BAD] = COLOR_PAIR(5) | A_BOLD },
+         init_pair(8, COLOR_WHITE, COLOR_MAGENTA);
+         init_pair(9, COLOR_YELLOW, COLOR_MAGENTA);
+         init_pair(10, COLOR_GREEN, COLOR_MAGENTA);
+         init_pair(11, COLOR_RED, COLOR_MAGENTA);
+         init_pair(12, COLOR_BLACK, COLOR_YELLOW);
+         static const int attrs_color[3][2][M_MAX] = {
+            [0][0] = { [M_IDLE] = 0,
+                       [M_SCAN] = COLOR_PAIR(1),
+                       [M_NEW] = COLOR_PAIR(1),
+                       [M_FLAG] = COLOR_PAIR(6),
+                       [M_BAD] = COLOR_PAIR(2) },
+            [0][1] = { [M_IDLE] = A_BOLD,
+                       [M_SCAN] = COLOR_PAIR(1),
+                       [M_NEW] = COLOR_PAIR(1) | A_BOLD,
+                       [M_FLAG] = COLOR_PAIR(6) | A_BOLD,
+                       [M_BAD] = COLOR_PAIR(2) | A_BOLD },
+            [1][0] = { [M_IDLE] = COLOR_PAIR(3),
+                       [M_SCAN] = COLOR_PAIR(4),
+                       [M_NEW] = COLOR_PAIR(4),
+                       [M_FLAG] = COLOR_PAIR(7),
+                       [M_BAD] = COLOR_PAIR(5) },
+            [1][1] = { [M_IDLE] = COLOR_PAIR(3) | A_BOLD,
+                       [M_SCAN] = COLOR_PAIR(4),
+                       [M_NEW] = COLOR_PAIR(4) | A_BOLD,
+                       [M_FLAG] = COLOR_PAIR(7) | A_BOLD,
+                       [M_BAD] = COLOR_PAIR(5) | A_BOLD },
+            [2][0] = { [M_IDLE] = COLOR_PAIR(8),
+                       [M_SCAN] = COLOR_PAIR(9),
+                       [M_NEW] = COLOR_PAIR(9),
+                       [M_FLAG] = COLOR_PAIR(10),
+                       [M_BAD] = COLOR_PAIR(11),
+                       [M_INCSEARCH] = COLOR_PAIR(12) | A_DIM },
+            [2][1] = { [M_IDLE] = COLOR_PAIR(8) | A_BOLD,
+                       [M_SCAN] = COLOR_PAIR(9),
+                       [M_NEW] = COLOR_PAIR(9) | A_BOLD,
+                       [M_FLAG] = COLOR_PAIR(10) | A_BOLD,
+                       [M_BAD] = COLOR_PAIR(11) | A_BOLD,
+                       [M_INCSEARCH] = COLOR_PAIR(12) },
          };
          memcpy(attrs, attrs_color, sizeof(attrs));
        }
@@ -1023,6 +1084,53 @@ mbox_run(struct mbox *b)
   scan_and_redraw();
 }
 
+static void
+enter_incsearch(void)
+{
+  print_status("Incremental search...");
+  is_active = 1;
+  is_pos = 0;
+  redraw_line(cursor_at);
+}
+
+static int
+handle_incsearch(int ch)
+{
+  if ((ch == KEY_BACKSPACE || ch == KEY_DC) && is_pos)
+    --is_pos;
+  else if (ch >= ' ' && ch <= '~')
+    {
+      if (is_pos < sizeof(is_buf) - 1)
+       is_buf[is_pos++] = ch;
+    }
+  else
+    {
+      print_status("");
+      is_active = 0;
+      is_pos = 0;
+      redraw_line(cursor_at);
+      return 0;
+    }
+
+  is_buf[is_pos] = 0;
+  for (int i=0; i<cursor_max; i++)
+    {
+      struct mbox *b = mbox_array[i];
+      if (!strncmp(b->name, is_buf, is_pos))
+       {
+         if (i != cursor_at)
+           {
+             move_cursor(i);
+             return 1;
+           }
+         break;
+       }
+    }
+
+  redraw_line(cursor_at);
+  return 1;
+}
+
 #define STR2(c) #c
 #define STR(c) STR2(c)
 
@@ -1186,6 +1294,13 @@ restart:
          remains *= 10;
          halfdelay((remains > 255) ? 255 : remains);
          int ch = getch();
+         if (ch < 0)
+           continue;
+         if (is_active && handle_incsearch(ch))
+           {
+             refresh();
+             continue;
+           }
          for (int i=0; i<num_mboxes; i++)
            if (ch == mbox_array[i]->o.hotkey)
              {
@@ -1252,6 +1367,9 @@ restart:
              allow_osd = 0;
              print_status("On-screen display is now disabled. Watch your step.");
              break;
+           case '/':
+             enter_incsearch();
+             break;
            default:
              if (ch >= '0' && ch <= '9')
                {