I sent this diff in 2011 (?) with a bunch of other diffs. It fixes tab completion for filenames containing special characters like [], () and so.
This code affects interactive mode only, and I don't know a way to do automated testing of this. Suggestions welcome. Index: edit.c =================================================================== RCS file: /cvs/src/bin/ksh/edit.c,v retrieving revision 1.35 diff -u -r1.35 edit.c --- edit.c 10 Sep 2012 01:25:30 -0000 1.35 +++ edit.c 26 Sep 2012 21:32:42 -0000 @@ -348,7 +348,7 @@ { char *toglob; char **words; - int nwords, i, idx, escaping; + int nwords; XPtrV w; struct source *s, *sold; @@ -357,20 +357,6 @@ toglob = add_glob(str, slen); - /* remove all escaping backward slashes */ - escaping = 0; - for (i = 0, idx = 0; toglob[i]; i++) { - if (toglob[i] == '\\' && !escaping) { - escaping = 1; - continue; - } - - toglob[idx] = toglob[i]; - idx++; - if (escaping) escaping = 0; - } - toglob[idx] = '\0'; - /* * Convert "foo*" (toglob) to an array of strings (words) */ @@ -378,7 +364,7 @@ s = pushs(SWSTR, ATEMP); s->start = s->str = toglob; source = s; - if (yylex(ONEWORD) != LWORD) { + if (yylex(ONEWORD|UNESCAPE) != LWORD) { source = sold; internal_errorf(0, "fileglob: substitute error"); return 0; @@ -394,15 +380,12 @@ if (nwords == 1) { struct stat statb; - /* Check if globbing failed (returned glob pattern), - * but be careful (E.g. toglob == "ab*" when the file - * "ab*" exists is not an error). - * Also, check for empty result - happens if we tried - * to glob something which evaluated to an empty - * string (e.g., "$FOO" when there is no FOO, etc). + /* Check if file exists, also, check for empty + * result - happens if we tried to glob something + * which evaluated to an empty string (e.g., + * "$FOO" when there is no FOO, etc). */ - if ((strcmp(words[0], toglob) == 0 && - stat(words[0], &statb) < 0) || + if ((lstat(words[0], &statb) < 0) || words[0][0] == '\0') { x_free_words(nwords, words); words = NULL; Index: lex.c =================================================================== RCS file: /cvs/src/bin/ksh/lex.c,v retrieving revision 1.45 diff -u -r1.45 lex.c --- lex.c 9 Mar 2011 09:30:39 -0000 1.45 +++ lex.c 26 Sep 2012 21:32:43 -0000 @@ -299,6 +299,10 @@ } /* FALLTHROUGH */ default: + if (cf & UNESCAPE) { + *wp++ = QCHAR, *wp++ = c; + break; + } Xcheck(ws, wp); if (c) { /* trailing \ is lost */ *wp++ = CHAR, *wp++ = '\\'; Index: lex.h =================================================================== RCS file: /cvs/src/bin/ksh/lex.h,v retrieving revision 1.11 diff -u -r1.11 lex.h --- lex.h 29 May 2006 18:22:24 -0000 1.11 +++ lex.h 26 Sep 2012 21:32:43 -0000 @@ -113,6 +113,7 @@ #define CMDWORD BIT(8) /* parsing simple command (alias related) */ #define HEREDELIM BIT(9) /* parsing <<,<<- delimiter */ #define HEREDOC BIT(10) /* parsing heredoc */ +#define UNESCAPE BIT(11) /* remove backslashes */ #define HERES 10 /* max << in line */ -- open source wizard