From 08f9d454e02de3df6c4a926fc9dbbce05efbbce0 Mon Sep 17 00:00:00 2001 From: joerg Date: Sat, 10 Aug 1996 13:38:44 +0000 Subject: Finally implement a simple commandline history in DDB. Emacs-style line editing has already been there (did anybody ever notice this? :), so i `only' had to add ^P and ^N. The approach is fairly minimalistic, with the advantage of keeping the bloat as small as 864 bytes of .text and 16 bytes of .bss, plus 10*120 bytes malloc'ed history buffer at the first use. --- sys/ddb/db_input.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/sys/ddb/db_input.c b/sys/ddb/db_input.c index f71ed8a..5e737ca 100644 --- a/sys/ddb/db_input.c +++ b/sys/ddb/db_input.c @@ -23,7 +23,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: db_input.c,v 1.12 1995/12/10 19:07:59 bde Exp $ + * $Id: db_input.c,v 1.13 1996/05/08 04:28:34 gpalmer Exp $ */ /* @@ -32,6 +32,7 @@ */ #include +#include #include #include @@ -53,6 +54,13 @@ static char * db_lbuf_end; /* end of input line buffer */ static char * db_lc; /* current character */ static char * db_le; /* one past last character */ +/* + * Simple input line history support. + */ +static char * db_lhistory; +static int db_lhistlsize, db_lhistidx, db_lhistcur; +#define DB_LHIST_NLINES 10 + #define CTRL(c) ((c) & 0x1f) #define isspace(c) ((c) == ' ' || (c) == '\t') #define BLANK ' ' @@ -171,11 +179,46 @@ db_inputchar(c) break; case CTRL('r'): db_putstring("^R\n", 3); + redraw: if (db_le > db_lbuf_start) { db_putstring(db_lbuf_start, db_le - db_lbuf_start); db_putnchars(BACKUP, db_le - db_lc); } break; + case CTRL('p'): + /* Make previous history line the active one. */ + if (db_lhistcur >= 0) { + bcopy(db_lhistory + db_lhistcur * db_lhistlsize, + db_lbuf_start, db_lhistlsize); + db_lhistcur--; + goto hist_redraw; + } + break; + case CTRL('n'): + /* Make next history line the active one. */ + if (db_lhistcur < db_lhistidx - 1) { + db_lhistcur += 2; + bcopy(db_lhistory + db_lhistcur * db_lhistlsize, + db_lbuf_start, db_lhistlsize); + } else { + /* + * ^N through tail of history, reset the + * buffer to zero length. + */ + *db_lbuf_start = '\0'; + db_lhistcur = db_lhistidx; + } + + hist_redraw: + db_putnchars(BACKUP, db_le - db_lbuf_start); + db_putnchars(BLANK, db_le - db_lbuf_start); + db_putnchars(BACKUP, db_le - db_lbuf_start); + db_le = index(db_lbuf_start, '\0'); + if (db_le[-1] == '\r' || db_le[-1] == '\n') + *--db_le = '\0'; + db_lc = db_le; + goto redraw; + case '\n': case '\r': *db_le++ = c; @@ -211,6 +254,20 @@ db_readline(lstart, lsize) char * lstart; int lsize; { + if (db_lhistory && lsize != db_lhistlsize) { + /* Should not happen, but to be sane, throw history away. */ + FREE(db_lhistory, M_TEMP); + db_lhistory = 0; + } + if (db_lhistory == 0) { + /* Initialize input line history. */ + db_lhistlsize = lsize; + db_lhistidx = -1; + MALLOC(db_lhistory, char *, lsize * DB_LHIST_NLINES, + M_TEMP, M_NOWAIT); + } + db_lhistcur = db_lhistidx; + db_force_whitespace(); /* synch output position */ db_lbuf_start = lstart; @@ -222,8 +279,20 @@ db_readline(lstart, lsize) continue; db_printf("\n"); /* synch output position */ - *db_le = 0; + + if (db_le - db_lbuf_start > 1) { + /* Maintain input line history for non-empty lines. */ + if (++db_lhistidx == DB_LHIST_NLINES) { + /* Rotate history. */ + ovbcopy(db_lhistory + db_lhistlsize, db_lhistory, + db_lhistlsize * (DB_LHIST_NLINES - 1)); + db_lhistidx--; + } + bcopy(lstart, db_lhistory + (db_lhistidx * db_lhistlsize), + db_lhistlsize); + } + return (db_le - db_lbuf_start); } -- cgit v1.1