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

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

patch-1.5.11cvs.tamo.patterns.3

Line 
1--- a/curs_lib.c        Tue Oct  4 19:00:05 2005
2+++ b/curs_lib.c        Wed Oct  5 18:36:54 2005
3@@ -130,6 +130,7 @@
4     mutt_refresh ();
5     getyx (stdscr, y, x);
6     ret = _mutt_enter_string (buf, buflen, y, x, complete, multiple, files, numfiles, es);
7+    complete &= ~(M_CLEAR);
8   }
9   while (ret == 1);
10   CLEARLINE (LINES-1);
11--- a/curs_main.c       Tue Oct  4 19:00:05 2005
12+++ b/curs_main.c       Wed Oct  5 18:36:54 2005
13@@ -811,7 +811,7 @@
14 
15        CHECK_ATTACH;
16        mutt_pattern_func (M_DELETE, _("Delete messages matching: "));
17-       menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
18+       menu->redraw = REDRAW_FULL;
19        break;
20 
21 #ifdef USE_POP
22@@ -866,8 +874,8 @@
23          menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
24          if (Context->msgcount && (Sort & SORT_MASK) == SORT_THREADS)
25            mutt_draw_tree (Context);
26-         menu->redraw = REDRAW_FULL;
27-       }
28+       }
29+       menu->redraw = REDRAW_FULL;
30        break;   
31 
32       case OP_QUIT:
33@@ -915,6 +923,8 @@
34          menu->current = menu->oldcurrent;
35        else
36          menu->redraw = REDRAW_MOTION;
37+       if (op == OP_SEARCH || op == OP_SEARCH_REVERSE)
38+         menu->redraw = REDRAW_FULL;
39        break;
40 
41       case OP_SORT:
42@@ -964,7 +974,7 @@
43        CHECK_MSGCOUNT;
44         CHECK_VISIBLE;
45        mutt_pattern_func (M_TAG, _("Tag messages matching: "));
46-       menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
47+       menu->redraw = REDRAW_FULL;
48        break;
49 
50       case OP_MAIN_UNDELETE_PATTERN:
51@@ -977,16 +987,16 @@
52 CHECK_IMAP_ACL(IMAP_ACL_DELETE);
53 #endif
54 
55-       if (mutt_pattern_func (M_UNDELETE, _("Undelete messages matching: ")) == 0)
56-         menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
57+       mutt_pattern_func (M_UNDELETE, _("Undelete messages matching: "));
58+       menu->redraw = REDRAW_FULL;
59        break;
60 
61       case OP_MAIN_UNTAG_PATTERN:
62 
63        CHECK_MSGCOUNT;
64         CHECK_VISIBLE;
65-       if (mutt_pattern_func (M_UNTAG, _("Untag messages matching: ")) == 0)
66-         menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
67+       mutt_pattern_func (M_UNTAG, _("Untag messages matching: "));
68+       menu->redraw = REDRAW_FULL;
69        break;
70 
71        /* --------------------------------------------------------------------
72--- a/enter.c   Tue Oct  4 19:00:05 2005
73+++ b/enter.c   Wed Oct  5 18:36:54 2005
74@@ -567,6 +567,17 @@
75            else
76              BEEP (); /* let the user know that nothing matched */
77            replace_part (state, 0, buf);
78+         }
79+         else if (flags & M_PATTERN)
80+         {
81+           if ((i = state->curpos) && state->wbuf[i - 1] == '~')
82+           {
83+             if (mutt_ask_pattern (buf, buflen))
84+               replace_part (state, i, buf);
85+             rv = 1;
86+             goto bye;
87+           }
88+           goto self_insert;
89          }
90          else
91            goto self_insert;
92--- a/pattern.c Tue Oct  4 19:00:05 2005
93+++ b/pattern.c Wed Oct  5 18:36:54 2005
94@@ -25,6 +25,8 @@
95 #include "keymap.h"
96 #include "mailbox.h"
97 #include "copy.h"
98+#include "mutt_menu.h"
99+#include "mutt_curses.h"
100 
101 #include <string.h>
102 #include <stdlib.h>
103@@ -45,57 +47,103 @@
104 static int eat_range (pattern_t *pat, BUFFER *, BUFFER *);
105 static int patmatch (const pattern_t *pat, const char *buf);
106 
107+#define EAT_REGEXP     1
108+#define EAT_DATE       2
109+#define EAT_RANGE      3
110 struct pattern_flags
111 {
112   int tag;     /* character used to represent this op */
113   int op;      /* operation to perform */
114   int class;
115-  int (*eat_arg) (pattern_t *, BUFFER *, BUFFER *);
116+  int eat_arg;
117+  char *desc;
118 }
119 Flags[] =
120 {
121-  { 'A', M_ALL,                        0,              NULL },
122-  { 'b', M_BODY,               M_FULL_MSG,     eat_regexp },
123-  { 'B', M_WHOLE_MSG,          M_FULL_MSG,     eat_regexp },
124-  { 'c', M_CC,                 0,              eat_regexp },
125-  { 'C', M_RECIPIENT,          0,              eat_regexp },
126-  { 'd', M_DATE,               0,              eat_date },
127-  { 'D', M_DELETED,            0,              NULL },
128-  { 'e', M_SENDER,             0,              eat_regexp },
129-  { 'E', M_EXPIRED,            0,              NULL },
130-  { 'f', M_FROM,               0,              eat_regexp },
131-  { 'F', M_FLAG,               0,              NULL },
132-  { 'g', M_CRYPT_SIGN,         0,              NULL },
133-  { 'G', M_CRYPT_ENCRYPT,      0,              NULL },
134-  { 'h', M_HEADER,             M_FULL_MSG,     eat_regexp },
135-  { 'H', M_HORMEL,             0,              eat_regexp },
136-  { 'i', M_ID,                 0,              eat_regexp },
137-  { 'k', M_PGP_KEY,            0,              NULL },
138-  { 'l', M_LIST,               0,              NULL },
139-  { 'L', M_ADDRESS,            0,              eat_regexp },
140-  { 'm', M_MESSAGE,            0,              eat_range },
141-  { 'n', M_SCORE,              0,              eat_range },
142-  { 'N', M_NEW,                        0,              NULL },
143-  { 'O', M_OLD,                        0,              NULL },
144-  { 'p', M_PERSONAL_RECIP,     0,              NULL },
145-  { 'P', M_PERSONAL_FROM,      0,              NULL },
146-  { 'Q', M_REPLIED,            0,              NULL },
147-  { 'r', M_DATE_RECEIVED,      0,              eat_date },
148-  { 'R', M_READ,               0,              NULL },
149-  { 's', M_SUBJECT,            0,              eat_regexp },
150-  { 'S', M_SUPERSEDED,         0,              NULL },
151-  { 't', M_TO,                 0,              eat_regexp },
152-  { 'T', M_TAG,                        0,              NULL },
153-  { 'u', M_SUBSCRIBED_LIST,    0,              NULL },
154-  { 'U', M_UNREAD,             0,              NULL },
155-  { 'v', M_COLLAPSED,          0,              NULL },
156-  { 'V', M_CRYPT_VERIFIED,     0,              NULL },
157-  { 'x', M_REFERENCE,          0,              eat_regexp },
158-  { 'X', M_MIMEATTACH,         0,              eat_range },
159-  { 'y', M_XLABEL,             0,              eat_regexp },
160-  { 'z', M_SIZE,               0,              eat_range },
161-  { '=', M_DUPLICATED,         0,              NULL },
162-  { '$', M_UNREFERENCED,       0,              NULL },
163+  { 'A', M_ALL,                        0,              0,
164+       N_("all messages") },
165+  { 'b', M_BODY,               M_FULL_MSG,     EAT_REGEXP,
166+       N_("messages whose body matches EXPR") },
167+  { 'B', M_WHOLE_MSG,          M_FULL_MSG,     EAT_REGEXP,
168+       N_("messages whose body or headers match EXPR") },
169+  { 'c', M_CC,                 0,              EAT_REGEXP,
170+       N_("messages whose CC header matches EXPR") },
171+  { 'C', M_RECIPIENT,          0,              EAT_REGEXP,
172+       N_("messages whose recipient matches EXPR") },
173+  { 'd', M_DATE,               0,              EAT_DATE,
174+       N_("messages sent in DATERANGE") },
175+  { 'D', M_DELETED,            0,              0,
176+       N_("deleted messages") },
177+  { 'e', M_SENDER,             0,              EAT_REGEXP,
178+       N_("messages whose Sender header matches EXPR") },
179+  { 'E', M_EXPIRED,            0,              0,
180+       N_("expired messages") },
181+  { 'f', M_FROM,               0,              EAT_REGEXP,
182+       N_("messages whose From header matches EXPR") },
183+  { 'F', M_FLAG,               0,              0,
184+       N_("flagged messages") },
185+  { 'g', M_CRYPT_SIGN,                 0,              0,
186+       N_("cryptographically signed messages") },
187+  { 'G', M_CRYPT_ENCRYPT,      0,              0,
188+       N_("cryptographically encrypted messages") },
189+  { 'h', M_HEADER,             M_FULL_MSG,     EAT_REGEXP,
190+       N_("messages whose header matches EXPR") },
191+  { 'H', M_HORMEL,             0,              EAT_REGEXP,
192+       N_("messages whose spam tag matches EXPR") },
193+  { 'i', M_ID,                 0,              EAT_REGEXP,
194+       N_("messages whose Message-ID matches EXPR") },
195+  { 'k', M_PGP_KEY,            0,              0,
196+       N_("messages which contain PGP key") },
197+  { 'l', M_LIST,               0,              0,
198+       N_("messages addressed to known mailing lists") },
199+  { 'L', M_ADDRESS,            0,              EAT_REGEXP,
200+       N_("messages whose From/Sender/To/CC matches EXPR") },
201+  { 'm', M_MESSAGE,            0,              EAT_RANGE,
202+       N_("messages whose number is in RANGE") },
203+  { 'n', M_SCORE,              0,              EAT_RANGE,
204+       N_("messages whose score is in RANGE") },
205+  { 'N', M_NEW,                        0,              0,
206+       N_("new messages") },
207+  { 'O', M_OLD,                        0,              0,
208+       N_("old messages") },
209+  { 'p', M_PERSONAL_RECIP,     0,              0,
210+       N_("messages addressed to you") },
211+  { 'P', M_PERSONAL_FROM,      0,              0,
212+       N_("messages from you") },
213+  { 'Q', M_REPLIED,            0,              0,
214+       N_("messages which have been replied to") },
215+  { 'r', M_DATE_RECEIVED,      0,              EAT_DATE,
216+       N_("messages received in DATERANGE") },
217+  { 'R', M_READ,               0,              0,
218+       N_("already read messages") },
219+  { 's', M_SUBJECT,            0,              EAT_REGEXP,
220+       N_("messages whose Subject header matches EXPR") },
221+  { 'S', M_SUPERSEDED,         0,              0,
222+       N_("superseded messages") },
223+  { 't', M_TO,                 0,              EAT_REGEXP,
224+       N_("messages whose To header matches EXPR") },
225+  { 'T', M_TAG,                        0,              0,
226+       N_("tagged messages") },
227+  { 'u', M_SUBSCRIBED_LIST,    0,              0,
228+       N_("messages addressed to subscribed mailing lists") },
229+  { 'U', M_UNREAD,             0,              0,
230+       N_("unread messages") },
231+  { 'v', M_COLLAPSED,          0,              0,
232+       N_("messages in collapsed threads") },
233+  { 'V', M_CRYPT_VERIFIED,     0,              0,
234+       N_("cryptographically verified messages") },
235+  { 'x', M_REFERENCE,          0,              EAT_REGEXP,
236+       N_("messages whose References header matches EXPR") },
237+  { 'X', M_MIMEATTACH,         0,              EAT_RANGE,
238+       N_("messages with RANGE attachments") },
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@@ -252,7 +300,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@@ -298,7 +346,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@@ -854,13 +902,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@@ -1427,3 +1482,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  Tue Oct  4 19:00:05 2005
426+++ b/protos.h  Wed Oct  5 18:36:54 2005
427@@ -258,6 +259,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);