On 3/5/14 5:01 PM, Albert Shih wrote: > If you got a file name begin with "(" the completion didn't work. > > For example if I do > > mkdir emptydir > cd emptydir > touch \(\) > rm + Tab > > don't give me anything.
This is actually a general problem with empty completions (typing TAB at the end of a line) in general with bash-4.3 and the latest versions of the bash-completion package. The problem, as it usually is, is mismatched assumptions. There was a change between bash-4.2 and bash-4.3 prompted by this message thread from 2011 (!): http://lists.gnu.org/archive/html/bug-bash/2011-10/msg00059.html The problem, in a nutshell, was that complete and compgen need to act differently based on how they are invoked: from the command line for testing, and from within readline's completion engine. When invoked on the command line, the arguments are run through the usual word expansions; when run via the programmable completion code, they are not. That has implications for quoted words, and the bash-completion package assumes that the programmable completion code unconditionally dequotes all words passed to complete and compgen that are supposed to be treated as filenames (as the bash-4.2 code did). Here is a message describing what I ultimately put into bash-4.3: http://lists.gnu.org/archive/html/bug-bash/2011-10/msg00068.html This works, as far as it goes, but the problem with it is that it missed this particular case. When the original word doesn't have quotes (so readline doesn't find any quotes and doesn't set the flag indicating that), but the argument passed to compgen has quotes and therefore needs dequoting, the bash-4.3 code doesn't dequote it. The bash-4.2 code, since it dequoted unconditionally, doesn't have this problem. I've attached a patch that solves the problem with "empty" completions. It's a start, but it may require more work to capture all of the cases. (Frankly, I'm disappointed that this slipped through into bash-4.3. The change was made back in 2011, and has been in the devel tree since early 2012. Bash-4.3 testing versions were available for almost a year.) Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, ITS, CWRU c...@case.edu http://cnswww.cns.cwru.edu/~chet/
*** ../bash-4.3/pcomplete.c 2013-08-26 15:23:45.000000000 -0400 --- pcomplete.c 2014-03-07 13:12:42.000000000 -0500 *************** *** 184,187 **** --- 184,188 ---- COMPSPEC *pcomp_curcs; const char *pcomp_curcmd; + const char *pcomp_curtxt; #ifdef DEBUG *************** *** 754,757 **** --- 755,767 ---- dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character); } + /* Intended to solve a mismatched assumption by bash-completion. If + the text to be completed is empty, but bash-completion turns it into + a quoted string ('') assuming that this code will dequote it before + calling readline, do the dequoting. */ + else if (iscompgen && iscompleting && + pcomp_curtxt && *pcomp_curtxt == 0 && + text && (*text == '\'' || *text == '"') && text[1] == text[0] && text[2] == 0 && + rl_filename_dequoting_function) + dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character); else dfn = savestring (text); *************** *** 1523,1527 **** { COMPSPEC *cs, *oldcs; ! const char *oldcmd; STRINGLIST *ret; --- 1533,1537 ---- { COMPSPEC *cs, *oldcs; ! const char *oldcmd, *oldtxt; STRINGLIST *ret; *************** *** 1546,1552 **** --- 1556,1564 ---- oldcs = pcomp_curcs; oldcmd = pcomp_curcmd; + oldtxt = pcomp_curtxt; pcomp_curcs = cs; pcomp_curcmd = cmd; + pcomp_curtxt = word; ret = gen_compspec_completions (cs, cmd, word, start, end, foundp); *************** *** 1554,1557 **** --- 1566,1570 ---- pcomp_curcs = oldcs; pcomp_curcmd = oldcmd; + pcomp_curtxt = oldtxt; /* We need to conditionally handle setting *retryp here */