On Sat, Feb 14, 2009 at 07:52:31PM +0100, Simon 'corecode' Schubert wrote:
> Joerg Sonnenberger wrote:
>> On Sat, Feb 14, 2009 at 09:44:26AM -0800, Matthew Dillon wrote:
>>>     We should probably follow whatever NetBSD does there, but there is
>>>     no reason we can't turn it on in the default /etc/profile.
>>
>> NetBSD enables it in /root/.profile. Putting it in /etc/profile is bad
>> for two reasons:
>> (a) That file is processed by many !/bin/sh shells as well.
>> (b) Users can't overwrite that file directly.
>
> I don't see any harm in enabling it by default.

Please find attached a new version, which turns it on by default
only for interactive shell.
>From db23c03f005ebf9f369b4bbe82408668ee8be697 Mon Sep 17 00:00:00 2001
From: YONETANI Tomokazu <[email protected]>
Date: Sat, 14 Feb 2009 22:37:20 +0900
Subject: [PATCH] Add `set -o tabcomplete' to /bin/sh

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 |    6 ++++++
 bin/sh/options.c  |    2 ++
 bin/sh/options.h  |    4 +++-
 bin/sh/sh.1       |   11 +++++++++++
 4 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c
index 797685a..b0a8a6b 100644
--- a/bin/sh/histedit.c
+++ b/bin/sh/histedit.c
@@ -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 {
diff --git a/bin/sh/options.c b/bin/sh/options.c
index 82d3c19..d4d880c 100644
--- a/bin/sh/options.c
+++ b/bin/sh/options.c
@@ -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;
diff --git a/bin/sh/options.h b/bin/sh/options.h
index 3ca1c99..c8ee216 100644
--- a/bin/sh/options.h
+++ b/bin/sh/options.h
@@ -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];
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 19ca003..1195bc8 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -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.
-- 
1.6.0.6

Reply via email to