Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: zle messes up 'words' variable?



On Wed, May 4, 2011 at 3:56 AM, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> On May 3,  8:36pm, Felipe Contreras wrote:
> } Subject: Re: zle messes up 'words' variable?
> }
> } On Tue, May 3, 2011 at 5:39 PM, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> } >    change the current values of these parameters. Any existing values
> } >    will be hidden during execution of completion widgets; EXCEPT FOR
> } >    COMPSTATE, THE PARAMETERS ARE RESET ON EACH FUNCTION EXIT (INCLUDING
> } >    NESTED FUNCTION CALLS FROM WITHIN THE COMPLETION WIDGET) to the
> } >    values they had when the function was entered.
> } >
> } > In other words, these variable are always local in all scopes, unless
> } > they are explicitly declared otherwise (which in this case requires
> } > the use of typeset -h).  That's part of their special-ness, and is one
> } > of the things I assert is extremely unlikely to change.
> }
> } Except that 'words' is not really acting as local, and 'local' should
> } be considered 'declared otherwise'. That's part of the weirdness.
>
> "local" without -h has never changed the special properties of a zsh
> variable.  It would be "weird" in a large number of other cases if it
> were to be "fixed" for this case.
>
> } +typeset -h words
> }  complete -F _foo foo
>
> No, that's making words non-special at the wrong scope; it may work
> for your example because _foo never attempts to examine the special
> value of $words, but in practice you can't create a useful completion
> function without some reference to that special value.
>
> (However, I think it still fails for your example, because the
> typeset at global scope will be supplanted by the special local at
> completion scope.  You have to wait until the local scope exists
> before you can hide it with "typeset -h".)
>
> Once the special "words" is hidden, the bash completion widgets can
> ignore it because for them, the relevant bits are passed in "$@"; but
> the _bash_complete wrapper that's installed by "complete -F" needs
> access to $words in order to create the arguments it passes to _foo.
>
> Hence the scope where my patch added typeset -h is only correct place
> outside the the function called as $OPTARG where words can become non-
> special without changing the arguments passed by that function call.

You are right, however, it does work in git[1].

Here's a more complete example to what git is doing, and my proposed
'typeset -h' workaround.

---
#!bash

autoload -U +X bashcompinit && bashcompinit

set_vars ()
{
	cur=${COMP_WORDS[COMP_CWORD]}
	words=("${COMP_WORDS[@]}")
	cwords=$COMP_CWORD
}

_foo_bar ()
{
	local cur words cwords
	set_vars

	echo "foo bar: cur=${cur} words=${words} cwords=${cwords}" >>
/tmp/comp_test.txt
}

_foo ()
{
	typeset -h words

	local cur words cwords
	set_vars

	echo "foo: cur=${cur} words=${words} cwords=${cwords}" >> /tmp/comp_test.txt

	_foo_bar
}

complete -F _foo foo
---

[1] http://mid.gmane.org/1304605458-1483-1-git-send-email-felipe.contreras@xxxxxxxxx

-- 
Felipe Contreras



Messages sorted by: Reverse Date, Date, Thread, Author