summaryrefslogtreecommitdiff
path: root/bin/ksh
diff options
context:
space:
mode:
authorCamiel Dobbelaar <camield@cvs.openbsd.org>2001-02-19 09:49:55 +0000
committerCamiel Dobbelaar <camield@cvs.openbsd.org>2001-02-19 09:49:55 +0000
commit147724caa4166bbf864e69d7c6009148b51da7db (patch)
treeb2581b725dcb21de1157fade3ca9cb9f23fd0d71 /bin/ksh
parentdf3bcfa4b92155daf478bb54bc1b87efa61f5b18 (diff)
bash-like 'double-tab' completion
- bind TAB (^I) to complete-list by default - complete-list now lists 'ls style' not 'menu style' - complete-list first completes; if that does not work, it lists - fix a memleak in emacs.c, do_complete - completion now works after '=' (dd), and ':' (ssh) and ` (backtick) - a command can now start with a subdir from the current dir
Diffstat (limited to 'bin/ksh')
-rw-r--r--bin/ksh/c_ksh.c4
-rw-r--r--bin/ksh/edit.c20
-rw-r--r--bin/ksh/emacs.c115
-rw-r--r--bin/ksh/exec.c36
-rw-r--r--bin/ksh/misc.c9
-rw-r--r--bin/ksh/proto.h5
6 files changed, 94 insertions, 95 deletions
diff --git a/bin/ksh/c_ksh.c b/bin/ksh/c_ksh.c
index 974d24611c2..0b6c600193a 100644
--- a/bin/ksh/c_ksh.c
+++ b/bin/ksh/c_ksh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: c_ksh.c,v 1.13 2000/11/21 22:41:03 millert Exp $ */
+/* $OpenBSD: c_ksh.c,v 1.14 2001/02/19 09:49:50 camield Exp $ */
/*
* built-in Korn commands: c_*
@@ -1264,7 +1264,7 @@ c_kill(wp)
print_columns(shl_stdout, SIGNALS - 1,
kill_fmt_entry, (void *) &ki,
- ki.num_width + ki.name_width + mess_width + 3);
+ ki.num_width + ki.name_width + mess_width + 3, 1);
}
return 0;
}
diff --git a/bin/ksh/edit.c b/bin/ksh/edit.c
index 6b383785f8b..8754d863721 100644
--- a/bin/ksh/edit.c
+++ b/bin/ksh/edit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: edit.c,v 1.11 1999/11/14 22:04:02 d Exp $ */
+/* $OpenBSD: edit.c,v 1.12 2001/02/19 09:49:51 camield Exp $ */
/*
* Command line editing - common code
@@ -500,7 +500,7 @@ x_print_expansions(nwords, words, is_command)
XPtrV l;
/* Check if all matches are in the same directory (in this
- * case, we want to omitt the directory name)
+ * case, we want to omit the directory name)
*/
if (!is_command
&& (prefix_len = x_longest_prefix(nwords, words)) > 0)
@@ -533,7 +533,7 @@ x_print_expansions(nwords, words, is_command)
*/
x_putc('\r');
x_putc('\n');
- pr_menu(use_copy ? (char **) XPptrv(l) : words);
+ pr_list(use_copy ? (char **) XPptrv(l) : words);
if (use_copy)
XPfree(l); /* not x_free_words() */
@@ -739,7 +739,8 @@ x_command_glob(flags, str, slen, wordsp)
return nwords;
}
-#define IS_WORDC(c) !(ctype(c, C_LEX1) || (c) == '\'' || (c) == '"')
+#define IS_WORDC(c) !( ctype(c, C_LEX1) || (c) == '\'' || (c) == '"' \
+ || (c) == '`' || (c) == '=' || (c) == ':' )
static int
x_locate_word(buf, buflen, pos, startp, is_commandp)
@@ -779,7 +780,8 @@ x_locate_word(buf, buflen, pos, startp, is_commandp)
/* Figure out if this is a command */
for (p = start - 1; p >= 0 && isspace(buf[p]); p--)
;
- iscmd = p < 0 || strchr(";|&()", buf[p]);
+ iscmd = p < 0 || strchr(";|&()`", buf[p]);
+#if 0
if (iscmd) {
/* If command has a /, path, etc. is not searched;
* only current directory is searched, which is just
@@ -790,6 +792,7 @@ x_locate_word(buf, buflen, pos, startp, is_commandp)
break;
iscmd = p == end;
}
+#endif
*is_commandp = iscmd;
}
@@ -981,6 +984,7 @@ glob_path(flags, pat, wp, path)
{
const char *sp, *p;
char *xp;
+ int staterr;
int pathlen;
int patlen;
int oldsize, newsize, i, j;
@@ -1015,13 +1019,15 @@ glob_path(flags, pat, wp, path)
memcpy(xp, pat, patlen);
oldsize = XPsize(*wp);
- glob_str(Xstring(xs, xp), wp, 0);
+ glob_str(Xstring(xs, xp), wp, 1); /* mark dirs */
newsize = XPsize(*wp);
/* Check that each match is executable... */
words = (char **) XPptrv(*wp);
for (i = j = oldsize; i < newsize; i++) {
- if (search_access(words[i], X_OK, (int *) 0) >= 0) {
+ staterr = 0;
+ if ((search_access(words[i], X_OK, &staterr) >= 0)
+ || (staterr == EISDIR)) {
words[j] = words[i];
if (!(flags & XCF_FULLPATH))
memmove(words[j], words[j] + pathlen,
diff --git a/bin/ksh/emacs.c b/bin/ksh/emacs.c
index 2ef3ce5732e..5864be51940 100644
--- a/bin/ksh/emacs.c
+++ b/bin/ksh/emacs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: emacs.c,v 1.13 2000/01/24 03:12:12 millert Exp $ */
+/* $OpenBSD: emacs.c,v 1.14 2001/02/19 09:49:52 camield Exp $ */
/*
* Emacs-like command line editing and history
@@ -273,7 +273,7 @@ static struct x_defbindings const x_defbindings[] = {
{ XFUNC_transpose, 0, CTRL('T') },
#endif
{ XFUNC_complete, 1, CTRL('[') },
- { XFUNC_complete, 0, CTRL('I') },
+ { XFUNC_comp_list, 0, CTRL('I') },
{ XFUNC_comp_list, 1, '=' },
{ XFUNC_enumerate, 1, '?' },
{ XFUNC_expand, 1, '*' },
@@ -1776,92 +1776,51 @@ do_complete(flags, type)
Comp_type type;
{
char **words;
- int nwords = 0;
- int start, end;
+ int nwords;
+ int start, end, nlen, olen;
int is_command;
- int do_glob = 1;
- Comp_type t = type;
- char *comp_word = (char *) 0;
-
- if (type == CT_COMPLIST) {
- do_glob = 0;
- /* decide what we will do */
- nwords = x_cf_glob(flags,
- xbuf, xep - xbuf, xcp - xbuf,
- &start, &end, &words, &is_command);
- if (nwords > 0) {
- if (nwords > 1) {
- int len = x_longest_prefix(nwords, words);
-
- t = CT_LIST;
- /* Do completion if prefix matches original
- * prefix (ie, no globbing chars), otherwise
- * don't bother
- */
- if (strncmp(words[0], xbuf + start, end - start)
- == 0)
- comp_word = str_nsave(words[0], len,
- ATEMP);
- else
- type = CT_LIST;
- /* Redo globing to show full paths if this
- * is a command.
- */
- if (is_command) {
- do_glob = 1;
- x_free_words(nwords, words);
- }
- } else
- type = t = CT_COMPLETE;
- }
- }
- if (do_glob)
- nwords = x_cf_glob(flags | (t == CT_LIST ? XCF_FULLPATH : 0),
- xbuf, xep - xbuf, xcp - xbuf,
- &start, &end, &words, &is_command);
+ int completed = 0;
+
+ nwords = x_cf_glob(flags, xbuf, xep - xbuf, xcp - xbuf,
+ &start, &end, &words, &is_command);
+ /* no match */
if (nwords == 0) {
x_e_putc(BEL);
return;
}
- switch (type) {
- case CT_LIST:
+
+ if (type == CT_LIST) {
x_print_expansions(nwords, words, is_command);
x_redraw(0);
- break;
-
- case CT_COMPLIST:
- /* Only get here if nwords > 1 && comp_word is set */
- {
- int olen = end - start;
- int nlen = strlen(comp_word);
+ x_free_words(nwords, words);
+ return;
+ }
- x_print_expansions(nwords, words, is_command);
- xcp = xbuf + end;
- x_do_ins(comp_word + olen, nlen - olen);
- x_redraw(0);
- }
- break;
+ olen = end - start;
+ nlen = x_longest_prefix(nwords, words);
+ /* complete single match, or multi-match without globbing chars */
+ if ((nlen > olen) &&
+ ((nwords == 1) || (strncmp(words[0], xbuf + start, olen) == 0))) {
+ x_goto(xbuf + start);
+ x_delete(olen, FALSE);
+ x_escape(words[0], nlen, x_emacs_putbuf);
+ x_adjust();
+ completed = 1;
+ }
+ if ((nwords == 1) && (!ISDIRSEP(words[0][nlen - 1]))) {
+ x_ins(space);
+ completed = 1;
+ }
- case CT_COMPLETE:
- {
- int nlen = x_longest_prefix(nwords, words);
-
- if (nlen > 0) {
- x_goto(xbuf + start);
- x_delete(end - start, FALSE);
- x_escape(words[0], nlen, x_emacs_putbuf);
- x_adjust();
- /* If single match is not a directory, add a
- * space to the end...
- */
- if (nwords == 1
- && !ISDIRSEP(words[0][nlen - 1]))
- x_ins(space);
- } else
- x_e_putc(BEL);
- }
- break;
+ if (type == CT_COMPLIST && !completed) {
+ x_print_expansions(nwords, words, is_command);
+ completed = 1;
}
+
+ if (completed)
+ x_redraw(0);
+
+ x_free_words(nwords, words);
}
/* NAME:
diff --git a/bin/ksh/exec.c b/bin/ksh/exec.c
index 68443e8c521..ca696aa54bc 100644
--- a/bin/ksh/exec.c
+++ b/bin/ksh/exec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec.c,v 1.21 1999/07/15 20:35:33 millert Exp $ */
+/* $OpenBSD: exec.c,v 1.22 2001/02/19 09:49:52 camield Exp $ */
/*
* execute command tree
@@ -1595,7 +1595,39 @@ pr_menu(ap)
smi.arg_width = nwidth;
smi.num_width = dwidth;
print_columns(shl_out, n, select_fmt_entry, (void *) &smi,
- dwidth + nwidth + 2);
+ dwidth + nwidth + 2, 1);
+
+ return n;
+}
+
+/* XXX: horrible kludge to fit within the framework */
+
+static char *plain_fmt_entry ARGS((void *arg, int i, char *buf, int buflen));
+
+static char *
+plain_fmt_entry(arg, i, buf, buflen)
+ void *arg;
+ int i;
+ char *buf;
+ int buflen;
+{
+ shf_snprintf(buf, buflen, "%s", ((char *const *)arg)[i]);
+ return buf;
+}
+
+int
+pr_list(ap)
+ char *const *ap;
+{
+ char *const *pp;
+ int nwidth;
+ int i, n;
+
+ for (n = 0, nwidth = 0, pp = ap; *pp; n++, pp++) {
+ i = strlen(*pp);
+ nwidth = (i > nwidth) ? i : nwidth;
+ }
+ print_columns(shl_out, n, plain_fmt_entry, (void *) ap, nwidth + 1, 0);
return n;
}
diff --git a/bin/ksh/misc.c b/bin/ksh/misc.c
index 8ead4710d18..7de3ac2c98c 100644
--- a/bin/ksh/misc.c
+++ b/bin/ksh/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.11 2000/06/28 20:36:37 mickey Exp $ */
+/* $OpenBSD: misc.c,v 1.12 2001/02/19 09:49:53 camield Exp $ */
/*
* Miscellaneous functions
@@ -244,7 +244,7 @@ printoptions(verbose)
oi.opt_width = len;
}
print_columns(shl_stdout, n, options_fmt_entry, &oi,
- oi.opt_width + 5);
+ oi.opt_width + 5, 1);
} else {
/* short version ala ksh93 */
shprintf("set");
@@ -1090,12 +1090,13 @@ print_value_quoted(s)
* element
*/
void
-print_columns(shf, n, func, arg, max_width)
+print_columns(shf, n, func, arg, max_width, prefcol)
struct shf *shf;
int n;
char *(*func) ARGS((void *, int, char *, int));
void *arg;
int max_width;
+ int prefcol;
{
char *str = (char *) alloc(max_width + 1, ATEMP);
int i;
@@ -1111,7 +1112,7 @@ print_columns(shf, n, func, arg, max_width)
if (!cols)
cols = 1;
rows = (n + cols - 1) / cols;
- if (n && cols > rows) {
+ if (prefcol && n && cols > rows) {
int tmp = rows;
rows = cols;
diff --git a/bin/ksh/proto.h b/bin/ksh/proto.h
index 627a6f674ba..7a7c9a80dcb 100644
--- a/bin/ksh/proto.h
+++ b/bin/ksh/proto.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proto.h,v 1.8 1999/07/14 13:37:24 millert Exp $ */
+/* $OpenBSD: proto.h,v 1.9 2001/02/19 09:49:54 camield Exp $ */
/*
* prototypes for PD-KSH
@@ -78,6 +78,7 @@ char * search ARGS((const char *name, const char *path, int mode,
int *errnop));
int search_access ARGS((const char *path, int mode, int *errnop));
int pr_menu ARGS((char *const *ap));
+int pr_list ARGS((char *const *ap));
/* expr.c */
int evaluate ARGS((const char *expr, long *rval, int error_ok));
int v_evaluate ARGS((struct tbl *vp, const char *expr, volatile int error_ok));
@@ -200,7 +201,7 @@ int ksh_getopt ARGS((char **argv, Getopt *go, const char *options));
void print_value_quoted ARGS((const char *s));
void print_columns ARGS((struct shf *shf, int n,
char *(*func)(void *, int, char *, int),
- void *arg, int max_width));
+ void *arg, int max_width, int prefcol));
int strip_nuls ARGS((char *buf, int nbytes));
char *str_zcpy ARGS((char *dst, const char *src, int dsize));
int blocking_read ARGS((int fd, char *buf, int nbytes));