From 994688354412ae241ec090053ba38a1d998dbddf Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Tue, 12 Aug 2014 14:04:55 -0700 Subject: [PATCH] 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. --- doc/manual.xml.head | 6 ++--- enter.c | 11 ++++++++++ history.c | 53 +++++++++++++++++++++++++++++++++++++-------- history.h | 3 +++ 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 $history variable and can be made persistent using an external file specified using $history_file. You may cycle through them at an editor prompt by using the <history-up> -and/or <history-down> 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 <history-down> commands. Mutt will +remember the currently entered text as you cycle through history, and +will wrap around to the initial entry line. 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 -- 2.40.0