From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: (qmail 30124 invoked from network); 7 May 2020 20:41:05 -0000 Received-SPF: pass (primenet.com.au: domain of zsh.org designates 203.24.36.2 as permitted sender) receiver=inbox.vuxu.org; client-ip=203.24.36.2 envelope-from= Received: from ns1.primenet.com.au (HELO primenet.com.au) (203.24.36.2) by inbox.vuxu.org with ESMTPUTF8; 7 May 2020 20:41:05 -0000 Received: (qmail 16549 invoked by alias); 7 May 2020 20:40:51 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: List-Unsubscribe: X-Seq: 24822 Received: (qmail 17237 invoked by uid 1010); 7 May 2020 20:40:51 -0000 X-Qmail-Scanner-Diagnostics: from wout1-smtp.messagingengine.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.102.2/25801. spamassassin: 3.4.4. Clear:RC:0(64.147.123.24):SA:0(-1.1/5.0):. Processed in 4.393807 secs); 07 May 2020 20:40:51 -0000 X-Envelope-From: d.s@daniel.shahaf.name X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: none (ns1.primenet.com.au: domain at daniel.shahaf.name does not designate permitted sender hosts) X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduhedrkedtgdduhedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpeffhffvuffkjghfofggtgfgsehtqh dttdertdejnecuhfhrohhmpeffrghnihgvlhcuufhhrghhrghfuceougdrshesuggrnhhi vghlrdhshhgrhhgrfhdrnhgrmhgvqeenucggtffrrghtthgvrhhnpefhtdetfeehveeutd ehuddtieefgeettedtjedtffehudeiieejleetteekudetheenucfkphepuddtledrieei rdduhedrvdefleenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfh hrohhmpegurdhssegurghnihgvlhdrshhhrghhrghfrdhnrghmvg X-ME-Proxy: Date: Thu, 7 May 2020 20:40:07 +0000 From: Daniel Shahaf To: Dan Arad Cc: zsh-users@zsh.org Subject: Re: Help Request/Bug Report: comparguments causes _arguments to fail in certain cases Message-ID: <20200507204007.7487332d@tarpaulin.shahaf.local2> In-Reply-To: References: <20200503165802.6540ad48@tarpaulin.shahaf.local2> <20200504131830.3572e317@tarpaulin.shahaf.local2> <20200505164934.3f6b7f42@tarpaulin.shahaf.local2> X-Mailer: Claws Mail 3.17.3 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable > > > > After _python returned, my script was invoked again and printed > > > > `BUFFER=3Dpython ps.py` and `words=3Dpython*3* ps.py` (note the 3).= =20 > > > > I'm not sure offhand where this comes from. $context, $funcstack, et al > > may have clues. =20 >=20 >=20 > I may have neglected to say that I aliased `python` to `python3`, so it > makes sense since you said that words is the result of alias expansion. Yes, that'd be it. > > You might try looking up the place that originally populates $words and > > making it stash a copy of $words in another, read-only array; then you'= ll > > be able to use =C2=ABcompset -P=C2=BB and access that array. (Compare = vcs_info's > > use of *_orig keys in ${hook_com}.) =20 >=20 >=20 > I tried looking at things related to `vcs_info`, and I saw they were > outside of the Completion directory. > I was able to find the place where the `*_orig` keys are set, but couldn't > find where they are used. > It would be nice to get some context (or reference) about how this part of > zsh connects to compsys, and how variables like `hook_com` become availab= le > to completion functions. vcs_info has nothing to do with compsys. Sorry for the unclarity. *_orig variables would be used by hooks in people's dotfiles. There are examples of hooks in Misc/vcs_info-examples, though they don't access the *_orig keys. I was trying to explain by way of analogy: just like vcs_info sets ${hook_com[revision_orig]}, in order that if two hooks are installed the later one be able to access the original value even if the earlier one had modified ${hook_com[revision]}, so I imagined a ${words_orig} array, to let your completion function access the value of $words before the _arguments call in _python shifted some elements off it. > > Something along these lines, I think: > > > > local -a words2=3D( ${(z):-"$PREBUFFER${LBUFFER}x"} ) > > words2[-1]=3D${words2[-1]%x} =20 > > words2[1,${words2[(I)(;|&&|=E2=80=A6)]}]=3D() =20 >=20 >=20 > A lot for me to unpack here and in the paragraphs that follow. > I'll try to understand as much as I can, but will probably ask about it > later. Sure, feel free. =C2=AB${foo[(I)bar]}=C2=BB expands to an index into the array $foo; which i= ndex is determined by the pattern =C2=ABbar=C2=BB. (You can get quick help by tab completing after the opening round parenthesis; the full description of ${[(I)]} is in the manual.) Do consider the other two alternatives, though. Just because it's _possible_ to reimplement the $BUFFER-to-$words transformation doesn't imply that's the best way forward. Cheers, Daniel > Thanks! > Dan >=20 > On Tue, May 5, 2020 at 7:49 PM Daniel Shahaf wro= te: >=20 > > > > > Well, for starters, if you =C2=ABshift words=C2=BB, you should de= crement =20 > > CURRENT =20 > > > > > as well. > > > > > > > > > > However, _python uses the =C2=AB*::=E2=80=A6=C2=BB form of an _ar= guments optspec, > > > > > which should take care of $words/$NUMERIC for you. I assume the = =20 > > reason =20 > > > > > it didn't is that you used =C2=ABcompdef -p=C2=BB. Try -P instea= d? If I'm not > > > > > mistaken, that would also handle =C2=ABpython =E2=80=A6 script.py= =C2=BB for you > > > > > (where the ellipsis stands for python's --options). =20 > > > > > > > > > > > > I tested the 4 possible options, and found that switching -p with -P > > > > doesn't change anything, but shifting words and decrementing CURRENT > > > > works! But... I feel like it's a hack I'm not supposed to do > > > > (correct me if I'm wrong). =20 > > > > Those parameters are documented, and manipulated by a number of > > functions (including _python, as it happens), so you _are_ using the AP= I. > > See also the 'compset' builtin. > > > > However, as mentioned, I suspect that hardcoding a skip/decrement of one > > element won't DTRT if python is invoked with options (e.g., =C2=ABpython > > --foo script.py =C2=BB) =E2=80=94 not unless you reimplement _pyth= on's parsing > > of those options and any arguments to them. > > =20 > > > > I now tried using the BUFFER variable instead of words (since it =20 > > remains =20 > > > > unchanged), but found that it also has caveats: The BUFFER variable > > > > contains the raw value of the line, whereas the words array contain= s =20 > > the =20 > > > > words after expansions (I think that's the right term). =20 > > > > Partly. $words has undergone alias expansion, but not further > > expansions. In particular, the words are still quoted. > > =20 > > > > To demonstrate this I tried running again completion for `python ps= ,py` > > > > with `#compdef -P *`, and printing out BUFFER and words. The debug = =20 > > log =20 > > > > (and my terminal) showed the following: > > > > First of all _python was called and dispatched my script which prin= ted > > > > `BUFFER=3Dpython ps.py` and `words=3Dps.py`. =20 > > > > That's what I'd expect. > > =20 > > > > After _python returned, my script was invoked again and printed > > > > `BUFFER=3Dpython ps.py` and `words=3Dpython*3* ps.py` (note the 3).= =20 > > > > I'm not sure offhand where this comes from. $context, $funcstack, et al > > may have clues. > > =20 > > > > I do think the right solution is to be dispatched by _python with > > > > `#compdef -P *.py`, but to be able to run I need the words array as > > > > seen by _python =20 > > > > Once an element is shifted off $words, it's lost forever (free() is > > called on it), so there'll be no way to access a "previous" value of $w= ords > > unless a copy had been made somewhere. > > > > Moreover, consider that python may be itself wrapped by some precommand: > > for example, =C2=ABenv X=3DY python=C2=BB, =C2=ABsudo -u foo python=C2= =BB, or =C2=ABssh foo python=C2=BB. > > > > You might try looking up the place that originally populates $words and > > making it stash a copy of $words in another, read-only array; then you'= ll > > be able to use =C2=ABcompset -P=C2=BB and access that array. (Compare = vcs_info's > > use of *_orig keys in ${hook_com}.) > > =20 > > > > or a to understand how BUFFER can be expanded/converted to its =20 > > correct =20 > > > > form. If you have any input on this, I would very much appreciate > > > > it. =20 > > > > Something along these lines, I think: > > > > local -a words2=3D( ${(z):-"$PREBUFFER${LBUFFER}x"} ) > > words2[-1]=3D${words2[-1]%x} =20 > > words2[1,${words2[(I)(;|&&|=E2=80=A6)]}]=3D() =20 > > > > To understand the second line, see addx() in Src/Zle/zle_tricky.c. With > > that out of the way, the first line's a textbook use of the ${(z)} > > tokenizer. The third line just throws out everything until the start of > > the current _simple command_ (see zshmisc(1)) =E2=80=94 or, at least, i= t will > > once the ellipsis is filled out. > > > > Caveats: that snippet doesn't do alias expansion, doesn't try to deal > > with ${RBUFFER}, doesn't try to deal with SHORT_LOOPS, doesn't try to > > deal with precommands and precommand assignments, should be changed to > > use zZ+c+ if the INTERACTIVE_COMMENTS option is set=E2=80=A6 > > > > Although it's a plugin that I worked on myself, I should probably > > mention that zsh-syntax-highlighting has faced the same problem and you > > and implemented a solution to it, which handles a number of the above > > caveats. > > =20 > > > =20 > > > > There's also a third approach: instead of trying to run the binary, make > > it stash the output in a well-known location. For example, /usr/bin/foo > > could store the output in /usr/share/argcomplete/foo. (I've always > > wanted to standardize _some_ solution to this problem; I'm tired of > > writing completion functions by hand=E2=80=A6) > > > > Cheers, > > > > Daniel > > =20 >=20 >=20