-
-
Notifications
You must be signed in to change notification settings - Fork 135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix and test global completion in zsh #463
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## develop #463 +/- ##
========================================
Coverage 81.12% 81.12%
========================================
Files 10 10
Lines 784 784
========================================
Hits 636 636
Misses 148 148 ☔ View full report in Codecov by Sentry. |
@@ -139,9 +139,6 @@ _python_argcomplete_global() { | |||
__python_argcomplete_expand_tilde_by_ref executable | |||
else | |||
if [[ "$service" != "-default-" ]]; then | |||
# TODO: this may not be sufficient - see https://zsh.sourceforge.io/Doc/Release/Completion-System.html | |||
# May need to call _complete with avoid-completer=_python-argcomplete or something like that | |||
_default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kislyuk This was added in afdf75b, but I'm not sure what the intent was. This was causing default completions to be mixed in with the returned completions in my tests, and removing it doesn't seem to have caused any of the existing tests to fail. If you remember what problem this was addressing, I can take another look into it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@evanunderscore please do not delete this without a replacement, and especially please do not delete the comment. This was added in response to #454. Specifically, it was found that the default completer interferes with zsh completion in the redirect target context (words after >
or 2>
).
I didn't manage to write a test for this, and I since realized that this was a stopgap solution that will need to be further refined. For example, instead of calling _default unconditionally as a fallback here, we may need to call it only when certain contexts like -redirect-
are listed in $service
(see the link in the comment for a full list of contexts - there are others in the list that will almost certainly need similar treatment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the issue link, I did search initially but wasn't able to find it.
I've pushed a fix in 1f6e661. Rather than handle all of the special contexts, I've updated the compdef
command to only override -default-
which leaves the other special contexts undisturbed. The tests are all passing and I've poked around manually in the shell for a bit, and it seems to be working as expected.
Are you happy with this fix and the comment I've left?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately the macos tests are failing and I don't have a good way to troubleshoot them. I can just disable the global zsh tests on macos (since they weren't running at all before I added them), but it is strange that they were all passing before I made the compdef
change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue is that some of the runners already have python-argcomplete
installed as a dependency of pipx
, which explains why the failures seemed completely inconsistent - the tests were actually testing whichever version happened to be installed and not what was in the source. For now, I've added a step to uninstall it, but a better solution would be to revisit the change I suggested in #255. Without it, there is no good way to avoid this mismatch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than handle all of the special contexts, I've updated the compdef command to only override -default- which leaves the other special contexts undisturbed.
Sounds good, thanks.
if is-at-least 5.8; then | ||
nosort=(-o nosort) | ||
fi | ||
if [[ "${completions-}" =~ ([^\\]): && "${BASH_REMATCH[2]}" =~ [=/:] ]]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note this must use BASH_REMATCH
(as opposed to match
) because this script uses setopt local_options BASH_REMATCH
. The indexing is different because we haven't also set KSH_ARRAYS
and I haven't called __python_argcomplete_upshift_bash_rematch
.
local nospace=() | ||
if is-at-least 5.8; then | ||
nosort=(-o nosort) | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The -o
argument was removed in #433 due to incompatibility with zsh 5.7. The arguments to -o
were added in 5.8:
Changes between 5.7 and 5.8
[...]
The compadd builtin's -o option now takes an optional argument to specify the order of completion matches. This affects the display of candidate matches and the order in which they are selected when cycling between them using menu completion.
if is-at-least 5.8; then | ||
nosort=(-o nosort) | ||
fi | ||
if [[ "${completions-}" =~ ([^\\]): && "${match[1]}" =~ [=/:] ]]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note the different indexing semantics between match
and BASH_REMATCH
. Both versions are extracting the first match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The returned completion format is completion:description
, where colons are escaped with backslashes. This looks for the character before the first unescaped colon and checks it against the same characters used for bash.
@@ -1248,9 +1248,6 @@ def setUp(self): | |||
path = ":".join([os.path.join(BASE_DIR, "scripts"), TEST_DIR, "$PATH"]) | |||
sh.run_command("export PATH={0}".format(path)) | |||
sh.run_command("export PYTHONPATH={0}".format(BASE_DIR)) | |||
if self.repl_provider == bash_repl: | |||
# Disable the "python" module provided by bash-completion | |||
sh.run_command("complete -r python python2 python3") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was not actually doing anything, since self.repl_provider
is a separate method that calls bash_repl
. Since the tests were still passing, I'm assuming this is no longer needed.
7caa780
to
b6e38aa
Compare
1f6e661
to
a0dc5e3
Compare
The linked workaround seems no longer relevant. The Homebrew documentation no longer mentions the flag.
Thanks @evanunderscore. I'll do some more testing with the new compdef change and then roll a release. |
@evanunderscore after this change, global completion doesn't work in zsh for me, on both Linux and macos. How did you test it? |
@evanunderscore I have reverted the part of this PR that changes the zsh compdef line (and re-added the call to _default). It doesn't look like |
Actually, since the revert of just that part breaks tests, I'm going to go ahead and revert the whole PR; please reopen it when you have a chance and see if your changes can be reconciled with a version of the compdef line that works. |
OK, I think I found a way to preserve the behavior that we want - I've replaced In light of the apparent fragility of this change, it will require further testing and hopefully we can find a way to exercise it in CI. Note that it can be tricky to make sure that zsh unloaded the previous function and loaded the one that you edited - I had to remove |
@kislyuk The tests are failing because you've reintroduced the problem from #458 by not suppressing the default completions. As an example,
The completion of
Now it doesn't insert anything, and the resulting line is just I agree it's not ideal for unrelated tests to fail like this. The fix would be to have the shell tests
I tested on Ubuntu 22.04 with zsh 5.8.1 using the same method as the tests use, i.e.
To the best of my understanding, the change was being exercised in CI. The problem will have to be either with a mismatch between how you and I tested locally, or the version of zsh you're using, or something else specific to your environment. |
The Changing this to Can you try reverting your fix and changing the #compdef comment please? |
Fixes #451, #458, #462