summaryrefslogtreecommitdiff
path: root/bin/ksh
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2004-12-12 06:53:14 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2004-12-12 06:53:14 +0000
commit81ab06bd533ae45298f0aecec83cafc63aa2670c (patch)
tree4383820059ced16d90816e21f9d1892dc38a5c69 /bin/ksh
parentfa3d7811bc8e12ad43c058b0529b892103e249e9 (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.c25
-rw-r--r--bin/ksh/ksh.18
-rw-r--r--bin/ksh/ksh.1tbl8
-rw-r--r--bin/ksh/lex.c62
-rw-r--r--bin/ksh/misc.c3
-rw-r--r--bin/ksh/proto.h5
-rw-r--r--bin/ksh/sh.18
-rw-r--r--bin/ksh/sh.1tbl8
-rw-r--r--bin/ksh/sh.h3
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 */