[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Filename completion broken on single quote
From: |
lolilolicon |
Subject: |
Re: Filename completion broken on single quote |
Date: |
Tue, 18 Oct 2011 15:37:06 +0800 |
On Sun, Oct 16, 2011 at 10:52 PM, lolilolicon <lolilolicon@gmail.com> wrote:
> -- snip --
> I hope the above will help clarify what bash currently does, and how it's
> a bit crazy. I hope to discuss the correct behavior in each case later.
>
Below is the sane behavior I'd like to propose:
Inside an empty directory:
$ touch 1\'2 125 13 1\\\'5 24
$ complete -f foo
$ complete -F bar bar
$ type bar
bar is a function
bar ()
{
printf '\n[%s]\n' "${COMP_WORDS[COMP_CWORD]}";
compgen -f "${COMP_WORDS[COMP_CWORD]}"
}
$ foo 1'<TAB> # foo 1 (press <TAB> again, lists 1*)
$ foo 1\'<TAB> # foo 1\'2
$ foo 1\\\'<TAB> # foo 1\\\'5
$ bar 1'<TAB>
[1']
1'2
125
13
1\'5
$ bar 1\'<TAB>
[1\']
1'2
$ bar 1\\\'<TAB>
[1\\\']
1\'5
$ compgen -f "1'"
1'2
125
13
1\'5
$ compgen -f "1\'"
1'2
$ compgen -f "1\\\\\'" # (1\\\' is passed to compgen)
1\'5
So this means the three cases behave exactly the same way. How it works:
0. cword = the current word being completed
bcomp = the completion function, or engine, or whatever
1. cword is passed to bcomp; bcomp closes open quotes if any. bcomp
understands the quoting the way bash does, i.e. the way the user
does. bcomp closes the quotes by appending the quote characters
correspondingly.
2. bcomp performs the shell word expansions if requested. It does so
the way bash does. This will involve much details but let's ignore
that for now. Quote removal is also performed.
3. bcomp matches the expanded cword against a list, e.g. filenames, by
simple string matching, and gets a list of matched items.
4. bcomp filters the list as per post-processing rules if any.
5. In the case of "straignt" progcomp (`complete -f'): if bcomp returns
a single match, quote this match as bash would, and replace the
original cword on the command line with the quoted match, and signal
"mission complete" by appending a space for example; otherwise,
replace with the result from 2, quoted as bash would.
Using this theory, the "straignt" progcomp example happens like this:
(Note: marking cursor position with `_')
$ foo 1'<TAB>
0. cword = 1'
1. 1''
2. 1
3. 1'2
125
13
1\'5
4. (unchanged)
5. (more than one matched items)
$ foo 1_
$ foo 1\'<TAB>
0. cword = 1\'
1. 1\'
2. 1'
3. 1'2
4. (unchanged)
5. (mission complete, quote and replace)
$ foo 1\'2 _
$ foo 1\\\'<TAB>
0. cword = 1\\\'
1. 1\\\'
2. 1\'
3. 1\'5
4. (unchanged)
5. (mission complete, quote and replace)
$ foo 1\\\'5 _
Don't take me wrong, I understand this probably simple-minded theory won't
fit into the current completion framework directly. I'm just suggesting
maybe bash can accomplish the task in a way that is simple and predictable
as long as the user understands how bash's quoting works (and how readline
splits the command line into words).
I'm not trying to say that my sugguestion is better, that would be
completely out of place. Perhaps there's some fatal flaw in the proposal.
But I hope it sparks some improvement, even if just a little bit.