This solution only preserves the current input for the scratch buffer (the initial location in history when they first start editing).
If the user scrolls through history and starts editing a previous entry, their edits will not be preserved if they continue scrolling through history and back. enter.c | 10 ++++++++++ history.c | 31 ++++++++++++++++++++++++++++--- history.h | 2 ++ 3 files changed, 40 insertions(+), 3 deletions(-)
# HG changeset patch # User Kevin McCarthy <[email protected]> # Date 1367102432 25200 # Branch HEAD # Node ID a383773e5acc448005203ad92ad3781cd7e2d0b3 # Parent 6508708727911b0f792175ec3ce353bc31481d3f Save the scratch buffer when scrolling through history. (closes #3082) This solution only preserves the current input for the scratch buffer (the initial location in history when they first start editing). If the user scrolls through history and starts editing a previous entry, their edits will not be preserved if they continue scrolling through history and back. diff --git a/enter.c b/enter.c --- a/enter.c +++ b/enter.c @@ -297,22 +297,32 @@ first = 0; if (ch != OP_EDITOR_COMPLETE && ch != OP_EDITOR_COMPLETE_QUERY) state->tabs = 0; redraw = M_REDRAW_LINE; switch (ch) { 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; case OP_EDITOR_BACKSPACE: if (state->curpos == 0) BEEP (); else diff --git a/history.c b/history.c --- a/history.c +++ b/history.c @@ -254,41 +254,66 @@ struct history *h = GET_HISTORY(hclass); if (!HistSize || !h) return (""); /* disabled */ next = h->cur + 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] : ""); } char *mutt_history_prev (history_class_t hclass) { int prev; struct history *h = GET_HISTORY(hclass); if (!HistSize || !h) return (""); /* disabled */ prev = h->cur - 1; if (prev < 0) { prev = HistSize; - while (prev > 0 && h->hist[prev] == NULL) + 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->cur], s); +} diff --git a/history.h b/history.h --- a/history.h +++ b/history.h @@ -37,10 +37,12 @@ typedef enum history_class history_class_t; void mutt_init_history(void); 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
