Hi,

The patch fixes this for me. OK.

Ilya

> On Jul 2, 2017, at 13:46, Anton Lindqvist <anton.lindqv...@gmail.com> wrote:
> 
> Hi,
> 
>> On Fri, Jun 30, 2017 at 09:50:12PM -0700, Ilya Kaliman wrote:
>> Hi!
>> 
>> The tab-autocomplete does not seem to work for some strings in ksh.
>> How to reproduce:
>> 
>> mkdir "a a" "(bbb)" "(c c)"
>> cd a\ a && mkdir abc{1,2,3} && cd ..
>> cd \(bbb\) && mkdir abc{1,2,3} && cd ..
>> cd \(c\ c\) && mkdir abc{1,2,3} && cd ..
>> 
>> type "cd a\ a/" hit tab -> auto-completes to abc, offers abc1 abc2 abc3
>> type "cd \(bbb\)/" hit tab -> auto-completes to abc, offers abc1 abc2 abc3
>> type "cd \(c\ c\)/" hit tab -> does not autocomplete; expected - same
>> as previous.
> 
> Nice catch. As I see it, the bug you're seeing happens inside
> do_complete() while comparing the length of the input buffer and the
> results from the completion. Since the completions are passed through
> expand() causing escaped characters to be unescaped to their literal
> form while the input buffer remains escaped. You managed to find the
> perfect set of input causing the condition to when a completion
> succeeded to be invalidated:
> 
>  olen = strlen("\(c\ c\)/") = 9;
>  nlen = strlen("(c c)/abc") = 9;
> 
> Since `olen == nlen` no completion is performed. Please try out the diff
> below in which slashes are discarded when comparing the length. I don't
> know if any other character should be discarded as well, if true then it
> might be worth passing the input buffer through ksh's own lexer and
> parser in order to properly handle special characters, just like in
> x_file_glob().
> 
> Comments? OK?
> 
> Index: emacs.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/emacs.c,v
> retrieving revision 1.70
> diff -u -p -r1.70 emacs.c
> --- emacs.c    25 Jun 2017 17:28:39 -0000    1.70
> +++ emacs.c    2 Jul 2017 20:43:00 -0000
> @@ -1754,6 +1754,7 @@ do_complete(int flags,    /* XCF_{COMMAND,F
>    char **words;
>    int nwords;
>    int start, end, nlen, olen;
> +    int i, ndiscard;
>    int is_command;
>    int completed = 0;
> 
> @@ -1773,9 +1774,13 @@ do_complete(int flags,    /* XCF_{COMMAND,F
>    }
> 
>    olen = end - start;
> +    ndiscard = 0;
> +    for (i = start; i < end; i++)
> +        if (xbuf[i] == '\\')
> +            ndiscard++;
>    nlen = x_longest_prefix(nwords, words);
>    /* complete */
> -    if (nwords == 1 || nlen > olen) {
> +    if (nwords == 1 || nlen > olen - ndiscard) {
>        x_goto(xbuf + start);
>        x_delete(olen, false);
>        x_escape(words[0], nlen, x_do_ins);

Reply via email to