Yep. I've gotten this same feedback from a few others. Modified
patch (w/ mapping to ^\) is attached.
Thanks,
Steve
Jeremy Blosser wrote:
> On Mar 26, Steve Talley [[EMAIL PROTECTED]] wrote:
> > filter-message (default: &)
>
> FWIW, the edit-threads patch, which quite a lot of people use, uses
> & for one of it's primary functions.
diff -pruN2d mutt-1.3.28.orig/OPS mutt-1.3.28/OPS
--- mutt-1.3.28.orig/OPS Sat Jan 27 06:33:53 2001
+++ mutt-1.3.28/OPS Tue Mar 26 10:47:39 2002
@@ -82,4 +82,5 @@ OP_ENTER_MASK "enter a file mask"
OP_EXIT "exit this menu"
OP_FILTER "filter attachment through a shell command"
+OP_FILTER_MESSAGE "filter message through a shell command"
OP_FIRST_ENTRY "move to the first entry"
OP_FLAG_MESSAGE "toggle a message's 'important' flag"
diff -pruN2d mutt-1.3.28.orig/PATCHES mutt-1.3.28/PATCHES
--- mutt-1.3.28.orig/PATCHES Mon Nov 26 12:16:52 2001
+++ mutt-1.3.28/PATCHES Tue Mar 26 10:56:38 2002
@@ -0,0 +1 @@
+patch-1.3.28.st.filter_message.1
diff -pruN2d mutt-1.3.28.orig/commands.c mutt-1.3.28/commands.c
--- mutt-1.3.28.orig/commands.c Thu Nov 8 01:56:48 2001
+++ mutt-1.3.28/commands.c Tue Mar 26 10:47:39 2002
@@ -301,5 +301,10 @@ void pipe_msg (HEADER *h, FILE *fp, int
-/* the following code is shared between printing and piping */
+/*
+ * the following code is shared between printing and piping
+ *
+ * fpfout: NULL to direct the command's STDOUT to mutt's STDOUT, or
+ * non-null to redirect.
+ */
static int _mutt_pipe_message (HEADER *h, char *cmd,
@@ -307,5 +312,6 @@ static int _mutt_pipe_message (HEADER *h
int print,
int split,
- char *sep)
+ char *sep,
+ FILE **fpfout)
{
@@ -330,5 +336,5 @@ static int _mutt_pipe_message (HEADER *h
#endif
- if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0)
+ if ((thepid = mutt_create_filter (cmd, &fpout, fpfout, NULL)) < 0)
{
mutt_perror _("Can't create filter process");
@@ -369,5 +375,5 @@ static int _mutt_pipe_message (HEADER *h
mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], M_MESSAGEHOOK);
mutt_endwin (NULL);
- if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0)
+ if ((thepid = mutt_create_filter (cmd, &fpout, fpfout, NULL)) < 0)
{
mutt_perror _("Can't create filter process");
@@ -386,5 +392,5 @@ static int _mutt_pipe_message (HEADER *h
{
mutt_endwin (NULL);
- if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0)
+ if ((thepid = mutt_create_filter (cmd, &fpout, fpfout, NULL)) < 0)
{
mutt_perror _("Can't create filter process");
@@ -426,5 +432,6 @@ void mutt_pipe_message (HEADER *h)
0,
option (OPTPIPESPLIT),
- PipeSep);
+ PipeSep,
+ NULL);
}
@@ -447,5 +454,6 @@ void mutt_print_message (HEADER *h)
1,
option (OPTPRINTSPLIT),
- "\f") == 0)
+ "\f",
+ NULL) == 0)
mutt_message (h ? _("Message printed") : _("Messages printed"));
else
@@ -454,4 +462,87 @@ void mutt_print_message (HEADER *h)
}
+/*
+ * Filter a single message through the given command
+ */
+int filter_one_message (CONTEXT *ctx, HEADER *h, char *command)
+{
+ FILE *fpfout;
+ char tmp[_POSIX_PATH_MAX];
+ int omagic;
+ int rc;
+ int oerrno;
+ CONTEXT tmpctx;
+
+ _mutt_pipe_message (h, command,
+ option (OPTPIPEDECODE),
+ 0,
+ option (OPTPIPESPLIT),
+ PipeSep,
+ &fpfout);
+
+ /* Create tmp mbox for filter output */
+ mutt_mktemp (tmp);
+ omagic = DefaultMagic;
+ DefaultMagic = M_MBOX;
+ rc = (mx_open_mailbox (tmp, M_APPEND, &tmpctx) == NULL) ? -1 : 0;
+ DefaultMagic = omagic;
+
+ if (rc == -1)
+ {
+ mutt_error (_("could not create temporary folder: %s"), strerror (errno));
+ return -1;
+ }
+
+ /* Copy filter output to tmp mbox */
+ rc = mutt_copy_stream (fpfout, tmpctx.fp);
+ oerrno = errno;
+ rc = fflush(tmpctx.fp);
+
+ /* Close stream and tmp mbox */
+ safe_fclose (&fpfout);
+ mx_close_mailbox (&tmpctx, NULL);
+
+ if (rc == -1)
+ {
+ mutt_error (_("could not write temporary mail folder: %s"), strerror (errno));
+ return -1;
+ }
+
+ /* Replace the selected message with the filter output */
+ return mutt_replace_message (ctx, h, tmp, 0);
+}
+
+/*
+ * Filter a single or tagged messages through a user-specified command
+ */
+int mutt_filter_message (CONTEXT *ctx, HEADER *hdr)
+{
+ int i, j;
+ char buffer[LONG_STRING];
+
+ buffer[0] = 0;
+ if (mutt_get_field (_("Filter command: "), buffer, sizeof (buffer), M_CMD)
+ != 0 || !buffer[0])
+ return 0;
+
+ mutt_expand_path (buffer, sizeof (buffer));
+
+ /* Single message? */
+ if (hdr)
+ return filter_one_message (ctx, hdr, buffer);
+
+ /* Iterate through tagged messages */
+ for (i = 0; i < ctx->vcount; i++)
+ {
+ j = ctx->v2r[i];
+ if (ctx->hdrs[j]->tagged)
+ {
+ if (filter_one_message (ctx, ctx->hdrs[j], buffer) == -1)
+ return -1;
+ }
+ }
+
+ return 0;
+}
int mutt_select_sort (int reverse)
diff -pruN2d mutt-1.3.28.orig/curs_main.c mutt-1.3.28/curs_main.c
--- mutt-1.3.28.orig/curs_main.c Wed Jan 16 13:44:25 2002
+++ mutt-1.3.28/curs_main.c Tue Mar 26 10:47:39 2002
@@ -1693,4 +1693,5 @@ int mutt_index_menu (void)
case OP_EDIT_MESSAGE:
+ case OP_FILTER_MESSAGE:
CHECK_MSGCOUNT;
@@ -1708,5 +1709,10 @@ int mutt_index_menu (void)
#endif
- mutt_edit_message (Context, tag ? NULL : CURHDR);
+ if(op == OP_EDIT_MESSAGE) {
+ mutt_edit_message (Context, tag ? NULL : CURHDR);
+ } else {
+ mutt_filter_message (Context, tag ? NULL : CURHDR);
+ }
+
menu->redraw = REDRAW_FULL;
diff -pruN2d mutt-1.3.28.orig/doc/manual.sgml.head mutt-1.3.28/doc/manual.sgml.head
--- mutt-1.3.28.orig/doc/manual.sgml.head Sat Jan 12 04:39:49 2002
+++ mutt-1.3.28/doc/manual.sgml.head Tue Mar 26 10:47:39 2002
@@ -406,4 +406,18 @@ This command extracts PGP public keys fr
message(s) and adds them to your PGP public key ring.
+<p><bf/filter-message/<label id="filter-message"> (default: ^\)<newline>
+
+Asks for an external shell command and filters the current or tagged
+message(s) through it. Each tagged message will be filtered through a
+separate invocation of the command. The stdout of the command will be
+appended to the current folder as a new message, and the original
+message will be marked for deletion.
+
+This command is available in the index and pager. As with <ref
+id="pipe-message" name="pipe-message">, the variables <ref
+id="pipe_decode" name="$pipe_decode"> and <ref
+id="wait_key" name="$wait_key"> control the exact
+behaviour of this function.
+
<p><bf/forget-passphrase/<label id="forget-passphrase"> (default:
^F)<newline>
diff -pruN2d mutt-1.3.28.orig/editmsg.c mutt-1.3.28/editmsg.c
--- mutt-1.3.28.orig/editmsg.c Thu Oct 11 01:58:26 2001
+++ mutt-1.3.28/editmsg.c Tue Mar 26 10:47:39 2002
@@ -43,18 +43,9 @@ static int edit_one_message (CONTEXT *ct
{
char tmp[_POSIX_PATH_MAX];
- char buff[STRING];
int omagic;
int oerrno;
int rc;
- unsigned short o_read;
- unsigned short o_old;
-
- int of, cf;
-
CONTEXT tmpctx;
- MESSAGE *msg;
-
- FILE *fp = NULL;
struct stat sb;
@@ -83,5 +74,5 @@ static int edit_one_message (CONTEXT *ct
{
mutt_error (_("could not write temporary mail folder: %s"), strerror (oerrno));
- goto bail;
+ return -1;
}
@@ -91,4 +82,35 @@ static int edit_one_message (CONTEXT *ct
mutt_edit_file ((!Editor || mutt_strcmp ("builtin", Editor) == 0) ?
NONULL(Visual) : NONULL(Editor), tmp);
+
+ /* Replace the selected message with the filter output */
+ return mutt_replace_message (ctx, cur, tmp, mtime);
+}
+
+/*
+ * The following code is shared between editing and filtering
+ *
+ * return value:
+ *
+ * 1 message not modified
+ * 0 message edited successfully
+ * -1 error
+ */
+
+int mutt_replace_message (CONTEXT *ctx, HEADER *cur, char *tmp, time_t mtime)
+{
+ char buff[STRING];
+ int rc;
+
+ unsigned short o_read;
+ unsigned short o_old;
+
+ int of, cf;
+
+ CONTEXT tmpctx;
+ MESSAGE *msg;
+
+ FILE *fp = NULL;
+
+ struct stat sb;
if ((rc = stat (tmp, &sb)) == -1)
diff -pruN2d mutt-1.3.28.orig/functions.h mutt-1.3.28/functions.h
--- mutt-1.3.28.orig/functions.h Tue Sep 11 05:20:34 2001
+++ mutt-1.3.28/functions.h Tue Mar 26 10:47:39 2002
@@ -78,4 +78,5 @@ struct binding_t OpMain[] = {
{ "delete-thread", OP_DELETE_THREAD, "\004" },
{ "delete-subthread", OP_DELETE_SUBTHREAD, "\033d" },
+ { "filter-message", OP_FILTER_MESSAGE, "\034" },
{ "edit", OP_EDIT_MESSAGE, "e" },
{ "edit-type", OP_EDIT_TYPE, "\005" },
@@ -160,4 +161,5 @@ struct binding_t OpPager[] = {
{ "delete-thread", OP_DELETE_THREAD, "\004" },
{ "delete-subthread", OP_DELETE_SUBTHREAD, "\033d" },
+ { "filter-message", OP_FILTER_MESSAGE, "\034" },
{ "edit", OP_EDIT_MESSAGE, "e" },
{ "edit-type", OP_EDIT_TYPE, "\005" },
diff -pruN2d mutt-1.3.28.orig/protos.h mutt-1.3.28/protos.h
--- mutt-1.3.28.orig/protos.h Wed Jan 16 13:44:25 2002
+++ mutt-1.3.28/protos.h Tue Mar 26 10:47:39 2002
@@ -262,4 +262,6 @@ int mutt_display_message (HEADER *h);
int mutt_edit_attachment(BODY *);
int mutt_edit_message (CONTEXT *, HEADER *);
+int mutt_filter_message (CONTEXT *, HEADER *);
+int mutt_replace_message (CONTEXT *, HEADER *, char *, time_t);
int mutt_fetch_recips (ENVELOPE *out, ENVELOPE *in, int flags);
int mutt_chscmp (const char *s, const char *chs);