diff -Naurd mutt-1.5.12-old/PATCHES mutt-1.5.12-new/PATCHES
--- mutt-1.5.12-old/PATCHES	2006-07-14 18:12:47.000000000 +0000
+++ mutt-1.5.12-new/PATCHES	2006-08-03 17:01:28.000000000 +0000
@@ -0,0 +1 @@
+patch-1.5.12.vl.savehist.1
diff -Naurd mutt-1.5.12-old/enter.c mutt-1.5.12-new/enter.c
--- mutt-1.5.12-old/enter.c	2006-05-18 18:44:29.000000000 +0000
+++ mutt-1.5.12-new/enter.c	2006-08-03 17:01:28.000000000 +0000
@@ -548,7 +548,7 @@
 	      {
 		mutt_pretty_mailbox (buf);
 		if (!pass)
-		  mutt_history_add (hclass, buf);
+		  mutt_history_add (hclass, buf, 1);
 		rv = 0;
 		goto bye;
 	      }
@@ -653,7 +653,7 @@
 	/* Convert from wide characters */
 	my_wcstombs (buf, buflen, state->wbuf, state->lastchar);
 	if (!pass)
-	  mutt_history_add (hclass, buf);
+	  mutt_history_add (hclass, buf, 1);
 
 	if (multiple)
 	{
diff -Naurd mutt-1.5.12-old/globals.h mutt-1.5.12-new/globals.h
--- mutt-1.5.12-old/globals.h	2006-07-05 08:40:05.000000000 +0000
+++ mutt-1.5.12-new/globals.h	2006-08-03 17:01:28.000000000 +0000
@@ -51,6 +51,7 @@
 WHERE char *ForwFmt;
 WHERE char *Fqdn;
 WHERE char *HdrFmt;
+WHERE char *HistFile;
 WHERE char *Homedir;
 WHERE char *Hostname;
 #ifdef USE_IMAP
@@ -189,6 +190,7 @@
 WHERE short PagerContext;
 WHERE short PagerIndexLines;
 WHERE short ReadInc;
+WHERE short SaveHist;
 WHERE short SendmailWait;
 WHERE short SleepTime INITVAL (1);
 WHERE short Timeout;
diff -Naurd mutt-1.5.12-old/history.c mutt-1.5.12-new/history.c
--- mutt-1.5.12-old/history.c	2006-07-05 08:40:05.000000000 +0000
+++ mutt-1.5.12-new/history.c	2006-08-03 17:01:28.000000000 +0000
@@ -56,6 +56,144 @@
   h->last = 0;
 }
 
+void mutt_read_histfile (void)
+{
+  FILE *f;
+  int line = 0, hclass, read;
+  char *linebuf = NULL, *p;
+  size_t buflen;
+
+  if ((f = fopen (HistFile, "r")) == NULL)
+    return;
+
+  while ((linebuf = mutt_read_line (linebuf, &buflen, f, &line)) != NULL)
+  {
+    read = 0;
+    if (sscanf (linebuf, "%d:%n", &hclass, &read) < 1 || read == 0 ||
+        *(p = linebuf + strlen (linebuf) - 1) != '|')
+    {
+      mutt_error (_("Bad history file format (line %d)"), line);
+      break;
+    }
+    *p = '\0';
+    p = safe_strdup (linebuf + read);
+    if (p)
+    {
+      mutt_convert_string (&p, "utf-8", Charset, 0);
+      mutt_history_add (hclass, p, 0);
+      FREE (&p);
+    }
+  }
+
+  fclose (f);
+  FREE (&linebuf);
+}
+
+static void shrink_histfile (void)
+{
+  char tmpfname[_POSIX_PATH_MAX];
+  FILE *f, *tmp = NULL;
+  int n[HC_LAST] = { 0 };
+  int line, hclass;
+  char *linebuf = NULL;
+  size_t buflen;
+
+  if ((f = fopen (HistFile, "r")) == NULL)
+    return;
+
+  line = 0;
+  while ((linebuf = mutt_read_line (linebuf, &buflen, f, &line)) != NULL)
+  {
+    if (sscanf (linebuf, "%d", &hclass) < 1)
+    {
+      mutt_error (_("Bad history file format (line %d)"), line);
+      goto cleanup;
+    }
+    n[hclass]++;
+  }
+
+  for(hclass = HC_FIRST; hclass < HC_LAST; hclass++)
+    if (n[hclass] > SaveHist)
+    {
+      mutt_mktemp (tmpfname);
+      if ((tmp = safe_fopen (tmpfname, "w+")) == NULL)
+        mutt_perror (tmpfname);
+      break;
+    }
+
+  if (tmp != NULL)
+  {
+    rewind (f);
+    line = 0;
+    while ((linebuf = mutt_read_line (linebuf, &buflen, f, &line)) != NULL)
+    {
+      if (sscanf (linebuf, "%d", &hclass) < 1)
+      {
+        mutt_error (_("Bad history file format (line %d)"), line);
+        goto cleanup;
+      }
+      if (n[hclass]-- <= SaveHist)
+        fprintf (tmp, "%s\n", linebuf);
+    }
+  }
+
+cleanup:
+  fclose (f);
+  FREE (&linebuf);
+  if (tmp != NULL)
+  {
+    if (fflush (tmp) == 0 && (f = fopen (HistFile, "w")) != NULL)
+    {
+      rewind (tmp);
+      mutt_copy_stream (tmp, f);
+      fclose (f);
+    }
+    fclose (tmp);
+    unlink (tmpfname);
+  }
+}
+
+static void save_history (history_class_t hclass, const char *s)
+{
+  static int n = 0;
+  FILE *f;
+  char *tmp, *p;
+
+  if (!s || !*s)  /* This shouldn't happen, but it's safer. */
+    return;
+
+  if ((f = fopen (HistFile, "a")) == NULL)
+  {
+    mutt_perror ("fopen");
+    return;
+  }
+
+  tmp = safe_strdup (s);
+  mutt_convert_string (&tmp, Charset, "utf-8", 0);
+
+  /* Format of a history item (1 line): "<histclass>:<string>|".
+     We add a '|' in order to avoid lines ending with '\'. */
+  fprintf (f, "%d:", (int) hclass);
+  for (p = tmp; *p; p++)
+  {
+    /* Don't copy \n as a history item must fit on one line. The string
+       shouldn't contain such a character anyway, but as this can happen
+       in practice, we must deal with that. */
+    if (*p != '\n')
+      putc ((unsigned char) *p, f);
+  }
+  fputs ("|\n", f);
+
+  fclose (f);
+  FREE (&tmp);
+
+  if (--n < 0)
+  {
+    n = SaveHist;
+    shrink_histfile();
+  }
+}
+
 void mutt_init_history(void)
 {
   history_class_t hclass;
@@ -69,7 +207,7 @@
   OldSize = HistSize;
 }
   
