Add `set -o tabcomplete' to /bin/sh
authorYONETANI Tomokazu <y0netan1@dragonflybsd.org>
Sat, 14 Feb 2009 13:37:20 +0000 (22:37 +0900)
committerYONETANI Tomokazu <y0netan1@dragonflybsd.org>
Fri, 10 Apr 2009 23:17:00 +0000 (08:17 +0900)
When set, it binds <tab> to the libedit filename completion function.
Taken-From: NetBSD
In our version, it's turned on by default in an interactive shell.
If you don't like it, put the following line

  set +o tabcomplete >/dev/null 2>&1 || true

in your ~/.shinit (or whatever path $ENV is set to) .

bin/sh/histedit.c
bin/sh/options.c
bin/sh/options.h
bin/sh/sh.1

index 5348394..1c1e988 100644 (file)
@@ -67,6 +67,7 @@ History *hist;        /* history cookie */
 EditLine *el;  /* editline cookie */
 int displayhist;
 static FILE *el_in, *el_out, *el_err;
+unsigned char _el_fn_complete(EditLine *, int);
 
 STATIC char *fc_replace(const char *, char *, char *);
 
@@ -124,6 +125,9 @@ histedit(void)
                                if (hist)
                                        el_set(el, EL_HIST, history, hist);
                                el_set(el, EL_PROMPT, getprompt);
+                               el_set(el, EL_ADDFN, "rl-complete",
+                                   "ReadLine compatible completion function",
+                                   _el_fn_complete);
                        } else {
 bad:
                                out2str("sh: can't initialize editing\n");
@@ -140,6 +144,8 @@ bad:
                                el_set(el, EL_EDITOR, "vi");
                        else if (Eflag)
                                el_set(el, EL_EDITOR, "emacs");
+                       el_set(el, EL_BIND, "^I",
+                           tabcomplete ? "rl-complete" : "ed-insert", NULL);
                        el_source(el, NULL);
                }
        } else {
index 82d3c19..d4d880c 100644 (file)
@@ -97,6 +97,8 @@ procargs(int argc, char **argv)
                iflag = 1;
        if (mflag == 2)
                mflag = iflag;
+       /* turn on tabcomplete in an interactive shell by default */
+       tabcomplete = iflag;
        for (i = 0; i < NOPTS; i++)
                if (optlist[i].val == 2)
                        optlist[i].val = 0;
index 3ca1c99..c8ee216 100644 (file)
@@ -67,8 +67,9 @@ struct shparam {
 #define        privileged optlist[15].val
 #define        Tflag optlist[16].val
 #define        Pflag optlist[17].val
+#define        tabcomplete optlist[18].val
 
-#define NOPTS  18
+#define NOPTS  19
 
 struct optent {
        const char *name;
@@ -96,6 +97,7 @@ struct optent optlist[NOPTS] = {
        { "privileged", 'p',    0 },
        { "trapsasync", 'T',    0 },
        { "physical",   'P',    0 },
+       { "tabcomplete", '\0',  0 },
 };
 #else
 extern struct optent optlist[NOPTS];
index 19ca003..1195bc8 100644 (file)
@@ -315,6 +315,13 @@ Write each command
 variable)
 to standard error before it is executed.
 Useful for debugging.
+.It "\ \ " Em tabcomplete
+Enables filename completion in the command line editor.
+Typing a tab character will extend the current input word to match a
+filename.
+If more than one filename matches it is only extended to be the common prefix.
+Typing a second tab character will list all the matching names.
+Turned on by default in an interactive shell.
 .El
 .Pp
 The
@@ -2279,3 +2286,7 @@ was originally written by
 The
 .Nm
 utility does not recognize multibyte characters.
+.Pp
+The characters generated by filename completion should probably be quoted
+to ensure that the filename is still valid after the input line has been
+processed.