zsh-users
 help / color / mirror / code / Atom feed
* make aliases work inside the function? (using a preprocessor?)
@ 2016-05-04 13:46 Marc Chantreux
  2016-05-04 14:04 ` Peter Stephenson
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Marc Chantreux @ 2016-05-04 13:46 UTC (permalink / raw)
  To: zsh-users

hello zsh people,

I have

    % which €
	€ () {
	setopt localoptions unset nowarncreateglobal
	"$@" }
    % which l
        l: aliased to print -l
    % € l error 
        €: command not found: l

sometimes i really need aliases.
sometimes aliases seems to work inside functions.
sometimes i made some hacks like

	eval "xx () { $functions[xx] }"

sometimes it works, sometimes it doesn't. i spend some time in the
manual to make up my mind about how to fix it.

i guess i'll use a preprocessor (m4?) and maybe even an existing lib
(m4sh?) to generate my zsh scripts. any ideas about it?

regards.
marc



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: make aliases work inside the function? (using a preprocessor?)
  2016-05-04 13:46 make aliases work inside the function? (using a preprocessor?) Marc Chantreux
@ 2016-05-04 14:04 ` Peter Stephenson
  2016-05-04 14:55 ` Oliver Kiddle
  2016-05-04 17:21 ` Bart Schaefer
  2 siblings, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2016-05-04 14:04 UTC (permalink / raw)
  To: zsh-users

On Wed, 4 May 2016 13:46:32 +0000
Marc Chantreux <khatar@phear.org> wrote:
> sometimes i really need aliases.
> sometimes aliases seems to work inside functions.
>
> sometimes it works, sometimes it doesn't.

The probably is likely to be order dependence.  If you've defined an
alias, it's then available for expansion at the start of the command
line *even* if that word is defining a function.

This is explained in the FAQ (2.3; this is a long entry,
unsurprisingly).

pws


There is one other serious problem with aliases: consider
  
    alias l='/bin/ls -F'
    l() { /bin/ls -la "$@" | more }
  
  `l' in the function definition is in command position and is expanded
  as an alias, defining `/bin/ls' and `-F' as functions which call
  `/bin/ls', which gets a bit recursive.  This can be avoided if you use
  `function' to define a function, which doesn't expand aliases.  It is
  possible to argue for extra warnings somewhere in this mess.

One workaround for this is to use the "function" keyword instead:
  
    alias l='/bin/ls -F'
    function l { /bin/ls -la "$@" | more }
  
  The `l' after `function' is not expanded.  Note you don't need
  the `()' in this case, although it's harmless.

You need to be careful if you are defining a function with multiple
  names; most people don't need to do this, so it's an unusual problem,
  but in case you do you should be aware that in versions of the shell
  before 5.1 names after the first were expanded:
  
    function a b c { ... }
  
  Here, `b' and `c', but not `a', have aliases expanded.
  This oddity was fixed in version 5.1.

The rest of this item assumes you use the (more common,
  but equivalent) `()' definitions.

Bart Schaefer's rule is:  Define first those aliases you expect to
  use in the body of a function, but define the function first if the
  alias has the same name as the function.

If you aware of the problem, you can always escape part or all of the
  name of the function:
  
     'l'() { /bin/ls -la "$@" | more }
  
  Adding the quotes has no effect on the function definition, but
  suppresses alias expansion for the function name.  Hence this is
  guaranteed to be safe---unless you are in the habit of defining
  aliases for expressions such as 'l', which is valid, but probably
  confusing.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: make aliases work inside the function? (using a preprocessor?)
  2016-05-04 13:46 make aliases work inside the function? (using a preprocessor?) Marc Chantreux
  2016-05-04 14:04 ` Peter Stephenson
@ 2016-05-04 14:55 ` Oliver Kiddle
  2016-05-04 17:21 ` Bart Schaefer
  2 siblings, 0 replies; 5+ messages in thread
From: Oliver Kiddle @ 2016-05-04 14:55 UTC (permalink / raw)
  To: Marc Chantreux; +Cc: zsh-users

Marc Chantreux wrote:
>
> I have
>
>     % which €
> 	€ () {
> 	setopt localoptions unset nowarncreateglobal
> 	"$@" }
>     % which l
>         l: aliased to print -l
>     % € l error 
>         €: command not found: l

You could also try using:
  alias €='€ '

This doesn't enable alias expansion inside the function if that is
exactly what you need. But it does work for the example above: the
trailing space in the alias indicates that the next word is treated as
being in command position for alias expansion so l will be expanded
already outside the function.

It's quite common to use this with precommands, for example:
for com in command builtin time nice - nocorrect exec rusage noglob eval nohup;
    alias -- $com="$com "

Oliver


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: make aliases work inside the function? (using a preprocessor?)
  2016-05-04 13:46 make aliases work inside the function? (using a preprocessor?) Marc Chantreux
  2016-05-04 14:04 ` Peter Stephenson
  2016-05-04 14:55 ` Oliver Kiddle
@ 2016-05-04 17:21 ` Bart Schaefer
  2016-05-09 12:30   ` Marc Chantreux
  2 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2016-05-04 17:21 UTC (permalink / raw)
  To: Marc Chantreux; +Cc: Zsh Users

In addition to what PWS and Oliver have said, it's possibly important
to point out that --

On Wed, May 4, 2016 at 6:46 AM, Marc Chantreux <khatar@phear.org> wrote:
>
>     % which €
>         € () {
>         setopt localoptions unset nowarncreateglobal
>         "$@" }

-- aliases are never going to expand with the command word quoted as
in your  "$@" substitution there.  Oliver's suggestion would work, but
only because (as he mentioned) the alias would be expanded on the
interactive command line before the € function runs.

For this specific example, what you want is probably:

€ () {
   setopt localoptions unset nowarncreateglobal
   eval "$1" "${(q@)argv[2,-1]}"
}

The eval will expand aliases in $1 (the desired command word)
regardless of the order in which they are defined relative to the
function, and the (q@) assures that the rest of the arguments are
unmolested by eval.

Other uses of aliases need the approach outlined by Peter.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: make aliases work inside the function? (using a preprocessor?)
  2016-05-04 17:21 ` Bart Schaefer
@ 2016-05-09 12:30   ` Marc Chantreux
  0 siblings, 0 replies; 5+ messages in thread
From: Marc Chantreux @ 2016-05-09 12:30 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

Bart, Peter, Oliver: thank you very much for such a detailed answer.

i had some weird behaviors those last months experimenting some zsh based
features and now completly understand why. the thing is most of them are
very usefull to me and cannot be converted to functions

some examples:

https://github.com/eiro/zexperiment/blob/master/lib/basics.zsh#L34
https://github.com/eiro/zexperiment/blob/master/bin/uze.zsh#L55

the only way to make it work a reliable way is to use a preprocessor so
i plan to use m4.

once again: thanks for helping.

regards


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-05-09 12:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-04 13:46 make aliases work inside the function? (using a preprocessor?) Marc Chantreux
2016-05-04 14:04 ` Peter Stephenson
2016-05-04 14:55 ` Oliver Kiddle
2016-05-04 17:21 ` Bart Schaefer
2016-05-09 12:30   ` Marc Chantreux

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).