<<< Date Index >>>     <<< Thread Index >>>

[PATCH] expand mutt vars as we do environment vars



The attached patch causes mutt to expand mutt variables in the same
way that it expands environment variables. For example, you could do
something like this in a hook:

set sendmail="mysmtp -f $from"

A couple of gotchas: environment variables take precedence, and I
haven't gotten around to expanding them in a couple of places (notably
shell-escape).

At the very least it sets the stage for an easy way of doing xterm
titles :)

feedback welcome...
Index: init.c
===================================================================
RCS file: /home/roessler/cvs/mutt/init.c,v
retrieving revision 3.39
diff -u -p -r3.39 init.c
--- init.c      6 Sep 2005 03:16:11 -0000       3.39
+++ init.c      17 Sep 2005 04:16:11 -0000
@@ -49,6 +49,8 @@
 #include <errno.h>
 #include <sys/wait.h>
 
+static int var_to_string (int idx, char* val, size_t len);
+
 void toggle_quadoption (int opt)
 {
   int n = opt/4;
@@ -260,6 +262,7 @@ int mutt_extract_token (BUFFER *dest, BU
     else if (ch == '$' && (!qc || qc == '"') && (*tok->dptr == '{' || isalpha 
((unsigned char) *tok->dptr)))
     {
       char *env = NULL, *var = NULL;
+      int idx;
 
       if (*tok->dptr == '{')
       {
@@ -279,6 +282,14 @@ int mutt_extract_token (BUFFER *dest, BU
       }
       if (var && (env = getenv (var)))
        mutt_buffer_addstr (dest, env);
+      else if ((idx = mutt_option_index (var)) != -1)
+      {
+        /* expand settable mutt variables */
+        char val[LONG_STRING];
+  
+        if (var_to_string (idx, val, sizeof (val)))
+          mutt_buffer_addstr (dest, val);
+      }
       FREE (&var);
     }
     else
@@ -1991,108 +2002,112 @@ int mutt_var_value_complete (char *buffe
   if (mutt_strncmp (buffer, "set", 3) == 0)
   {
     int idx;
+    char val[LONG_STRING];
+
     strfcpy (var, pt, sizeof (var));
     /* ignore the trailing '=' when comparing */
     var[mutt_strlen (var) - 1] = 0;
     if ((idx = mutt_option_index (var)) == -1) 
       return 0; /* no such variable. */
-    else
+    else if (var_to_string (idx, val, sizeof (val)))
     {
-      char tmp [LONG_STRING], tmp2[LONG_STRING];
-      char *s, *d;
-      size_t dlen = buffer + len - pt - spaces;
-      char *vals[] = { "no", "yes", "ask-no", "ask-yes" };
+      snprintf (pt, len - (pt - buffer), "%s=\"%s\"", var, val);
+      return 1;
+    }
+  }
+  return 0;
+}
 
-      tmp[0] = '\0';
+static int var_to_string (int idx, char* val, size_t len)
+{
+  char tmp[LONG_STRING];
+  char *s, *d;
+  char *vals[] = { "no", "yes", "ask-no", "ask-yes" };
 
-      if ((DTYPE(MuttVars[idx].type) == DT_STR) || 
-         (DTYPE(MuttVars[idx].type) == DT_PATH) ||
-         (DTYPE(MuttVars[idx].type) == DT_RX))
-      {
-       strfcpy (tmp, NONULL (*((char **) MuttVars[idx].data)), sizeof (tmp));
-       if (DTYPE (MuttVars[idx].type) == DT_PATH)
-         mutt_pretty_mailbox (tmp);
-      }
-      else if (DTYPE (MuttVars[idx].type) == DT_ADDR)
-      {
-       rfc822_write_address (tmp, sizeof (tmp), *((ADDRESS **) 
MuttVars[idx].data), 0);
-      }
-      else if (DTYPE (MuttVars[idx].type) == DT_QUAD)
-       strfcpy (tmp, vals[quadoption (MuttVars[idx].data)], sizeof (tmp));
-      else if (DTYPE (MuttVars[idx].type) == DT_NUM)
-       snprintf (tmp, sizeof (tmp), "%d", (*((short *) MuttVars[idx].data)));
-      else if (DTYPE (MuttVars[idx].type) == DT_SORT)
-      {
-       const struct mapping_t *map;
-       char *p;
+  tmp[0] = '\0';
 
-       switch (MuttVars[idx].type & DT_SUBTYPE_MASK)
-       {
-         case DT_SORT_ALIAS:
-           map = SortAliasMethods;
-           break;
-         case DT_SORT_BROWSER:
-           map = SortBrowserMethods;
-           break;
-         case DT_SORT_KEYS:
-            if ((WithCrypto & APPLICATION_PGP))
-              map = SortKeyMethods;
-            else
-              map = SortMethods;
-           break;
-         default:
-           map = SortMethods;
-           break;
-       }
-       p = mutt_getnamebyvalue (*((short *) MuttVars[idx].data) & SORT_MASK, 
map);
-       snprintf (tmp, sizeof (tmp), "%s%s%s",
-                 (*((short *) MuttVars[idx].data) & SORT_REVERSE) ? "reverse-" 
: "",
-                 (*((short *) MuttVars[idx].data) & SORT_LAST) ? "last-" : "",
-                 p);
-      }
-      else if (DTYPE (MuttVars[idx].type) == DT_MAGIC)
-      {
-        char *p;
+  if ((DTYPE(MuttVars[idx].type) == DT_STR) || 
+      (DTYPE(MuttVars[idx].type) == DT_PATH) ||
+      (DTYPE(MuttVars[idx].type) == DT_RX))
+  {
+    strfcpy (tmp, NONULL (*((char **) MuttVars[idx].data)), sizeof (tmp));
+    if (DTYPE (MuttVars[idx].type) == DT_PATH)
+      mutt_pretty_mailbox (tmp);
+  }
+  else if (DTYPE (MuttVars[idx].type) == DT_ADDR)
+  {
+    rfc822_write_address (tmp, sizeof (tmp), *((ADDRESS **) 
MuttVars[idx].data), 0);
+  }
+  else if (DTYPE (MuttVars[idx].type) == DT_QUAD)
+    strfcpy (tmp, vals[quadoption (MuttVars[idx].data)], sizeof (tmp));
+  else if (DTYPE (MuttVars[idx].type) == DT_NUM)
+    snprintf (tmp, sizeof (tmp), "%d", (*((short *) MuttVars[idx].data)));
+  else if (DTYPE (MuttVars[idx].type) == DT_SORT)
+  {
+    const struct mapping_t *map;
+    char *p;
 
-        switch (DefaultMagic)
-        {
-          case M_MBOX:
-            p = "mbox";
-            break;
-          case M_MMDF:
-            p = "MMDF";
-            break;
-          case M_MH:
-            p = "MH";
-            break;
-          case M_MAILDIR:
-            p = "Maildir";
-            break;
-          default:
-            p = "unknown";
-        }
-        strfcpy (tmp, p, sizeof (tmp));
-      }
-      else if (DTYPE (MuttVars[idx].type) == DT_BOOL)
-       strfcpy (tmp, option (MuttVars[idx].data) ? "yes" : "no", sizeof (tmp));
-      else
-       return 0;
-      
-      for (s = tmp, d = tmp2; *s && (d - tmp2) < sizeof (tmp2) - 2;)
-      {
-       if (*s == '\\' || *s == '"')
-         *d++ = '\\';
-       *d++ = *s++;
-      }
-      *d = '\0';
-      
-      strfcpy (tmp, pt, sizeof (tmp));
-      snprintf (pt, dlen, "%s\"%s\"", tmp, tmp2);
-         
-      return 1;
+    switch (MuttVars[idx].type & DT_SUBTYPE_MASK)
+    {
+      case DT_SORT_ALIAS:
+        map = SortAliasMethods;
+        break;
+      case DT_SORT_BROWSER:
+        map = SortBrowserMethods;
+        break;
+      case DT_SORT_KEYS:
+        if ((WithCrypto & APPLICATION_PGP))
+          map = SortKeyMethods;
+        else
+          map = SortMethods;
+        break;
+      default:
+        map = SortMethods;
+        break;
     }
+    p = mutt_getnamebyvalue (*((short *) MuttVars[idx].data) & SORT_MASK, map);
+    snprintf (tmp, sizeof (tmp), "%s%s%s",
+              (*((short *) MuttVars[idx].data) & SORT_REVERSE) ? "reverse-" : 
"",
+              (*((short *) MuttVars[idx].data) & SORT_LAST) ? "last-" : "",
+              p);
   }
-  return 0;
+  else if (DTYPE (MuttVars[idx].type) == DT_MAGIC)
+  {
+    char *p;
+
+    switch (DefaultMagic)
+    {
+      case M_MBOX:
+        p = "mbox";
+        break;
+      case M_MMDF:
+        p = "MMDF";
+        break;
+      case M_MH:
+        p = "MH";
+        break;
+      case M_MAILDIR:
+        p = "Maildir";
+        break;
+      default:
+        p = "unknown";
+    }
+    strfcpy (tmp, p, sizeof (tmp));
+  }
+  else if (DTYPE (MuttVars[idx].type) == DT_BOOL)
+    strfcpy (tmp, option (MuttVars[idx].data) ? "yes" : "no", sizeof (tmp));
+  else
+    return 0;
+
+  for (s = tmp, d = val; *s && len - (d - val) > 2; len--)
+  {
+    if (*s == '\\' || *s == '"')
+      *d++ = '\\';
+    *d++ = *s++;
+  }
+  *d = '\0';
+
+  return 1;
 }
 
 /* Implement the -Q command line flag */

Attachment: pgp6huhgoMLzh.pgp
Description: PGP signature