Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Autocomplete doesn't work correctly on certain folder names
- X-seq: zsh-workers 51674
- From: Jun T <takimoto-j@xxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: Re: Autocomplete doesn't work correctly on certain folder names
- Date: Wed, 26 Apr 2023 13:22:53 +0900
- Archived-at: <https://zsh.org/workers/51674>
- In-reply-to: <CAH+w=7YP54qzH6wLw5XYUVOFX3a3AjVXOzVnBux956KHHe=f-A@mail.gmail.com>
- List-id: <zsh-workers.zsh.org>
- References: <CAEQc7iXik1WSQYt3XzSkRugwo6HOLifX7rzTWbBXXoc4bFCsxQ@mail.gmail.com> <CAN=4vMoeZ3JFkfgmv7HgnNye68Ad0vZ1VJUjw28MwF9Gdh3h8g@mail.gmail.com> <CAEQc7iXVyTnEU+4aEOLX7ODivo1T1BOq+D=ynoSeuUc8VakujQ@mail.gmail.com> <CAN=4vMrYYYTpvWQgSa4ScQUNAC9_kHzDNFSy09fwBwD4w-37fQ@mail.gmail.com> <CAH+w=7YQPWs6jVTmNvtuhYqLrmuGaObgmnxUVoEjCvzHy5MWtg@mail.gmail.com> <CAH+w=7YP54qzH6wLw5XYUVOFX3a3AjVXOzVnBux956KHHe=f-A@mail.gmail.com>
> 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