[-- Attachment #1: Type: text/plain, Size: 326 bytes --] I want to list the most recent file in the current directory. print -l -- *(-om[1,1]) works for ordinary filenames, but does not quote the output appropriately if the filename contains spaces. How do I quote the expression to accommodate filenames which contain spaces? TIA, Vin -- *Never for money, always for love* [-- Attachment #2: Type: text/html, Size: 1179 bytes --]
On Sat, Oct 23, 2021 at 12:15:35PM -0400, Vin Shelton wrote:
> I want to list the most recent file in the current directory.
> print -l -- *(-om[1,1])
> works for ordinary filenames, but does not quote the output appropriately
> if the filename contains spaces. How do I quote the expression to
> accommodate filenames which contain spaces?
# (doesn't handle newlines properly)
$ ls -Q -- *(-om[1,1])
# Ugly quoting with backslashes
$ printf %q *(-om[1,1])
# Put in variable, quote variable as needed
$ F="$(echo *(-om[1,1]))"
$ print -- ${(q)F}
Ciao
Dominik ^_^ ^_^
--
Dominik Vogt
[-- Attachment #1: Type: text/plain, Size: 234 bytes --] On 23/10/2021 17:15, Vin Shelton wrote: > print -l -- *(-om[1,1]) works for me? touch sue\ jane.txt print -l -- *(-om[1,1]) sue jane.txt also ls -l *(.om[1]) -rw-rw-r-- 1 david david 0 Oct 23 17:45 'sue jane.txt' zzapper [-- Attachment #2: Type: text/html, Size: 905 bytes --]
[-- Attachment #1: Type: text/plain, Size: 425 bytes --] Sorry didn't read question fully!! On 23/10/2021 17:15, Vin Shelton wrote: > I want to list the most recent file in the current directory. > print -l -- *(-om[1,1]) > works for ordinary filenames, but does not quote the output > appropriately if the filename contains spaces. How do I quote the > expression to accommodate filenames which contain spaces? > > TIA, > Vin > -- > /Never for money, always for love > / [-- Attachment #2: Type: text/html, Size: 2008 bytes --]
[-- Attachment #1: Type: text/plain, Size: 430 bytes --] Yes, but the spaces aren't quoted, so the output can't be used in another command. On Sat, Oct 23, 2021 at 12:48 PM david rayner <david@rayninfo.co.uk> wrote: > > On 23/10/2021 17:15, Vin Shelton wrote: > > print -l -- *(-om[1,1]) > > > works for me? > > > touch sue\ jane.txt > > print -l -- *(-om[1,1]) > > sue jane.txt > > > also > > ls -l *(.om[1]) > > -rw-rw-r-- 1 david david 0 Oct 23 17:45 'sue jane.txt' > > zzapper > [-- Attachment #2: Type: text/html, Size: 1272 bytes --]
On Sat, 2021-10-23 at 17:43 +0100, Dominik Vogt wrote:
> On Sat, Oct 23, 2021 at 12:15:35PM -0400, Vin Shelton wrote:
> > I want to list the most recent file in the current directory.
> > print -l -- *(-om[1,1])
> > works for ordinary filenames, but does not quote the output appropriately
> > if the filename contains spaces. How do I quote the expression to
> > accommodate filenames which contain spaces?
>
> # Put in variable, quote variable as needed
> $ F="$(echo *(-om[1,1]))"
> $ print -- ${(q)F}
An array would be neater since you get globbing for free... it also
extends more naturally if you need multiple files (print -l then handles
those on multiple lines, though there are other ways there).
f=(*(-om[1,1]))
print -l -- ${(q)f}
You get the choice of type of quoting here by changing the (q) to its
various relatives.
pws
On Sat, Oct 23, 2021 at 05:58:28PM +0100, Peter Stephenson wrote:
> f=(*(-om[1,1]))
> print -l -- ${(q)f}
Hmmmm
# filename with newline:
$ touch "c
d"
$ f=(c*d)
$ echo "${(q)f}"
c$'
'd
Why does the value contain a '$'?
Ciao
Dominik ^_^ ^_^
--
Dominik Vogt
On Sat, 2021-10-23 at 18:24 +0100, Dominik Vogt wrote:
> On Sat, Oct 23, 2021 at 05:58:28PM +0100, Peter Stephenson wrote:
> > f=(*(-om[1,1]))
> > print -l -- ${(q)f}
>
> Hmmmm
>
> # filename with newline:
> $ touch "c
> d"
> $ f=(c*d)
> $ echo "${(q)f}"
> c$'
> 'd
>
> Why does the value contain a '$'?
The $'...' form of quoting is a special one which can be used to quote
things that can't be quoted by backslashes. In this case, that's a
newline. Actually, a normal '<newline>' would work here, but $'...'
quoting is used for consistency with cases where that wouldn't work. If
you try it, you'll see it does indeed do the right thing.
pws
On Sat, Oct 23, 2021 at 10:32 AM Peter Stephenson
<p.w.stephenson@ntlworld.com> wrote:
>
> > $ echo "${(q)f}"
> > c$'
> > 'd
> >
> > Why does the value contain a '$'?
>
> The $'...' form of quoting is a special one
Also:
% printf "%s\n" "${(q)f}"
c$'\n'c
'Twas echo changed the \n to an actual newline.
[-- Attachment #1: Type: text/plain, Size: 1225 bytes --] Thanks. I had attempted to strip away unnecessary complexity from my problem, but I now see that was a mistake. I have a function, recent: # Print the names of the most recent files in the specified directory. # Usage: recent [count [file_pattern]]] [directory] # count defaults to 1 # file_pattern defaults to * # directory defaults to the current directory. local dir= if [[ $# -gt 2 ]]; then if [[ ! -d "$3" ]]; then print -u2 "$0: directory \"$3\" does not exist." return 1 fi [[ $3 != '.' ]] && dir="$3"/ fi print -l -- ${dir}${~2:-*}(-om[1,${1:-1}]) So far, so good. recent 3 ==> zsh/ Any Given Sunday.mkv TheEnglishPatient.mkv BUT ls -ld $( recent 3 ) ==> /usr/bin/ls: cannot access 'Any': No such file or directory /usr/bin/ls: cannot access 'Given': No such file or directory /usr/bin/ls: cannot access 'Sunday.mkv': No such file or directory -rw-r--r-- 1 acs acs 727146010 Oct 22 15:52 TheEnglishPatient.mkv drwxr-xr-x 3 acs acs 3488 Oct 23 12:20 zsh/ I would like to make the second example work. I don't particularly care how the first example looks. Do I really have to use an external command (like `printf') to make this work? - Vin [-- Attachment #2: Type: text/html, Size: 4372 bytes --]
On Sat, Oct 23, 2021 at 12:08 PM Vin Shelton <acs@alumni.princeton.edu> wrote: > > print -l -- ${dir}${~2:-*}(-om[1,${1:-1}]) You're still missing any of the (q) options on those expansions. The easiest thing to do here is something like local recent=( ${dir}${~2:-*}(-om[1,${1:-1}]) ) print -lr -- ${(@q-)recent} It's important to add the quoting after any globbing but before you print the result. > Do I really have to use an external command (like `printf') to make this work? printf is a zsh builtin, for some years now. But as long as you add quoting and do not use echo, you should be OK.
[-- Attachment #1: Type: text/plain, Size: 1625 bytes --] Thanks, (I had tried the (q) and the extra assignment after pws suggested it) but no luck: zsh -f nuc2% function recent { function> local dir= if [[ $# -gt 2 ]]; then if [[ ! -d "$3" ]]; then print -u2 "$0: directory \"$3\" does not exist." return 1 fi [[ $3 != '.' ]] && dir="$3"/ fi local f=( ${dir}${~2:-*}(-om[1,${1:-1}]) ) print -lr -- ${(@q-)f} } nuc2% recent 3 zsh 'Any Given Sunday.mkv' TheEnglishPatient.mkv nuc2% \ls -ld $(recent 3) ls: cannot access "'Any": No such file or directory ls: cannot access 'Given': No such file or directory ls: cannot access "Sunday.mkv'": No such file or directory -rw-r--r-- 1 acs acs 727146010 Oct 22 15:52 TheEnglishPatient.mkv drwxr-xr-x 3 acs acs 3488 Oct 23 12:20 zsh What am I doing wrong? Does quoting not work correctly in captured output? I appreciate knowing that printf is builtin; thanks. Sorry I missed that. - Vin On Sat, Oct 23, 2021 at 3:26 PM Bart Schaefer <schaefer@brasslantern.com> wrote: > On Sat, Oct 23, 2021 at 12:08 PM Vin Shelton <acs@alumni.princeton.edu> > wrote: > > > > print -l -- ${dir}${~2:-*}(-om[1,${1:-1}]) > > You're still missing any of the (q) options on those expansions. > > The easiest thing to do here is something like > > local recent=( ${dir}${~2:-*}(-om[1,${1:-1}]) ) > print -lr -- ${(@q-)recent} > > It's important to add the quoting after any globbing but before you > print the result. > > > Do I really have to use an external command (like `printf') to make this > work? > > printf is a zsh builtin, for some years now. But as long as you add > quoting and do not use echo, you should be OK. > [-- Attachment #2: Type: text/html, Size: 4999 bytes --]
[-- Attachment #1: Type: text/plain, Size: 2186 bytes --] I think to use it that way you should remove the quoting: print -lr -- ${(@)f} and use it like this: ls "${(f)$recent 3)}" to have the output of recent to be split at newlines and treated as separate arguments would be nice not to have to write all this boilerplate though (I use global aliases for that) hope someone will show a better/simpler way Pier Paolo Grassi Il giorno sab 23 ott 2021 alle ore 22:44 Vin Shelton < acs@alumni.princeton.edu> ha scritto: > Thanks, (I had tried the (q) and the extra assignment after pws suggested > it) but no luck: > > zsh -f > > nuc2% function recent { > function> local dir= > if [[ $# -gt 2 ]]; then > if [[ ! -d "$3" ]]; then > print -u2 "$0: directory \"$3\" does not exist." > return 1 > fi > [[ $3 != '.' ]] && dir="$3"/ > fi > > local f=( ${dir}${~2:-*}(-om[1,${1:-1}]) ) > print -lr -- ${(@q-)f} > } > nuc2% recent 3 > zsh > 'Any Given Sunday.mkv' > TheEnglishPatient.mkv > nuc2% \ls -ld $(recent 3) > ls: cannot access "'Any": No such file or directory > ls: cannot access 'Given': No such file or directory > ls: cannot access "Sunday.mkv'": No such file or directory > -rw-r--r-- 1 acs acs 727146010 Oct 22 15:52 TheEnglishPatient.mkv > drwxr-xr-x 3 acs acs 3488 Oct 23 12:20 zsh > > > What am I doing wrong? Does quoting not work correctly in captured output? > > I appreciate knowing that printf is builtin; thanks. Sorry I missed that. > > - Vin > > > On Sat, Oct 23, 2021 at 3:26 PM Bart Schaefer <schaefer@brasslantern.com> > wrote: > >> On Sat, Oct 23, 2021 at 12:08 PM Vin Shelton <acs@alumni.princeton.edu> >> wrote: >> > >> > print -l -- ${dir}${~2:-*}(-om[1,${1:-1}]) >> >> You're still missing any of the (q) options on those expansions. >> >> The easiest thing to do here is something like >> >> local recent=( ${dir}${~2:-*}(-om[1,${1:-1}]) ) >> print -lr -- ${(@q-)recent} >> >> It's important to add the quoting after any globbing but before you >> print the result. >> >> > Do I really have to use an external command (like `printf') to make >> this work? >> >> printf is a zsh builtin, for some years now. But as long as you add >> quoting and do not use echo, you should be OK. >> > [-- Attachment #2: Type: text/html, Size: 6341 bytes --]
On Sat, Oct 23, 2021 at 1:57 PM Pier Paolo Grassi <pierpaolog@gmail.com> wrote: > > and use it like this: > > ls "${(f)$recent 3)}" That doesn't work because if one of the file names has a newline in it, (f) will split it into two words. (Also I think you left out an open paren.) print -lr -- ${(q)f} and then eval ls -ld $(recent 3) seems to be the closest thing. > Il giorno sab 23 ott 2021 alle ore 22:44 Vin Shelton <acs@alumni.princeton.edu> ha scritto: >> >> What am I doing wrong? Does quoting not work correctly in captured output? The trouble is that "ls" doesn't interpret the quoting, when $(...) preserves it. So you have to emit the quotes in a form that the shell can interpret, and then use "eval" to make that happen. For extra safety, you could use ${(qqqq)f} instead.
[-- Attachment #1: Type: text/plain, Size: 1384 bytes --] >That doesn't work because if one of the file names has a newline in >it, (f) will split it into two words. (Also I think you left out an >open paren.) sorry about that, I haven't ever considered newlines in filenames, since I wouldn't put them in the first place. Of course that's not to say that cannot happen anyway, of course. And yes, it should have been: ls "${(f)$(recent 3)}" thanks for catching that Pier Paolo Grassi Il giorno dom 24 ott 2021 alle ore 00:42 Bart Schaefer < schaefer@brasslantern.com> ha scritto: > On Sat, Oct 23, 2021 at 1:57 PM Pier Paolo Grassi <pierpaolog@gmail.com> > wrote: > > > > and use it like this: > > > > ls "${(f)$recent 3)}" > > That doesn't work because if one of the file names has a newline in > it, (f) will split it into two words. (Also I think you left out an > open paren.) > > print -lr -- ${(q)f} > > and then > > eval ls -ld $(recent 3) > > seems to be the closest thing. > > > Il giorno sab 23 ott 2021 alle ore 22:44 Vin Shelton < > acs@alumni.princeton.edu> ha scritto: > >> > >> What am I doing wrong? Does quoting not work correctly in captured > output? > > The trouble is that "ls" doesn't interpret the quoting, when $(...) > preserves it. So you have to emit the quotes in a form that the shell > can interpret, and then use "eval" to make that happen. > > For extra safety, you could use ${(qqqq)f} instead. > [-- Attachment #2: Type: text/html, Size: 2284 bytes --]
Fundamentally, you're dealing with a limitation of Zsh (and almost all
other shells): There is no way to "return" a list from a function.
$( ) captures stdout, which is a *stream*, not inherently a list or any
other structure. Using $( ) means you have to serialize your data, even
if only by putting NULs between each element:
recent(){
local l=( *(om[1,$1]) )
print -rn ${(pj:\0:)l}
}
ls -ld -- "${(0)$(recent 3)}"
There's an alternate convention in shell programming where results are
instead saved in a parameter, either of the user's choosing, or
sometimes hardcoded as 'reply'.
recent(){
# Use $reply if no parameter name given
typeset -ga "${2:=reply}"
set -A "$2" *(om[1,$1])
}
recent 3 files; ls -ld $files
This way, there's no serialization, forking, or reading and writing to
pipes.
On Sat Oct 23, 2021 at 7:24 PM CDT, Pier Paolo Grassi wrote:
> >That doesn't work because if one of the file names has a newline in
> >it, (f) will split it into two words. (Also I think you left out an
> >open paren.)
>
> sorry about that, I haven't ever considered newlines in filenames, since
> I
> wouldn't put them in the first place. Of course that's not to say that
> cannot happen anyway, of course.
> And yes, it should have been:
>
> ls "${(f)$(recent 3)}"
>
> thanks for catching that
>
> Pier Paolo Grassi
>
>
> Il giorno dom 24 ott 2021 alle ore 00:42 Bart Schaefer <
> schaefer@brasslantern.com> ha scritto:
>
> > On Sat, Oct 23, 2021 at 1:57 PM Pier Paolo Grassi <pierpaolog@gmail.com>
> > wrote:
> > >
> > > and use it like this:
> > >
> > > ls "${(f)$recent 3)}"
> >
> > That doesn't work because if one of the file names has a newline in
> > it, (f) will split it into two words. (Also I think you left out an
> > open paren.)
> >
> > print -lr -- ${(q)f}
> >
> > and then
> >
> > eval ls -ld $(recent 3)
> >
> > seems to be the closest thing.
> >
> > > Il giorno sab 23 ott 2021 alle ore 22:44 Vin Shelton <
> > acs@alumni.princeton.edu> ha scritto:
> > >>
> > >> What am I doing wrong? Does quoting not work correctly in captured
> > output?
> >
> > The trouble is that "ls" doesn't interpret the quoting, when $(...)
> > preserves it. So you have to emit the quotes in a form that the shell
> > can interpret, and then use "eval" to make that happen.
> >
> > For extra safety, you could use ${(qqqq)f} instead.
> >
On Sun, Oct 24, 2021 at 02:24:04AM +0200, Pier Paolo Grassi wrote:
> >That doesn't work because if one of the file names has a newline in
> >it, (f) will split it into two words. (Also I think you left out an
> >open paren.)
>
> sorry about that, I haven't ever considered newlines in filenames, since I
> wouldn't put them in the first place.
Maybe just stop putting spaces in filenames. Unix systems are
cluttered with scripts and other programs that cannot handle
whitespace, asterisks, hyphens, semicola and other charaters with
a special shell or program meaning anyway. (The vast majority of
people forget to put variables in double quotes in their scripts.)
Passing funny file names to programs is asking for trouble. In
the worst case it can destroy or compromise your system.
You could try this solution where the most recent entries are
automatically put into an array (needs some work to deal with *
matching nothing):
precmd () { __recent=( *(-om) ) }
$ ls -- "${(@)__recent[1,3]}"
Or if it's only about ls, you could write a function "ls-recent"
that implements the logic.
The suggestions with "eval" or automatic unquoting of values may
be a path to disaster.
Ciao
Dominik ^_^ ^_^
--
Dominik Vogt
On Sat, Oct 23, 2021 at 07:32:09PM -0500, Paul wrote: > recent(){ > # Use $reply if no parameter name given > typeset -ga "${2:=reply}" > set -A "$2" *(om[1,$1]) > } > recent 3 files; ls -ld $files ^^^^^^ ls -ld -- "${files[@]}" Ciao Dominik ^_^ ^_^ -- Dominik Vogt
On Sun, Oct 24, 2021 at 3:48 AM Dominik Vogt <dominik.vogt@gmx.de> wrote:
>
> On Sat, Oct 23, 2021 at 07:32:09PM -0500, Paul wrote:
> > recent(){
> > # Use $reply if no parameter name given
> > typeset -ga "${2:=reply}"
> > set -A "$2" *(om[1,$1])
> > }
>
> > recent 3 files; ls -ld $files
> ^^^^^^
>
> ls -ld -- "${files[@]}"
The "--" is a good addition but the other suggested changes only make
a difference if KSH_ARRAYS or SH_WORD_SPLIT is set. Neither is set in
native mode and few zsh users set them.
It's one of the nice things about zsh that you can use the shorter
$foo and $#foo instead of "${foo[@]}" and ${#foo[@]}. I wish there was
an option to disable null elision with a corresponding expansion flag
to turn it on similar to no_sh_word_split and ${(=)name}
Roman.
Roman Perepelitsa wrote on Sun, Oct 24, 2021 at 09:22:46 +0200:
> > It's one of the nice things about zsh that you can use the shorter
> $foo and $#foo instead of "${foo[@]}" and ${#foo[@]}. I wish there was
> an option to disable null elision with a corresponding expansion flag
> to turn it on similar to no_sh_word_split and ${(=)name}
I'm in two minds about this.
On the one hand, null elision breaks the principle of least surprise —
both in reference to other programming languages, and in reference to
SH_WORD_SPLIT's default behaviour being the unlike-Bourne-shell
behaviour.
On the other hand, making it on by default would be backwards
incompatible, and making it off by default would mean there's yet
another syntax-changing option for everyone to keep in mind when they
review random autoloaded functions' code.
All in all, perhaps this is a change to keep in mind for 6.0 (deferring
it to a major version due to the incompatibility).
Thoughts?
Cheers,
Daniel
On Mon, Oct 25, 2021 at 9:45 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
>
> Roman Perepelitsa wrote on Sun, Oct 24, 2021 at 09:22:46 +0200:
> > > It's one of the nice things about zsh that you can use the shorter
> > $foo and $#foo instead of "${foo[@]}" and ${#foo[@]}. I wish there was
> > an option to disable null elision with a corresponding expansion flag
> > to turn it on similar to no_sh_word_split and ${(=)name}
>
> I'm in two minds about this.
>
> On the one hand, null elision breaks the principle of least surprise —
> both in reference to other programming languages, and in reference to
> SH_WORD_SPLIT's default behaviour being the unlike-Bourne-shell
> behaviour.
>
> On the other hand, making it on by default would be backwards
> incompatible, and making it off by default would mean there's yet
> another syntax-changing option for everyone to keep in mind when they
> review random autoloaded functions' code.
How about a two-step approach with the possibility of stopping after the first?
Step 1: Add an option to disable null elision. Off by default.
Step 2: Make this option the default in native mode.
I would be 99% satisfied with step 1. I would be less satisfied if
step 2 was implemented because I hate when my scripts break. Granted,
even step 1 will break "plugins" that attempt to work with any options
but at least it won't break executable scripts. It's also nice that
this option would affect parsing, only evaluation, so it won't be
necessary to care about it when defining functions.
I do get your point about the difficulty of reading plugins when you
have to keep in mind all possible options that the code can be
evaluated with (how many plugins work with no_glob? mine don't). I
still think it's worth it to have *this* option. Dropping all those
quotes would remove noise from code and make comprehension easier. I
realise that few users would benefit from this. Not many write zsh
scripts to begin with and a small number of those would enable a new
option.
Roman.
On Mon, Oct 25, 2021 at 12:45 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote: > > Roman Perepelitsa wrote on Sun, Oct 24, 2021 at 09:22:46 +0200: > > > It's one of the nice things about zsh that you can use the shorter > > $foo and $#foo instead of "${foo[@]}" and ${#foo[@]}. I wish there was > > an option to disable null elision with a corresponding expansion flag > > to turn it on similar to no_sh_word_split and ${(=)name} Note there isn't a ${(=)name}, it's just $=name or ${=name}. > On the one hand, null elision breaks the principle of least surprise This is another one of those where it depends on who is being surprised. A person coming from csh would not be surprised by null-elision and in fact would be surprised by the opposite. > On the other hand, making it on by default would be backwards > incompatible, and making it off by default would mean there's yet > another syntax-changing option for everyone to keep in mind If we ignore the global option and focus on expansion flags, this becomes much less problematic; we could add a flag with this semantic ... but if you're going to need a flag, you might as well need double quotes as well.
Roman Perepelitsa wrote on Mon, 25 Oct 2021 20:02 +00:00: > I would be 99% satisfied with step 1. I would be less satisfied if > step 2 was implemented because I hate when my scripts break. Granted, > even step 1 will break "plugins" that attempt to work with any options > but at least it won't break executable scripts. In addition to these two categories, there's also plugins that set non-default options explicitly for their own use, and users who do that in their zshrc's and then post usage questions that don't start with a «zsh -f». > It's also nice that this option would affect parsing, only evaluation, > so it won't be necessary to care about it when defining functions. How so? If a function f is written under the assumption null elision is disabled, but is run with null elision enabled, then it would silently do the wrong thing, rather than, say, error out. I don't see why a function's caller should decide whether the callee should or shouldn't elide nulls. I think the function's author should make that decision. > I do get your point about the difficulty of reading plugins when you > have to keep in mind all possible options that the code can be > evaluated with (how many plugins work with no_glob? mine don't). Writing plugins that are meant to be sourced by others is a pain, not only because of options but also because of aliases. Having some way to provide packaged code to others in a way that the code will run under predictable syntax would be nice… but that's yet another thread. (E.g., perhaps the new behaviour should be triggered by magic bytes at the top of the sourced file. Or perhaps we should start adding some directory under ~ to the default fpath, e.g., ~/.local/share/zsh [plus or minus XDG base dirs support]) > I still think it's worth it to have *this* option. Dropping all those > quotes would remove noise from code and make comprehension easier. I > realise that few users would benefit from this. Not many write zsh > scripts to begin with and a small number of those would enable a new > option. Yeah. I assume that if we make this change, then once the incompatibility wave is past us (i.e., once everyone has made their code Y2k compliant, so to speak), the resulting language would be more intuitive — just like it's more intuitive with NO_SH_WORD_SPLIT than with sh's word splitting behaviour. Well, why not push an implementation to a branch? If you've got the tuits, of course. Cheers, Daniel
On 2021-10-25 1:41 p.m., Daniel Shahaf wrote:
> Yeah. I assume that if we make this change, then once the
> incompatibility wave is past us (i.e., once everyone has made their code
> Y2k compliant, so to speak), the resulting language would be more
> intuitive — just like it's more intuitive with NO_SH_WORD_SPLIT than
> with sh's word splitting behaviour.
>
> Well, why not push an implementation to a branch? If you've got the
> tuits, of course.
But wouldn't such a thing be enabled via some option, so that nothing
changes unless you explicitly activate it? I have the same assumption
regarding my various bitches and complaints -- some option enables the
change so that nothing is different out of the box.
On Mon, Oct 25, 2021 at 1:41 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
>
> I don't see why a function's caller should decide whether the callee
> should or shouldn't elide nulls. I think the function's author should
> make that decision. [...] Having some
> way to provide packaged code to others in a way that the code will
> run under predictable syntax would be nice…
Isn't that what
emulate zsh [options] -c 'autoload -U packagebootstrapper'
is for? Yeah, some syntactic sugar would be nice (e.g., it's a pain
to have to quote the argument of the -c option, rather than [say]
using a code block in braces).
Anyway, we haven't yet explored all the ramifications of changing null
elision. What effect does it have on $(...) in an array context, for
example? Any?
On Mon, Oct 25, 2021 at 2:01 PM Ray Andrews <rayandrews@eastlink.ca> wrote:
>
> But wouldn't such a thing be enabled via some option, so that nothing
> changes unless you explicitly activate it?
The discussion at the point where you jumped in is about how long we
have to wait before making it the default so you'd no longer
explicitly activate it.
Traditionally the answer would be "forever". The last attempt to do
it differently resulted in the dead zsh 2.5 fork (I hope I'm
remembering that number correctly, it's been a really long time.)
On Mon, Oct 25, 2021 at 10:42 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
>
> Roman Perepelitsa wrote on Mon, 25 Oct 2021 20:02 +00:00:
>
> > It's also nice that this option would affect parsing, only evaluation,
> > so it won't be necessary to care about it when defining functions.
>
> How so?
Some options can be set within a function for the function to work as
the author has intended. For example, extended_glob.
function foo() {
emulate -L zsh -o extended_glob
# can extended-glob here to one's heart's content
[[ $1 == a## ]]
}
Other options must be set when the function is defined. For example,
brace_expand.
# if brace_expand is unset here, bar is screwed
unset brace_expand # bwa-ha-ha
function bar() {
emulate -L zsh -o brace_expand # this won't help
typeset var{1,2,3}=42
}
setopt brace_expand # this won't help either
bar # oh no!
Options of the second kind cause more grief.
As Bar says, autoload -Uz is key when it comes to loading plugins and
sourcing is a losing game (I learned this from Bart earlier).
Sometimes you still have to have a function in a plugin that must run
with user options but at least that's just for evaluation and not for
parsing.
Roman.