diff options
author | joerg <joerg@FreeBSD.org> | 1996-08-10 13:38:44 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 1996-08-10 13:38:44 +0000 |
commit | 08f9d454e02de3df6c4a926fc9dbbce05efbbce0 (patch) | |
tree | 47fdc1668b4cca134e7a9108a13f31e5b130f8b1 /sys/ddb | |
parent | 6d942cc83d6307d306f463abfa4a86a64bf4fad9 (diff) | |
download | FreeBSD-src-08f9d454e02de3df6c4a926fc9dbbce05efbbce0.zip FreeBSD-src-08f9d454e02de3df6c4a926fc9dbbce05efbbce0.tar.gz |
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.
Diffstat (limited to 'sys/ddb')
-rw-r--r-- | sys/ddb/db_input.c | 73 |
1 files 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 <sys/param.h> +#include <sys/malloc.h> #include <sys/systm.h> #include <machine/cons.h> @@ -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); } |