zsh-workers
 help / color / Atom feed
* Bug report: `setopt noaliases` not respected in `local` statement without assignment.
@ 2020-03-26  9:54 Marlon Richert
  2020-03-26  9:59 ` Roman Perepelitsa
  0 siblings, 1 reply; 9+ messages in thread
From: Marlon Richert @ 2020-03-26  9:54 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 685 bytes --]

Test case:

alias -g tail="multitail -Cs --follow-all"
f() {
  setopt localoptions no_aliases
  local tail
  tail=1
  echo $tail
}
g() {
  setopt localoptions no_aliases
  local tail=1
  echo $tail
}

$ type -f f
f () {
        setopt localoptions no_aliases
        local multitail -Cs --follow-all
        tail=1
        echo $tail
}

$ type -f g
g () {
        setopt localoptions no_aliases
        local tail=1
        echo $tail
}

As you can see, `setopt noaliases` works as expected in function `g` where
`local tail=1` is used, but not in function `f` where `local tail` is used
without an assignment statement.

See https://github.com/junegunn/fzf/issues/1938 for more info.

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

* Re: Bug report: `setopt noaliases` not respected in `local` statement without assignment.
  2020-03-26  9:54 Bug report: `setopt noaliases` not respected in `local` statement without assignment Marlon Richert
@ 2020-03-26  9:59 ` Roman Perepelitsa
  2020-03-26 10:27   ` Marlon Richert
  0 siblings, 1 reply; 9+ messages in thread
From: Roman Perepelitsa @ 2020-03-26  9:59 UTC (permalink / raw)
  To: Marlon Richert; +Cc: Zsh hackers list

On Thu, Mar 26, 2020 at 10:55 AM Marlon Richert
<marlon.richert@gmail.com> wrote:
>
> Test case:
>
> alias -g tail="multitail -Cs --follow-all"
> f() {
>   setopt localoptions no_aliases
>   local tail
>   tail=1
>   echo $tail
> }

Alias expansion happens when functions get parsed. If you don't want
`tail` to be alias-expanded within function `f`, you need to add
`setopt no_aliases` before the function of `f`.

> g() {
>   setopt localoptions no_aliases
>   local tail=1
>   echo $tail
> }

`tail` within `local tail=1` is not subject to global alias expansion.

Roman.

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

* Re: Bug report: `setopt noaliases` not respected in `local` statement without assignment.
  2020-03-26  9:59 ` Roman Perepelitsa
@ 2020-03-26 10:27   ` Marlon Richert
  2020-03-26 10:38     ` Roman Perepelitsa
  0 siblings, 1 reply; 9+ messages in thread
From: Marlon Richert @ 2020-03-26 10:27 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Zsh hackers list

