Hi Kevin,

Thanks for all your comments! Here is the updated patch, in which I implemented all your suggestions.

Gregory
diff --git a/compose.c b/compose.c
index a7520516..e7e59148 100644
--- a/compose.c
+++ b/compose.c
@@ -993,10 +993,7 @@ static void compose_menu_redraw (MUTTMENU *menu)
   if (menu->redraw & REDRAW_STATUS)
   {
     compose_status_line (buf, sizeof (buf), 0, MuttStatusWindow->cols, menu, NONULL(ComposeFormat));
-    mutt_window_move (MuttStatusWindow, 0, 0);
-    SETCOLOR (MT_COLOR_STATUS);
-    mutt_paddstr (MuttStatusWindow->cols, buf);
-    NORMAL_COLOR;
+    mutt_filter_and_draw_status_window (MuttStatusWindow, buf);
     menu->redraw &= ~REDRAW_STATUS;
   }
 
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index cf8656b4..25ced981 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -6,7 +6,7 @@ SAMPLES = Mush.rc Pine.rc gpg.rc pgp2.rc pgp5.rc pgp6.rc Tin.rc \
 	sample.mailcap sample.muttrc sample.muttrc-sidebar sample.muttrc-tlr \
 	sample.muttrc-compress sample.muttrc-starter \
 	sample.vimrc-sidebar colors.default colors.linux smime.rc \
-	ca-bundle.crt smime_keys_test.pl mutt_xtitle markdown2html \
+	ca-bundle.crt smime_keys_test.pl mutt_xtitle mutt_xtitle.c markdown2html \
 	bgedit-detectgui.sh bgedit-screen-tmux.sh \
 	mutt_oauth2.py mutt_oauth2.py.README
 
diff --git a/contrib/mutt_xtitle b/contrib/mutt_xtitle
index f9b8a23f..70584a45 100755
--- a/contrib/mutt_xtitle
+++ b/contrib/mutt_xtitle
@@ -1,9 +1,12 @@
 #!/bin/sh
 # Demonstration of format string pipes. Sets the xterm title and returns the
 # string unchanged.
+# See also the mutt_xtitle.c program in this directory, which does the same thing
+# without spawning a shell on each invocation.
 #
-# Example usage:
+# Example usages:
 # set status_format="mutt_xtitle '%r %f (%L) [Msgs:%?M?%M/?%m%?n? New:%n?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b?]'|"
+# set status_filter=mutt_xtitle
 
-printf "\033]0;$1\007" > /dev/tty
+printf "\033]0;%s\007" "$1" > /dev/tty
 echo "$1"
diff --git a/contrib/mutt_xtitle.c b/contrib/mutt_xtitle.c
new file mode 100644
index 00000000..3d13580a
--- /dev/null
+++ b/contrib/mutt_xtitle.c
@@ -0,0 +1,19 @@
+/*
+ * Demonstration of format string pipes. Sets the xterm title and returns the
+ * string unchanged.
+ * See also the mutt_xtitle script in this directory, which does the same thing
+ * but spawns a shell on each invocation.
+ *
+ * Example usages:
+ * set status_format="mutt_xtitle '%r %f (%L) [Msgs:%?M?%M/?%m%?n? New:%n?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b?]'|"
+ * set status_filter=mutt_xtitle
+ */
+#include <stdio.h>
+int main (int argc, char **argv)
+{
+  FILE *f; char *s = "";
+  if (argc > 1) s = argv[1];
+  if ((f = fopen ("/dev/tty", "w"))) fprintf (f, "\033]0;%s\007", s);
+  printf ("%s", s);
+  return 0;
+}
diff --git a/curs_lib.c b/curs_lib.c
index 01bcde69..4434f27e 100644
--- a/curs_lib.c
+++ b/curs_lib.c
@@ -775,6 +775,13 @@ void mutt_reflow_windows (void)
   MuttMessageWindow->row_offset = LINES - 1;
 
   memcpy (MuttIndexWindow, MuttStatusWindow, sizeof (mutt_window_t));
