Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Help Request/Bug Report: comparguments causes _arguments to fail in certain cases
Hi there,
>From what I understand, bug reports should be mailed here. If I'm wrong I'd
be happy to be redirected to the correct medium.
What I want to report is probably not a bug, and stems from my
misunderstanding of compsys. Any help will be greatly appreciated.
The following is a copy paste of the a this question
<https://stackoverflow.com/questions/61560687/comparguments-causes-arguments-to-fail-in-certain-cases>
I asked on stack overflow:
*I'm writing a zsh completion script for arbitrary python scripts (similar
to argcomplete <https://github.com/kislyuk/argcomplete>).*
*I'm trying to get the script to work in several use cases:*
*1. The script is invoked directly (e.g. ~/script.py)*
*2. The script is invoked through python (e.g. python script.py)*
*3. The script is invoked as a python module (e.g. python -m script)*
*I have so far managed to successfully handle the first case, but the
second case fails to retrieve any completions. Using zsh completion debug
log I was able to see where things went wrong:*
*The _arguments function calls a builtin function named comparguments. In
the first case the function returns 0 and the control flow continues as
expected. In the second case the function fails and causes _arguments to
immediately return 1. This happens even though the arguments to
comparguments are identical in both cases.*
*Here <https://gist.github.com/dan1994/45f97442dc488338b59ed8ddf70424e1> is
a link to debug logs for both situations. For the first scenario
comparguments is called in line 199, and in the second scenario it is
called in line 197.*
*My script:*
*#compdef -p **
*_python_script() {*
* # Expand all words*
* local -a expanded_words*
* __pyzshcomplete_exapnd_tilde_in_all_words*
* # Check if we should run or else quit*
* __pyzshcomplete_should_run || return 1*
* # Skip any other completion function*
* _compskip=all*
* # Retrieve valid completions and pass them to _arguments*
* local arguments=(*
* ${(f)"$(PYZSHCOMPLETE=1 __python_argcomplete_run
${expanded_words[@]})"}*
* )*
* _arguments -s -w : ${arguments[@]}*
* # Always return 0 - if _arguments fails, compsys for some reason
invokes*
* # this script again consuming more time and gaining nothing.*
* # If we are in this context there shouldn't be other completions
anyways so*
* # no reason to return 1 anyways...*
* return 0*
*}*
*__pyzshcomplete_exapnd_tilde_in_all_words() {*
* for ((i = 1; i <= $#words; i++)); do*
* expanded_words[$i]=${~words[$i]}*
* done*
*}*
*### The following code is taken from the argcomplete project, including*
*### original copyright. Changes from the original will be marked by a
comment*
*### Starting with CHANGE.*
*### Original code:*
*###
https://github.com/kislyuk/argcomplete/blob/v1.11.1/argcomplete/bash_completion.d/python-argcomplete
<https://github.com/kislyuk/argcomplete/blob/v1.11.1/argcomplete/bash_completion.d/python-argcomplete>*
*# Copyright 2012-2019, Andrey Kislyuk and argcomplete contributors.*
*# Licensed under the Apache License. See
https://github.com/kislyuk/argcomplete
<https://github.com/kislyuk/argcomplete> for more info.*
*# CHANGE: This function is a heavily refactored copy of the first part of*
*# _python_argcomplete_global*
*__pyzshcomplete_should_run() {*
* local executable=${expanded_words[1]}*
* if [[ $executable == python* ]] || [[ $executable == pypy* ]]; then*
* # If 2nd word is the -m flag, check that the module has the magic
string*
* [[ ${expanded_words[2]} == -m ]] && __python_argcomplete_run \*
* $executable -m argcomplete._check_module ${expanded_words[3]}
&& \*
* return 0*
* # If 2nd word is a file, check that it has the magic string*
* [[ -f ${expanded_words[2]} ]] &&
__python_argcomplete_scan_head_noerr \*
* ${expanded_words[2]} && return 0*
* return 1*
* fi*
* # Assume the first word is a script and find its path*
* local script_path*
* # Search in path*
* if type -p $executable > /dev/null 2>&1; then*
* script_path=$(type -p $executable | sed -r "s:$executable is ::")*
* # Check if it's a file*
* elif [[ -f $executable ]]; then*
* script_path=$executable*
* fi*
* # If found a path, scan for magic*
* if [[ -n $script_path ]]; then*
* __python_argcomplete_scan_head_noerr $script_path && return 0*
* return 1*
* fi*
* return 1*
*}*
*# Run something, muting output or redirecting it to the debug stream*
*# depending on the value of _ARC_DEBUG.*
*__python_argcomplete_run() {*
* if [[ -z "$_ARC_DEBUG" ]]; then*
* "$@" 8>&1 9>&2 1>/dev/null 2>&1*
* else*
* "$@" 8>&1 9>&2 1>&9 2>&1*
* fi*
*}*
*# Scan the beginning of an executable file ($1) for a regexp ($2). By
default,*
*# scan for the magic string indicating that the executable supports the*
*# argcomplete completion protocol. Scan the first kilobyte.*
*__python_argcomplete_scan_head() {*
* # CHANGE: the zsh read builtin has different options and behaves
differently*
* read -s -r -k 1024 -u 0 < "$1"*
* [[ "$REPLY" =~ ${2:-PYTHON_ARGCOMPLETE_OK} ]]*
*}*
*__python_argcomplete_scan_head_noerr() {*
* __python_argcomplete_scan_head "$@" 2>/dev/null*
*}*
*EDIT:*
*In order to temporarily bypass the problem I tried adding a shift words
before calling _arguments. This caused comparguments to succeed (!), but
still causes _arguments to fail with a no arguments message later on.*
*I added the log for this case to the gist linked above.*
--
Dan Arad
dan1994@xxxxxxxxx
Messages sorted by:
Reverse Date,
Date,
Thread,
Author