]> granicus.if.org Git - neomutt/commitdiff
This patch implements the "%* " notation, which is analogous to "%> "
authorDavid Champion <dgc@uchicago.edu>
Mon, 9 Jul 2007 01:27:35 +0000 (18:27 -0700)
committerDavid Champion <dgc@uchicago.edu>
Mon, 9 Jul 2007 01:27:35 +0000 (18:27 -0700)
but gives precedence to the right side instead of to the left when the
fill length is zero. The default $pager_format is updated to use it so
that %P is always available at the edge of the screen.

commands.c
curs_lib.c
doc/manual.xml.head
init.h
lib.h
menu.c
muttlib.c
query.c
recvcmd.c

index 2fdcb7ffae394885e925ee7326422dbfc1daaae9..85a67b233fdbcf38c7c26403c2920bb8af4bf0d9 100644 (file)
@@ -283,7 +283,7 @@ void ci_bounce_message (HEADER *h, int *redraw)
   if (mutt_strwidth (prompt) > COLS - extra_space)
   {
     mutt_format_string (prompt, sizeof (prompt),
-                       0, COLS-extra_space, 0, 0,
+                       0, COLS-extra_space, FMT_LEFT, 0,
                        scratch, sizeof (scratch), 0);
     safe_strcat (prompt, sizeof (prompt), "...?");
   }
