diff -rdu mutt.old/PATCHES mutt/PATCHES
--- mutt.old/PATCHES	Tue Nov 12 15:40:25 2002
+++ mutt/PATCHES	Tue Nov 12 15:41:32 2002
@@ -1,0 +1 @@
+patch-1.5.1.vl.savehist.1
diff -rdu mutt.old/enter.c mutt/enter.c
--- mutt.old/enter.c	Thu Jan 24 13:10:49 2002
+++ mutt/enter.c	Tue Nov 12 15:41:32 2002
@@ -524,7 +524,7 @@
 	      {
 		mutt_pretty_mailbox (buf);
 		if (!pass)
-		  mutt_history_add (hclass, buf);
+		  mutt_history_add (hclass, buf, 1);
 		rv = 0;
 		goto bye;
 	      }
@@ -651,7 +651,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 -rdu mutt.old/globals.h mutt/globals.h
--- mutt.old/globals.h	Tue Sep 10 12:07:53 2002
+++ mutt/globals.h	Tue Nov 12 15:41:32 2002
@@ -49,6 +49,7 @@
 WHERE char *ForwFmt;
 WHERE char *Fqdn;
 WHERE char *HdrFmt;
+WHERE char *HistFile;
 WHERE char *Homedir;
 WHERE char *Hostname;
 #ifdef USE_IMAP
@@ -149,6 +150,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 -rdu mutt.old/history.c mutt/history.c
--- mutt.old/history.c	Tue Sep 10 12:07:53 2002
+++ mutt/history.c	Tue Nov 12 15:41:32 2002
@@ -52,6 +52,117 @@
   h->last = 0;
 }
 
+static void 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';
+    mutt_history_add (hclass, linebuf + read, 0);
+  }
+
+  safe_free ((void **) &linebuf);
+  fclose (f);
+}
+
+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);
+  safe_free ((void **) &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;
+
+  if ((f = fopen (HistFile, "a")) == NULL)
+  {
+    mutt_perror ("fopen");
+    return;
+  }
+
+  fprintf (f, "%d:%s|\n", (int) hclass, s); /* avoid line ending with '\' */
+  fclose (f);
+  if (--n < 0)
+  {
+    n = SaveHist;
+    shrink_histfile();
+  }
+}
+
 void mutt_init_history(void)
 {
   history_class_t hclass;
@@ -63,9 +174,10 @@
     init_history(&History[hclass]);
 
   OldSize = HistSize;
+  read_histfile();
 }
   
-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];
@@ -79,6 +191,8 @@
     if (prev < 0) prev = HistSize - 1;
     if (!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 -rdu mutt.old/history.h mutt/history.h
--- mutt.old/history.h	Thu Jan 24 13:10:49 2002
+++ mutt/history.h	Tue Nov 12 15:41:32 2002
@@ -35,7 +35,7 @@
 typedef enum history_class history_class_t;
 
 void mutt_init_history(void);
-void mutt_history_add(history_class_t, const char *);
+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 -rdu mutt.old/init.h mutt/init.h
--- mutt.old/init.h	Tue Nov 12 15:14:07 2002
+++ mutt/init.h	Tue Nov 12 15:41:32 2002
@@ -712,6 +712,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
@@ -2079,6 +2084,12 @@
   ** .pp
   ** \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 },
   /*
