Autocomplete issue
Closed this issue · 8 comments
- I've checked the existing issues and I'm not duplicating a report.
- I'm using the latest version of
zimfw
. - I've checked the Changelog and I'm not being affected by documented changes.
- I've checked the 📢 Announcements and I'm not being affected by announced changes.
- I was able to reproduce the issue with a clean installation of Zim.
- I've pasted the output of
zimfw info
below.
Describe the bug
When trying to cd
into similar named directories it fails to autocomplete, sometimes.
Steps to reproduce
The fist 4 steps restart the shell with a clean installation of Zim in a temporary directory.
Use exec zsh
when restarting the terminal or restarting the shell is needed.
cd ${$(mktemp -d):A}
ZDOTDIR=${PWD} HOME=${PWD} ZIM_HOME=${PWD}/.zim exec zsh
curl -fsSL https://raw.githubusercontent.com/zimfw/install/master/install.zsh | zsh
exec zsh
mkdir -p tmp/{users,utils}
cd tmp
- type
cd u
and then Tab to autocomplete.
Current behavior
When pressing Tab it incorrectly autocompletes to uT
and then utils/
if you press Tab again.
Expected behavior
It should give correct autocomplete, proving users/
and utils/
as options.
Screenshots
simplescreenrecorder-2022-06-20_16.40.16.mp4
zimfw info
zimfw version: 1.9.1 (built at 2022-05-24 21:25:10 UTC, previous commit is 5bcfb8c)
ZIM_HOME: /home/sqve/.local/share/zim
Zsh version: 5.9
System info: Linux calcifer 5.18.5-arch1-1 #1 SMP PREEMPT_DYNAMIC Thu, 16 Jun 2022 20:40:45 +0000 x86_64 GNU/Linux
Hey @sQVe! Thanks for the detailed report! I was able to reproduce it in macOS too (which has a case insensitive file system), and even with setopt caseglob
.
Our matcher-list
configuration is known to be buggy. See a longer discussion in zimfw/zimfw#212. Your example adds to the long list of expected behavior discussed in that issue.
@marlonrichert has figured out a great configuration for the completion system in https://github.com/marlonrichert/zsh-autocomplete/blob/main/scripts/.autocomplete.config. I haven't had time to explore the details of his implementation, but I believe we might be able to figure out the solution for a fuzzy completion like we expect based on his work.
I tried playing around with this module and if I unset NO_CASE_GLOB
and comment out zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' '+r:|?=**'
I get the correct completion for this case. I'm well aware that it isn't that simple but thought it might be worth noting.
I tried changing the matcher-list
to https://github.com/marlonrichert/zsh-autocomplete/blob/4decd760641377e818d11146ef1249f5474c224a/scripts/.autocomplete.config#L64-L72 and that seems to work well, as far as I can tell.
Cool. I believe you'll also need an extra configuration to enable the loose and fuzzy matchers. This is done here: https://github.com/marlonrichert/zsh-autocomplete/blob/4decd760641377e818d11146ef1249f5474c224a/scripts/.autocomplete.config#L26-L33
I'm a bit unsure what the differences between the three are. Just setting:
zstyle ':completion:*' matcher-list \
'm:{[:lower:]-}={[:upper:]_} r:|[.]=**' \
'+l:|=*'
Seems to work fine for my use-cases.
The documentation for Zsh completion matchers has been a mess for years. However, I recently wrote completely new documentation for it, which has been released with Zsh 5.9: https://zsh.sourceforge.io/Doc/Release/Completion-Widgets.html#Completion-Matching-Control
Hopefully, this makes things more clear.
(Note, however, that there are long-standing bugs in the :||=
matchers. The docs that I wrote describe how they are intended to work, but they don’t actually work like that at present. I would avoid them for now.)
@marlonrichert Cheers for great information! Could you possibly provide insight into what the matcher-list I'm using above actually does?
-
m:{[:lower:]-}={[:upper:]_}
-
Each lowercase letter in the input can also match its uppercase counterpart and each
-
in the input can also match a_
. -
r:|[.]=**
-
r:|.=**
-
Each empty substring in the input that has a
.
to the right of it can match any substring, including those containing other instances of.
. (If you had just a single*
there, then it couldn’t match substrings containing.
) In other words, this inserts a wildcard to the left of each.
. -
+
-
If the previous matcher fails, then append this matcher to it and try again. (Note that this is unique to
zstyle […] matcher-list
and thus not handled in the chapter I linked to above. See here instead.) -
l:|=*
-
If there is an empty substring at the left edge of the input (which is by definition always the case), then it can match any substring. In other words, this adds a wildcard to the left edge of the input.