Ticket #2076: patch-1.5.11.tamo.patterns.3

File patch-1.5.11.tamo.patterns.3, 12.1 kB (added by anonymous, 17 months ago)

patch-1.5.11.tamo.patterns.3

Line 
1diff -r 1e1c7c437979 -r 1482d7450916 curs_lib.c
2--- a/curs_lib.c        Mon Sep 19 06:22:55 2005
3+++ b/curs_lib.c        Mon Sep 19 12:23:52 2005
4@@ -130,6 +130,7 @@
5     mutt_refresh ();
6     getyx (stdscr, y, x);
7     ret = _mutt_enter_string (buf, buflen, y, x, complete, multiple, files, numfiles, es);
8+    complete &= ~(M_CLEAR);
9   }
10   while (ret == 1);
11   CLEARLINE (LINES-1);
12--- a/curs_main.c       Mon Sep 19 06:22:55 2005
13+++ b/curs_main.c       Mon Sep 19 12:23:52 2005
14@@ -811,7 +811,7 @@
15 
16        CHECK_ATTACH;
17        mutt_pattern_func (M_DELETE, _("Delete messages matching: "));
18-       menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
19+       menu->redraw = REDRAW_FULL;
20        break;
21 
22 #ifdef USE_POP
23@@ -866,8 +874,8 @@
24          menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
25          if (Context->msgcount && (Sort & SORT_MASK) == SORT_THREADS)
26            mutt_draw_tree (Context);
27-         menu->redraw = REDRAW_FULL;
28-       }
29+       }
30+       menu->redraw = REDRAW_FULL;
31        break;   
32 
33       case OP_QUIT:
34@@ -915,6 +923,8 @@
35          menu->current = menu->oldcurrent;
36        else
37          menu->redraw = REDRAW_MOTION;
38+       if (op == OP_SEARCH || op == OP_SEARCH_REVERSE)
39+         menu->redraw = REDRAW_FULL;
40        break;
41 
42       case OP_SORT:
43@@ -964,7 +974,7 @@
44        CHECK_MSGCOUNT;
45         CHECK_VISIBLE;
46        mutt_pattern_func (M_TAG, _("Tag messages matching: "));
47-       menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
48+       menu->redraw = REDRAW_FULL;
49        break;
50 
51       case OP_MAIN_UNDELETE_PATTERN:
52@@ -977,16 +987,16 @@
53 CHECK_IMAP_ACL(IMAP_ACL_DELETE);
54 #endif
55 
56-       if (mutt_pattern_func (M_UNDELETE, _("Undelete messages matching: ")) == 0)
57-         menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
58+       mutt_pattern_func (M_UNDELETE, _("Undelete messages matching: "));
59+       menu->redraw = REDRAW_FULL;
60        break;
61 
62       case OP_MAIN_UNTAG_PATTERN:
63 
64        CHECK_MSGCOUNT;
65         CHECK_VISIBLE;
66-       if (mutt_pattern_func (M_UNTAG, _("Untag messages matching: ")) == 0)
67-         menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
68+       mutt_pattern_func (M_UNTAG, _("Untag messages matching: "));
69+       menu->redraw = REDRAW_FULL;
70        break;
71 
72        /* --------------------------------------------------------------------
73diff -r 1e1c7c437979 -r 1482d7450916 enter.c
74--- a/enter.c   Mon Sep 19 06:22:55 2005
75+++ b/enter.c   Mon Sep 19 12:23:52 2005
76@@ -567,6 +567,17 @@
77            else
78              BEEP (); /* let the user know that nothing matched */
79            replace_part (state, 0, buf);
80+         }
81+         else if (flags & M_PATTERN)
82+         {
83+           if ((i = state->curpos) && state->wbuf[i - 1] == '~')
84+           {
85+             if (mutt_ask_pattern (buf, buflen))
86+               replace_part (state, i, buf);
87+             rv = 1;
88+             goto bye;
89+           }
90+           goto self_insert;
91          }
92          else
93            goto self_insert;
94diff -r 1e1c7c437979 -r 1482d7450916 pattern.c
95--- a/pattern.c Mon Sep 19 06:22:55 2005
96+++ b/pattern.c Mon Sep 19 12:23:52 2005
97@@ -25,6 +25,8 @@
98 #include "keymap.h"
99 #include "mailbox.h"
100 #include "copy.h"
101+#include "mutt_menu.h"
102+#include "mutt_curses.h"
103 
104 #include <string.h>
105 #include <stdlib.h>
106@@ -45,56 +47,101 @@
107 static int eat_range (pattern_t *pat, BUFFER *, BUFFER *);
108 static int patmatch (const pattern_t *pat, const char *buf);
109 
110+#define EAT_REGEXP     1
111+#define EAT_DATE       2
112+#define EAT_RANGE      3
113 struct pattern_flags
114 {
115   int tag;     /* character used to represent this op */
116   int op;      /* operation to perform */
117   int class;
118-  int (*eat_arg) (pattern_t *, BUFFER *, BUFFER *);
119+  int eat_arg;
120+  char *desc;
121 }
122 Flags[] =
123 {
124-  { 'A', M_ALL,                        0,              NULL },
125-  { 'b', M_BODY,               M_FULL_MSG,     eat_regexp },
126-  { 'B', M_WHOLE_MSG,          M_FULL_MSG,     eat_regexp },
127-  { 'c', M_CC,                 0,              eat_regexp },
128-  { 'C', M_RECIPIENT,          0,              eat_regexp },
129-  { 'd', M_DATE,               0,              eat_date },
130-  { 'D', M_DELETED,            0,              NULL },
131-  { 'e', M_SENDER,             0,              eat_regexp },
132-  { 'E', M_EXPIRED,            0,              NULL },
133-  { 'f', M_FROM,               0,              eat_regexp },
134-  { 'F', M_FLAG,               0,              NULL },
135-  { 'g', M_CRYPT_SIGN,         0,              NULL },
136-  { 'G', M_CRYPT_ENCRYPT,      0,              NULL },
137-  { 'h', M_HEADER,             M_FULL_MSG,     eat_regexp },
138-  { 'H', M_HORMEL,             0,              eat_regexp },
139-  { 'i', M_ID,                 0,              eat_regexp },
140-  { 'k', M_PGP_KEY,            0,              NULL },
141-  { 'l', M_LIST,               0,              NULL },
142-  { 'L', M_ADDRESS,            0,              eat_regexp },
143-  { 'm', M_MESSAGE,            0,              eat_range },
144-  { 'n', M_SCORE,              0,              eat_range },
145-  { 'N', M_NEW,                        0,              NULL },
146-  { 'O', M_OLD,                        0,              NULL },
147-  { 'p', M_PERSONAL_RECIP,     0,              NULL },
148-  { 'P', M_PERSONAL_FROM,      0,              NULL },
149-  { 'Q', M_REPLIED,            0,              NULL },
150-  { 'r', M_DATE_RECEIVED,      0,              eat_date },
151-  { 'R', M_READ,               0,              NULL },
152-  { 's', M_SUBJECT,            0,              eat_regexp },
153-  { 'S', M_SUPERSEDED,         0,              NULL },
154-  { 't', M_TO,                 0,              eat_regexp },
155-  { 'T', M_TAG,                        0,              NULL },
156-  { 'u', M_SUBSCRIBED_LIST,    0,              NULL },
157-  { 'U', M_UNREAD,             0,              NULL },
158-  { 'v', M_COLLAPSED,          0,              NULL },
159-  { 'V', M_CRYPT_VERIFIED,     0,              NULL },
160-  { 'x', M_REFERENCE,          0,              eat_regexp },
161-  { 'y', M_XLABEL,             0,              eat_regexp },
162-  { 'z', M_SIZE,               0,              eat_range },
163-  { '=', M_DUPLICATED,         0,              NULL },
164-  { '$', M_UNREFERENCED,       0,              NULL },
165+  { 'A', M_ALL,                        0,              0,
166+       N_("all messages") },
167+  { 'b', M_BODY,               M_FULL_MSG,     EAT_REGEXP,
168+       N_("messages whose body matches EXPR") },
169+  { 'B', M_WHOLE_MSG,          M_FULL_MSG,     EAT_REGEXP,
170+       N_("messages whose body or headers match EXPR") },
171+  { 'c', M_CC,                 0,              EAT_REGEXP,
172+       N_("messages whose CC header matches EXPR") },
173+  { 'C', M_RECIPIENT,          0,              EAT_REGEXP,
174+       N_("messages whose recipient matches EXPR") },
175+  { 'd', M_DATE,               0,              EAT_DATE,
176+       N_("messages sent in DATERANGE") },
177+  { 'D', M_DELETED,            0,              0,
178+       N_("deleted messages") },
179+  { 'e', M_SENDER,             0,              EAT_REGEXP,
180+       N_("messages whose Sender header matches EXPR") },
181+  { 'E', M_EXPIRED,            0,              0,
182+       N_("expired messages") },
183+  { 'f', M_FROM,               0,              EAT_REGEXP,
184+       N_("messages whose From header matches EXPR") },
185+  { 'F', M_FLAG,               0,              0,
186+       N_("flagged messages") },
187+  { 'g', M_CRYPT_SIGN,                 0,              0,
188+       N_("cryptographically signed messages") },
189+  { 'G', M_CRYPT_ENCRYPT,      0,              0,
190+       N_("cryptographically encrypted messages") },
191+  { 'h', M_HEADER,             M_FULL_MSG,     EAT_REGEXP,
192+       N_("messages whose header matches EXPR") },
193+  { 'H', M_HORMEL,             0,              EAT_REGEXP,
194+       N_("messages whose spam tag matches EXPR") },
195+  { 'i', M_ID,                 0,              EAT_REGEXP,
196+       N_("messages whose Message-ID matches EXPR") },
197+  { 'k', M_PGP_KEY,            0,              0,
198+       N_("messages which contain PGP key") },
199+  { 'l', M_LIST,               0,              0,
200+       N_("messages addressed to known mailing lists") },
201+  { 'L', M_ADDRESS,            0,              EAT_REGEXP,
202+       N_("messages whose From/Sender/To/CC matches EXPR") },
203+  { 'm', M_MESSAGE,            0,              EAT_RANGE,
204+       N_("messages whose number is in RANGE") },
205+  { 'n', M_SCORE,              0,              EAT_RANGE,
206+       N_("messages whose score is in RANGE") },
207+  { 'N', M_NEW,                        0,              0,
208+       N_("new messages") },
209+  { 'O', M_OLD,                        0,              0,
210+       N_("old messages") },
211+  { 'p', M_PERSONAL_RECIP,     0,              0,
212+       N_("messages addressed to you") },
213+  { 'P', M_PERSONAL_FROM,      0,              0,
214+       N_("messages from you") },
215+  { 'Q', M_REPLIED,            0,              0,
216+       N_("messages which have been replied to") },
217+  { 'r', M_DATE_RECEIVED,      0,              EAT_DATE,
218+       N_("messages received in DATERANGE") },
219+  { 'R', M_READ,               0,              0,
220+       N_("already read messages") },
221+  { 's', M_SUBJECT,            0,              EAT_REGEXP,
222+       N_("messages whose Subject header matches EXPR") },
223+  { 'S', M_SUPERSEDED,         0,              0,
224+       N_("superseded messages") },
225+  { 't', M_TO,                 0,              EAT_REGEXP,
226+       N_("messages whose To header matches EXPR") },
227+  { 'T', M_TAG,                        0,              0,
228+       N_("tagged messages") },
229+  { 'u', M_SUBSCRIBED_LIST,    0,              0,
230+       N_("messages addressed to subscribed mailing lists") },
231+  { 'U', M_UNREAD,             0,              0,
232+       N_("unread messages") },
233+  { 'v', M_COLLAPSED,          0,              0,
234+       N_("messages in collapsed threads") },
235+  { 'V', M_CRYPT_VERIFIED,     0,              0,
236+       N_("cryptographically verified messages") },
237+  { 'x', M_REFERENCE,          0,              EAT_REGEXP,
238+       N_("messages whose References header matches EXPR") },
239+  { 'y', M_XLABEL,             0,              EAT_REGEXP,
240+       N_("messages whose X-Label header matches EXPR") },
241+  { 'z', M_SIZE,               0,              EAT_RANGE,
242+       N_("messages whose size is in RANGE") },
243+  { '=', M_DUPLICATED,         0,              0,
244+       N_("duplicated messages") },
245+  { '$', M_UNREFERENCED,       0,              0,
246+       N_("unreferenced messages") },
247   { 0 }
248 };
249 
250@@ -251,7 +298,7 @@
251   return match;
252 }
253 
254-int eat_regexp (pattern_t *pat, BUFFER *s, BUFFER *err)
255+static int eat_regexp (pattern_t *pat, BUFFER *s, BUFFER *err)
256 {
257   BUFFER buf;
258   int r;
259@@ -292,7 +339,7 @@
260   return 0;
261 }
262 
263-int eat_range (pattern_t *pat, BUFFER *s, BUFFER *err)
264+static int eat_range (pattern_t *pat, BUFFER *s, BUFFER *err)
265 {
266   char *tmp;
267   int do_exclusive = 0;
268@@ -848,13 +895,20 @@
269 
270        if (entry->eat_arg)
271        {
272+         int eatrv = 0;
273          if (!*ps.dptr)
274          {
275            snprintf (err->data, err->dsize, _("missing parameter"));
276            mutt_pattern_free (&curlist);
277            return NULL;
278          }
279-         if (entry->eat_arg (tmp, &ps, err) == -1)
280+         switch (entry->eat_arg)
281+         {
282+           case EAT_REGEXP: eatrv = eat_regexp (tmp, &ps, err); break;
283+           case EAT_DATE: eatrv = eat_date (tmp, &ps, err); break;
284+           case EAT_RANGE: eatrv = eat_range (tmp, &ps, err); break;
285+         }
286+         if (eatrv == -1)
287          {
288            mutt_pattern_free (&curlist);
289            return NULL;
290@@ -1405,3 +1459,134 @@
291   mutt_error _("Not found.");
292   return (-1);
293 }
294+
295+static void pattern_entry (char *s, size_t l, MUTTMENU * menu, int num)
296+{
297+  LIST **PatTable = (LIST **) menu->data;
298+
299+  mutt_format_string (s, l, 0, COLS, 0, ' ', PatTable[num]->data,
300+                    mutt_strlen (PatTable[num]->data), 0);
301+}
302+
303+static char pattern_menu (LIST *pats)
304+{
305+  int patmax = 0;
306+  LIST **PatTable = NULL;
307+  MUTTMENU *menu;
308+  int i, done = 0;
309+  char helpstr[SHORT_STRING], buf[LONG_STRING];
310+  LIST *pat;
311+  char rv = 0;
312+
313+  for (i = 0, pat = pats; pat; pat = pat->next)
314+  {
315+      if (i == patmax)
316+      {
317+       patmax += 5;
318+       safe_realloc (&PatTable, sizeof (LIST *) * patmax);
319+      }
320+      PatTable[i++] = pat;
321+  }
322+
323+  helpstr[0] = 0;
324+  mutt_make_help (buf, sizeof (buf), _("Exit  "), MENU_GENERIC, OP_EXIT);
325+  safe_strcat (helpstr, sizeof (helpstr), buf);
326+  mutt_make_help (buf, sizeof (buf), _("Select  "), MENU_GENERIC,
327+                 OP_GENERIC_SELECT_ENTRY);
328+  safe_strcat (helpstr, sizeof (helpstr), buf);
329+  mutt_make_help (buf, sizeof (buf), _("Help"), MENU_GENERIC, OP_HELP);
330+  safe_strcat (helpstr, sizeof (helpstr), buf);
331+
332+  menu = mutt_new_menu ();
333+  menu->max = i;
334+  menu->make_entry = pattern_entry;
335+  menu->menu = MENU_GENERIC;
336+  menu->help = helpstr;
337+  menu->data = PatTable;
338+  menu->title = _("Patterns");
339+
340+  mutt_clear_error ();
341+
342+  while (!done)
343+  {
344+    switch (mutt_menuLoop (menu))
345+    {
346+    case OP_GENERIC_SELECT_ENTRY:
347+      rv = PatTable[menu->current]->data[1];
348+      done = 1;
349+      break;
350+
351+    case OP_EXIT:
352+      rv = 0;
353+      done = 1;
354+      break;
355+    }
356+  }
357+
358+  mutt_menuDestroy (&menu);
359+  FREE (&PatTable);
360+
361+  set_option (OPTNEEDREDRAW);
362+
363+  return (rv);
364+}
365+
366+static LIST *list_patterns ()
367+{
368+  LIST *first = NULL, *last = NULL, *cur = NULL;
369+  int i;
370+
371+  for (i = 0; Flags[i].tag; i++)
372+  {
373+    char buf[LONG_STRING];
374+    switch (Flags[i].eat_arg)
375+    {
376+    case EAT_REGEXP:
377+      snprintf (buf, sizeof (buf), _("~%c EXPR       %s"),
378+                (char) Flags[i].tag, _(Flags[i].desc));
379+      break;
380+    case EAT_RANGE:
381+      snprintf (buf, sizeof (buf), _("~%c RANGE      %s"),
382+                (char) Flags[i].tag, _(Flags[i].desc));
383+      break;
384+    case EAT_DATE:
385+      snprintf (buf, sizeof (buf), _("~%c DATERANGE  %s"),
386+                (char) Flags[i].tag, _(Flags[i].desc));
387+      break;
388+    default:
389+      snprintf (buf, sizeof (buf), _("~%c            %s"),
390+                (char) Flags[i].tag, _(Flags[i].desc));
391+    }
392+    cur = (LIST *) safe_calloc (1, sizeof (LIST));
393+    cur->data = safe_strdup (buf);
394+    if (!first)
395+      first = cur;
396+    if (last)
397+      last->next = cur;
398+    last = cur;
399+  }
400+  if (cur)
401+    cur->next = NULL;
402+  return (first);
403+}
404+
405+int mutt_ask_pattern (char *buf, size_t buflen)
406+{
407+  char c;
408+  LIST *l;
409+  int rv = 0;
410+
411+  if (!buf || buflen < 3)
412+    return 0;
413+  if ((l = list_patterns()))
414+  {
415+    if ((c = pattern_menu (l)))
416+    {
417+      sprintf (buf, "%c ", c); /* __SPRINTF_CHECKED__ */
418+      rv = 1;
419+    }
420+    mutt_free_list (&l);
421+  }
422+  return rv;
423+}
424+
425--- a/protos.h  Mon Sep 19 06:22:55 2005
426+++ b/protos.h  Mon Sep 19 12:23:52 2005
427@@ -257,6 +258,7 @@
428 int mutt_addwch (wchar_t);
429 int mutt_alias_complete (char *, size_t);
430 int mutt_alloc_color (int fg, int bg);
431+int mutt_ask_pattern (char *, size_t);
432 int mutt_any_key_to_continue (const char *);
433 int mutt_buffy_check (int);
434 int mutt_buffy_notify (void);