Re: Listing patterns in the help screen
On Sat, Mar 12, 2005 at 03:48:32PM +0900, Tamotsu Takahashi wrote:
> On Fri, Mar 11, 2005 at 09:18:00PM -0800, Aaron Lehmann wrote:
> > I think listing mutt's patterns in the help screen would be useful.
> > I'm always forgetting which letters correspond to certain things, and
>
> Me too.
> And it should be easy to parse Flags[] (in pattern.c).
> It's a very good idea!
That's a good way to do it. Here's a patch. Since I cleaned up many of
the descriptions to make them more consistent, I applied those changes
to the manual as well.
Index: help.c
===================================================================
RCS file: /home/roessler/cvs/mutt/help.c,v
retrieving revision 3.2
diff -u -r3.2 help.c
--- help.c 3 Feb 2005 17:01:43 -0000 3.2
+++ help.c 12 Mar 2005 09:05:44 -0000
@@ -31,6 +31,8 @@
#include <ctype.h>
#include <string.h>
+extern struct pattern_flags Flags[];
+
static struct binding_t *help_lookupFunction (int op, int menu)
{
int i;
@@ -308,6 +310,39 @@
}
}
+static void dump_flags (FILE *f)
+{
+ int i;
+ char flagname[] = "~ ";
+
+ for (i = 0; Flags[i].tag; i++)
+ {
+ flagname[1] = Flags[i].tag;
+
+ switch (Flags[i].argument)
+ {
+ case PATTERN_TAKES_NOTHING:
+ format_line (f, 0, flagname, "", _(Flags[i].description));
+ break;
+ case PATTERN_TAKES_EXPR:
+ format_line (f, 0, flagname, _("EXPR"), _(Flags[i].description));
+ break;
+ case PATTERN_TAKES_USER:
+ format_line (f, 0, flagname, _("USER"), _(Flags[i].description));
+ break;
+ case PATTERN_TAKES_SUBJECT:
+ format_line (f, 0, flagname, _("SUBJECT"), _(Flags[i].description));
+ break;
+ case PATTERN_TAKES_RANGE:
+ format_line (f, 0, flagname, _("[MIN]-[MAX]"),
_(Flags[i].description));
+ break;
+ case PATTERN_TAKES_ID:
+ format_line (f, 0, flagname, _("ID"), _(Flags[i].description));
+ break;
+ }
+ }
+}
+
void mutt_help (int menu)
{
char t[_POSIX_PATH_MAX];
@@ -343,6 +378,9 @@
if (menu != MENU_PAGER)
dump_unbound (f, OpGeneric, Keymaps[MENU_GENERIC], Keymaps[menu]);
+ fputs (_("\nPattern flags:\n\n"), f);
+ dump_flags(f);
+
fclose (f);
snprintf (buf, sizeof (buf), _("Help for %s"), desc);
Index: mutt.h
===================================================================
RCS file: /home/roessler/cvs/mutt/mutt.h,v
retrieving revision 3.40
diff -u -r3.40 mutt.h
--- mutt.h 28 Feb 2005 15:15:23 -0000 3.40
+++ mutt.h 12 Mar 2005 09:05:44 -0000
@@ -865,6 +865,26 @@
int tabs;
} ENTER_STATE;
+/* used by pattern.c */
+
+struct pattern_flags
+{
+ int tag; /* character used to represent this op */
+ int op; /* operation to perform */
+ int class;
+ int (*eat_arg) (pattern_t *, BUFFER *, BUFFER *);
+ enum
+ {
+ PATTERN_TAKES_NOTHING,
+ PATTERN_TAKES_EXPR,
+ PATTERN_TAKES_RANGE,
+ PATTERN_TAKES_USER,
+ PATTERN_TAKES_ID,
+ PATTERN_TAKES_SUBJECT
+ } argument;
+ const char *description; /* description for the help screen */
+};
+
/* flags for the STATE struct */
#define M_DISPLAY (1<<0) /* output is displayed to the user */
#define M_VERIFY (1<<1) /* perform signature verification */
Index: pattern.c
===================================================================
RCS file: /home/roessler/cvs/mutt/pattern.c,v
retrieving revision 3.14
diff -u -r3.14 pattern.c
--- pattern.c 9 Feb 2005 09:05:38 -0000 3.14
+++ pattern.c 12 Mar 2005 09:05:45 -0000
@@ -39,55 +39,128 @@
static int eat_date (pattern_t *pat, BUFFER *, BUFFER *);
static int eat_range (pattern_t *pat, BUFFER *, BUFFER *);
-struct pattern_flags
+struct pattern_flags Flags[] =
{
- int tag; /* character used to represent this op */
- int op; /* operation to perform */
- int class;
- int (*eat_arg) (pattern_t *, BUFFER *, BUFFER *);
-}
-Flags[] =
-{
- { 'A', M_ALL, 0, NULL },
- { 'b', M_BODY, M_FULL_MSG, eat_regexp },
- { 'B', M_WHOLE_MSG, M_FULL_MSG, eat_regexp },
- { 'c', M_CC, 0, eat_regexp },
- { 'C', M_RECIPIENT, 0, eat_regexp },
- { 'd', M_DATE, 0, eat_date },
- { 'D', M_DELETED, 0, NULL },
- { 'e', M_SENDER, 0, eat_regexp },
- { 'E', M_EXPIRED, 0, NULL },
- { 'f', M_FROM, 0, eat_regexp },
- { 'F', M_FLAG, 0, NULL },
- { 'g', M_CRYPT_SIGN, 0, NULL },
- { 'G', M_CRYPT_ENCRYPT, 0, NULL },
- { 'h', M_HEADER, M_FULL_MSG, eat_regexp },
- { 'H', M_HORMEL, 0, eat_regexp },
- { 'i', M_ID, 0, eat_regexp },
- { 'k', M_PGP_KEY, 0, NULL },
- { 'L', M_ADDRESS, 0, eat_regexp },
- { 'l', M_LIST, 0, NULL },
- { 'm', M_MESSAGE, 0, eat_range },
- { 'n', M_SCORE, 0, eat_range },
- { 'N', M_NEW, 0, NULL },
- { 'O', M_OLD, 0, NULL },
- { 'p', M_PERSONAL_RECIP, 0, NULL },
- { 'P', M_PERSONAL_FROM, 0, NULL },
- { 'Q', M_REPLIED, 0, NULL },
- { 'R', M_READ, 0, NULL },
- { 'r', M_DATE_RECEIVED, 0, eat_date },
- { 's', M_SUBJECT, 0, eat_regexp },
- { 'S', M_SUPERSEDED, 0, NULL },
- { 'T', M_TAG, 0, NULL },
- { 't', M_TO, 0, eat_regexp },
- { 'U', M_UNREAD, 0, NULL },
- { 'v', M_COLLAPSED, 0, NULL },
- { 'V', M_CRYPT_VERIFIED, 0, NULL },
- { 'x', M_REFERENCE, 0, eat_regexp },
- { 'y', M_XLABEL, 0, eat_regexp },
- { 'z', M_SIZE, 0, eat_range },
- { '=', M_DUPLICATED, 0, NULL },
- { '$', M_UNREFERENCED, 0, NULL },
+ { 'A', M_ALL, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("all messages") },
+ { 'b', M_BODY, M_FULL_MSG, eat_regexp,
+ PATTERN_TAKES_EXPR,
+ N_("messages which contain EXPR in the message body") },
+ { 'B', M_WHOLE_MSG, M_FULL_MSG, eat_regexp,
+ PATTERN_TAKES_EXPR,
+ N_("messages which contain EXPR in the whole message") },
+ { 'c', M_CC, 0, eat_regexp,
+ PATTERN_TAKES_USER,
+ N_("messages carbon-copied to USER") },
+ { 'C', M_RECIPIENT, 0, eat_regexp,
+ PATTERN_TAKES_USER,
+ N_("messages either To: or Cc: USER") },
+ { 'd', M_DATE, 0, eat_date,
+ PATTERN_TAKES_RANGE,
+ N_("messages with \"date-sent\" in a date range") },
+ { 'D', M_DELETED, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("deleted messages") },
+ { 'e', M_SENDER, 0, eat_regexp,
+ PATTERN_TAKES_USER,
+ N_("messages which contain USER in the \"Sender\" field") },
+ { 'E', M_EXPIRED, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("expired messages") },
+ { 'f', M_FROM, 0, eat_regexp,
+ PATTERN_TAKES_USER,
+ N_("messages originating from USER") },
+ { 'F', M_FLAG, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("flagged messages") },
+ { 'g', M_CRYPT_SIGN, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("cryptographically signed messages") },
+ { 'G', M_CRYPT_ENCRYPT, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("cryptographically encrypted messages") },
+ { 'h', M_HEADER, M_FULL_MSG, eat_regexp,
+ PATTERN_TAKES_EXPR,
+ N_("messages which contain EXPR in the message header") },
+ { 'H', M_HORMEL, 0, eat_regexp,
+ PATTERN_TAKES_EXPR,
+ N_("messages with a spam attribute matching EXPR") },
+ { 'i', M_ID, 0, eat_regexp,
+ PATTERN_TAKES_ID,
+ N_("messages matching ID in the \"Message-ID\" field") },
+ { 'k', M_PGP_KEY, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("messages containing PGP key material") },
+ { 'L', M_ADDRESS, 0, eat_regexp,
+ PATTERN_TAKES_USER,
+ N_("messages either originated or received by USER") },
+ { 'l', M_LIST, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("messages addressed to a known mailing list") },
+ { 'm', M_MESSAGE, 0, eat_range,
+ PATTERN_TAKES_RANGE,
+ N_("messages in the range MIN to MAX *)") },
+ { 'n', M_SCORE, 0, eat_range,
+ PATTERN_TAKES_RANGE,
+ N_("messages with a score in the range MIN to MAX") },
+ { 'N', M_NEW, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("new messages") },
+ { 'O', M_OLD, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("old messages") },
+ { 'p', M_PERSONAL_RECIP, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("messages addressed to you (consults alternates)") },
+ { 'P', M_PERSONAL_FROM, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("messages from you (consults alternates)") },
+ { 'Q', M_REPLIED, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("messages which have been replied to") },
+ { 'R', M_READ, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("read messages") },
+ { 'r', M_DATE_RECEIVED, 0, eat_date,
+ PATTERN_TAKES_RANGE,
+ N_("messages with \"date-received\" in a date range") },
+ { 's', M_SUBJECT, 0, eat_regexp,
+ PATTERN_TAKES_SUBJECT,
+ N_("messages having SUBJECT in the \"Subject\" field") },
+ { 'S', M_SUPERSEDED, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("superseded messages") },
+ { 'T', M_TAG, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("tagged messages") },
+ { 't', M_TO, 0, eat_regexp,
+ PATTERN_TAKES_USER,
+ N_("messages addressed to USER") },
+ { 'U', M_UNREAD, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("unread messages") },
+ { 'v', M_COLLAPSED, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("messages in collapsed threads") },
+ { 'V', M_CRYPT_VERIFIED, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("cryptographically verified messages") },
+ { 'x', M_REFERENCE, 0, eat_regexp,
+ PATTERN_TAKES_EXPR,
+ N_("messages which contain EXPR in the \"References\" field") },
+ { 'y', M_XLABEL, 0, eat_regexp,
+ PATTERN_TAKES_EXPR,
+ N_("messages which contain EXPR in the \"X-Label\" field") },
+ { 'z', M_SIZE, 0, eat_range,
+ PATTERN_TAKES_RANGE,
+ N_("messages with a size in the range MIN to MAX"), },
+ { '=', M_DUPLICATED, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("duplicated messages (see $duplicate_threads)") },
+ { '$', M_UNREFERENCED, 0, NULL,
+ PATTERN_TAKES_NOTHING,
+ N_("unreferenced messages (requires threaded view)") },
{ 0 }
};