]> granicus.if.org Git - mutt/commitdiff
Add a scratch buffer to the history ring. (closes #3082)
authorKevin McCarthy <kevin@8t8.us>
Tue, 12 Aug 2014 21:04:55 +0000 (14:04 -0700)
committerKevin McCarthy <kevin@8t8.us>
Tue, 12 Aug 2014 21:04:55 +0000 (14:04 -0700)
This patch creates an extra slot in the history ring for a scratch
buffer (at h->last).  If you are editing inside that buffer, it is
preserved when you scroll up/down through the history.  Editing while in
other places in history are *not* preserved with this patch.

Another behavior change worth noting with this patch: the position in
history is now reset to the scratch buffer after each input entry.
Before, the position would be stay wherever it was - you didn't restart
at the "bottom" each time.

doc/manual.xml.head
enter.c
history.c
history.h

index 37606670f267dfa462bccf3f4d677461ecb78088..b84ffbbd73ef008eb82df50ab44d4e91217d816c 100644 (file)
@@ -580,9 +580,9 @@ is controlled by the <link linkend="history">$history</link> variable
 and can be made persistent using an external file specified using <link
 linkend="history-file">$history_file</link>.  You may cycle through them
 at an editor prompt by using the <literal>&lt;history-up&gt;</literal>
-and/or <literal>&lt;history-down&gt;</literal> commands. But notice that
-Mutt does not remember the currently entered text, it only cycles
-through history and wraps around at the end or beginning.
+and/or <literal>&lt;history-down&gt;</literal> commands.  Mutt will
+remember the currently entered text as you cycle through history, and
+will wrap around to the initial entry line.
 </para>
 
 <para>
diff --git a/enter.c b/enter.c
index 077c1e63a60d85f9eb60601bd2e287c6bcbda39a..377e7a1c221415618bbcfd11add47f9395eb2e8b 100644 (file)
--- a/enter.c
+++ b/enter.c
@@ -302,12 +302,22 @@ int _mutt_enter_string (char *buf, size_t buflen, int y, int x,
       {
        case OP_EDITOR_HISTORY_UP:
          state->curpos = state->lastchar;
+         if (mutt_history_at_scratch (hclass))
+         {
+           my_wcstombs (buf, buflen, state->wbuf, state->curpos);
+           mutt_history_save_scratch (hclass, buf);
+         }
          replace_part (state, 0, mutt_history_prev (hclass));
          redraw = M_REDRAW_INIT;
          break;
 
        case OP_EDITOR_HISTORY_DOWN:
          state->curpos = state->lastchar;
+         if (mutt_history_at_scratch (hclass))
+         {
+           my_wcstombs (buf, buflen, state->wbuf, state->curpos);
+           mutt_history_save_scratch (hclass, buf);
+         }
          replace_part (state, 0, mutt_history_next (hclass));
          redraw = M_REDRAW_INIT;
          break;
@@ -732,6 +742,7 @@ self_insert:
   
   bye:
   
+  mutt_reset_history_state (hclass);
   FREE (&tempbuf);
   return rv;
 }
index 9efbdb47d4ad88546835f7071a25f38fc378c437..e72e9fb233fbe419f4e68958e27f4afabaa89c40 100644 (file)
--- a/history.c
+++ b/history.c
@@ -45,14 +45,14 @@ static void init_history (struct history *h)
   {
     if (h->hist)
     {
-      for (i = 0 ; i < OldSize ; i ++)
+      for (i = 0 ; i <= OldSize ; i ++)
        FREE (&h->hist[i]);
       FREE (&h->hist);
     }
   }
   
   if (HistSize)
-    h->hist = safe_calloc (HistSize, sizeof (char *));
+    h->hist = safe_calloc (HistSize + 1, sizeof (char *));
   
   h->cur = 0;
   h->last = 0;
@@ -230,7 +230,7 @@ void mutt_history_add (history_class_t hclass, const char *s, int save)
   if (*s)
   {
     prev = h->last - 1;
-    if (prev < 0) prev = HistSize - 1;
+    if (prev < 0) prev = HistSize;
 
     /* don't add to prompt history:
      *  - lines beginning by a space
@@ -241,7 +241,7 @@ void mutt_history_add (history_class_t hclass, const char *s, int save)
       if (save && SaveHist)
         save_history (hclass, s);
       mutt_str_replace (&h->hist[h->last++], s);
-      if (h->last > HistSize - 1)
+      if (h->last > HistSize)
        h->last = 0;
     }
   }
@@ -257,9 +257,12 @@ char *mutt_history_next (history_class_t hclass)
     return (""); /* disabled */
 
   next = h->cur + 1;
-  if (next > HistSize - 1)
+  if (next > HistSize)
     next = 0;
-  h->cur = h->hist[next] ? next : 0;
+  if (h->hist[next] || (next == h->last))
+    h->cur = next;
+  else
+    h->cur = 0;
   return (h->hist[h->cur] ? h->hist[h->cur] : "");
 }
 
@@ -274,11 +277,43 @@ char *mutt_history_prev (history_class_t hclass)
   prev = h->cur - 1;
   if (prev < 0)
   {
-    prev = HistSize - 1;
-    while (prev > 0 && h->hist[prev] == NULL)
+    prev = HistSize;
+    while ((prev > 0) && (prev != h->last) && (h->hist[prev] == NULL))
       prev--;
   }
-  if (h->hist[prev])
+  if (h->hist[prev] || (prev == h->last))
     h->cur = prev;
   return (h->hist[h->cur] ? h->hist[h->cur] : "");
 }
+
+void mutt_reset_history_state (history_class_t hclass)
+{
+  struct history *h = GET_HISTORY(hclass);
+
+  if (!HistSize || !h)
+    return; /* disabled */
+
+  h->cur = h->last;
+}
+
+int mutt_history_at_scratch (history_class_t hclass)
+{
+  struct history *h = GET_HISTORY(hclass);
+
+  if (!HistSize || !h)
+    return 0; /* disabled */
+
+  return h->cur == h->last;
+}
+
+void mutt_history_save_scratch (history_class_t hclass, const char *s)
+{
+  struct history *h = GET_HISTORY(hclass);
+
+  if (!HistSize || !h)
+    return; /* disabled */
+
+  /* Don't check if s has a value because the scratch buffer may contain
+   * an old garbage value that should be overwritten */
+  mutt_str_replace (&h->hist[h->last], s);
+}
index 0bd37ddb3dcdc9cac52a52e224d07a272570f596..994526b630f75e83682bf8364ba127614da5e0de 100644 (file)
--- a/history.h
+++ b/history.h
@@ -41,5 +41,8 @@ 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);
+void mutt_reset_history_state (history_class_t);
+int mutt_history_at_scratch (history_class_t);
+void mutt_history_save_scratch (history_class_t, const char *);
 
 #endif