[Top][All Lists]

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

Re: bash tab variable expansion question?

From: Chet Ramey
Subject: Re: bash tab variable expansion question?
Date: Tue, 06 Sep 2011 21:11:16 -0400
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:6.0.1) Gecko/20110830 Thunderbird/6.0.1

Hash: SHA1

On 9/5/11 2:05 AM, Martin von Gagern wrote:
> On -10.01.-28163 20:59, Chet Ramey wrote:
>>> Bash-4.2 tries to leave what the
>>> user typed alone, but that leads to an inherently ambiguous situation:
>>> when do you quote the `$' in a filename (or, in this case, a directory
>>> name)?  It could be a shell variable, and it could be a character in
>>> the filename.
> I'm not sure I'd EVER want completion to escape a $. If I want a
> variable, I'll type $, either by itself or inside double quotation
> marks. If I want a $ included in a file name, then I'll type \$ or
> enclose it in single quotation marks. The above I'd do even for partial
> file names. So if bash sees an unquoted $, then I'd call it a variable,
> and no ambiguity involved.

You might, but `$' has the annoying habit of showing up far too often
in Windows filenames, or in shares mounted from Windows.

>> That is the problem, in a nutshell.  I posted a partial patch at the
>> end of March that applied a heuristic to avoid quoting variable
>> expansions in most cases, but there was no way to get the bash-4.1
>> behavior back.
> Can you explain these heuristics?

Sure.  Bash has to decide when to expand a variable name in the directory
name it's passed.  Those names, for simplicity's sake, always start with
`$', so if bash successfully completes a variable name, it removes `$'
from the list of characters that will cause the filename to be quoted.
Similarly for ${...} and $(...), which cause `{' and `}' or `(' and `)'
to be removed also, respectively.  This prevents the unwanted quoting of
`$', but is imperfect because it doesn't really handle the case where
other characters in the filename need to be quoted.  The `$' will end
up being quoted if, for instance, the filename to be completed in $HOME
contains spaces.

This is at about line 160 of the diff I posted.

> The heuristics apparently don't work well with programmatic completion.

If the compspec is the one posted earlier, the options defeat the

> With _longopt <http://tinyurl.com/3va3hyz > from the debian bashcomp
> project set up for ls, I get "\$HOME/.bash" as the completion for
> "$HOME/.bash". And I get no completion at all for "ls $HOM", probably
> because there is no dir of that name.
> Can we do the following for programmatic completion?
> 1. If the insertion point is at a variable reference, and the
>    referenced variable does not exist, then complete variable name
>    without delegating to programmatic completion

The `-o bashdefault' option mostly handles this case.  However, whether
or not to perform programmable completion depends on the command, not
the word to be completed.

> 2. Otherwise, store the original String for each word
> 3. Perform variable expansion for each word
> 4. Perform completion on the expanded words
> 5. In the completed words, search for the expanded but uncomleted
>    strings from 3. and replace them with the unexpanded forms from 2.

This is a reasonable approach for a progcomp to take.  It's not usually
that complicated -- you really only have one word you're trying to
complete, which may expand to multiple completions.

The other problem is what I explained in my message to Clark Wang: there
is no way for a compspec to tell readline to not quote the completion as
a filename, and no way to selectively tell readline which matches are and
which are not filenames.

- -- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU    address@hidden    http://cnswww.cns.cwru.edu/~chet/
Version: GnuPG v1.4.10 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/


reply via email to

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