+
+  if (! option (OPTSTATUSVISIBLE))
+  {
+    MuttStatusWindow->rows = 0;
+    MuttStatusWindow->cols = 0;
+  }
+
   MuttIndexWindow->rows = MAX(LINES - MuttStatusWindow->rows -
 			      MuttHelpWindow->rows - MuttMessageWindow->rows, 0);
   MuttIndexWindow->row_offset = option (OPTSTATUSONTOP) ? MuttStatusWindow->rows :
@@ -1457,6 +1464,73 @@ void mutt_paddstr (int n, const char *s)
     addch (' ');
 }
 
+static char *mutt_filter_status_line (char *s)
+{
+  BUFFER *command; FILE *filter; char *ps, *rs; size_t ps_size; int r; pid_t pid;
+
+  rs = safe_strdup (s);
+
+  if (!StatusFilter)
+    return rs;
+
+  command = mutt_buffer_pool_get ();
+  mutt_expand_file_fmt (command, StatusFilter, s);
+
+  if ((pid = mutt_create_filter (command->data, NULL, &filter, NULL)) < 0)
+  {
+    dprint (1, (debugfile, "calling status_filter command failed\n"));
+    goto cleanup;
+  }
+  ps = mutt_read_line (NULL, &ps_size, filter, NULL, 0);
+  safe_fclose (&filter);
+  r = mutt_wait_filter (pid);
+  if (ps != NULL && r == 0)
+  {
+    FREE (&rs);
+    rs = ps;
+  }
+  else
+  {
+    if (ps != NULL) FREE (&ps);
+    dprint (1, (debugfile, "status_filter command failed\n"));
+  }
+
+ cleanup:
+  mutt_buffer_pool_release (&command);
+  return rs;
+}
+
+void mutt_filter_and_draw_status_window (mutt_window_t *w, char *s)
+{
+  s = mutt_filter_status_line (s);
+
+  if (option (OPTSTATUSVISIBLE))
+    mutt_draw_status_window (w, s);
+
+  FREE (&s);
+}
+
+void mutt_draw_status_window (mutt_window_t *w, char *s)
+{
+  /* Do not check for OPTSTATUSVISIBLE here because the status bar of the pager
+     mini-index must be drawn even when it is unset (see pager_menu_redraw()). */
+  SETCOLOR (MT_COLOR_STATUS);
+  mutt_window_move (w, 0, 0);
+  mutt_paddstr (w->cols, s);
+  NORMAL_COLOR;
+}
+
+void mutt_draw_help_window (mutt_window_t *w, const char *s)
+{
+  if (! option (OPTHELP))
+    return;
+
+  SETCOLOR (MT_COLOR_STATUS);
+  mutt_window_move (w, 0, 0);
+  mutt_paddstr (w->cols, s);
+  NORMAL_COLOR;
+}
+
 /* See how many bytes to copy from string so its at most maxlen bytes
  * long and maxwid columns wide */
 size_t mutt_wstr_trunc (const char *src, size_t maxlen, size_t maxwid, size_t *width)
