Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: zftp functions with styles and avoiding patcomps problems



Sven Wischnowsky wrote:
> - _patcomps and _postpatcomps are now assocs (we can do this now that
>   we have the (K) subscript flag)

zfinit uses these for checking whether new completion for zftp is loaded
(and hence old completion is not needed).

I've also modified the functions to use styles instead of keys to
zfconfig.  The existing keys are carried over to styles in the obvious way;
the context looks like e.g. :zftp:zfput:.  There are two additional keys:
titlebar (boolean), which determines whether zftp_chpwd alters your
titlebar (defaults on if you don't set it), and chpwd, which determines
whether zftp_chpwd calls chpwd after you close the connection (defaults to
whether or not you have chpwd defined when zfinit runs).

One more change:  zfput now takes a -r option to put directories
recursively.  This should be very useful for uploads.  Currently the -r
option requires the remote machine to understand /'s as directory
separators, and none of the other commands has a recursive option.  Both of
these could be probably be improved if necessary.

--- Doc/Zsh/zftpsys.yo.zf	Fri Dec 10 19:48:31 1999
+++ Doc/Zsh/zftpsys.yo	Wed Dec 15 19:16:57 1999
@@ -271,10 +271,15 @@
 subsect(Sending files)
 startitem()
 findex(zfput)
-item(tt(zfput var(file1) ...))(
+item(tt(zfput [ -r ] var(file1) ...))(
 Send all the var(file1) ... given separately to the remote server.  If a
 filename contains a `tt(/)', the full filename is used locally to find the
 file, but only the basename is used for the remote file name.
+
+With the option tt(-r), if any of the var(files) are directories they are
+sent recursively with all their subdirectories, including files beginning
+with `tt(.)'.  This requires that the remote machine understand UNIX file
+semantics. as `tt(/)' is used as a directory separator.
 )
 findex(zfuput)
 item(tt(zfuput [ -vs ] var(file1) ...))(
@@ -486,11 +491,11 @@
 This function shows the status of the transfer.  It will not write anything
 unless the output is going to a terminal; however, if you transfer files in
 the background, you should turn off progress reports by hand using
-`tt(zfconfig[progress]=none)'.  (Background file transfers don't work on all
-OSes.) Note also that if you alter it, any output em(must) be to standard
-error, as standard output may be a file being received.  The form of the
-progess meter, or whether it is used at all, can be configured without
-altering the function, as described in the next section.
+`tt(zstyle ':zftp:*' progress none)'.  Note also that if you alter it, any
+output em(must) be to standard error, as standard output may be a file
+being received.  The form of the progess meter, or whether it is used at
+all, can be configured without altering the function, as described in the
+next section.
 )
 findex(zffcache)
 item(tt(zffcache))(
@@ -504,39 +509,78 @@
 
 subsect(Configuration)
 cindex(zftp function system, configuration)
-pindex(zfconfig)
+cindex(zftp function system, styles)
+cindex(styles in zftp functions)
 
-The tt(zfinit) function defines an associative array tt(zfconfig).
-Elements of this may subsequently be set to change the behaviour of the
-tt(zftp) functions using standard syntax (for example,
-`tt(zfconfig[progress]=percent)'.  tt(zfconfig) may also contain
-various other values used by the function system, so it should not be used
-as the target of an assignment for a complete array.  The following keys
-are understood.
+Various styles are available using the standard shell style mechanism,
+described in
+ifzman(zmanref(zshmodules))\
+ifnzman(noderef(The zutil Module)). Briefly, the
+command `tt(zstyle ':zftp:*') var(style) var(value) ...'.
+defines the var(style) to have value var(value) (more than one may be
+given, although that is not useful in the cases described here).  These
+values will then be used throughout the zftp function system.  For more
+precise control, the first argument, which gives a context in which the
+style applies, can be modified to include a particular function, as for
+example `tt(:zftp:zfget:)': the style will then have the given value only
+in the tt(zfget) function.  Values for the same style in different contexts
+may be set; the most specific function will be used, where
+strings are held to be more specific than patterns, and longer patterns and
+shorter patterns.  Note that only the top level function name, as called by
+the user, is used; calling of lower level functions is transparent to the
+user.  Hence modifications to the title bar in tt(zftp_chpwd) use the
+contexts tt(:zftp:zfopen:), tt(:zftp:zfcd:), etc., depending where it was
+called from.  The following styles are understood:
 
 startitem()
 item(tt(progress))(
 Controls the way that tt(zftp_progress) reports on the progress of a
 transfer.  If empty, unset, or `tt(none)', no progress report is made; if
-`tt(bar)' (the default), a growing bar of inverse video is shown; if
-`tt(percent)' (or any other string, though this may change in future), the
-percentage of the file transferred is shown.  The bar meter requires that
-the width of the terminal be available via the tt($COLUMNS) parameter
-(normally this is set automatically).  If the size of the file being
-transferred is not available, tt(bar) and tt(percent) meters will simply
-show the number of bytes transferred so far.
+`tt(bar)' a growing bar of inverse video is shown; if `tt(percent)' (or any
+other string, though this may change in future), the percentage of the file
+transferred is shown.  The bar meter requires that the width of the
+terminal be available via the tt($COLUMNS) parameter (normally this is set
+automatically).  If the size of the file being transferred is not
+available, tt(bar) and tt(percent) meters will simply show the number of
+bytes transferred so far.
+
+When tt(zfinit) is run, if this style is not defined for the context
+tt(:zftp:*), it will be set to `bar'.
 )
 item(tt(update))(
 Specifies the minimum time interval between updates of the progress meter
 in seconds.  No update is made unless new data has been received, so the
 actual time interval is limited only by tt($ZFTP_TIMEOUT).
+
+As described for tt(progress), tt(zfinit) will force this to default to 1.
 )
 item(tt(remote_glob))(
-If set to a non-zero length, filename generation (globbing) is
+If set to `1', `yes' or `true', filename generation (globbing) is
 performed on the remote machine instead of by zsh itself; see below.
 )
+item(tt(titlebar))(
+If set to `1', `yes' or `true', tt(zftp_chpwd) will put the remote host and
+remote directory into the titlebar of terminal emulators such as xterm or
+sun-cmd that allow this.
+
+As described for tt(progress), tt(zfinit) will force this to default to 1.
+)
+item(tt(chpwd))(
+If set to `1' `yes' or `true', tt(zftp_chpwd) will call the function
+tt(chpwd) when a connection is closed.  This is useful if the remote host
+details were put into the terminal title bar by tt(zftp_chpwd) and your
+usual tt(chpwd) also modifies the title bar.
+
+When tt(zfinit) is run, it will determine whether tt(chpwd) exists and if
+so it will set the default value for the style to 1 if none exists
+already.
+)
 enditem()
 
+Note that there is also an associative array tt(zfconfig) which contains
+values used by the function system.  This should not be modified or
+overwritten.
+
 subsect(Remote globbing)
 cindex(zftp function system, remote globbing)
 
@@ -554,13 +598,12 @@
 if retrieved, will be cached, so that subsequent globs in the same
 directory without an intervening tt(zfcd) are much faster.
 
-If the key tt(remote_glob) of the tt(zfconfig) associative array (see
-above) is set to a non-zero length, globbing is instead performed on the
-remote host: the server is asked for a list of matching files.  This is
-highly dependent on how the server is implemented, though typically UNIX
-servers will provide support for basic glob patterns.  This may in some
-cases be faster, as it avoids retrieving the entire list of directory
-contents.
+If the tt(remote_glob) style (see above) is set, globbing is instead
+performed on the remote host: the server is asked for a list of matching
+files.  This is highly dependent on how the server is implemented, though
+typically UNIX servers will provide support for basic glob patterns.  This
+may in some cases be faster, as it avoids retrieving the entire list of
+directory contents.
 
 subsect(Automatic and temporary reopening)
 cindex(zftp function system, automatic reopening)
--- Functions/Zftp/zfanon.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfanon	Wed Dec 15 18:31:05 1999
@@ -2,6 +2,7 @@
 
 emulate -L zsh
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfanon:
 local opt opt_1 dir
 
 while getopts :1 opt; do
--- Functions/Zftp/zfcd.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfcd	Wed Dec 15 18:31:05 1999
@@ -20,6 +20,7 @@
 #     work just as long as the directory structures under the home match.
 
 emulate -L zsh
+[[ $curcontext = :zf*: ]] || local curcontext=:zfcd:
 
 if [[ $1 = /* ]]; then
   zfautocheck -dn || return 1
--- Functions/Zftp/zfcget.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfcget	Wed Dec 15 18:31:05 1999
@@ -12,6 +12,7 @@
 
 emulate -L zsh
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfcget:
 local loc rem stat=0 opt opt_G opt_t remlist locst remst
 local tmpfile=${TMPPREFIX}zfcget$$ rstat tsize
 
--- Functions/Zftp/zfclose.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfclose	Wed Dec 15 18:31:05 1999
@@ -1,3 +1,4 @@
 # function zfclose {
+[[ $curcontext = :zf*: ]] || local curcontext=:zfclose:
 zftp close
 # }
--- Functions/Zftp/zfcput.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfcput	Wed Dec 15 18:31:06 1999
@@ -12,6 +12,7 @@
 
 emulate -L zsh
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfcput:
 local loc rem stat=0 locst remst offs tailtype
 local tmpfile=${TMPPREFIX}zfcget$$ rstat
 
--- Functions/Zftp/zfdir.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfdir	Wed Dec 15 18:31:06 1999
@@ -22,6 +22,7 @@
 emulate -L zsh
 setopt extendedglob
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfdir:
 local file opt optlist redir i newargs force
 local curdir=$zfconfig[curdir_$ZFTP_SESSION]
 local otherdir=$zfconfig[otherdir_$ZFTP_SESSION]
--- Functions/Zftp/zfgcp.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfgcp	Wed Dec 15 18:31:06 1999
@@ -16,6 +16,7 @@
 
 emulate -L zsh
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfgcp:
 local opt remlist rem loc opt_G opt_t
 integer stat do_close
 
--- Functions/Zftp/zfget.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfget	Wed Dec 15 18:31:06 1999
@@ -19,6 +19,7 @@
 
 emulate -L zsh
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfget:
 local loc rem opt remlist opt_G opt_t opt_c
 integer stat do_close
 
--- Functions/Zftp/zfgoto.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfgoto	Wed Dec 15 18:31:06 1999
@@ -8,6 +8,7 @@
 
 emulate -L zsh
 setopt extendedglob
+[[ $curcontext = :zf*: ]] || local curcontext=:zfgoto:
 
 # Set ZFTP_BMFILE if not already set.  This should agree with
 # the corresponding line in zfmark.
--- Functions/Zftp/zfhere.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfhere	Wed Dec 15 18:31:06 1999
@@ -1,5 +1,6 @@
 # function zfhere {
 # Change to the directory corresponding to $PWD on the server.
 # See zfcd for how this works.
+[[ $curcontext = :zf*: ]] || local curcontext=:zfhere:
 zfcd $PWD
 # }
--- Functions/Zftp/zfinit.zf	Wed Dec 15 18:36:29 1999
+++ Functions/Zftp/zfinit	Wed Dec 15 19:10:43 1999
@@ -1,10 +1,19 @@
 emulate -L zsh
 
-[[ $1 = -n ]] || zmodload -e zftp || zmodload -ia zftp
+[[ $1 = -n ]] || zmodload -e zftp || zmodload -ia zftp || return 1
+
+if zmodload -i zutil; then
+  local arr
+  # Set defaults for styles if none set.
+  zstyle -g arr ':zftp:*' progress || zstyle ':zftp:*' progress bar
+  zstyle -g arr ':zftp:*' update   || zstyle ':zftp:*' update   1
+  zstyle -g arr ':zftp:*' titlebar || zstyle ':zftp:*' titlebar true
+  if functions chpwd >&/dev/null && ! zstyle -g arr ':zftp:*' chpwd; then
+    zstyle ':zftp:*' chpwd true
+  fi
 
-if [[ ${+zfconfig} = 0 ]]; then
   typeset -gA zfconfig
-  zfconfig=(progress bar update 1 lastsession default)
+  zfconfig=(lastsession default)
 fi
 
 alias zfcd='noglob zfcd'
@@ -22,7 +31,7 @@
 # zftp completions: only use these if new-style completion is not
 # active.
 #
-if [[ ${#_patcomps} -eq 0 || ${_patcomps[(i)zf*]} -gt ${#_patcomps} ]]; then
+if [[ ${#_patcomps} -eq 0 || -z ${_patcomps[(i)zf*]} ]]; then
   # only way of getting that noglob out of the way: this is unnecessary with
   # widget-based completion
   setopt completealiases
@@ -55,3 +64,5 @@
   compctl -s '$(zftp session)' -S : -x 'C[0,*:*]' \
     -K zftransfer_match -- zftransfer
 fi
+
+return 0
--- Functions/Zftp/zfls.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfls	Wed Dec 15 18:31:06 1999
@@ -1,6 +1,7 @@
 # function zfls {
 
 emulate -L zsh
+[[ $curcontext = :zf*: ]] || local curcontext=:zfls:
 
 # directory hack, see zfcd
 if [[ $1 = $HOME || $1 = $HOME/* ]]; then
--- Functions/Zftp/zfmark.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfmark	Wed Dec 15 18:31:06 1999
@@ -7,6 +7,7 @@
 
 emulate -L zsh
 setopt extendedglob
+[[ $curcontext = :zf*: ]] || local curcontext=:zfmark:
 
 # Set ZFTP_BMFILE if not already set.  This should agree with
 # the corresponding line in zfgoto.
--- Functions/Zftp/zfopen.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfopen	Wed Dec 15 18:31:06 1999
@@ -7,6 +7,7 @@
 
 emulate -L zsh
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfopen:
 local opt dir opt_1 setparams
 
 while getopts :1 opt; do
--- Functions/Zftp/zfparams.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfparams	Wed Dec 15 18:31:06 1999
@@ -1,6 +1,7 @@
 # function zfparams {
 
 emulate -L zsh
+[[ $curcontext = :zf*: ]] || local curcontext=:zfparams:
 
 if [[ $# -eq 1 && $1 = - ]]; then
   # Delete existing parameter set.
--- Functions/Zftp/zfpcp.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfpcp	Wed Dec 15 18:31:06 1999
@@ -14,6 +14,7 @@
 
 emulate -L zsh
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfpcp:
 local rem loc
 integer stat do_close
 
--- Functions/Zftp/zfput.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfput	Wed Dec 15 18:31:06 1999
@@ -3,19 +3,64 @@
 # off any directory parts to get the remote filename (i.e. always
 # goes into current remote directory).  Use zfpcp to specify new
 # file name or new directory at remote end.
+#
+# -r means put recursively:  any directories encountered will have
+#    all their contents to arbitrary depth transferred.  Note that
+#    this creates the required directories.  Any files in subdirectories
+#    whose names begin with a `.' will also be included.
 
 emulate -L zsh
 
-local loc rem
-integer stat do_close
+[[ $curcontext = :zf*: ]] || local curcontext=:zfput:
+local opt opt_r
+integer stat do_close abort
+
+while getopts :r opt; do
+  [[ $opt = '?' ]] && print "zfget: bad option: -$OPTARG" && return 1
+  eval "opt_$opt=1"
+done
+(( OPTIND > 1 )) && shift $(( OPTIND - 1 ))
 
 zfautocheck
 
-for loc in $*; do
-  rem=${loc:t}
-  zftp put $rem <$loc
-  [[ $? == 0 ]] || stat=$?
-done
+zfput_sub() {
+  local subdirs loc rem
+  integer stat
+  subdirs=()
+
+  for loc in $*; do
+    if [[ -n $opt_r ]]; then
+      if [[ -d $loc ]]; then
+	subdirs=($subdirs $loc)
+	continue
+      else
+	rem=$loc
+      fi
+    else
+      rem=${loc:t}
+    fi
+
+    zftp put $rem <$loc
+    (( $? )) && stat=$?
+    if ! zftp test; then
+      abort=1
+      (( stat )) || stat=1
+      break;
+    fi
+  done
+
+  while (( $#subdirs  && ! abort )); do
+    zftp mkdir ${subdirs[1]}
+    zfput_sub ${subdirs[1]}/*(ND)
+    (( $? )) && stat=$?
+    shift subdirs
+  done
+
+  return $stat
+}
+
+zfput_sub $*
+stat=$?
 
 (( $do_close )) && zfclose
 
--- Functions/Zftp/zfsession.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfsession	Wed Dec 15 18:31:06 1999
@@ -3,6 +3,7 @@
 
 emulate -L zsh
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfsession:
 local opt opt_l opt_v opt_o opt_d hadopts
 
 while getopts ":lovd" opt; do
--- Functions/Zftp/zfstat.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfstat	Wed Dec 15 18:31:06 1999
@@ -6,6 +6,7 @@
 setopt localoptions unset
 unsetopt ksharrays
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfstat:
 local i stat=0 opt opt_v
 
 while getopts :v opt; do
--- Functions/Zftp/zftp_chpwd.zf	Fri Dec 10 19:48:30 1999
+++ Functions/Zftp/zftp_chpwd	Wed Dec 15 18:31:06 1999
@@ -22,14 +22,13 @@
   zfconfig[lastdir_$ZFTP_SESSION]=
 
   # return the display to standard
-  # uncomment the following line if you have a chpwd which shows directories
-  chpwd
+  zstyle -t ":zftp$curcontext" chpwd && chpwd
 else
   [[ -n $ZFTP_PWD ]] && zfconfig[lastdir_$ZFTP_SESSION]=$ZFTP_PWD
   zfconfig[lastloc_$ZFTP_SESSION]="$ZFTP_HOST:$ZFTP_PWD"
   zfconfig[lastuser_$ZFTP_SESSION]="$ZFTP_USER"
   local args
-  if [[ -t 1 && -t 2 ]]; then
+  if [[ -t 1 && -t 2 ]] && zstyle -t ":zftp$curcontext" titlebar; then
     local str=$zfconfig[lastloc_$ZFTP_SESSION]
     [[ ${#str} -lt 70 ]] && str="%m: %~  $str"
     case $TERM in
--- Functions/Zftp/zftp_progress.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zftp_progress	Wed Dec 15 18:45:56 1999
@@ -1,7 +1,7 @@
 # function zftp_progress {
 # Basic progress metre, showing the percent of the file transferred.
 # You want growing bars?  You gottem.
-# zfconfig keys:
+# styles used (context :zftp:zfparent_function:):
 #   progress
 #       empty or `none'                  no progress meter
 #       `bar'                            use a growing bar of inverse video
@@ -11,16 +11,17 @@
 #   update
 #       Minimum time in seconds between updates of the progress display.
 
-# Don't show progress unless stderr is a terminal
-[[ ! -t 2 || ${zfconfig[progress]} = (|none) ]] && return 0
+local style update=1
 
-# Tunable parameters.
-# How many seconds to wait before printing an updated progress report.
-integer update=${zfconfig[update]:-1}
 # What style: either bar for growing bars, or anything else for simple
 # percentage.  For bar we need to have the terminal width in COLUMNS,
 # which is often set automatically, but you never know.
-local style=${zfconfig[progress]}
+zstyle -s ":zftp$curcontext" progress style
+# How many seconds to wait before printing an updated progress report.
+zstyle -s ":zftp$curcontext" update update
+
+# Don't show progress unless stderr is a terminal
+[[ ! -t 2 || $style = (|none) ]] && return 0
 
 if [[ -n $ZFTP_TRANSFER ]]; then
   # avoid a `parameter unset' message
--- Functions/Zftp/zftransfer.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zftransfer	Wed Dec 15 18:46:09 1999
@@ -4,6 +4,7 @@
 
 emulate -L zsh
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zftransfer:
 local sess1 sess2 file1 file2 oldsess=${ZFTP_SESSION}
 
 if [[ $# -ne 2 ]]; then
@@ -39,7 +40,9 @@
 # the size from the pipe --- and if it does, it's probably wrong.
 # To avoid that, try to get the size and set it for the progress to
 # see.
-if [[ $zfconfig[progress] != none ]]; then
+local style
+zstyle -s ':zftp:zftransfer:' progress style
+if [[ -n $style && $style != none ]]; then
   local ZFTP_TSIZE array tmpfile=${TMPPREFIX}zft$$
   zftp remote $file1 >$tmpfile 2>/dev/null
   array=($(<$tmpfile))
@@ -49,7 +52,7 @@
 
 # We do the RHS of the pipeline in a subshell, too, so that
 # the LHS can get SIGPIPE when it exits.
-{ zfconfig[progress]=none
+{ zstyle '*' progress none
   zftp get $file1 } |
 ( zftp session $sess2
   zfautocheck && zftp put $file2 )
--- Functions/Zftp/zftype.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zftype	Wed Dec 15 18:31:06 1999
@@ -1,5 +1,6 @@
 # function zftype {
 local type zftmp=${TMPPREFIX}zftype$$
+[[ $curcontext = :zf*: ]] || local curcontext=:zftype:
 
 zfautocheck -d
 
--- Functions/Zftp/zfuget.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfuget	Wed Dec 15 18:31:06 1999
@@ -25,6 +25,7 @@
 
 emulate -L zsh
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfuget:
 local loc rem locstats remstats doit tmpfile=${TMPPREFIX}zfuget$$
 local rstat remlist opt opt_v opt_s opt_G opt_t
 integer stat do_close
--- Functions/Zftp/zfuput.zf	Sun Nov 28 17:42:27 1999
+++ Functions/Zftp/zfuput	Wed Dec 15 18:31:06 1999
@@ -11,6 +11,7 @@
 
 emulate -L zsh
 
+[[ $curcontext = :zf*: ]] || local curcontext=:zfuput:
 local loc rem locstats remstats doit tmpfile=${TMPPREFIX}zfuput$$
 local rstat opt opt_v opt_s
 integer stat do_close
-- 
Peter Stephenson <pws@xxxxxxxxxxxxxxxxxxxxxxxx>



Messages sorted by: Reverse Date, Date, Thread, Author