* Most Recent File @ 2021-10-23 16:15 Vin Shelton 2021-10-23 16:43 ` Dominik Vogt ` (2 more replies) 0 siblings, 3 replies; 27+ messages in thread From: Vin Shelton @ 2021-10-23 16:15 UTC (permalink / raw) To: Zsh-Users List [-- 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 --] ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 16:15 Most Recent File Vin Shelton @ 2021-10-23 16:43 ` Dominik Vogt 2021-10-23 16:58 ` Peter Stephenson 2021-10-23 16:47 ` david rayner 2021-10-23 16:51 ` david rayner 2 siblings, 1 reply; 27+ messages in thread From: Dominik Vogt @ 2021-10-23 16:43 UTC (permalink / raw) To: zsh-users 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 16:43 ` Dominik Vogt @ 2021-10-23 16:58 ` Peter Stephenson 2021-10-23 17:24 ` Dominik Vogt 0 siblings, 1 reply; 27+ messages in thread From: Peter Stephenson @ 2021-10-23 16:58 UTC (permalink / raw) To: zsh-users 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 16:58 ` Peter Stephenson @ 2021-10-23 17:24 ` Dominik Vogt 2021-10-23 17:32 ` Peter Stephenson 0 siblings, 1 reply; 27+ messages in thread From: Dominik Vogt @ 2021-10-23 17:24 UTC (permalink / raw) To: zsh-users 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 17:24 ` Dominik Vogt @ 2021-10-23 17:32 ` Peter Stephenson 2021-10-23 18:39 ` Bart Schaefer 2021-10-23 19:07 ` Vin Shelton 0 siblings, 2 replies; 27+ messages in thread From: Peter Stephenson @ 2021-10-23 17:32 UTC (permalink / raw) To: zsh-users 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 17:32 ` Peter Stephenson @ 2021-10-23 18:39 ` Bart Schaefer 2021-10-23 19:07 ` Vin Shelton 1 sibling, 0 replies; 27+ messages in thread From: Bart Schaefer @ 2021-10-23 18:39 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh Users 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. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 17:32 ` Peter Stephenson 2021-10-23 18:39 ` Bart Schaefer @ 2021-10-23 19:07 ` Vin Shelton 2021-10-23 19:26 ` Bart Schaefer 1 sibling, 1 reply; 27+ messages in thread From: Vin Shelton @ 2021-10-23 19:07 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh-Users List [-- 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 --] ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 19:07 ` Vin Shelton @ 2021-10-23 19:26 ` Bart Schaefer 2021-10-23 20:43 ` Vin Shelton 0 siblings, 1 reply; 27+ messages in thread From: Bart Schaefer @ 2021-10-23 19:26 UTC (permalink / raw) To: Vin Shelton; +Cc: Peter Stephenson, Zsh-Users List 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. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 19:26 ` Bart Schaefer @ 2021-10-23 20:43 ` Vin Shelton 2021-10-23 20:56 ` Pier Paolo Grassi 0 siblings, 1 reply; 27+ messages in thread From: Vin Shelton @ 2021-10-23 20:43 UTC (permalink / raw) To: Bart Schaefer; +Cc: Peter Stephenson, Zsh-Users List [-- 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 --] ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 20:43 ` Vin Shelton @ 2021-10-23 20:56 ` Pier Paolo Grassi 2021-10-23 22:42 ` Bart Schaefer 0 siblings, 1 reply; 27+ messages in thread From: Pier Paolo Grassi @ 2021-10-23 20:56 UTC (permalink / raw) To: Vin Shelton; +Cc: Bart Schaefer, Peter Stephenson, Zsh-Users List [-- 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 --] ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 20:56 ` Pier Paolo Grassi @ 2021-10-23 22:42 ` Bart Schaefer 2021-10-24 0:24 ` Pier Paolo Grassi 0 siblings, 1 reply; 27+ messages in thread From: Bart Schaefer @ 2021-10-23 22:42 UTC (permalink / raw) To: Pier Paolo Grassi; +Cc: Vin Shelton, Peter Stephenson, Zsh-Users List 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. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 22:42 ` Bart Schaefer @ 2021-10-24 0:24 ` Pier Paolo Grassi 2021-10-24 0:32 ` Paul 2021-10-24 1:37 ` Most Recent File Dominik Vogt 0 siblings, 2 replies; 27+ messages in thread From: Pier Paolo Grassi @ 2021-10-24 0:24 UTC (permalink / raw) To: Bart Schaefer; +Cc: Vin Shelton, Peter Stephenson, Zsh-Users List [-- 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 --] ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-24 0:24 ` Pier Paolo Grassi @ 2021-10-24 0:32 ` Paul 2021-10-24 1:45 ` Dominik Vogt 2021-10-24 1:37 ` Most Recent File Dominik Vogt 1 sibling, 1 reply; 27+ messages in thread From: Paul @ 2021-10-24 0:32 UTC (permalink / raw) To: Pier Paolo Grassi, Bart Schaefer Cc: Vin Shelton, Peter Stephenson, Zsh-Users List 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. > > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-24 0:32 ` Paul @ 2021-10-24 1:45 ` Dominik Vogt 2021-10-24 7:22 ` Roman Perepelitsa 0 siblings, 1 reply; 27+ messages in thread From: Dominik Vogt @ 2021-10-24 1:45 UTC (permalink / raw) To: zsh-users 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-24 1:45 ` Dominik Vogt @ 2021-10-24 7:22 ` Roman Perepelitsa 2021-10-25 19:45 ` Disabling null elision (was: Re: Most Recent File) Daniel Shahaf 0 siblings, 1 reply; 27+ messages in thread From: Roman Perepelitsa @ 2021-10-24 7:22 UTC (permalink / raw) To: dominik.vogt, Zsh Users 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. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Disabling null elision (was: Re: Most Recent File) 2021-10-24 7:22 ` Roman Perepelitsa @ 2021-10-25 19:45 ` Daniel Shahaf 2021-10-25 20:02 ` Roman Perepelitsa 2021-10-25 20:05 ` Bart Schaefer 0 siblings, 2 replies; 27+ messages in thread From: Daniel Shahaf @ 2021-10-25 19:45 UTC (permalink / raw) To: Zsh Users; +Cc: Roman Perepelitsa 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Disabling null elision (was: Re: Most Recent File) 2021-10-25 19:45 ` Disabling null elision (was: Re: Most Recent File) Daniel Shahaf @ 2021-10-25 20:02 ` Roman Perepelitsa 2021-10-25 20:41 ` Daniel Shahaf 2021-10-25 20:05 ` Bart Schaefer 1 sibling, 1 reply; 27+ messages in thread From: Roman Perepelitsa @ 2021-10-25 20:02 UTC (permalink / raw) To: Daniel Shahaf; +Cc: Zsh Users 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. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Disabling null elision (was: Re: Most Recent File) 2021-10-25 20:02 ` Roman Perepelitsa @ 2021-10-25 20:41 ` Daniel Shahaf 2021-10-25 21:00 ` Ray Andrews ` (2 more replies) 0 siblings, 3 replies; 27+ messages in thread From: Daniel Shahaf @ 2021-10-25 20:41 UTC (permalink / raw) To: zsh-users 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Disabling null elision (was: Re: Most Recent File) 2021-10-25 20:41 ` Daniel Shahaf @ 2021-10-25 21:00 ` Ray Andrews 2021-10-25 21:09 ` Bart Schaefer 2021-10-25 21:05 ` Bart Schaefer 2021-10-25 21:20 ` Roman Perepelitsa 2 siblings, 1 reply; 27+ messages in thread From: Ray Andrews @ 2021-10-25 21:00 UTC (permalink / raw) To: zsh-users 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. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Disabling null elision (was: Re: Most Recent File) 2021-10-25 21:00 ` Ray Andrews @ 2021-10-25 21:09 ` Bart Schaefer 0 siblings, 0 replies; 27+ messages in thread From: Bart Schaefer @ 2021-10-25 21:09 UTC (permalink / raw) To: Ray Andrews; +Cc: Zsh Users 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.) ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Disabling null elision (was: Re: Most Recent File) 2021-10-25 20:41 ` Daniel Shahaf 2021-10-25 21:00 ` Ray Andrews @ 2021-10-25 21:05 ` Bart Schaefer 2021-10-25 21:20 ` Roman Perepelitsa 2 siblings, 0 replies; 27+ messages in thread From: Bart Schaefer @ 2021-10-25 21:05 UTC (permalink / raw) To: Daniel Shahaf; +Cc: Zsh Users 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? ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Disabling null elision (was: Re: Most Recent File) 2021-10-25 20:41 ` Daniel Shahaf 2021-10-25 21:00 ` Ray Andrews 2021-10-25 21:05 ` Bart Schaefer @ 2021-10-25 21:20 ` Roman Perepelitsa 2 siblings, 0 replies; 27+ messages in thread From: Roman Perepelitsa @ 2021-10-25 21:20 UTC (permalink / raw) To: Daniel Shahaf; +Cc: Zsh Users 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. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Disabling null elision (was: Re: Most Recent File) 2021-10-25 19:45 ` Disabling null elision (was: Re: Most Recent File) Daniel Shahaf 2021-10-25 20:02 ` Roman Perepelitsa @ 2021-10-25 20:05 ` Bart Schaefer 1 sibling, 0 replies; 27+ messages in thread From: Bart Schaefer @ 2021-10-25 20:05 UTC (permalink / raw) To: Daniel Shahaf; +Cc: Zsh Users, Roman Perepelitsa 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. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-24 0:24 ` Pier Paolo Grassi 2021-10-24 0:32 ` Paul @ 2021-10-24 1:37 ` Dominik Vogt 1 sibling, 0 replies; 27+ messages in thread From: Dominik Vogt @ 2021-10-24 1:37 UTC (permalink / raw) To: zsh-users 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 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 16:15 Most Recent File Vin Shelton 2021-10-23 16:43 ` Dominik Vogt @ 2021-10-23 16:47 ` david rayner 2021-10-23 16:54 ` Vin Shelton 2021-10-23 16:51 ` david rayner 2 siblings, 1 reply; 27+ messages in thread From: david rayner @ 2021-10-23 16:47 UTC (permalink / raw) To: zsh-users [-- 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 --] ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 16:47 ` david rayner @ 2021-10-23 16:54 ` Vin Shelton 0 siblings, 0 replies; 27+ messages in thread From: Vin Shelton @ 2021-10-23 16:54 UTC (permalink / raw) To: david rayner; +Cc: Zsh-Users List [-- 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 --] ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Most Recent File 2021-10-23 16:15 Most Recent File Vin Shelton 2021-10-23 16:43 ` Dominik Vogt 2021-10-23 16:47 ` david rayner @ 2021-10-23 16:51 ` david rayner 2 siblings, 0 replies; 27+ messages in thread From: david rayner @ 2021-10-23 16:51 UTC (permalink / raw) To: zsh-users [-- 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 --] ^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2021-10-25 21:22 UTC | newest] Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-10-23 16:15 Most Recent File Vin Shelton 2021-10-23 16:43 ` Dominik Vogt 2021-10-23 16:58 ` Peter Stephenson 2021-10-23 17:24 ` Dominik Vogt 2021-10-23 17:32 ` Peter Stephenson 2021-10-23 18:39 ` Bart Schaefer 2021-10-23 19:07 ` Vin Shelton 2021-10-23 19:26 ` Bart Schaefer 2021-10-23 20:43 ` Vin Shelton 2021-10-23 20:56 ` Pier Paolo Grassi 2021-10-23 22:42 ` Bart Schaefer 2021-10-24 0:24 ` Pier Paolo Grassi 2021-10-24 0:32 ` Paul 2021-10-24 1:45 ` Dominik Vogt 2021-10-24 7:22 ` Roman Perepelitsa 2021-10-25 19:45 ` Disabling null elision (was: Re: Most Recent File) Daniel Shahaf 2021-10-25 20:02 ` Roman Perepelitsa 2021-10-25 20:41 ` Daniel Shahaf 2021-10-25 21:00 ` Ray Andrews 2021-10-25 21:09 ` Bart Schaefer 2021-10-25 21:05 ` Bart Schaefer 2021-10-25 21:20 ` Roman Perepelitsa 2021-10-25 20:05 ` Bart Schaefer 2021-10-24 1:37 ` Most Recent File Dominik Vogt 2021-10-23 16:47 ` david rayner 2021-10-23 16:54 ` Vin Shelton 2021-10-23 16:51 ` david rayner
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).