index 70fca1710352e9510607b184d371eb7f45d66c6f..e9dbaa8b3a1f04c80a7bd476ed0f468fe20384d3 100644 (file)
@@ -292,7 +292,7 @@ void mutt_curses_error (const char *fmt, ...)
   
   dprint (1, (debugfile, "%s\n", scratch));
   mutt_format_string (Errorbuf, sizeof (Errorbuf),
-                     0, COLS-2, 0, 0, scratch, sizeof (scratch), 0);
+                     0, COLS-2, FMT_LEFT, 0, scratch, sizeof (scratch), 0);
 
   if (!option (OPTKEEPQUIET))
   {
@@ -317,7 +317,7 @@ void mutt_curses_message (const char *fmt, ...)
   va_end (ap);
 
   mutt_format_string (Errorbuf, sizeof (Errorbuf),
-                     0, COLS-2, 0, 0, scratch, sizeof (scratch), 0);
+                     0, COLS-2, FMT_LEFT, 0, scratch, sizeof (scratch), 0);
 
   if (!option (OPTKEEPQUIET))
   {
@@ -641,7 +641,7 @@ int mutt_addwch (wchar_t wc)
 
 void mutt_format_string (char *dest, size_t destlen,
                         int min_width, int max_width,
-                        int right_justify, char m_pad_char,
+                        int justify, char m_pad_char,
                         const char *s, size_t n,
                         int arboreal)
 {
@@ -688,7 +688,7 @@ void mutt_format_string (char *dest, size_t destlen,
   w = (int)destlen < min_width ? destlen : min_width;
   if (w <= 0)
     *p = '\0';
-  else if (right_justify)
+  else if (justify == FMT_RIGHT)       /* right justify */
   {
     p[w] = '\0';
     while (--p >= dest)
@@ -696,7 +696,27 @@ void mutt_format_string (char *dest, size_t destlen,
     while (--w >= 0)
       dest[w] = m_pad_char;
   }
-  else
+  else if (justify == FMT_CENTER)      /* center */
+  {
+    char *savedp = p;
+    int half = (w+1) / 2; /* half of cushion space */
+
+    p[w] = '\0';
+
+    /* move str to center of buffer */
+    while (--p >= dest)
+      p[half] = *p;
+
+    /* fill rhs */
+    p = savedp + half;
+    while (--w >= half)
+      *p++ = m_pad_char;
+
+    /* fill lhs */
+    while (half--)
+      dest[half] = m_pad_char;
+  }
+  else                                 /* left justify */
   {
     while (--w >= 0)
       *p++ = m_pad_char;
@@ -718,13 +738,15 @@ static void mutt_format_s_x (char *dest,
                             const char *s,
                             int arboreal)
 {
-  int right_justify = 1;
+  int justify = FMT_RIGHT;
   char *p;
   int min_width;
   int max_width = INT_MAX;
 
   if (*prefix == '-')
-    ++prefix, right_justify = 0;
+    ++prefix, justify = FMT_LEFT;
+  else if (*prefix == '=')
+    ++prefix, justify = FMT_CENTER;
   min_width = strtol (prefix, &p, 10);
   if (*p == '.')
   {
@@ -735,7 +757,7 @@ static void mutt_format_s_x (char *dest,
   }
 
   mutt_format_string (dest, destlen, min_width, max_width,
-                     right_justify, ' ', s, mutt_strlen (s), arboreal);
+                     justify, ' ', s, mutt_strlen (s), arboreal);
 }
 
 void mutt_format_s (char *dest,
@@ -756,7 +778,7 @@ void mutt_format_s_tree (char *dest,
 
 /*
  * mutt_paddstr (n, s) is almost equivalent to
- * mutt_format_string (bigbuf, big, n, n, 0, ' ', s, big, 0), addstr (bigbuf)
+ * mutt_format_string (bigbuf, big, n, n, FMT_LEFT, ' ', s, big, 0), addstr (bigbuf)
  */
 
 void mutt_paddstr (int n, const char *s)
index 09873698567dbba5c29b8226431c652016cca9b7..b6a6d3d87fd92f010013983a03294bb90c065569 100644 (file)
@@ -3259,6 +3259,72 @@ something like <literal>unhook send-hook</literal>.
 
 </sect1>
 
+<sect1 id="formatstrings">
+<title>Format Strings</title>
+
+<para>
+Format strings are a general concept you'll find in several locations
+through the mutt configuration, especially in the
+<link linkend="index-format">&dollar;index&lowbar;format"</link>,
+<link linkend="pager-format">&dollar;pager&lowbar;format"</link>,
+<link linkend="status-format">&dollar;status&lowbar;format"</link>,
+and other ``*_format'' variables. These can be very straightforward,
+and it's quite possible you already know how to use them.
+</para>
+
+<para>
+The most basic format string element is a percent symbol followed
+by another character. For example, <literal>%s</literal>
+represents a message's Subject: header in the <link
+linkend="index-format">&dollar;index&lowbar;format"</link> variable. The
+``expandos'' available are documented with each format variable, but
+there are general modifiers available with all formatting expandos,
+too. Those are our concern here.
+</para>
+
+<para>
+Some of the modifers are borrowed right out of C (though you might
+know them from Perl, Python, shell, or another langugage). These are
+the [-]m.n modifiers, as in <literal>%-12.12s</literal>. As with
+such programming languages, these modifiers allow you to specify the
+minumum and maximum size of the resulting string, as well as its
+justification. If the ``-'' sign follows the percent, the string will
+be left-justified instead of right-justified. If there's a number
+immediately following that, it's the minimum amount of space the
+formatted string will occupy -- if it's naturally smaller than that, it
+will be padded out with spaces.  If a decimal point and another number
+follow, that's the maximum space allowable -- the string will not be
+permitted to exceed that width, no matter its natural size. Each of
+these three elements is optional, so that all these are legal format
+strings:
+<literal>%-12s</literal>
+<literal>%4c</literal>
+<literal>%.15F</literal>
+<literal>%-12.15L</literal>
+</para>
+
+<para>
+Mutt adds some other modifiers to format strings. If you use an equals
+symbol (<literal>=</literal>) as a numeric prefix (like the minus
+above), it will force the string to be centered within its minimum
+space range. For example, <literal>%=14y</literal> will reserve 14
+characters for the %y expansion -- that's the X-Label: header, in
+<literal>&dollar;index&lowbar;format</literal>. If the expansion
+results in a string less than 14 characters, it will be centered in a
+14-character space.  If the X-Label for a message were "test", that
+expansion would look like ``     test     ''.
+</para>
+
+<para>
+There are two very little-known modifiers that affect the way that an
+expando is replaced. If there is an underline (``&lowbar;'') character
+between any format modifiers (as above) and the expando letter, it will
+expands in all lower case. And if you use a colon (``:''), it will
+replace all decimal points with underlines.
+</para>
+
+</sect1>
+
 </chapter>
 
 <chapter id="advancedusage">
diff --git a/init.h b/init.h
index 2674bef8d06ef6f850f3999011757b5db9b55b3e..73260a153b850242c47952b97d8f1330d56481d9 100644 (file)
--- a/init.h
+++ b/init.h
@@ -225,7 +225,9 @@ struct option_t MuttVars[] = {
   **             (please see the ``$attachments'' section for possible speed effects)
   ** .dt %>X .dd right justify the rest of the string and pad with character "X"
   ** .dt %|X .dd pad to the end of the line with character "X"
+  ** .dt %*X .dd soft-fill with character "X" as pad
   ** .de
+  ** For an explanation of `soft-fill', see the ``$$index_format'' documentation.
   */
   { "attach_sep",      DT_STR,  R_NONE, UL &AttachSep, UL "\n" },
   /*
@@ -614,7 +616,9 @@ struct option_t MuttVars[] = {
   ** .dt %u  .dd owner name (or numeric uid, if missing)
   ** .dt %>X .dd right justify the rest of the string and pad with character "X"
   ** .dt %|X .dd pad to the end of the line with character "X"
+  ** .dt %*X .dd soft-fill with character "X" as pad
   ** .de
+  ** For an explanation of `soft-fill', see the ``$$index_format'' documentation.
   */
   { "followup_to",     DT_BOOL, R_NONE, OPTFOLLOWUPTO, 1 },
   /*
@@ -1036,7 +1040,15 @@ struct option_t MuttVars[] = {
   **                function ``strftime''; a leading bang disables locales.
   ** .dt %>X    .dd right justify the rest of the string and pad with character "X"
   ** .dt %|X    .dd pad to the end of the line with character "X"
+  ** .dt %*X    .dd soft-fill with character "X" as pad
   ** .de
+  ** `Soft-fill' deserves some explanation. Normal right-justification
+  ** will print everything to the left of the %>, displaying padding and
+  ** the whatever lies to the right only if there's room. By contrast,
+  ** soft-fill gives priority to the right-hand side, guaranteeing space
+  ** to display it and showing padding only if there's still room. If
+  ** necessary, soft-fill will eat text leftwards to make room for
+  ** rightward text.
   ** .pp
   ** See also: ``$$to_chars''.
   */
@@ -1352,7 +1364,7 @@ struct option_t MuttVars[] = {
   ** default, Mutt will display the line after the last one on the screen
   ** at the top of the next page (0 lines of context).
   */
-  { "pager_format",    DT_STR,  R_PAGER, UL &PagerFmt, UL "-%Z- %C/%m: %-20.20n   %s%> -- (%P)" },
+  { "pager_format",    DT_STR,  R_PAGER, UL &PagerFmt, UL "-%Z- %C/%m: %-20.20n   %s% -- (%P)" },
   /*
   ** .pp
   ** This variable controls the format of the one-line message ``status''
@@ -2739,7 +2751,9 @@ struct option_t MuttVars[] = {
   ** .dt %V  .dd currently active limit pattern, if any *
   ** .dt %>X .dd right justify the rest of the string and pad with "X"
   ** .dt %|X .dd pad to the end of the line with "X"
+  ** .dt %*X .dd soft-fill with character "X" as pad
   ** .de
+  ** For an explanation of `soft-fill', see the ``$$index_format'' documentation.
   ** .pp
   ** * = can be optionally printed if nonzero
   ** .pp
diff --git a/lib.h b/lib.h
index e022bb34d74d9dfd8d7aca8c08508e20222bf3d5..7ff3ebe4259c124e8373136e1a0045aa2c2e9894 100644 (file)
--- a/lib.h
+++ b/lib.h
 # define MAX(a,b) ((a) < (b) ? (b) : (a))
 # define MIN(a,b) ((a) < (b) ? (a) : (b))
 
+/* For mutt_format_string() justifications */
+/* Making left 0 and center -1 is of course completely nonsensical, but
+ * it retains compatibility for any patches that call mutt_format_string.
+ * Once patches are updated to use FMT_*, these can be made sane. */
+#define FMT_LEFT       0
+#define FMT_RIGHT      1
+#define FMT_CENTER     -1
 
 #define FOREVER while (1)
 
diff --git a/menu.c b/menu.c
index e8393b1754f40090c34da255aba3f66507a1308b..631bbed3aad22e2fedf8a9fe2326e6da29bbfd56 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -160,7 +160,7 @@ void menu_pad_string (char *s, size_t n)
   int shift = option (OPTARROWCURSOR) ? 3 : 0;
   int cols = COLS - shift;
 
-  mutt_format_string (s, n, cols, cols, 0, ' ', scratch, mutt_strlen (scratch), 1);
+  mutt_format_string (s, n, cols, cols, FMT_LEFT, ' ', scratch, mutt_strlen (scratch), 1);
   s[n - 1] = 0;
   FREE (&scratch);
 }
index 497b5f8b08550397b52f21efddc289522193eb79..ccfc86959c10e6c4dcbcb0acf1f233b73a9a2a03 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -999,6 +999,7 @@ void mutt_FormatString (char *dest,         /* output buffer */
 {
   char prefix[SHORT_STRING], buf[LONG_STRING], *cp, *wptr = dest, ch;
   char ifstring[SHORT_STRING], elsestring[SHORT_STRING];
+  char remainder[LONG_STRING];
   size_t wlen, count, len, wid;
   pid_t pid;
   FILE *filter;
@@ -1147,7 +1148,7 @@ void mutt_FormatString (char *dest,               /* output buffer */
        cp = prefix;
        count = 0;
        while (count < sizeof (prefix) &&
-              (isdigit ((unsigned char) *src) || *src == '.' || *src == '-'))
+              (isdigit ((unsigned char) *src) || *src == '.' || *src == '-' || *src == '='))
        {
          *cp++ = *src++;
          count++;
@@ -1239,6 +1240,46 @@ void mutt_FormatString (char *dest,              /* output buffer */
        }
        break; /* skip rest of input */
       }
+      /* soft fill */
+      else if (ch == '*')
+      {
+       int space;
+
+       /* truncate to fit remainder, pad with chr. */
+       ch = *src++;    /* pad chr */
+       mutt_FormatString (remainder, sizeof(remainder), 0, src, callback,
+         data, flags);
+
+       len = mutt_strlen(remainder);
+       space = COLS - wlen - len;      /* bytes remaining unformatted */
+
+       /* if space > 0, this is space that needs to be filled */
+       if (space > 0)
+       {
+         memset(wptr, ch, space);
+         wptr += space;
+         wlen += space;
+       }
+
+       /* if space < 0, there's not enough room for remainder -- backtrack */
+       else if (space < 0) {
+         wptr += space;
+         wlen += space;
+         if (wlen < 0) {
+           wptr = dest;
+           wlen = 0;
+         }
+       }
+
+       /* Since remainder is already formatted, copy it *
+        * in.  This prevents having to format it twice. */
+       if (len > COLS)
+         len = COLS;
+       memcpy(wptr, remainder, len);
+       wptr += len;
+       wlen += len;
+      }
+
       else
       {
        short tolower =  0;
diff --git a/query.c b/query.c
index 1f88dbee7e8b92f15152d23a9794428a1f0461ee..248394b0957b481010ec18491d8cda3c36d4495e 100644 (file)
--- a/query.c
+++ b/query.c
@@ -204,7 +204,7 @@ static void query_entry (char *s, size_t slen, MUTTMENU *m, int num)
 
   mutt_format_string (buf2, sizeof (buf2),
                      FirstColumn + 2, FirstColumn + 2,
-                     0, ' ', table[num].data->name,
+                     FMT_LEFT, ' ', table[num].data->name,
                      mutt_strlen (table[num].data->name), 0);
 
   snprintf (s, slen, " %c %3d %s %-*.*s %s", 
index ff5954eed3e9f4a0163fd4c2ad442dea01684538..7890cfbe7c91ac0344a26a9002b766f5ccab33f6 100644 (file)
--- a/recvcmd.c
+++ b/recvcmd.c
@@ -182,7 +182,7 @@ void mutt_attach_bounce (FILE * fp, HEADER * hdr,
   if (mutt_strwidth (prompt) > COLS - extra_space)
   {
     mutt_format_string (prompt, sizeof (prompt) - 4,
-                       0, COLS-extra_space, 0, 0,
+                       0, COLS-extra_space, FMT_LEFT, 0,
                        prompt, sizeof (prompt), 0);
     safe_strcat (prompt, sizeof (prompt), "...?");
   }