summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin McCarthy <kevin@8t8.us>2014-08-12 14:04:55 -0700
committerKevin McCarthy <kevin@8t8.us>2014-08-12 14:04:55 -0700
commit994688354412ae241ec090053ba38a1d998dbddf (patch)
tree5619d73d90b0617a1787106e02dc4df26db87cd5
parentb36a729bd1e4b915e11c1f55240b6cc0ad7014f6 (diff)
Add a scratch buffer to the history ring. (closes #3082)
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.
-rw-r--r--doc/manual.xml.head6
-rw-r--r--enter.c11
-rw-r--r--history.c53
-rw-r--r--history.h3
4 files changed, 61 insertions, 12 deletions
diff --git a/doc/manual.xml.head b/doc/manual.xml.head
index 37606670..b84ffbbd 100644
--- a/doc/manual.xml.head
+++ b/doc/manual.xml.head
@@ -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 077c1e63..377e7a1c 100644
--- 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;
}
diff --git a/history.c b/history.c
index 9efbdb47..e72e9fb2 100644
--- 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);
+}
diff --git a/history.h b/history.h
index 0bd37ddb..994526b6 100644
--- 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