Hi,
I sent this patch to [EMAIL PROTECTED] a few months ago but didn't
get a reply... Maybe someone will see it here.
This patch adds a real history list to the input routine (used for the
commands `colon', `title', etc). C-p is used to go through the history
list from the latest to the oldest command, C-n for the opposite (also
with the up/down arrow keys). The history list is, as before, global to
all commands, I don't know if that's a problem for most users. Also,
when the input routine was called for the first time, C-p used to clear
the input line (a side effect of restoring a previous empty line), with
my patch it doesn't do that anymore.
Duplicate commands are moved to the front of the list and not added
again. The list is never freed since it's supposed to live as long as
the screen session anyway, if you feel it's necessary I can add a
routine to free it at exit (and possibly, add a clearinputhistory
command).
I couldn't find a CVS tree anywhere (the Savannah CVS repo is empty) so
this patch is against 4.0.2.
All feedback is welcome.
--
Romain Francoise <[EMAIL PROTECTED]> | No one should fear what they
it's a miracle -- http://orebokech.com/ | cannot see. --Beth Gibbons
--- screen-4.0.2.orig/input.c
+++ screen-4.0.2/input.c
@@ -41,10 +41,12 @@
char buf[101]; /* text buffer */
int len; /* length of the editible string */
int pos; /* cursor position in editable string */
+ struct inpline *prev, *next;
};
-static struct inpline inphist; /* XXX: should be a dynamic list */
-
+/* History list: inphist is the head of the list, inpcur is a pointer to
+ the current position when walking the list. */
+static struct inpline *inphist, *inpcur;
struct inpdata
{
@@ -275,14 +277,32 @@
LGotoPos(flayer, ++x, INPUTLINE);
inpdata->inp.pos++;
}
- else if (ch == '\020' || (unsigned char)ch == 0220) /* CTRL-P */
- {
+ else if ((ch == '\020' || (unsigned char)ch == 0220
+ || ch == '\016' || (unsigned char)ch == 0216)
+ && inphist) /* CTRL-P or CTRL-N */
+ {
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 (ch == '\020' || (unsigned char)ch == 0220) /* CTRL-P */
+ {
+ if (!inpcur)
+ inpcur = inphist;
+ else if (inpcur->next)
+ inpcur = inpcur->next;
+ }
+ else if (ch == '\016' || (unsigned char)ch == 0216) /* CTRL-N */
+ {
+ if (!inpcur)
+ for (inpcur = inphist; inpcur && inpcur->next;
+ inpcur = inpcur->next);
+ else if (inpcur->prev)
+ inpcur = inpcur->prev;
+ }
+ memcpy(&inpdata->inp, inpcur, sizeof(struct inpline));
+
if (inpdata->inp.len > inpdata->inpmaxlen)
inpdata->inp.len = inpdata->inpmaxlen;
if (inpdata->inp.pos > inpdata->inp.len)
@@ -309,9 +329,45 @@
if (ch != '\004' && ch != '\n' && ch != '\r')
inpdata->inp.len = 0;
inpdata->inp.buf[inpdata->inp.len] = 0;
+ inpcur = NULL;
if (inpdata->inp.len && inpdata->inpmode == 0)
- inphist = inpdata->inp; /* structure copy */
+ {
+ struct inpline *inpelt, *inpdupe = NULL;
+ for (inpelt = inphist; inpelt && !inpdupe; inpelt = inpelt->next)
+ if (strcmp(inpdata->inp.buf, inpelt->buf) == 0)
+ inpdupe = inpelt;
+ if (!inpdupe)
+ {
+ if ((inpelt = malloc(sizeof(struct inpline))) == NULL)
+ {
+ Msg(0, "No memory for history element, not saving");
+ }
+ else
+ {
+ memcpy(inpelt, &inpdata->inp, sizeof(struct inpline));
+ if (inphist)
+ inphist->prev = inpelt;
+ inpelt->next = inphist;
+ inpelt->prev = NULL;
+ inphist = inpelt;
+ }
+ }
+ else
+ {
+ /* Move duplicate element to the front. */
+ if (inpdupe->prev)
+ {
+ inpdupe->prev->next = inpdupe->next;
+ if (inpdupe->next)
+ inpdupe->next->prev = inpdupe->prev;
+ inpdupe->next = inphist;
+ inpdupe->prev = NULL;
+ inphist->prev = inpdupe;
+ inphist = inpdupe;
+ }
+ }
+ }
flayer->l_data = 0;
InpAbort(); /* redisplays... */
_______________________________________________
screen-users mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/screen-users