On 05 Apr 2021, at 16:55, dukeofpurl@gmx.com wrote: > em() { emacs $1 -geometry "56x23" } > such that I can pass a to `em' and bingo-bango I'm off programming some C code. NO joy! Do you get an error? That function works perfectly fine on my system (not that I use emacs, and had to remember how to exit emacs) but no issues. -- ɹןʇnqן <mailto:lbutler@covisp.net> tel:+1.303.219.0564
[-- Attachment #1: Type: text/plain, Size: 829 bytes --] On 4/5/21 4:55 PM, dukeofpurl@gmx.com wrote: > I'm trying to set up the following alias (function actually): em() > { emacs $1 -geometry "56x23" } such that I can pass a to `em' and > bingo-bango I'm off programming some C code. I use functions like that all the time. Perhaps it's in the way that it's set up. Are you adding this to your ~/.zshrc file, or manually defining the function? I've got the following in my ~/.zshrc file and it works perfectly. pd() { [ -n "${1}" ] && pushd "${1}" || popd; } It's using parameters on a function, just like you're trying to do. It works a treat. Aside: Yes, I'm lazy and don't want to type pushd or popd. Instead, the pd function determines which command to run based on if $1 is set or not. -- Grant. . . . unix || die [-- Attachment #2: S/MIME Cryptographic Signature --] [-- Type: application/pkcs7-signature, Size: 4013 bytes --]
On Mon, 5 Apr 2021 18:16:45 -0600
lb@covisp.net wrote:
> On 05 Apr 2021, at 16:55, dukeofpurl@gmx.com wrote:
> > em() { emacs $1 -geometry "56x23" }
>
> > such that I can pass a to `em' and bingo-bango I'm off programming
> > some C code. NO joy!
>
> Do you get an error?
>
> That function works perfectly fine on my system (not that I use
> emacs, and had to remember how to exit emacs) but no issues.
No error! It simply won't load the filename I pass to the zsh function.
`--> uname -a
Linux antixbox 4.9.235-antix.1-amd64-smp #1 SMP PREEMPT Mon Sep 14 19:26:52 EEST 2020 x86_64 GNU/Linux
`--> em ./hello.c
brings up an empty emacs editor.
Duke
Turner Valley, Alberta, Canada
>>>>> On April 5, 2021 Duke Normandin <dukeofpurl@gmx.com> wrote: >> On 05 Apr 2021, at 16:55, dukeofpurl@gmx.com wrote: >> > em() { emacs $1 -geometry "56x23" } > No error! It simply won't load the filename I pass to the zsh function. works for me. maybe 'emacs' is aliased or otherwise overriden? % whence -va emacs add 'echo' before 'emacs' and see what it prints? what if you directly run % emacs ./hello.c -geometry "56x23" does it load hello.c then? I thought maybe emacs might not like the -geometry argument after the filename, but it works for me. Maybe a problem with your .emacs? Try adding '-q' to the emacs invocation to test that hypotheses, however, then you'd see the same problem running emacs directly above. btw, you might consider: em() { emacs -geometry "56x23" "$@" } which lets you pass any number of files (including none) Greg
2021-04-05 20:47:47 -0600, Grant Taylor:
[...]
> pd() {
> [ -n "${1}" ] && pushd "${1}" || popd;
> }
>
> It's using parameters on a function, just like you're trying to do. It
> works a treat.
>
> Aside: Yes, I'm lazy and don't want to type pushd or popd. Instead, the pd
> function determines which command to run based on if $1 is set or not.
[...]
That function would run popd when pushd fails. It's generally a
bad idea to use this kind of a && b || c in place of proper
if/then/else constructs.
pd() {
if [ "$#" -gt 0 ]; then
pushd "$@"
else
popd
fi
}
Or for the very lazy:
pd()if (($#)){pushd "$@"} else {popd}
--
Stephane
On 07 Apr 2021, at 01:05, Stephane Chazelas <stephane@chazelas.org> wrote:
> 2021-04-05 20:47:47 -0600, Grant Taylor:
> [...]
>> pd() {
>> [ -n "${1}" ] && pushd "${1}" || popd;
>> }
>>
>> It's using parameters on a function, just like you're trying to do. It
>> works a treat.
>>
>> Aside: Yes, I'm lazy and don't want to type pushd or popd. Instead, the pd
>> function determines which command to run based on if $1 is set or not.
> [...]
>
> That function would run popd when pushd fails. It's generally a
> bad idea to use this kind of a && b || c in place of proper
> if/then/else constructs.
Bad idea, or just a style "this is proper practice" sort of thing?
I can't imagine any 'bad idea' from this, as it is doing the same basic thing.
--
ɹןʇnqן
<mailto:lbutler@covisp.net>
tel:+1.303.219.0564
> On 07 April 2021 at 13:48 lb@covisp.net wrote:
>
> On 07 Apr 2021, at 01:05, Stephane Chazelas <stephane@chazelas.org> wrote:
> > 2021-04-05 20:47:47 -0600, Grant Taylor:
> > [...]
> >> pd() {
> >> [ -n "${1}" ] && pushd "${1}" || popd;
> >> }
>
> > That function would run popd when pushd fails. It's generally a
> > bad idea to use this kind of a && b || c in place of proper
> > if/then/else constructs.
>
> Bad idea, or just a style "this is proper practice" sort of thing?
>
> I can't imagine any 'bad idea' from this, as it is doing the same basic thing.
Stephane is pointing out that what you want is:
if [[ -n $1 ]]; then
pushd "$1"
else
popd
fi
but what you've got is (writing out in full for clarity):
if [[ -n $1 ]]; then
if ! pushd "$1"; then
popd
fi
else
popd
fi
because of the slightly obscure but nonetheless well-defined way && and || work.
pws
Stephane Chazelas wrote on Wed, 07 Apr 2021 07:05 +00:00:
> Or for the very lazy:
>
> pd()if (($#)){pushd "$@"} else {popd}
Or this:
pd()p${${=:-op ush}[1+$#]}d $1
OP here! Problem solved! The issue I was having turned out to be emacs v27.1 on my antiX Linux distro. It as been nuked and v26.1 re-installed! My newbie zsh function that fires up emacs with a filename works just dandy! Thanks for all the help and extras!! -- Duke
[-- Attachment #1: Type: text/plain, Size: 856 bytes --] On 4/7/21 6:48 AM, lb@covisp.net wrote: > Bad idea, or just a style "this is proper practice" sort of thing? > > I can't imagine any 'bad idea' from this, as it is doing the same > basic thing. Stephane is correct. It's actually a bug which I occasionally tickle. I've just never been motivated to do anything about it. The bug is when I would try to p(ush)d to a directory that doesn't exist, e.g. typo. I end up unwittingly doing a popd backwards. I just actually hacked this together. pd () { [ $# -eq 1 ] && pushd "${1}" [ $# -eq 0 ] && popd } I should have expected (and did) that my function would be scrutinized. Which I'm cool with. But even my buggy version demonstrates that function parameters do work, which is what the OP's question was about. ;-) -- Grant. . . . unix || die [-- Attachment #2: S/MIME Cryptographic Signature --] [-- Type: application/pkcs7-signature, Size: 4013 bytes --]
Grant Taylor wrote on Thu, 08 Apr 2021 01:06 +00:00:
> pd () {
> [ $# -eq 1 ] && pushd "${1}"
> [ $# -eq 0 ] && popd
> }
This will return non-zero when pushd succeeds.
setopt PRINT_EXIT_VALUE
☺
[-- Attachment #1: Type: text/plain, Size: 424 bytes --] On 4/7/21 7:25 PM, Daniel Shahaf wrote: > This will return non-zero when pushd succeeds. You are correct. pd () { [ $# -eq 1 ] && pushd "${1}" && return 0 [ $# -eq 0 ] && popd } > setopt PRINT_EXIT_VALUE I should have seen the bug you report as I have $? in the RPROMPT conditionally when it's > 0. So ... one would think I would have seen that. -- Grant. . . . unix || die [-- Attachment #2: S/MIME Cryptographic Signature --] [-- Type: application/pkcs7-signature, Size: 4013 bytes --]
Grant Taylor wrote on Thu, Apr 08, 2021 at 20:55:37 -0600:
> On 4/7/21 7:25 PM, Daniel Shahaf wrote:
> > This will return non-zero when pushd succeeds.
>
> You are correct.
>
> pd () {
> [ $# -eq 1 ] && pushd "${1}" && return 0
> [ $# -eq 0 ] && popd
> }
This still discards pushd's exit code if it's *non*-zero.
Yet another variant:
pd() case $+1 in (0) popd;; (1) pushd "$1";; esac
Or if golfing:
pd()$# $1;0()popd;1()pushd $1
On 09/04/2021 23:49, Daniel Shahaf wrote:
>
> Yet another variant:
>
> pd() case $+1 in (0) popd;; (1) pushd "$1";; esac
>
> Or if golfing:
>
> pd()$# $1;0()popd;1()pushd $1
>
Daniel thanks for these
I suspect that the case-esac structure is a neglected control structure.
One way or another we are all golfers all seeking an elegant solution.
> I suspect that the case-esac structure is a neglected control structure.
indeed. and combined to the neglected alternative syntax (man zshmisc)
(probably inspired by rc, as well as the neglected rcquote option), you have:
pd () case $+1 { (0) popd ;; (*) pushd "$1" ;; }
[-- Attachment #1: Type: text/plain, Size: 1491 bytes --] On 4/9/21 4:49 PM, Daniel Shahaf wrote: > This still discards pushd's exit code if it's *non*-zero. ACK > Yet another variant: > > pd() case $+1 in (0) popd;; (1) pushd "$1";; esac Why use "$+1"? I would have thought to use "$#" instead. > Or if golfing: > > pd()$# $1;0()popd;1()pushd $1 I feel like this is going outside the box. If I'm interpreting it correctly, it's actually defining three functions; pd, 0, and 1, each of which do a teeny tiny piece / sub-function. Wherein pd calls either 0 or 1 + first argument. I'll give credit for it. But it's not what I originally thought it was going to be. I was naively thinking that it was going to be some alternate syntax for a case statement. That's the effect you get, but not the method. Aside: If I was going to do this, I'd probably protect the sub-functions so they don't get clobbered: % functions pd pd () { pd$# $1 } % functions pd0 pd0 () { popd } % functions pd1 pd1 () { pushd $1 } Also, a bug: Passing more than one argument fails. I do play Vim golf. But I've learned that compacting things as tight as possible can make them more difficult to understand ~> maintain in the future. A la. Perl becoming what seems like line noise. So my golfing tends to be interactive Vim and everything else, especially when explaining / teaching something new to someone, is fully expanded. -- Grant. . . . unix || die [-- Attachment #2: S/MIME Cryptographic Signature --] [-- Type: application/pkcs7-signature, Size: 4013 bytes --]
[-- Attachment #1: Type: text/plain, Size: 499 bytes --] On 4/10/21 10:30 AM, Grant Taylor wrote: > Why use "$+1"? I would have thought to use "$#" instead. I found the answer to my own question. man zshexpn ${+name} If name is the name of a set parameter `1' is substituted, otherwise `0' is substituted. This also avoids ticking the number of parameters bug introduced by $#. I always end up learning something from or as a direct result of reading messages from this list. :-) -- Grant. . . . unix || die [-- Attachment #2: S/MIME Cryptographic Signature --] [-- Type: application/pkcs7-signature, Size: 4013 bytes --]
Grant Taylor wrote on Sat, Apr 10, 2021 at 10:30:21 -0600: > On 4/9/21 4:49 PM, Daniel Shahaf wrote: > > Yet another variant: > > > > pd() case $+1 in (0) popd;; (1) pushd "$1";; esac > > Why use "$+1"? I would have thought to use "$#" instead. > > > Or if golfing: > > > > pd()$# $1;0()popd;1()pushd $1 > > I feel like this is going outside the box. If I'm interpreting it > correctly, it's actually defining three functions; pd, 0, and 1, each of > which do a teeny tiny piece / sub-function. Wherein pd calls either 0 or 1 > + first argument. Correct. > Aside: If I was going to do this, [...] It wasn't meant to be used as production code. Daniel
>> I suspect that the case-esac structure is a neglected control structure.
> indeed. and combined to the neglected alternative syntax (man zshmisc)
> (probably inspired by rc, as well as the neglected rcquote option), you have:
>
> pd () case $+1 { (0) popd ;; (*) pushd "$1" ;; }
>
Am using a case statement as a ***visually elegant way*** of excluding a
potentially changing list of Global Aliases from being automatically
expanded
The following excludes any single Uppercase Letter , any Alias V
followed by a number, Any beginning with G
function dontExpandGlobalAlias()
{
if [ $# -gt 0 ] ; then
case $1 in
[A-Z] | V<-> | G* ) ;;
*) echo "Yes expand"
;;
esac
fi
}
Just wondered if anyone had any input/improvements with or without GOLF
On Wed, Apr 14, 2021 at 4:10 AM zzapper <zsh@rayninfo.co.uk> wrote: > > Am using a case statement as a ***visually elegant way*** of excluding a > potentially changing list of Global Aliases from being automatically > expanded Sorry, you're using this ... where? ... to achieve that? > if [ $# -gt 0 ] ; then > case $1 in > [A-Z] | V<-> | G* ) ;; > *) echo "Yes expand" > ;; > esac > fi It's generally preferable to use [[ ... ]] instead of [ ... ] because "[" is just another name for "test" and "]" is just one of its arguments, whereas "[[" and "]]" are syntax tokens with parsing rules for what appears between them. However, since you're comparing numbers, you could use (( $# > 0 )) here. However you really don't need that test at all: case "$1" in ("") false;; ([A-Z]|V<->|G*);; (*) echo "Yes expand";; esac You probably don't even need the first "false'' case, I threw it in just to keep the same $? as your original "if". case "$1" in (|[A-Z]|V<->|G*);; (*) echo "Yes expand";; esac
> However you really don't need that test at all:
> case "$1" in
> ("") false;;
> ([A-Z]|V<->|G*);;
> (*) echo "Yes expand";;
> esac
i would have written ${1-} so -u can be used.
also: i really think that using terminators as "continuation"
ease the code reading because
* it makes code more aligned
* it's easier to spot a different terminator than ;;
case "${1-}"
in ('') do_nothing
;; (hello*) greetings
;| (*world) greetings # twice
;; (long)
multiple commands
comes in indented lines
;;
esac
regards
marc
Bart Schaefer wrote on Thu, Apr 15, 2021 at 11:19:16 -0700:
> On Wed, Apr 14, 2021 at 4:10 AM zzapper <zsh@rayninfo.co.uk> wrote:
> > if [ $# -gt 0 ] ; then
>
> It's generally preferable to use [[ ... ]] instead of [ ... ] because
> "[" is just another name for "test" and "]" is just one of its
> arguments, whereas "[[" and "]]" are syntax tokens with parsing rules
> for what appears between them. However, since you're comparing
> numbers, you could use (( $# > 0 )) here.
In general, «(( ${+foo[1]} ))» is faster than «(( ${#foo} ))», because
the latter takes O(N) time where N is the length of the array, where's
the former is O(1). For the positional arguments, that'd be «(( $+1 ))».
On Thu, Apr 15, 2021 at 12:56 PM Marc Chantreux <eiro@phear.org> wrote: > > > However you really don't need that test at all: > > case "$1" in > > ("") false;; > > ([A-Z]|V<->|G*);; > > (*) echo "Yes expand";; > > esac > > i would have written ${1-} so -u can be used. I'm not following that at all: -u where? > also: i really think that using terminators as "continuation" > ease the code reading Entirely my opinion, but I find your example much MORE difficult to read. > * it makes code more aligned Only if you start with the (jarring to me) "in" on a new line. > * it's easier to spot a different terminator than ;; For that, I'd put the terminator on a line by itself, which I would also do if the case branch was more than one line or if the case pattern was quite long, but with short patterns and the terminators all ;; it seems unnecessary.
hello, > > i would have written ${1-} so -u can be used. > I'm not following that at all: -u where? oopps. sorry i was too fast writting this. i meant nounset option. i want my shell to yell at me as soon as i do something wrong so my ~/.zshenv starts with setopt warncreateglobal nounset pipefail > > also: i really think that using terminators as "continuation" > > ease the code reading > Entirely my opinion, but I find your example much MORE difficult to read. Thanks for the feedback! As always, i think everyone comes with cultural biases when it comes to coding style. when i read case "$var" in (a*) write ;; (b*) something ;; (c*) cool ;; esac i would like to see/write # in raku given $var { when /a*/ { write } when /b*/ { something } when /c*/ { cool } } # in rc switch ($var) { case a* ; write case b* ; something case c* ; cool } and i used to actually read/write # zsh case "$var" { (a*) write ;; (b*) something ;; (c*) cool ;; } because i though for many years that alternative syntax will replace the old one the way zshcompsys replaced zshcompctl. but: * it will never happen and i have to fall back with the classic syntax whenever i contribute to existing codebases. * i started replace zsh by dash or rc in my scripts whenever the awesomeness of zsh doesn't help a lot (which means "lot of them") so now i try to stick to POSIX syntax whenever it's easy to do it but i try to adapt the coding style so the code keep staying attractive to me. > > * it's easier to spot a different terminator than ;; > For that, I'd put the terminator on a line by itself, which I would > also do if the case branch was more than one line or if the case > pattern was quite long, but with short patterns and the terminators > all ;; it seems unnecessary. indeed. what i just did is to remove a "useless new line". ... some code there ;; (newcase) and ... some code there ;; (newcase) both to me and the interpreter and the second one looks much more natural to me. i'm not trying to convince anyone. i was really please to read your feedback so i try to share my opinion on it. regards marc
Thank you for all these responses have yet to absorb the latest ones but I'm trying to build up a library of control structures for future use
2021-04-15 20:30:46 +0000, Daniel Shahaf:
> Bart Schaefer wrote on Thu, Apr 15, 2021 at 11:19:16 -0700:
> > On Wed, Apr 14, 2021 at 4:10 AM zzapper <zsh@rayninfo.co.uk> wrote:
> > > if [ $# -gt 0 ] ; then
> >
> > It's generally preferable to use [[ ... ]] instead of [ ... ] because
> > "[" is just another name for "test" and "]" is just one of its
> > arguments, whereas "[[" and "]]" are syntax tokens with parsing rules
> > for what appears between them. However, since you're comparing
> > numbers, you could use (( $# > 0 )) here.
>
> In general, «(( ${+foo[1]} ))» is faster than «(( ${#foo} ))», because
> the latter takes O(N) time where N is the length of the array, where's
> the former is O(1).
Beware that (( ${+foo[1]} )) approach doesn't work when the
ksharrays option is enabled. (though I'd expect one would
generally only use that option as part of the ksh emulation to
interpret ksh code, so that would likely not be a problem).
It also does't work for associative arrays.
FWIW, [[ -v foo[1] ]] seems to be slightly faster.
I'd still use (( $#foo )) or (( $#foo > 0 )) for legibility.
--
Stephane