Greetings and felicitations!

Two things about auto-completion annoyed me in ksh for almost 4 years:
( `|' shows the position of cursor after auto-completion)

1) tilde bug:
$ ls ~/nonexist<TAB>
$ ls ~/nonexist\* |
(i.e. it expands to something insensible, instead of doing nothing like
in /home/<your_user_name>/nonexist case)

2) square bracket bug:
$ touch 'so[me]_file'
$ ls so\[<TAB>
$ ls so\[|
(i.e. nothing happens)


behavior after the patch:

1)
$ ls ~/nonexist<TAB>
$ ls ~/nonexist|

2)
$ ls so[<TAB>
$ ls so\[me\]_file |


(it should work for all kinds of auto-completions, and both
in vi and emacs mode)


While I was testing to see if I broke something by fixing these two,
I also discovered that auto-completions now work in much more sensible
and useful way for strings with variables:

before patch:
$ ls -d tmp
$ tmp
$ ls $HOME/tm<TAB>
$ ls /home/s/tm |

after patch:
$ ls $HOME/tm<TAB>
$ ls /home/s/tmp/|

make test -- shows no errors.


Patch:


Index: edit.c
===================================================================
RCS file: /OpenBSD/src/bin/ksh/edit.c,v
retrieving revision 1.33
diff -r1.33 edit.c
414c414
<       expand(yylval.cp, &w, DOGLOB|DOTILDE|DOMARKDIRS);
---
>       expand(yylval.cp, &w, DOCOMPLETION|DOGLOB|DOTILDE|DOMARKDIRS);
487c487
<       pat = evalstr(toglob, DOPAT|DOTILDE);
---
>       pat = evalstr(toglob, DOCOMPLETION|DOPAT|DOTILDE);
650c650
< /* Given a string, copy it and possibly add a '*' to the end.  The
---
> /* Given a string, copy it and add a '*' to the end.  The
657,658d656
<       char *s;
<       bool saw_slash = false;
663,684c661,663
<       toglob = str_nsave(str, slen + 1, ATEMP); /* + 1 for "*" */
<       toglob[slen] = '\0';
< 
<       /*
<        * If the pathname contains a wildcard (an unquoted '*',
<        * '?', or '[') or parameter expansion ('$'), or a ~username
<        * with no trailing slash, then it is globbed based on that
<        * value (i.e., without the appended '*').
<        */
<       for (s = toglob; *s; s++) {
<               if (*s == '\\' && s[1])
<                       s++;
<               else if (*s == '*' || *s == '[' || *s == '?' || *s == '$'
<                        || (s[1] == '(' /*)*/ && strchr("*...@!", *s)))
<                       break;
<               else if (*s == '/')
<                       saw_slash = true;
<       }
<       if (!*s && (*toglob != '~' || saw_slash)) {
<               toglob[slen] = '*';
<               toglob[slen + 1] = '\0';
<       }
---
>       toglob = str_nsave(str, slen + 1, ATEMP);
>       toglob[slen] = '*';
>       toglob[slen + 1] = '\0';
Index: eval.c
===================================================================
RCS file: /OpenBSD/src/bin/ksh/eval.c,v
retrieving revision 1.34
diff -r1.34 eval.c
557c557
<                                       glob(p, wp, f & DOMARKDIRS);
---
>                                       glob(p, wp, f & (DOCOMPLETION | 
> DOMARKDIRS));
599c599
<                                       if (f & (DOPAT | DOGLOB)) {
---
>                                       if (!(f & DOCOMPLETION) && f & (DOPAT | 
> DOGLOB)) {
606d605
<                               case '*':
607a607,610
>                                       if (f & DOCOMPLETION)
>                                               break;
>                                       /* fall through */
>                               case '*':
617,620c620,624
<                                       if ((f & DOBRACE_) && (c == OBRACE ||
<                                           (fdo & DOBRACE_))) {
<                                               fdo |= DOBRACE_|DOMAGIC_;
<                                               *dp++ = MAGIC;
---
>                                       if (!(f & DOCOMPLETION) &&
>                                               (f & DOBRACE_) &&
>                                               (c == OBRACE || (fdo & 
> DOBRACE_))) {
>                                                       fdo |= 
> DOBRACE_|DOMAGIC_;
>                                                       *dp++ = MAGIC;
936c940
< glob(char *cp, XPtrV *wp, int markdirs)
---
> glob(char *cp, XPtrV *wp, int flags)
940,942c944,947
<       if (glob_str(cp, wp, markdirs) == 0)
<               XPput(*wp, debunk(cp, cp, strlen(cp) + 1));
<       else
---
>       if (glob_str(cp, wp, flags & DOMARKDIRS) == 0) {
>               if (!(flags & DOCOMPLETION))
>                       XPput(*wp, debunk(cp, cp, strlen(cp) + 1));
>       } else
1144,1145c1149,1150
<                       return dp;
<               memcpy(dp, sp, s - sp);
---
>                       return dp; 
>               memmove(dp, sp, s - sp);
Index: tree.h
===================================================================
RCS file: /OpenBSD/src/bin/ksh/tree.h,v
retrieving revision 1.10
diff -r1.10 tree.h
128a129
> #define DOCOMPLETION BIT(11)  /* hint that we are doing an auto-completion */

Reply via email to