[-- Attachment #1: Type: text/plain, Size: 1148 bytes --]

Aha. So, if I want that aliases don't get expanded in the functions in
https://github.com/junegunn/fzf/blob/master/shell/completion.zsh, then
where should I put the `setopt noaliases` statement? Does it suffice to
just put `emulate -L zsh; setopt localoptions noaliases;` at the top of the
file? I don't want the noaliases option to leak into my own shell
environment.

Or is there a better solution possible here than using noaliases?

On Thu, 26 Mar 2020 at 11:59, Roman Perepelitsa <roman.perepelitsa@gmail.com>
wrote:

> On Thu, Mar 26, 2020 at 10:55 AM Marlon Richert
> <marlon.richert@gmail.com> wrote:
> >
> > Test case:
> >
> > alias -g tail="multitail -Cs --follow-all"
> > f() {
> >   setopt localoptions no_aliases
> >   local tail
> >   tail=1
> >   echo $tail
> > }
>
> Alias expansion happens when functions get parsed. If you don't want
> `tail` to be alias-expanded within function `f`, you need to add
> `setopt no_aliases` before the function of `f`.
>
> > g() {
> >   setopt localoptions no_aliases
> >   local tail=1
> >   echo $tail
> > }
>
> `tail` within `local tail=1` is not subject to global alias expansion.
>
> Roman.
>

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

* Re: Bug report: `setopt noaliases` not respected in `local` statement without assignment.
  2020-03-26 10:27   ` Marlon Richert
@ 2020-03-26 10:38     ` Roman Perepelitsa
  2020-03-26 22:34       ` Daniel Shahaf
  0 siblings, 1 reply; 9+ messages in thread
From: Roman Perepelitsa @ 2020-03-26 10:38 UTC (permalink / raw)
  To: Marlon Richert; +Cc: Zsh hackers list

On Thu, Mar 26, 2020 at 11:27 AM Marlon Richert
<marlon.richert@gmail.com> wrote:
>
> Aha. So, if I want that aliases don't get expanded in the functions in https://github.com/junegunn/fzf/blob/master/shell/completion.zsh, then where should I put the `setopt noaliases` statement? Does it suffice to just put `emulate -L zsh; setopt localoptions noaliases;` at the top of the file? I don't want the noaliases option to leak into my own shell environment.
>
> Or is there a better solution possible here than using noaliases?

The official solution to this problem is to use autoloadable functions
instead of sourcing zsh scripts with function definitions.

One practical alternative is to add a bit of code at the top and at
the bottom of completion.zsh. Like this:

    'builtin' 'local' '-a' '_fzf_completion_opts'
    [[ ! -o 'aliases'         ]] || _fzf_completion_opts+=('aliases')
    [[ ! -o 'sh_glob'         ]] || _fzf_completion_opts+=('sh_glob')
    [[ ! -o 'no_brace_expand' ]] || _fzf_completion_opts+=('no_brace_expand')
    'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand'

    # the meat of completion.zsh goes here

    (( ${#_fzf_completion_opts} )) && setopt ${_fzf_completion_opts[@]}
    'builtin' 'unset' '_fzf_completion_opts'

Note that this doesn't just disable aliases but also changes a couple
other options that similarly affect parsing of functions. (You could
also wrap the whole script in try-always to make sure options are
restored even if evaluation of the script stops prematurely.)

Another alternative is to rename completion.zsh to
internal-completion.zsh and place this shim in place of the original
completion.zsh:

    'builtin' 'emulate' 'zsh' '-o' 'no_aliases' '-c' 'builtin source
${${(%):-%x}:h}/internal-completion.zsh'

Roman.




> On Thu, 26 Mar 2020 at 11:59, Roman Perepelitsa <roman.perepelitsa@gmail.com> wrote:
>>
>> On Thu, Mar 26, 2020 at 10:55 AM Marlon Richert
>> <marlon.richert@gmail.com> wrote:
>> >
>> > Test case:
>> >
>> > alias -g tail="multitail -Cs --follow-all"
>> > f() {
>> >   setopt localoptions no_aliases
>> >   local tail
>> >   tail=1
>> >   echo $tail
>> > }
>>
>> Alias expansion happens when functions get parsed. If you don't want
>> `tail` to be alias-expanded within function `f`, you need to add
>> `setopt no_aliases` before the function of `f`.
>>
>> > g() {
>> >   setopt localoptions no_aliases
>> >   local tail=1
>> >   echo $tail
>> > }
>>
>> `tail` within `local tail=1` is not subject to global alias expansion.
>>
>> Roman.

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

* Re: Bug report: `setopt noaliases` not respected in `local` statement without assignment.
  2020-03-26 10:38     ` Roman Perepelitsa
@ 2020-03-26 22:34       ` Daniel Shahaf
  2020-03-29 10:24         ` Roman Perepelitsa
  0 siblings, 1 reply; 9+ messages in thread
From: Daniel Shahaf @ 2020-03-26 22:34 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Marlon Richert, Zsh hackers list

Roman Perepelitsa wrote on Thu, 26 Mar 2020 11:38 +0100:
> On Thu, Mar 26, 2020 at 11:27 AM Marlon Richert
> <marlon.richert@gmail.com> wrote:
> >
> > Aha. So, if I want that aliases don't get expanded in the functions in https://github.com/junegunn/fzf/blob/master/shell/completion.zsh, then where should I put the `setopt noaliases` statement? Does it suffice to just put `emulate -L zsh; setopt localoptions noaliases;` at the top of the file? I don't want the noaliases option to leak into my own shell environment.
> >
> > Or is there a better solution possible here than using noaliases?  
> 
> The official solution to this problem is to use autoloadable functions
> instead of sourcing zsh scripts with function definitions.
> 

Note that the -U flag should be passed to «autoload» in that case.

> One practical alternative is to add a bit of code at the top and at
> the bottom of completion.zsh. Like this:
> 
>     'builtin' 'local' '-a' '_fzf_completion_opts'
>     [[ ! -o 'aliases'         ]] || _fzf_completion_opts+=('aliases')
>     [[ ! -o 'sh_glob'         ]] || _fzf_completion_opts+=('sh_glob')
>     [[ ! -o 'no_brace_expand' ]] || _fzf_completion_opts+=('no_brace_expand')
>     'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand'
> 
>     # the meat of completion.zsh goes here
> 
>     (( ${#_fzf_completion_opts} )) && setopt ${_fzf_completion_opts[@]}
>     'builtin' 'unset' '_fzf_completion_opts'
> 

z-sy-h does something similar with aliases:

https://github.com/zsh-users/zsh-syntax-highlighting/blob/d1802e388e94aca25380a3a9aeb4a2b7ba661b41/zsh-syntax-highlighting.zsh#L30-L36https://github.com/zsh-users/zsh-syntax-highlighting/blob/d1802e388e94aca25380a3a9aeb4a2b7ba661b41/zsh-syntax-highlighting.zsh#L442-L444

For options, z-sy-h uses «emulate -L» for the vast majority of its
code.  It's on our todo list (issue #688) to add a «emulate zsh -o …
-c 'source …'» shim around the entry point script, as Roman proposes
below.

> Note that this doesn't just disable aliases but also changes a couple
> other options that similarly affect parsing of functions. (You could
> also wrap the whole script in try-always to make sure options are
> restored even if evaluation of the script stops prematurely.)
> 

There are a few other options to worry about, e.g., KSH_ARRAYS,
IGNORE_CLOES_BRACES.

> Another alternative is to rename completion.zsh to
> internal-completion.zsh and place this shim in place of the original
> completion.zsh:
> 
>     'builtin' 'emulate' 'zsh' '-o' 'no_aliases' '-c' 'builtin source
> ${${(%):-%x}:h}/internal-completion.zsh'
> 
> Roman.
> 

Cheers,

Daniel

> 
> 
> 
> > On Thu, 26 Mar 2020 at 11:59, Roman Perepelitsa <roman.perepelitsa@gmail.com> wrote:  
> >>
> >> On Thu, Mar 26, 2020 at 10:55 AM Marlon Richert
> >> <marlon.richert@gmail.com> wrote:  
> >> >
> >> > Test case:
> >> >
> >> > alias -g tail="multitail -Cs --follow-all"
> >> > f() {
> >> >   setopt localoptions no_aliases
> >> >   local tail
> >> >   tail=1
> >> >   echo $tail  
> >> > }  
> >>
> >> Alias expansion happens when functions get parsed. If you don't want
> >> `tail` to be alias-expanded within function `f`, you need to add
> >> `setopt no_aliases` before the function of `f`.
> >>  
> >> > g() {
> >> >   setopt localoptions no_aliases
> >> >   local tail=1
> >> >   echo $tail  
> >> > }  
> >>
> >> `tail` within `local tail=1` is not subject to global alias expansion.
> >>
> >> Roman.  


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

* Re: Bug report: `setopt noaliases` not respected in `local` statement without assignment.
  2020-03-26 22:34       ` Daniel Shahaf
@ 2020-03-29 10:24         ` Roman Perepelitsa
  2020-03-29 20:47           ` Daniel Shahaf
  0 siblings, 1 reply; 9+ messages in thread
From: Roman Perepelitsa @ 2020-03-29 10:24 UTC (permalink / raw)
  To: Daniel Shahaf; +Cc: Marlon Richert, Zsh hackers list

On Thu, Mar 26, 2020 at 11:34 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
>
> There are a few other options to worry about, e.g., KSH_ARRAYS,
> IGNORE_CLOES_BRACES.

Good point.

I also should've mentioned that `emulate zsh -o no_aliases -c "..."`
shouldn't be used if some of the functions you define must run with
user-defined options. E.g., if you want to respect user's
dot_glob/no_dot_glob (fzf does) or
interactive_comments/no_interactive_comments (f-sy-h does), then this
approach is out.

Here's another option that doesn't require one to create a new file:

  () { 'emulate' '-L' 'zsh' '-o' 'no_aliases' && 'eval' "$(<<\END

  # original file content goes here

  END
  )"; }

Downsides:

  - one fork (increases loading time)
  - breaks syntax highlighting in code editors
  - zcompile won't be effective at speeding up loading time
  - some aliases can still break this; for example: alias -g '()'=nope

Roman.

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

* Re: Bug report: `setopt noaliases` not respected in `local` statement without assignment.
  2020-03-29 10:24         ` Roman Perepelitsa
@ 2020-03-29 20:47           ` Daniel Shahaf
  2020-03-29 21:03             ` Roman Perepelitsa
  0 siblings, 1 reply; 9+ messages in thread
From: Daniel Shahaf @ 2020-03-29 20:47 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Marlon Richert, Zsh hackers list

Roman Perepelitsa wrote on Sun, 29 Mar 2020 12:24 +0200:
> On Thu, Mar 26, 2020 at 11:34 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> >
> > There are a few other options to worry about, e.g., KSH_ARRAYS,
> > IGNORE_CLOES_BRACES.  
> 
> Good point.
> 
> I also should've mentioned that `emulate zsh -o no_aliases -c "..."`
> shouldn't be used if some of the functions you define must run with
> user-defined options. E.g., if you want to respect user's
> dot_glob/no_dot_glob (fzf does) or
> interactive_comments/no_interactive_comments (f-sy-h does), then this
> approach is out.

z-sy-h handles this by saving ${options} to an associative array before
resetting the options so it can execute:

    86	  # Before we 'emulate -L', save the user's options
    87	  local -A zsyh_user_options
    88	  if zmodload -e zsh/parameter; then
    89	    zsyh_user_options=("${(kv)options[@]}")
    90	  else
    91	    local canonical_options onoff option raw_options
    92	    raw_options=(${(f)"$(emulate -R zsh; set -o)"})
    93	    canonical_options=(${${${(M)raw_options:#*off}%% *}#no} ${${(M)raw_options:#*on}%% *})
    94	    for option in "${canonical_options[@]}"; do
    95	      [[ -o $option ]]
    96	      # This variable cannot be eliminated c.f. workers/42101.
    97	      onoff=${${=:-off on}[2-$?]}
    98	      zsyh_user_options+=($option $onoff)
    99	    done
   100	  fi
   101	  typeset -r zsyh_user_options
   102	
   103	  emulate -L zsh

(I'll fix lines 95-98 in a minute, though.)

Cheers,

Daniel

> Here's another option that doesn't require one to create a new file:
> 
>   () { 'emulate' '-L' 'zsh' '-o' 'no_aliases' && 'eval' "$(<<\END
> 
>   # original file content goes here
> 
>   END
>   )"; }
> 
> Downsides:
> 
>   - one fork (increases loading time)
>   - breaks syntax highlighting in code editors
>   - zcompile won't be effective at speeding up loading time
>   - some aliases can still break this; for example: alias -g '()'=nope

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

* Re: Bug report: `setopt noaliases` not respected in `local` statement without assignment.
  2020-03-29 20:47           ` Daniel Shahaf
@ 2020-03-29 21:03             ` Roman Perepelitsa
  2020-03-29 21:12               ` Daniel Shahaf
  0 siblings, 1 reply; 9+ messages in thread
From: Roman Perepelitsa @ 2020-03-29 21:03 UTC (permalink / raw)
  To: Daniel Shahaf; +Cc: Marlon Richert, Zsh hackers list

On Sun, Mar 29, 2020 at 10:47 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> z-sy-h handles this by saving ${options} to an associative array before
> resetting the options so it can execute:

Right. This is done in function _zsh_highlight in
zsh-syntax-highlighting.zsh. My point is that you cannot rename
zsh-syntax-highlighting.zsh to zsh-syntax-highlighting-impl.zsh and
replace the original zsh-syntax-highlighting.zsh with `emulate zsh -o
no_aliases -c 'source zsh-syntax-highlighting-impl.zsh'` because
you'll no longer be able to access user options from _zsh_highlight.
Sticky emulation mode is cool but in this case it provides too much
insulation.

Roman.

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

* Re: Bug report: `setopt noaliases` not respected in `local` statement without assignment.
  2020-03-29 21:03             ` Roman Perepelitsa
@ 2020-03-29 21:12               ` Daniel Shahaf
  0 siblings, 0 replies; 9+ messages in thread
From: Daniel Shahaf @ 2020-03-29 21:12 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Marlon Richert, Zsh hackers list

Roman Perepelitsa wrote on Sun, 29 Mar 2020 21:03 +00:00:
> On Sun, Mar 29, 2020 at 10:47 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> > z-sy-h handles this by saving ${options} to an associative array before
> > resetting the options so it can execute:
> 
> Right. This is done in function _zsh_highlight in
> zsh-syntax-highlighting.zsh. My point is that you cannot rename
> zsh-syntax-highlighting.zsh to zsh-syntax-highlighting-impl.zsh and
> replace the original zsh-syntax-highlighting.zsh with `emulate zsh -o
> no_aliases -c 'source zsh-syntax-highlighting-impl.zsh'` because
> you'll no longer be able to access user options from _zsh_highlight.
> Sticky emulation mode is cool but in this case it provides too much
> insulation.

Yeah, the code I quoted needs to run before options are changed —
i.e., in the outer script, before the 'emulate' call.  That's precisely
why that code's written in a KSH_ARRAYS-compatible way.  (It wasn't
at first, but people opened bug reports…)


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

end of thread, back to index

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-26  9:54 Bug report: `setopt noaliases` not respected in `local` statement without assignment Marlon Richert
2020-03-26  9:59 ` Roman Perepelitsa
2020-03-26 10:27   ` Marlon Richert
2020-03-26 10:38     ` Roman Perepelitsa
2020-03-26 22:34       ` Daniel Shahaf
2020-03-29 10:24         ` Roman Perepelitsa
2020-03-29 20:47           ` Daniel Shahaf
2020-03-29 21:03             ` Roman Perepelitsa
2020-03-29 21:12               ` Daniel Shahaf

zsh-workers

Archives are clonable: git clone --mirror http://inbox.vuxu.org/zsh-workers

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.zsh.workers


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git