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

PATCH: pws-21: bookmarks for zftp functions



This implements the zfmark and zfgoto functions which allow you to set a
bookmark at user@host:directory location when using the zftp functions.
zfgoto -n allows you to use ncftp bookmarks, at least assuming the format
and location my version of ncftp has for its bookmark file.  Old and new
completion for both types is implemented.  If anyone wants to add .netrc
support, feel free.

I could have made zfopen and zfanon default to zfgoto if they failed, but
I'd rather the user knew which command to use in the first place.

Also a couple of tweaks:  autoload statements for the zftp functions now
appear in zfinit, in case only zfinit was autoloaded; the test for
$_patcomps didn't have the underscore.

I bet I've missed something.

--- Completion/Builtins/_zftp.mk	Fri Jun 11 18:28:12 1999
+++ Completion/Builtins/_zftp	Fri Jun 11 18:26:26 1999
@@ -43,6 +43,19 @@
   compgen -k hosts
   ;;
 
+  *(goto|mark))
+  # complete bookmarks.  First decide if ncftp mode is go.
+  if [[ $words[2] = -*n* ]]; then
+    if [[ -f ~/.ncftp/bookmarks ]]; then
+      compadd - $(awk -F, 'NR > 2 { print $1 }' ~/.ncftp/bookmarks)
+    fi
+  else
+    if [[ -f ${ZFTP_BMFILE:=${ZDOTDIR:-$HOME}/.zfbkmarks} ]]; then
+      compadd - $(awk '{print $1}' $ZFTP_BMFILE)
+    fi
+  fi
+  ;;
+
   *)
   # dunno... try ordinary completion after all.
   unset _compskip
--- Doc/Zsh/zftpsys.yo.mk	Wed Jun  2 13:24:40 1999
+++ Doc/Zsh/zftpsys.yo	Fri Jun 11 18:38:37 1999
@@ -45,21 +45,24 @@
 directory of the source distribution are available; they all begin with the
 two letters `tt(zf)'.  They may already have been installed on your system;
 otherwise, you will need to find them and copy them.  The directory should
-appear as one of the elements of the tt($fpath) array, and the functions
-should be autoloaded.  Finally, to initialise the use of the system you
-need to call the tt(zfinit) function.  The following code in your
-tt(.zshrc) will arrange for this; assume the functions are stored in the
-directory tt(~/myfns):
+appear as one of the elements of the tt($fpath) array (this should already
+be the case if they were installed), and at least the function tt(zfinit)
+should be autoloaded; it will autoload the rest.  Finally, to initialise
+the use of the system you need to call the tt(zfinit) function.  The
+following code in your tt(.zshrc) will arrange for this; assume the
+functions are stored in the directory tt(~/myfns):
 
 tt(indent(
 nofill(fpath=(~/myfns $fpath))
-nofill(autoload ~/myfns/zf*(:t))
+nofill(autoload zfinit)
 nofill(zfinit)
 ))
 
 Note that tt(zfinit) assumes you are using the tt(zmodload) method to
 load the tt(zftp) command.  If it is already built into the shell, change
-tt(zfinit) to tt(zfinit -n).
+tt(zfinit) to tt(zfinit -n).  It is helpful (though not essential) if the
+call to tt(zfinit) appears after any code to initialise the new completion
+system, else unnecessary tt(compctl) commands will be given.
 
 texinode(Zftp Functions)(Miscellaneous Features)(Installation)(Zftp Function System)
 sect(Functions)
@@ -281,6 +284,41 @@
 )
 enditem()
 
+subsect(Bookmarks)
+The two functions tt(zfmark) and tt(zfgoto) allow you to `bookmark' the
+present location (host, user and directory) of the current FTP connection
+for later use.  The file to be used for storing and retrieving bookmarks is
+given by the parameter tt($ZFTP_BMFILE); if not set when one of the two
+functions is called, it will be set to the file tt(.zfbfmarks) in the
+directory where your zsh startup files live (usually tt(~)).
+
+startitem()
+item(tt(zfmark [ )var(bookmark)tt( ]))(
+If given an argument, mark the current host, user and directory under the
+name var(bookmark) for later use by tt(zfgoto).  If there is no connection
+open, use the values for the last connection immediately before it was
+closed; it is an error if there is none.  Any existing bookmark
+under the same name will be silently replaced.
+
+If not given an argument, list the existing bookmarks and the points to
+which they refer in the form var(user)tt(@)var(host)tt(:)var(directory).
+)
+item(tt(zfgoto [ -n ] )var(bookmark))(
+Return to the location given by var(bookmark), as previously set by
+tt(zfmark).  If the location has user `tt(ftp)' or `tt(anonymous)', open
+the connection with tt(zfanon), so that no password is required.  If the
+user and host parameters match those currently stored, those will be used,
+and again no password is required.  Otherwise a password will be prompted
+for.
+
+With the option tt(-n), the bookmark is taken to be a nickname stored by
+the tt(ncftp) program in its bookmark file, which is assumed to be
+tt(~/.ncftp/bookmarks).  The function works identically in other ways.
+Note that there is no mechanism for adding or modifying tt(ncftp) bookmarks
+from the zftp functions.
+)
+enditem()
+
 subsect(Other functions)
 Mostly, these functions will not be called directly (apart from
 tt(zfinit)), but are described here for completeness.  You may wish to
