[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bug, or someone wanna explain to me why this is a POSIX feature?

From: Michael Witten
Subject: Re: Bug, or someone wanna explain to me why this is a POSIX feature?
Date: Mon, 08 Aug 2011 21:42:42 -0000

On Mon, 8 Aug 2011 21:40:39 +0200, Davide Brini wrote:

> On Mon, 8 Aug 2011 21:14:50 +0200, Davide Brini <address@hidden> wrote:
>> In fact, you could do the same thing with
>> foo() { # hit tab here
>> and I'm sure you wouldn't consider that an empty line.
> I have to take that back: it looks like bash treats the above differently
> depending on whether enter was pressed or not:
> foo() { # hit tab here
> Display all 2138 possibilities? (y or n)
> foo() {  # hit enter here
> > # hit tab here
> Display all 112 possibilities? (y or n)
> The latter only attemps completion from names in the current directory.
> On the other hand, with no_empty_cmd_completion set, no completion at all is
> attempted in the first case, while the second case still attempts completion
> from local names.

This behavior does indeed seem buggy.

>From the following:

  $ info '(bash)The Shopt Builtin'

we have:

        If set, and Readline is being used, Bash will not attempt to
        search the `PATH' for possible completions when completion is
        attempted on an empty line.

Now, firstly, there is possibly a conceptual conflict between `empty_cmd' and
`empty line', but seeing as virtually everything that can be input is defined
as a command of some sort or another, maybe there's no problem.

At any rate, the input:

  $ foo() { # hit tab here, right after the space character.

is not only a non-empty line, but it is also an incomplete function definition
*command*, according to the nomenclature and shell grammar specified by POSIX:

  Base Definitions Issue 7, IEEE Std 1003.1-2008

Hence, it seems to me that completion should be attempted regardless of
whether `no_empty_cmd_completion' is set; of course, searching `PATH'
for a completion would likely result in no available completions anyway.

Moreover, given that searching `PATH' is mentioned, one could easily
imagine that the completion in question is that of the names of simple
commands. In that capacity, there is no simple command to complete (in
other words, there is an `empty' command to complete). In this case, then,
it is correct for there to be no completion when `no_empty_cmd_completion'
is set, and it is correct for there to be a list of all available commands
when `no_empty_cmd_completion' is unset (which would appear to be the
current behavior).

Now, what about the continuation of the command line?

  $ foo() {# hit enter here
  > #hit tab here.

According to the same POSIX documentation:

      Each time the user enters a <newline> prior to completing a
      command line in an interactive shell, the value of this variable
      shall be subjected to parameter expansion and written to standard
      error. The default value is "> " . This volume of POSIX.1-2008
      specifies the effects of the variable only for systems supporting
      the User Portability Utilities option.

and together with bash's shopt options `cmdhist' and `lithist', it would
seem that bash [mostly] treats `multi-line' commands (as bash calls them)
as one large single command line. Hence, a tab on a continuation line might
be expected to invoke only file name completion (which does happen, and is
indeed orthogonal to the setting of `no_empty_cmd_completion').

Unfortunately, such behavior is still inconsistent with the current completion
behavior as described above, because bash basically converts an interactive
newline in a compound command to a semicolon, thereby initiating another
simple command.

For instance, regardless of `no_empty_cmd_completion', the following:

  $ foo() { echo a; ech#tab

completes `echo' on my system.

When the option is set, the following:

  $ foo() { echo a; #tab

doesn't attempt any completion (visibly, anyway). However, when the option is
UNset, completion is attempted based on all available commands (thousands).

So, based on the existing semantics and descriptions, one would expect 

  $ foo() {#enter
  > #tab

to make no completion attempt when the option is set, and to make an attempt
based on all available command names when unset, but not the current behavior,
which is to suggest file name completions.

Now, of course, completion is much more complex than just command name and
file name completion, and I think it could be improved to be more useful.

For instance, according to shell grammar, any compound command is acceptable
as the body of a function, so that we could have this:

  $ i=0
  $ foo()
  > while [ $i -lt 10 ]; do i=$((i + 1)); echo $i; done
  $ foo#enter
  $ bar()
  > if [ $i -eq 10 ]; then echo 11; fi
  $ bar

Thus, for instance, completing function definition commands should produce
results like this:

  $ foo() #tab
  (             {             case          if            while         until

Also, why doesn't `shopt' have option completion? etc.

In any case, even if `no_empty_cmd_completion' were to behave as Linda
expected, her tabs would still get eaten when pasted on the interactive
command line.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]