On Sun, Oct 16, 2011 at 10:52 PM, lolilolicon <loliloli...@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.