diff --git a/curs_main.c b/curs_main.c
index 19427025..535b3518 100644
--- a/curs_main.c
+++ b/curs_main.c
@@ -592,10 +592,7 @@ static void index_menu_redraw (MUTTMENU *menu)
   if (menu->redraw & REDRAW_STATUS)
   {
     menu_status_line (buf, sizeof (buf), menu, NONULL (Status));
-    mutt_window_move (MuttStatusWindow, 0, 0);
-    SETCOLOR (MT_COLOR_STATUS);
-    mutt_paddstr (MuttStatusWindow->cols, buf);
-    NORMAL_COLOR;
+    mutt_filter_and_draw_status_window (MuttStatusWindow, buf);
     menu->redraw &= ~REDRAW_STATUS;
     if (option(OPTTSENABLED) && TSSupported)
     {
diff --git a/globals.h b/globals.h
index a0a07af1..0471d9f9 100644
--- a/globals.h
+++ b/globals.h
@@ -178,6 +178,7 @@ WHERE char *Visual;
 WHERE char *CurrentFolder;
 WHERE char *LastFolder;
 
+WHERE char *StatusFilter;
 
 WHERE const char *ReleaseDate;
 
diff --git a/init.h b/init.h
index 31c2ae41..6fe73e15 100644
--- a/init.h
+++ b/init.h
@@ -4166,6 +4166,15 @@ struct option_t MuttVars[] = {
   /* L10N:
      $status_format default value
   */
+  { "status_filter", DT_STR, R_NONE, {.p=&StatusFilter}, {.p=0} },
+  /*
+  ** .pp
+  ** When set, specifies a command used to filter the status line, which is
+  ** displayed in the main status bar if $$status_visible is set.
+  ** This command does not filter the status line of the mini-index that is
+  ** displayed when $$pager_index_lines is non-zero.
+  ** .pp
+  */
   { "status_format", DT_STR|DT_L10N_STR, R_BOTH, {.p=&Status}, {.p=N_("-%r-Mutt: %f [Msgs:%?M?%M/?%m%?n? New:%n?%?o? Old:%o?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b?%?B? Back:%B?%?l? %l?]---(%s/%S)-%>-(%P)---")} },
   /*
   ** .pp
@@ -4248,6 +4257,14 @@ struct option_t MuttVars[] = {
   ** the first line of the screen rather than near the bottom. If $$help
   ** is \fIset\fP, too it'll be placed at the bottom.
   */
+  { "status_visible", DT_BOOL, R_REFLOW, {.l=OPTSTATUSVISIBLE}, {.l=1} },
+  /*
+  ** .pp
+  ** Unsetting this variable causes the main status bar to be hidden.
+  ** This variable has no effect on the status bar of the mini-index that
+  ** is displayed when $$pager_index_lines is non-zero.
+  ** .pp
+  */
   { "strict_threads",	DT_BOOL, R_RESORT|R_RESORT_INIT|R_INDEX, {.l=OPTSTRICTTHREADS}, {.l=0} },
   /*
   ** .pp
diff --git a/menu.c b/menu.c
index a7fff292..41e17cb5 100644
--- a/menu.c
+++ b/menu.c
@@ -230,13 +230,7 @@ void menu_redraw_full (MUTTMENU *menu)
   move (0, 0);
   clrtobot ();
 
-  if (option (OPTHELP))
-  {
-    SETCOLOR (MT_COLOR_STATUS);
-    mutt_window_move (menu->helpwin, 0, 0);
-    mutt_paddstr (menu->helpwin->cols, menu->help);
-    NORMAL_COLOR;
-  }
+  mutt_draw_help_window (menu->helpwin, menu->help);
   menu->offset = 0;
   menu->pagelen = menu->indexwin->rows;
 
@@ -253,10 +247,7 @@ void menu_redraw_status (MUTTMENU *menu)
   char buf[STRING];
 
   snprintf (buf, sizeof (buf), MUTT_MODEFMT, menu->title);
-  SETCOLOR (MT_COLOR_STATUS);
-  mutt_window_move (menu->statuswin, 0, 0);
-  mutt_paddstr (menu->statuswin->cols, buf);
-  NORMAL_COLOR;
+  mutt_filter_and_draw_status_window (menu->statuswin, buf);
   menu->redraw &= ~REDRAW_STATUS;
 }
 
diff --git a/mutt.h b/mutt.h
index 8f45e67f..2f1ea5cd 100644
--- a/mutt.h
+++ b/mutt.h
@@ -570,6 +570,7 @@ enum
   OPTWRAPSEARCH,
   OPTWRITEBCC,		/* write out a bcc header? */
   OPTXMAILER,
+  OPTSTATUSVISIBLE,
 
   OPTCRYPTUSEGPGME,
   OPTCRYPTUSEPKA,
diff --git a/mutt_curses.h b/mutt_curses.h
index f21e0eab..ceb44d83 100644
--- a/mutt_curses.h
+++ b/mutt_curses.h
@@ -208,6 +208,9 @@ int mutt_window_mvprintw (mutt_window_t *, int row, int col, const char *fmt, ..
 void mutt_window_clrtoeol (mutt_window_t *);
 void mutt_window_clearline (mutt_window_t *, int row);
 void mutt_window_getyx (mutt_window_t *, int *y, int *x);
+void mutt_filter_and_draw_status_window (mutt_window_t *, char *);
+void mutt_draw_status_window (mutt_window_t *, char *);
+void mutt_draw_help_window (mutt_window_t *, const char *);
 
 
 static inline int mutt_window_wrap_cols(mutt_window_t *win, short wrap)
diff --git a/pager.c b/pager.c
index 4346b638..58f27761 100644
--- a/pager.c
+++ b/pager.c
@@ -1706,13 +1706,7 @@ static void pager_menu_redraw (MUTTMENU *pager_menu)
       }
     }
 
-    if (option (OPTHELP))
-    {
-      SETCOLOR (MT_COLOR_STATUS);
-      mutt_window_move (MuttHelpWindow, 0, 0);
-      mutt_paddstr (MuttHelpWindow->cols, rd->helpstr);
-      NORMAL_COLOR;
-    }
+    mutt_draw_help_window (MuttHelpWindow, rd->helpstr);
 
 #if defined (USE_SLANG_CURSES) || defined (HAVE_RESIZETERM)
     if (Resize != NULL)
@@ -1877,24 +1871,20 @@ static void pager_menu_redraw (MUTTMENU *pager_menu)
       strfcpy(pager_progress_str, (rd->topline == 0) ? "all" : "end", sizeof(pager_progress_str));
 
     /* print out the pager status bar */
-    mutt_window_move (rd->pager_status_window, 0, 0);
-    SETCOLOR (MT_COLOR_STATUS);
-
     if (IsHeader (rd->extra) || IsMsgAttach (rd->extra))
     {
       size_t l1 = rd->pager_status_window->cols * MB_LEN_MAX;
       size_t l2 = sizeof (buffer);
       hfi.hdr = (IsHeader (rd->extra)) ? rd->extra->hdr : rd->extra->bdy->hdr;
       mutt_make_string_info (buffer, l1 < l2 ? l1 : l2, rd->pager_status_window->cols, NONULL (PagerFmt), &hfi, 0);
-      mutt_paddstr (rd->pager_status_window->cols, buffer);
+      mutt_filter_and_draw_status_window (rd->pager_status_window, buffer);
     }
     else
     {
       char bn[STRING];
       snprintf (bn, sizeof (bn), "%s (%s)", rd->banner, pager_progress_str);
-      mutt_paddstr (rd->pager_status_window->cols, bn);
+      mutt_filter_and_draw_status_window (rd->pager_status_window, bn);
     }
-    NORMAL_COLOR;
     if (option(OPTTSENABLED) && TSSupported)
     {
       menu_status_line (buffer, sizeof (buffer), rd->index, NONULL (TSStatusFormat));
@@ -1913,11 +1903,7 @@ static void pager_menu_redraw (MUTTMENU *pager_menu)
 
     /* print out the index status bar */
     menu_status_line (buffer, sizeof (buffer), rd->index, NONULL(Status));
-
-    mutt_window_move (rd->index_status_window, 0, 0);
-    SETCOLOR (MT_COLOR_STATUS);
-    mutt_paddstr (rd->index_status_window->cols, buffer);
-    NORMAL_COLOR;
+    mutt_draw_status_window (rd->index_status_window, buffer);
   }
 
   pager_menu->redraw = 0;

Reply via email to