Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Autocomplete doesn't work correctly on certain folder names



> 2023/04/22 4:59, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> OK, thanks.  The following matcher-list demonstrates the oddity:
> 
> zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*'
(snip)
> Given the provided example of
> 
> my-longfoldername-firstname
> you-longfoldername-secondname
> 
> I believe** the resulting partial completion should be
> 
> y-longfoldername-
(snip)
> ** I may be incorrect about the expected answer, the juxtaposition of
> the prefix with the first hyphen also seems to matter.

Please try putting a breakpoint at join_psfx(); this function is called
with sfx=4 (i.e., true).
When it is called for the first time, it does almost nothing,
but at the second time, it calls sub_match() (compmatch.c:2493)

    } else if ((len = sub_match(&md, o->word, o->wlen, sfx)) != o->wlen) {

Here,
o->word="my-longfoldername-firstname", o->len=3,
md.cl->word="you-longfoldername-secondname", md.cl->wlen=4.

sub_match() returns 1 (= len), meaning that one character (the
first '-' before the 'long') can be moved into the common prefix.

Then, at line 2509:
        if ((joinl = join_sub(&md, *sstr + len, *slen - len,

Here,
*sstr="my-longfoldername-firstname", len=1, *slen=3
(*sstr+len = "y-longfoldername-firstname", *slen - len = 2).
But md.str="-longfoldername-secondname", md.len=3.

I first thought join_sub() should be called with the second argument
"-longfoldername-firstname".
This can be done by the patch below, and "apparently" it works:

% cd long<TAB>
gives
% cd -long-foldername-
and hitting more <TAB>s will work as expected.


But if we look into join_sub(), lines 2221-2223,
        if (sfx) {
            ow += ol; nw += nl;
        }
Before line 2222 (without the patch below)
ow = str = "y-long...-firstname" and nw = "-long...-secondname".
(with the patch ow = '-long...firstname").
Why these pointers need be advanced by ol=2 and nl=3?
It looks as if join_sub() expects ow='my-long.." and nw="you-long.."??

I don't know what are the correct values for these pointers
and lengths. I just hope my analysis will help someone to figure
out the real fix.

PS
join_sub() tries all the matcher (including 'm:{a-zA-Z}={A-Za-z}').
Whether there is a '-' or not matters because '-' is not in the range
'{a-zA-Z}'.


diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c
index ddcecd589..c9d4a3d24 100644
--- a/Src/Zle/compmatch.c
+++ b/Src/Zle/compmatch.c
@@ -2506,8 +2506,8 @@ join_psfx(Cline ot, Cline nt, Cline *orest, Cline *nrest, int sfx)
 	    Cline joinl;
 	    int jlen;
 
-	    if ((joinl = join_sub(&md, *sstr + len, *slen - len,
-				  &jlen, sfx, !(o->flags & CLF_JOIN)))) {
+	    if ((joinl = join_sub(&md, *sstr + (sfx ? *slen - len : len),
+			    *slen - len, &jlen, sfx, !(o->flags & CLF_JOIN)))) {
 		/* We have one, insert it into the list. */
 		joinl->flags |= CLF_DIFF;
 		if (len + jlen != *slen) {







Messages sorted by: Reverse Date, Date, Thread, Author