zsh-workers
 help / color / mirror / code / Atom feed
* Example function
@ 1999-01-26 18:42 Phil Pennock
  1999-01-27  0:25 ` Bart Schaefer
  0 siblings, 1 reply; 4+ messages in thread
From: Phil Pennock @ 1999-01-26 18:42 UTC (permalink / raw)
  To: Zsh Development Workers

Hi,

      
A couple of months back zefram decided that he wanted one of my sicker
zsh shell functions for the examples.  I gave it to him then.  Here it  
is again for inclusion.

      
It's a zless which automatically determines from the file extension
which decompressor to use.  The comments explain it.  This has evolved
over about a year and a half, hence my needing help sorting out the
array bit.

Uhm, have fun or whatever.  Peter, any chance of this going in your next
sub-distrib?

Thanks

PS: Note that the last line is 108 chars long; your mailer may
interfere?

-----------------------------< cut here >-------------------------------
#!/usr/bin/zsh -f
#
# zsh function script to run less on various inputs, decompressing as required.
# Author: Phil Pennock.  zsh-hacks@athenaeum.demon.co.uk
# Thanks to zefram@fysh.org for a great deal of help in sorting this out,
# ie wrt syntax for unsetting members of arrays and eval "$(...)" when I
# asked for something better than . =(...)
# Other than that the whole sick beauty is mine.
#
# Use -zforce to pass through a display-formatting command
#  zless -zforce 'bzip2 -dc' foo-no-dotbz2
#  zless -zforce 'od -hc' foo-binfile
#
# If you can understand all of this without reference to zshexpn(1)
# and zshparam(1) then you either have a photographic memory or you
# need to get out more.
#

[[ $# -ge 1 ]] || return
local -i i loi max
local dispfunc lessopts
set -A dispfunc
set -A lessopts
loi=1 
max=$[$#+1]
for ((i=1; i != $max ; ++i))
do
	dispfunc[i]='<' 
	[[ $argv[i] = \-zforce ]] && {
		dispfunc[i+2]="$argv[i+1]"
		argv[i,i+1]=()
		dispfunc[i,i+1]=()
		let max-=2
		continue
	}
	[[ $argv[i] = \-* ]] && {
		lessopts[loi++]="$argv[i]" 
		argv[i,i]=()
		dispfunc[i,i]=()
		let max-=1
		let i-=1
		continue
	}
	[[ $argv[i] = *.gz ]] && dispfunc[i]=zcat 
	[[ $argv[i] = *.bz2 ]] && dispfunc[i]='bzip2 -dc' 
	[[ $argv[i] = *.Z ]] && dispfunc[i]=zcat 
	[[ $argv[i] = *.bz ]] && dispfunc[i]='bzip -dc' 
done
eval "$(print command less "${(@)lessopts}" "=($dispfunc[i=1] \"${(@Nej:\") =($dispfunc[++i] \":)argv}\")")"
-----------------------------< cut here >-------------------------------
-- 
--> Phil Pennock ; GAT d- s+:+ a23 C++(++++) UL++++/I+++/S+++/B++/H+$ P++@$
L+++ E-@ W(+) N>++ o !K w--- O>+ M V !PS PE Y+ PGP+ t-- 5++ X+ R !tv b++>+++
DI+ D+ G+ e+ h* r y?


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

* Re: Example function
  1999-01-26 18:42 Example function Phil Pennock
@ 1999-01-27  0:25 ` Bart Schaefer
  1999-01-27  0:37   ` Bart Schaefer
  0 siblings, 1 reply; 4+ messages in thread
From: Bart Schaefer @ 1999-01-27  0:25 UTC (permalink / raw)
  To: Phil Pennock, Zsh Development Workers

On Jan 26,  6:42pm, Phil Pennock wrote:
> Subject: Example function
>       
> It's a zless which automatically determines from the file extension
> which decompressor to use.  The comments explain it.  This has evolved
> over about a year and a half, hence my needing help sorting out the
> array bit.

This is certainly interesting, but I'm really puzzled why you wanted to
do it the way you did it.  For example, why build a parallel dispfunc
array and then merge it with argv at the end, rather than just rewrite
argv in place (which you already do in some instances)?

Also the (@) flags in the variable expansions in the last line are
extraneous.

Anyway, here's how I'd write that same function (runs in 3.0.5, too, which
Phil's doesn't because of the for (( )) syntax):

function zl() {
  emulate -R zsh
  [[ $# -ge 1 ]] || return
  local lessopts
  set -A lessopts
  integer i=1 loi=1
  while ((i <= $#))
  do
    case $argv[i] in
    -zforce) argv[i,i+2]=("=($argv[i+1] \"$argv[i+2]\")"); ((++i));;
    -*) lessopts[loi++]=\"$argv[i]\"; argv[i]=(); continue;;
    *.(gz|Z)) argv[i]="=(zcat \"$argv[i]\")";;
    *.bz2) argv[i]="=(bzip2 -dc \"$argv[i]\")";;
    *.bz) argv[i]="=(bzip -dc \"$argv[i]\")";;
    esac
    ((++i))
  done
  eval command less $lessopts $*
}

Of course, this still assumes you don't have any less options or file names
that contain double-quote characters ...

(One of the things on the associative-array wishlist is "reverse pattern"
lookup, that is, treat the array keys as patterns and match them against
the subscript.  Then you could do silly stuff like

	typeset -A map
	map=('*.(gz|Z)'	zcat
	     '*.bz2' 'bzip2 -dc'
	     '*.bz' 'bzip -dc'
	     '*' '<')
	eval ${(q)map[$argv[i]]} '$argv[i]'

where I'm using (q) as the fictional reverse-pattern query flag; probably
there's a better letter.)


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

* Re: Example function
  1999-01-27  0:25 ` Bart Schaefer
