diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2004-12-12 06:53:14 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2004-12-12 06:53:14 +0000 |
commit | 81ab06bd533ae45298f0aecec83cafc63aa2670c (patch) | |
tree | 4383820059ced16d90816e21f9d1892dc38a5c69 /bin/ksh | |
parent | fa3d7811bc8e12ad43c058b0529b892103e249e9 (diff) |
csh-style ! history completion, which can be activated by using
set -o csh-history (off by default)
this is not feature complete, and likely never will be. no ^
and ! has some oddities ... ksh's internal history stuff has got
some very odd behaviours that are rather nasty
ok various developers
Diffstat (limited to 'bin/ksh')
-rw-r--r-- | bin/ksh/history.c | 25 | ||||
-rw-r--r-- | bin/ksh/ksh.1 | 8 | ||||
-rw-r--r-- | bin/ksh/ksh.1tbl | 8 | ||||
-rw-r--r-- | bin/ksh/lex.c | 62 | ||||
-rw-r--r-- | bin/ksh/misc.c | 3 | ||||
-rw-r--r-- | bin/ksh/proto.h | 5 | ||||
-rw-r--r-- | bin/ksh/sh.1 | 8 | ||||
-rw-r--r-- | bin/ksh/sh.1tbl | 8 | ||||
-rw-r--r-- | bin/ksh/sh.h | 3 |
9 files changed, 119 insertions, 11 deletions
diff --git a/bin/ksh/history.c b/bin/ksh/history.c index d71e0786a51..31c7c8345d7 100644 --- a/bin/ksh/history.c +++ b/bin/ksh/history.c @@ -1,4 +1,4 @@ -/* $OpenBSD: history.c,v 1.24 2004/08/03 12:44:59 danh Exp $ */ +/* $OpenBSD: history.c,v 1.25 2004/12/12 06:53:13 deraadt Exp $ */ /* * command history @@ -63,7 +63,6 @@ static int hist_execute ARGS((char *cmd)); static int hist_replace ARGS((char **hp, const char *pat, const char *rep, int global)); static char **hist_get ARGS((const char *str, int approx, int allow_cur)); -static char **hist_get_newest ARGS((int allow_cur)); static char **hist_get_oldest ARGS((void)); static void histbackup ARGS((void)); @@ -426,7 +425,7 @@ hist_get(str, approx, allow_cur) } /* Return a pointer to the newest command in the history */ -static char ** +char ** hist_get_newest(allow_cur) int allow_cur; { @@ -527,6 +526,26 @@ findhist(start, fwd, str, anchored) return -1; } +int +findhistrel(str) + const char *str; +{ + int maxhist = histptr - history; + int start = maxhist - 1; + int rec = atoi(str); + + if (rec == 0) + return -1; + if (rec > 0) { + if (rec > maxhist) + return -1; + return rec - 1; + } + if (rec > maxhist) + return -1; + return start + rec + 1; +} + /* * set history * this means reallocating the dataspace diff --git a/bin/ksh/ksh.1 b/bin/ksh/ksh.1 index 322724270d5..4f5390802f7 100644 --- a/bin/ksh/ksh.1 +++ b/bin/ksh/ksh.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ksh.1,v 1.79 2004/12/04 07:05:13 jaredy Exp $ +.\" $OpenBSD: ksh.1,v 1.80 2004/12/12 06:53:13 deraadt Exp $ .\" .\" Copyright (c) 1980, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -3415,6 +3415,12 @@ Print job notification messages asynchronously, instead of just before the prompt. Only used if job control is enabled .Pq Fl m . +.It Ic csh-history +Enables a subset of +.Xr csh 1 Ns -style +history editing using the +.Ql ! +character. .It Fl C Ic noclobber Prevent .Ic \&> diff --git a/bin/ksh/ksh.1tbl b/bin/ksh/ksh.1tbl index 41fb79eb036..3d786cd9e97 100644 --- a/bin/ksh/ksh.1tbl +++ b/bin/ksh/ksh.1tbl @@ -1,4 +1,4 @@ -.\" $OpenBSD: ksh.1tbl,v 1.79 2004/12/04 07:05:13 jaredy Exp $ +.\" $OpenBSD: ksh.1tbl,v 1.80 2004/12/12 06:53:13 deraadt Exp $ .\" .\" Copyright (c) 1980, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -3415,6 +3415,12 @@ Print job notification messages asynchronously, instead of just before the prompt. Only used if job control is enabled .Pq Fl m . +.It Ic csh-history +Enables a subset of +.Xr csh 1 Ns -style +history editing using the +.Ql ! +character. .It Fl C Ic noclobber Prevent .Ic \&> diff --git a/bin/ksh/lex.c b/bin/ksh/lex.c index 044e19eabfb..a505b9cebc8 100644 --- a/bin/ksh/lex.c +++ b/bin/ksh/lex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lex.c,v 1.22 2004/11/10 21:13:54 deraadt Exp $ */ +/* $OpenBSD: lex.c,v 1.23 2004/12/12 06:53:13 deraadt Exp $ */ /* * lexical analysis and source input @@ -163,6 +163,66 @@ yylex(cf) Xcheck(ws, wp); switch (state) { case SBASE: + if (Flag(FCSHHISTORY) && (source->flags & SF_TTY) && c == '!') { + char **replace = NULL; + + c2 = getsc(); + if (c2 == '\0') + ; + else if (c2 == ' ' || c2 == '\t') + ungetsc(c2); + else if (c2 == '!') + replace = hist_get_newest(0); + else if (isdigit(c2) || c2 == '-' || + isalpha(c2)) { + int get = !isalpha(c2); + char match[200], *str = match; + + *str++ = c2; + do { + if ((c2 = getsc()) == '\0') + break; + if (c2 == '\t' || c2 == ' ' || + c2 == '\n') { + ungetsc(c2); + break; + } + *str++ = c2; + } while (str < &match[sizeof(match)-1]); + *str = '\0'; + + if (get) { + int h = findhistrel(match); + if (h >= 0) + replace = &history[h]; + } else { + int h = findhist(-1, 0, match, TRUE); + if (h >= 0) + replace = &history[h]; + } + } + + /* + * XXX ksh history buffer saves un-expanded + * commands. Until the history buffer code is + * changed to contain expanded commands, we + * ignore the bad commands (spinning sucks) + */ + if (replace && **replace == '!') + ungetsc(c2); + else if (replace) { + Source *s; + + /* do not strdup replacement via alloc */ + s = pushs(SREREAD, + source->areap); + s->start = s->str = *replace; + s->next = source; + source = s; + continue; + } else + ungetsc(c2); + } if (c == '[' && (cf & (VARASN|ARRAYVAR))) { *wp = EOS; /* temporary */ if (is_wdvarname(Xstring(ws, wp), FALSE)) diff --git a/bin/ksh/misc.c b/bin/ksh/misc.c index 045f2867e9c..157b81bede2 100644 --- a/bin/ksh/misc.c +++ b/bin/ksh/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.20 2003/10/22 07:40:38 jmc Exp $ */ +/* $OpenBSD: misc.c,v 1.21 2004/12/12 06:53:13 deraadt Exp $ */ /* * Miscellaneous functions @@ -139,6 +139,7 @@ const struct option options[] = { #endif { "bgnice", 0, OF_ANY }, { (char *) 0, 'c', OF_CMDLINE }, + { "csh-history", 0, OF_ANY }, /* non-standard */ #ifdef EMACS { "emacs", 0, OF_ANY }, { "emacs-usemeta", 0, OF_ANY }, /* non-standard */ diff --git a/bin/ksh/proto.h b/bin/ksh/proto.h index cd96b8776d1..ddd8e7bff17 100644 --- a/bin/ksh/proto.h +++ b/bin/ksh/proto.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proto.h,v 1.12 2004/11/04 19:20:07 deraadt Exp $ */ +/* $OpenBSD: proto.h,v 1.13 2004/12/12 06:53:13 deraadt Exp $ */ /* * prototypes for PD-KSH @@ -99,6 +99,9 @@ int histN ARGS((void)); int histnum ARGS((int n)); int findhist ARGS((int start, int fwd, const char *str, int anchored)); +int findhistrel ARGS((const char *str)); +char **hist_get_newest ARGS((int allow_cur)); + #endif /* HISTORY */ /* io.c */ void errorf ARGS((const char *fmt, ...)) diff --git a/bin/ksh/sh.1 b/bin/ksh/sh.1 index 7ff5db13fe3..25dbfdefe77 100644 --- a/bin/ksh/sh.1 +++ b/bin/ksh/sh.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sh.1,v 1.53 2004/12/10 01:56:56 jaredy Exp $ +.\" $OpenBSD: sh.1,v 1.54 2004/12/12 06:53:13 deraadt Exp $ .\" .\" Copyright (c) 1980, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -2830,6 +2830,12 @@ Print job notification messages asynchronously, instead of just before the prompt. Only used if job control is enabled .Pq Fl m . +.It Ic csh-history +Enables a subset of +.Xr csh 1 Ns -style +history editing using the +.Ql ! +character. .It Fl C Ic noclobber Prevent .Ic \&> diff --git a/bin/ksh/sh.1tbl b/bin/ksh/sh.1tbl index 97f3eb7202b..6a34db829d5 100644 --- a/bin/ksh/sh.1tbl +++ b/bin/ksh/sh.1tbl @@ -1,4 +1,4 @@ -.\" $OpenBSD: sh.1tbl,v 1.53 2004/12/10 01:56:56 jaredy Exp $ +.\" $OpenBSD: sh.1tbl,v 1.54 2004/12/12 06:53:13 deraadt Exp $ .\" .\" Copyright (c) 1980, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -2830,6 +2830,12 @@ Print job notification messages asynchronously, instead of just before the prompt. Only used if job control is enabled .Pq Fl m . +.It Ic csh-history +Enables a subset of +.Xr csh 1 Ns -style +history editing using the +.Ql ! +character. .It Fl C Ic noclobber Prevent .Ic \&> diff --git a/bin/ksh/sh.h b/bin/ksh/sh.h index afdab72d617..1eb3ddd50dd 100644 --- a/bin/ksh/sh.h +++ b/bin/ksh/sh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sh.h,v 1.18 2004/05/31 10:36:35 otto Exp $ */ +/* $OpenBSD: sh.h,v 1.19 2004/12/12 06:53:13 deraadt Exp $ */ /* * Public Domain Bourne/Korn shell @@ -463,6 +463,7 @@ enum sh_flag { #endif FBGNICE, /* bgnice */ FCOMMAND, /* -c: (invocation) execute specified command */ + FCSHHISTORY, /* csh-style history enabled */ #ifdef EMACS FEMACS, /* emacs command editing */ FEMACSUSEMETA, /* use 8th bit as meta */ |