From: Sadrul Habib Chowdhury Date: Fri, 13 Feb 2009 04:28:58 +0000 (-0500) Subject: Multiple input history X-Git-Url: https://repo.or.cz/w/screen-lua.git/commitdiff_plain/52b776c6f253c39e7b5cf2802a634b44c07ea8ea Multiple input history Based on initial patch by Romain Francoise. I had actually committed his patch in a branch, but some bits of the implementation looked a bit more complicated than necessary. So I scratched that for this, which looks pretty similar, but I think is a bit simpler to understand. The behaviour is mostly the same, e.g. duplicate commands are moved at the beginning of the history, and not added again. There is currently no limit to the number of inputs to save in history. But it can certainly be added if necessary. Fixes #25074. --- diff --git a/src/input.c b/src/input.c index ae6cde4..165a4c8 100644 --- a/src/input.c +++ b/src/input.c @@ -46,10 +46,14 @@ struct inpline char buf[101]; /* text buffer */ int len; /* length of the editible string */ int pos; /* cursor position in editable string */ + struct inpline *next, *prev; }; -static struct inpline inphist; /* XXX: should be a dynamic list */ - +/* 'inphist' is used to store the current input when scrolling through history. + * inpline->prev == history-prev + * inpline->next == history-next + */ +static struct inpline inphist; struct inpdata { @@ -147,6 +151,7 @@ int data; inpdata->inpmaxlen = len; inpdata->inpfinfunc = finfunc; inpdata->inp.pos = inpdata->inp.len = 0; + inpdata->inp.prev = inphist.prev; inpdata->inpmode = mode; inpdata->privdata = data; if (!priv) @@ -204,6 +209,7 @@ int *plen; char ch; struct inpdata *inpdata; struct display *inpdisplay; + int prev, next; inpdata = (struct inpdata *)flayer->l_data; inpdisplay = display; @@ -323,22 +329,27 @@ int *plen; LGotoPos(flayer, ++x, INPUTLINE); inpdata->inp.pos++; } - else if (ch == '\020' || (unsigned char)ch == 0220) /* CTRL-P */ - { + else if ((prev = ((ch == '\020' || (unsigned char)ch == 0220) && /* CTRL-P */ + inpdata->inp.prev)) || + (next = ((ch == '\016' || (unsigned char)ch == 0216) && /* CTRL-N */ + inpdata->inp.next))) + { struct mchar mc; mc = mchar_so; if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO)) LClearArea(flayer, inpdata->inpstringlen, INPUTLINE, inpdata->inpstringlen + inpdata->inp.len - 1, INPUTLINE, 0, 0); - inpdata->inp = inphist; /* structure copy */ + if (prev && !inpdata->inp.next) + inphist = inpdata->inp; + memcpy(&inpdata->inp, prev ? inpdata->inp.prev : inpdata->inp.next, sizeof(struct inpline)); if (inpdata->inp.len > inpdata->inpmaxlen) inpdata->inp.len = inpdata->inpmaxlen; if (inpdata->inp.pos > inpdata->inp.len) inpdata->inp.pos = inpdata->inp.len; - x = inpdata->inpstringlen; + x = inpdata->inpstringlen; p = inpdata->inp.buf; - + if (!(inpdata->inpmode & INP_NOECHO)) { while (p < inpdata->inp.buf+inpdata->inp.len) @@ -347,7 +358,7 @@ int *plen; LPutChar(flayer, &mc, x++, INPUTLINE); } } - x = inpdata->inpstringlen + inpdata->inp.pos; + x = inpdata->inpstringlen + inpdata->inp.pos; LGotoPos(flayer, x, INPUTLINE); } @@ -359,9 +370,36 @@ int *plen; inpdata->inp.buf[inpdata->inp.len] = 0; if (inpdata->inp.len && !(inpdata->inpmode & (INP_NOECHO | INP_RAW))) - inphist = inpdata->inp; /* structure copy */ - - flayer->l_data = 0; /* so inpdata does not get freed */ + { + struct inpline *store; + + /* Look for a duplicate first */ + for (store = inphist.prev; store; store = store->prev) + { + if (strcmp(store->buf, inpdata->inp.buf) == 0) + { + if (store->next) + store->next->prev = store->prev; + if (store->prev) + store->prev->next = store->next; + store->pos = inpdata->inp.pos; + break; + } + } + + if (!store) + { + store = malloc(sizeof(struct inpline)); + memcpy(store, &inpdata->inp, sizeof(struct inpline)); + } + store->next = &inphist; + store->prev = inphist.prev; + if (inphist.prev) + inphist.prev->next = store; + inphist.prev = store; + } + + flayer->l_data = 0; /* so inpdata does not get freed */ InpAbort(); /* redisplays... */ *ppbuf = pbuf; *plen = len;