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

Re: Something wrong with prompt themes

On Dec 7,  1:44am, Adam Spiers wrote:
} Subject: Re: Something wrong with prompt themes
} [...] noticed a bug which prevents most help texts from being displayed
} normally: if you haven't used or previewed a particular theme, its
} help function won't have been loaded, so `prompt -h foo' won't display
} the help.  [...] so we return to the question, "how best to load an
} autoloaded function without actually causing any function within the
} autoload file to be run?"  When I last asked this, Bart suggested:
}     function loadauto {
}         emulate -L zsh
}         local f
}         f=( $^fpath/$1(N) )
}         eval "function $1 {
}             $(< $f[1])
}         }"
}     }
} [...] I looked at the autoload -X and +X options, but if
} I read the docs and thought about it correctly, they don't help.

That "loadauto" function is almost exactly equivalent to "autoload +X".

} but this won't work, since the files in question are of the autoload
} variety which explicitly define the function `foo' (and some other
} functions at the same time in fact), and then have a
}   foo "$@"
} as the last line.

That should be

	[[ -o kshautoload ]] || foo "$@"

or else foo will be executed twice.  I haven't checked whether the prompt
functions have a problem with this.  (Hmm, this points out a problem with
"autoload +X" -- the function *won't* be executed the first time it is
called following "autoload +X" when kshautoload is set, if that particular
trick was used in the function's definition.)

It's presently impossible to cause some second function that's defined
in the same file as an autoloaded function to become loaded without also
executing the autoloaded one.  I can't even think of a way to make this
possible.  You either have to execute the contents of the file, causing
the additional functions therein to become defined; or parse it as the
body of a function (and thereby not execute it).  There isn't any way
to selectively execute the commands, particularly if both ksh-style and
zsh-style autoloads are to be supported at the same time.

An additional but more easily surmounted problem is that those additional
functions are completely unknown to zsh.  There's no mechanism to say that
"file X provides function Y" and thus cause X to be read when Y is run.

The best (non-general) solution I can think of would be for the primary
function to accept a "don't execute now" switch, like so:

    # contents of file "foo" somewhere in $fpath
    foo_helper() { echo I am so helpfoo with "$@" }
    foo() {
	[[ $1 = --no-execute ]] && return 0
	echo I need help with "$@" ; foo_helper "$@"
    [[ -o kshautoload ]] || foo "$@"

Now the commands

    autoload foo
    foo --no-execute

will load foo and foo_helper without running either of them.

Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

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