-void mutt_history_add (history_class_t hclass, const char *s)
+void mutt_history_add (history_class_t hclass, const char *s, int save)
 {
   int prev;
   struct history *h = &History[hclass];
@@ -88,6 +226,8 @@
      */
     if (*s != ' ' && (!h->hist[prev] || mutt_strcmp (h->hist[prev], s) != 0))
     {
+      if (save && SaveHist)
+        save_history (hclass, s);
       mutt_str_replace (&h->hist[h->last++], s);
       if (h->last > HistSize - 1)
 	h->last = 0;
diff -Naurd mutt-1.5.12-old/history.h mutt-1.5.12-new/history.h
--- mutt-1.5.12-old/history.h	2005-09-18 08:22:22.000000000 +0000
+++ mutt-1.5.12-new/history.h	2006-08-03 17:01:28.000000000 +0000
@@ -35,7 +35,8 @@
 typedef enum history_class history_class_t;
 
 void mutt_init_history(void);
-void mutt_history_add(history_class_t, const char *);
+void mutt_read_histfile(void);
+void mutt_history_add(history_class_t, const char *, int);
 char *mutt_history_next(history_class_t);
 char *mutt_history_prev(history_class_t);
 
diff -Naurd mutt-1.5.12-old/init.c mutt-1.5.12-new/init.c
--- mutt-1.5.12-old/init.c	2006-07-05 08:40:05.000000000 +0000
+++ mutt-1.5.12-new/init.c	2006-08-03 17:01:28.000000000 +0000
@@ -3012,6 +3012,8 @@
       mutt_exit(1);
   }
 
+  mutt_read_histfile ();
+
 #if 0
   set_option (OPTWEED); /* turn weeding on by default */
 #endif
diff -Naurd mutt-1.5.12-old/init.h mutt-1.5.12-new/init.h
--- mutt-1.5.12-old/init.h	2006-07-05 08:40:05.000000000 +0000
+++ mutt-1.5.12-new/init.h	2006-08-03 17:01:28.000000000 +0000
@@ -779,6 +779,11 @@
   ** the string history buffer. The buffer is cleared each time the
   ** variable is set.
   */
+  { "history_file",     DT_PATH, R_NONE, UL &HistFile, UL "~/.mutthistory" },
+  /*
+  ** .pp
+  ** The file in which Mutt will save its history.
+  */
   { "honor_followup_to", DT_QUAD, R_NONE, OPT_MFUPTO, M_YES },
   /*
   ** .pp
@@ -2385,6 +2390,12 @@
   ** \fBNote:\fP This only applies to mbox and MMDF folders, Mutt does not
   ** delete MH and Maildir directories.
   */
+  { "save_history",     DT_NUM,  R_NONE, UL &SaveHist, 0 },
+  /*
+  ** .pp
+  ** This variable controls the size of the history saved in the
+  ** ``$$history_file'' file.
+  */
   { "save_name",	DT_BOOL, R_NONE, OPTSAVENAME, 0 },
   /*
   ** .pp
