Re: [PATCH] new fmtpipe updates
* On 2007.03.13, in <20070313210222.GB24389@xxxxxxxxxxxxxxxxx>,
* "Brendan Cully" <brendan@xxxxxxxxxx> wrote:
>
> On further reflection, I think your fmtpipe.3 patch should work well
> enough -- people will just have to get used to putting their string in
> extra quoting. But the one you submitted seems to have some garbage in
> it ('/tmp/ass', and an #if 0 block), and doesn't really quote things
> properly for shell (embedded single quotes would break it). Can you
> clean these things up, and maybe add the \| check?
These are fixed in fmtpipe.4, attached.
I've also added a mutt_xtitle program in mutt_xtitle.c, with hooks into
Makefile.am. It's sufficient for a common case of setting xterm titles,
e.g.:
set pager_format="mutt_xtitle '%-.20n: %.40s' '-%Z- %C/%m: %-20.20n %s' |"
That should help make the xterm titlebar use case more out-of-box.
But if it's not important, feel free to ignore the Makefile.am and
mutt_xtitle.c hunks in the diff.
--
-D. dgc@xxxxxxxxxxxx NSIT University of Chicago
diff -r dc8f0c4a6287 Makefile.am
--- a/Makefile.am Tue Mar 13 12:39:59 2007 -0700
+++ b/Makefile.am Wed Mar 14 01:59:17 2007 -0500
@@ -2,7 +2,7 @@
## Use aclocal -I m4; automake --foreign
AUTOMAKE_OPTIONS = 1.6 foreign
-EXTRA_PROGRAMS = mutt_dotlock pgpring pgpewrap makedoc
+EXTRA_PROGRAMS = mutt_dotlock pgpring pgpewrap makedoc mutt_xtitle
if BUILD_IMAP
IMAP_SUBDIR = imap
@@ -15,7 +15,7 @@ bin_SCRIPTS = muttbug flea @SMIMEAUX_TAR
BUILT_SOURCES = keymap_defs.h patchlist.c
-bin_PROGRAMS = mutt @DOTLOCK_TARGET@ @PGPAUX_TARGET@
+bin_PROGRAMS = mutt mutt_xtitle @DOTLOCK_TARGET@ @PGPAUX_TARGET@
mutt_SOURCES = $(BUILT_SOURCES) \
addrbook.c alias.c attach.c base64.c browser.c buffy.c color.c \
crypt.c cryptglue.c \
@@ -90,6 +90,10 @@ pgpring_LDADD = @LIBOBJS@ $(INTLLIBS)
pgpring_LDADD = @LIBOBJS@ $(INTLLIBS)
pgpring_DEPENDENCIES = @LIBOBJS@ $(INTLDEPS)
+mutt_xtitle_SOURCES = mutt_xtitle.c
+mutt_xtitle_LDADD = @LIBOBJS@
+mutt_xtitle_DEPENDENCIES = @LIBOBJS@
+
mutt_dotlock.c: dotlock.c
cp $(srcdir)/dotlock.c mutt_dotlock.c
diff -r dc8f0c4a6287 PATCHES
--- a/PATCHES Tue Mar 13 12:39:59 2007 -0700
+++ b/PATCHES Wed Mar 07 14:06:01 2007 -0500
@@ -0,0 +1,1 @@
+patch-1.5.14.dgc.fmtpipe.3
diff -r dc8f0c4a6287 mutt.h
--- a/mutt.h Tue Mar 13 12:39:59 2007 -0700
+++ b/mutt.h Tue Mar 06 23:45:52 2007 -0500
@@ -143,7 +143,8 @@ typedef enum
M_FORMAT_OPTIONAL = (1<<3),
M_FORMAT_STAT_FILE = (1<<4), /* used by mutt_attach_fmt */
M_FORMAT_ARROWCURSOR = (1<<5), /* reserve space for arrow_cursor */
- M_FORMAT_INDEX = (1<<6) /* this is a main index entry */
+ M_FORMAT_INDEX = (1<<6), /* this is a main index entry */
+ M_FORMAT_NOFILTER = (1<<7) /* do not allow filtering on this pass */
} format_flag;
/* types for mutt_add_hook() */
diff -r dc8f0c4a6287 mutt_xtitle.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mutt_xtitle.c Wed Mar 14 02:30:58 2007 -0500
@@ -0,0 +1,53 @@
+/*
+ * Sets the window title to argv[1] (in an xterm-like way)
+ * and echoes back remaining arguments.
+ *
+ * Example usage:
+ * set pager_format="mutt_xtitle '%-.20n: %.40s' '-%Z- %C/%m: %-20.20n %s'
|"
+ *
+ * This sets the xterm title to show the sender's name and the subject
+ * whenever viewing a message, and uses the default pager_format for
+ * the actual header line in the pager.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main(int argc, char *argv[])
+{
+ FILE *tty;
+ int i;
+
+ /* check for help patterns */
+ if (argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
+ fprintf(stderr,
+ "usage: set xyz_format=\"%s 'window title' "
+ "'other format text' |\"\n", argv[0]);
+ exit (2);
+ }
+
+ /* We'll write the xterm title sequence to /dev/tty if possible */
+ tty = fopen("/dev/tty", "w");
+ if (tty) {
+ fprintf(tty, "\033]0;%s\007", argv[1]);
+ fclose(tty);
+ }
+ /* or stdout as a fallback */
+ else {
+ printf("\033]0;%s\007", argv[1]);
+ }
+
+ /* write remaining arguments to stdout, space-separated */
+ for (i = 2; i < argc-1; i++) {
+ printf("%s ", argv[i]);
+ }
+
+ /* print final arg with no trailing space */
+ if (i == argc-1)
+ printf("%s", argv[i]);
+
+ exit (0);
+}
diff -r dc8f0c4a6287 muttlib.c
--- a/muttlib.c Tue Mar 13 12:39:59 2007 -0700
+++ b/muttlib.c Wed Mar 14 01:32:17 2007 -0500
@@ -996,12 +996,122 @@ void mutt_FormatString (char *dest, /*
char prefix[SHORT_STRING], buf[LONG_STRING], *cp, *wptr = dest, ch;
char ifstring[SHORT_STRING], elsestring[SHORT_STRING];
size_t wlen, count, len, col, wid;
+ pid_t pid;
+ FILE *filter;
+ int n;
+ char *recycler;
prefix[0] = '\0';
destlen--; /* save room for the terminal \0 */
wlen = (flags & M_FORMAT_ARROWCURSOR && option (OPTARROWCURSOR)) ? 3 : 0;
col = wlen;
-
+
+ if ((flags & M_FORMAT_NOFILTER) == 0)
+ {
+ int off = -1;
+
+ /* Do not consider filters if no pipe at end */
+ n = mutt_strlen(src);
+ if (n > 0 && src[n-1] == '|')
+ {
+ /* Scan backwards for backslashes */
+ off = n;
+ while (off > 0 && src[off-2] == '\\')
+ off--;
+ }
+
+ /* If number of backslashes is even, the pipe is real. */
+ /* n-off is the number of backslashes. */
+ if (off > 0 && ((n-off) % 2) == 0)
+ {
+ BUFFER *srcbuf, *word, *command;
+ char srccopy[LONG_STRING];
+ int i = 0;
+
+ dprint(2, (debugfile, "fmtpipe = %s\n", src));
+
+ strncpy(srccopy, src, n);
+ srccopy[n-1] = '\0';
+
+ /* prepare BUFFERs */
+ srcbuf = mutt_buffer_from(NULL, srccopy);
+ srcbuf->dptr = srcbuf->data;
+ word = mutt_buffer_init(NULL);
+ command = mutt_buffer_init(NULL);
+
+ /* Iterate expansions across successive arguments */
+ do {
+ char *p;
+
+ /* Extract the command name and copy to command line */
+ dprint(2, (debugfile, "fmtpipe +++: %s\n", srcbuf->dptr));
+ if (word->data)
+ *word->data = '\0';
+ mutt_extract_token(word, srcbuf, 0);
+ dprint(2, (debugfile, "fmtpipe %2d: %s\n", i++, word->data));
+ mutt_buffer_addch(command, '\'');
+ mutt_FormatString(buf, sizeof(buf), word->data, callback, data,
+ flags | M_FORMAT_NOFILTER);
+ for (p = buf; p && *p; p++)
+ {
+ if (*p == '\'')
+ /* shell quoting doesn't permit escaping a single quote within
+ * single-quoted material. double-quoting instead will lead
+ * shell variable expansions, so break out of the single-quoted
+ * span, insert a double-quoted single quote, and resume. */
+ mutt_buffer_addstr(command, "'\"'\"'");
+ else
+ mutt_buffer_addch(command, *p);
+ }
+ mutt_buffer_addch(command, '\'');
+ mutt_buffer_addch(command, ' ');
+ } while (MoreArgs(srcbuf));
+
+ dprint(2, (debugfile, "fmtpipe > %s\n", command->data));
+
+ wptr = dest; /* reset write ptr */
+ wlen = (flags & M_FORMAT_ARROWCURSOR && option (OPTARROWCURSOR)) ? 3 : 0;
+ if ((pid = mutt_create_filter(command->data, NULL, &filter, NULL)))
+ {
+ n = fread(dest, 1, destlen /* already decremented */, filter);
+ fclose(filter);
+ dest[n] = '\0';
+ dprint(2, (debugfile, "fmtpipe < %s\n", dest));
+
+ if (pid != -1)
+ mutt_wait_filter(pid);
+
+ /* If the result ends with '%', this indicates that the filter
+ * generated %-tokens that mutt can expand. Eliminate the '%'
+ * marker and recycle the string through mutt_FormatString().
+ * To literally end with "%", use "%%". */
+ if (dest[--n] == '%')
+ {
+ dest[n] = '\0'; /* remove '%' */
+ if (dest[--n] != '%')
+ {
+ recycler = safe_strdup(dest);
+ if (recycler)
+ {
+ mutt_FormatString(dest, destlen++, recycler, callback, data,
flags);
+ safe_free(&recycler);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Filter failed; erase write buffer */
+ *wptr = '\0';
+ }
+
+ mutt_buffer_free(&command);
+ mutt_buffer_free(&srcbuf);
+ mutt_buffer_free(&word);
+ return;
+ }
+ }
+
while (*src && wlen < destlen)
{
if (*src == '%')