@ 1999-01-27  0:37   ` Bart Schaefer
  0 siblings, 0 replies; 4+ messages in thread
From: Bart Schaefer @ 1999-01-27  0:37 UTC (permalink / raw)
  To: Bart Schaefer, Phil Pennock, Zsh Development Workers

On Jan 26,  4:25pm, Bart Schaefer wrote:
> Subject: Re: Example function
> (One of the things on the associative-array wishlist is "reverse pattern"
> lookup, that is, treat the array keys as patterns and match them against
> the subscript.  Then you could do silly stuff like
> 
> 	typeset -A map
> 	map=('*.(gz|Z)'	zcat
> 	     '*.bz2' 'bzip2 -dc'
> 	     '*.bz' 'bzip -dc'
> 	     '*' '<')
> 	eval ${(q)map[$argv[i]]} '$argv[i]'
> 
> where I'm using (q) as the fictional reverse-pattern query flag; probably
> there's a better letter.)

Incidentally, the reason this isn't there already is that associative arrays
are unordered hashes, so you can't predict _which_ pattern will match the
subscript when you do the query -- '*' might match before '*.bz' is tried.


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

* Re: Example function
@ 1999-02-01 10:48 Sven Wischnowsky
  0 siblings, 0 replies; 4+ messages in thread
From: Sven Wischnowsky @ 1999-02-01 10:48 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> (One of the things on the associative-array wishlist is "reverse pattern"
> lookup, that is, treat the array keys as patterns and match them against
> the subscript.  Then you could do silly stuff like
> 
> 	typeset -A map
> 	map=('*.(gz|Z)'	zcat
> 	     '*.bz2' 'bzip2 -dc'
> 	     '*.bz' 'bzip -dc'
> 	     '*' '<')
> 	eval ${(q)map[$argv[i]]} '$argv[i]'
> 
> where I'm using (q) as the fictional reverse-pattern query flag; probably
> there's a better letter.)
> 
> Incidentally, the reason this isn't there already is that associative arrays
> are unordered hashes, so you can't predict _which_ pattern will match the
> subscript when you do the query -- '*' might match before '*.bz' is tried.

I was thinking about this... we could make the code keep a counter in
assoc arrays, increment it whenever a new key is added and store the
current value in the structure for this new element. Then we can treat 
the whole thing as being sorted by `time of addition'.

Hm, does this sound like the right thing?

Bye
 Sven

P.S.: Is `foo=( ${(kv)foo[(I)^key]} )' the easiest way to remove a
      key/value-pair from an associative array?

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


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

end of thread, other threads:[~1999-02-01 10:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-01-26 18:42 Example function Phil Pennock
1999-01-27  0:25 ` Bart Schaefer
1999-01-27  0:37   ` Bart Schaefer
1999-02-01 10:48 Sven Wischnowsky

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).