@@ -427,9 +465,9 @@
 
 subsect(Completion)
 
-Completion of remote files and directories is supported.  The older,
-tt(compctl)-style completion is defined when tt(zfinit) is called; support
-for the new widget-based completion system is provided in the function
-tt(Completion/Builtins/_zftp), which should be installed with the other
-functions of the completion system and hence should automatically be
+Completion of remote files, directories and bookmarks is supported.  The
+older, tt(compctl)-style completion is defined when tt(zfinit) is called;
+support for the new widget-based completion system is provided in the
+function tt(Completion/Builtins/_zftp), which should be installed with the
+other functions of the completion system and hence should automatically be
 available.
--- Functions/Zftp/zfgoto.mk	Fri Jun 11 17:55:33 1999
+++ Functions/Zftp/zfgoto	Fri Jun 11 17:55:19 1999
@@ -0,0 +1,86 @@
+# zfgoto bname
+# Go to bookmark bname, a location on a remote FTP host.  Unless
+# this was the last session or is for anonymous FTP, prompt for
+# the user's password.
+
+emulate -L zsh
+setopt extendedglob
+
+# Set ZFTP_BMFILE if not already set.  This should agree with
+# the corresponding line in zfmark.
+: ${ZFTP_BMFILE:=${ZFDOTDIR:-$HOME}/.zfbkmarks}
+
+typeset -A bkmarks
+local line ncftp opt optlist
+
+while [[ $1 == -* ]]; do
+  if [[ $1 == - || $1 == -- ]]; then
+    shift;
+    break;
+  fi
+  optlist=${1#-}
+  for (( i = 1; i <= $#optlist; i++)); do
+    opt=$optlist[$i]
+    case $opt in
+      n) ncftp=1
+	 ;;
+      *) print option $opt not recognised >&2
+	 return 1
+	 ;;
+    esac
+  done
+  shift
+done
+
+if (( $# != 1 )); then
+  print "Usage: zfgoto bookmark" >&2
+  return 1
+fi
+
+if [[ -n $ncftp && -f ~/.ncftp/bookmarks ]]; then
+  local oldifs=$IFS
+  IFS=,
+  while read -rA line; do
+    bkmarks[$line[1]]="${line[3]:-anonymous}@${line[2]}:${line[6]}"
+  done < ~/.ncftp/bookmarks
+  IFS=$oldifs
+elif [[ -f $ZFTP_BMFILE ]]; then
+  # read in file:  could optimise this by recording last read time
+  # comparing with file
+  while read -r line; do
+    # ignore blank and comment lines
+    [[ $line = [[:blank:]]# || $line = [[:blank:]]#'#'* ]] && continue
+    bkmarks[${line%% *}]="${line#* }"
+  done <$ZFTP_BMFILE
+fi
+
+line=${bkmarks[$1]}
+
+if [[ -z $line ]]; then
+  print "Bookmark \`$1' not found" >&2
+  return 1
+fi
+
+local user host dir
+user=${line%%@*}
+line=${line#*@}
+host=${line%%:*}
+dir=${line#*:}
+
+if [[ $user = ftp || $user = anonymous ]]; then
+  # Anonymous ftp, so we don't need password etc.
+  zfanon $host && [[ -n $dir ]] && zfcd $dir
+elif [[ $zflastsession = ${host}:* && $user = $zflastuser ]]; then
+  # This was the last session, so assume it's still setup in the
+  # open parameters
+  zfopen && [[ -n $dir ]] && zfcd $dir
+else
+  # Last try: see if it's in the parameters.
+  local params
+  params=($(zftp params))
+  if [[ $host = $params[1] && $user = $params[2] ]]; then
+    zfopen && [[ -n $dir ]] && zfcd $dir
+  else
+    zfopen $host $user && [[ -n $dir ]] && zfcd $dir
+  fi
+fi
--- Functions/Zftp/zfinit.mk	Fri Jun 11 18:29:44 1999
+++ Functions/Zftp/zfinit	Fri Jun 11 18:36:36 1999
@@ -1,3 +1,5 @@
+emulate -L zsh
+
 [[ $1 = -n ]] || zmodload -ia zftp
 
 alias zfcd='noglob zfcd'
@@ -6,6 +8,11 @@
 alias zfdir='noglob zfdir'
 alias zfuget='noglob zfuget'
 
+autoload -U zfanon zfautocheck zfcd zfcd_match zfcget zfclose zfcput
+autoload -U zfdir zfgcp zfget zfget_match zfgoto zfhere zfinit zfls
+autoload -U zfmark zfopen zfparams zfpcp zfput zfrglob zfrtime zfstat
+autoload -U zftp_chpwd zftp_progress zftype zfuget zfuput
+
 # only way of getting that noglob out of the way: this is unnecessary with
 # widget-based completion and can be commented out.
 setopt completealiases
@@ -14,7 +21,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 || ${_patcomps[(i)zf*]} -gt ${#_patcomps} ]]; then
   compctl -f -x 'p[1]' \
     -k '(open params user login type ascii binary mode put putat
     get getat append appendat ls dir local remote mkdir rmdir delete
@@ -25,4 +32,9 @@
   compctl -K zfcd_match -S/ -q zfcd zfdir zfls
   compctl -K zfget_match zfget zfgcp zfuget zfcget
   compctl -k hosts zfanon zfopen zfparams
+  compctl -s \
+    '$(awk '\''{print $1}'\'' ${ZFTP_BMFILE:-${ZDOTDIR:-$HOME}/.zfbkmarks})' \
+    -x 'W[1,-*n*]' \
+    -s '$(awk -F, '\''NR > 2 { print $1 }'\'' ~/.ncftp/bookmarks)' -- \
+    zfgoto zfmark
 fi
--- Functions/Zftp/zfmark.mk	Fri Jun 11 17:55:37 1999
+++ Functions/Zftp/zfmark	Fri Jun 11 17:21:31 1999
@@ -0,0 +1,49 @@
+# zfmark [bname]
+# Set a bookmark for the current zftp connection, or use the
+# information about the last session if there isn't one.
+# A bookmark includes both the host *and* the directory on that host.
+#
+# Without bname, list the current bookmarks and their locations.
+
+emulate -L zsh
+setopt extendedglob
+
+# Set ZFTP_BMFILE if not already set.  This should agree with
+# the corresponding line in zfgoto.
+: ${ZFTP_BMFILE:=${ZDOTDIR:-$HOME}/.zfbkmarks}
+
+typeset -A bkmarks
+local line
+
+if [[ -f $ZFTP_BMFILE ]]; then
+  # read in file:  could optimise this by recording last read time
+  # comparing with file
+  while read -r line; do
+    # ignore blank and comment lines
+    [[ $line = [[:blank:]]# || $line = [[:blank:]]#'#'* ]] && continue
+    bkmarks[${line%% *}]="${line#* }"
+  done <$ZFTP_BMFILE
+fi
+
+if (( $# == 0 )); then
+  for line in ${(ko)bkmarks}; do
+    print -r- "$line ${bkmarks[$line]}"
+  done
+  return 0
+elif (( $# > 1 )); then
+  print "Usage: zfmark [bookmark]" >&2
+  return 1
+fi
+
+if [[ -n $ZFTP_HOST ]]; then
+  bkmarks[$1]="${ZFTP_USER}@${ZFTP_HOST}:${ZFTP_PWD}"
+elif [[ -n $zflastsession ]]; then
+  bkmarks[$1]="${zflastuser}@${zflastsession}"
+else
+  print "No current or recent ZFTP session to bookmark." >&2
+  return 1
+fi
+
+for line in ${(ko)bkmarks}; do
+  print -r- "$line ${bkmarks[$line]}"
+done >$ZFTP_BMFILE
--- Functions/Zftp/zftp_chpwd.mk	Mon Apr 19 16:46:15 1999
+++ Functions/Zftp/zftp_chpwd	Fri Jun 11 17:21:01 1999
@@ -24,6 +24,7 @@
 else
   [[ -n $ZFTP_PWD ]] && zflastdir=$ZFTP_PWD
   zflastsession="$ZFTP_HOST:$ZFTP_PWD"
+  zflastuser="$ZFTP_USER"
   local args
   if [[ -t 1 && -t 2 ]]; then
     local str=$zflastsession

-- 
Peter Stephenson <pws@xxxxxxxxxxxxxxxxx>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy



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