# This function is designed to do a poor person's automount in # the user space, typically of a sshfs file system as this is # entirely controlled by the user. # # Return 0 if the path is available, possibly after mounting, 1 if # it is still not available at the end of the function. # # The style mount-path in context :chpwd: is set to an array of pairs of # paths and URL-style references looking like # # /local/dir method:path-to-dir # # If the argument to the function is a path that doesn't exist, the # system checks to see if the path is under /local/dir.  If, so the # other element of the pair is examined.  If "method" is a known method # for moutning the remote path path-to-dir the path, it is mounted and # the function returns success. # # Currently the only method knonwn is sshfs, in which case path-to-dir # is a standard ssh path e.g. "rhost:/home/mydir".  Mounting is done # simply: "sshfs -o workaround=rename path-to_dir /local/dir".  This # may become more configurable in future.  It is assumed the user # has an appropriate ssh agent running, else the call may prompt for # login info at an unexpected place. # # Does not currently handle (the unusual case of) recursive mounts, # i.e. /local/dir and /local/dir/under/that does not handle the second case. # # The return status is 0 if the path exists; 1 if it does not exist # (even if a mount was made in an attempt to provide it); 2 if some # condition other than a missing directory was found, in particular # bad zstyle configuration or an sshfs failure. emulate -L zsh setopt extendedglob cbases # Nothing to if path exists. # # We'll allow the path to be something other than a directory as we # are in any case going to check prefixes. if [[ -e $1 ]]; then   if [[ -d $1 ]]; then     # As this may be the mount point itself, we'll assume it     # should be non-empty, though we don't know for sure.     local -a files     files=($1/*(DN))     (( ${#files} )) && return 0   else     # Not a directory, so assume everything is OK.     return 0   fi fi local -a match mbegin mend local dir if [[ $1 = /* ]]; then   dir="$1" else   # Hmm... We can't use (:a) or (:A) as the path doesn't yet exist in   # the file system.  We'll just bang it on the end of $PWD..   # It's not clear whether we should remove symbolic links from   # $PWD as we don't know whether the user has or has not rationalised   # the zstyle accordingly.   dir="$PWD/$1"   # Rationalise ..'s --- a bit naive, but hopefully good enough...   while [[ $dir = (#b)(*/)([^/]##)/..(/*|) ]]; do     dir="$match[1]${match[3]##/}"   done   dir=${dir%%/#} fi local -a mpath # If no directories we could mount, fail silently zstyle -a ':chpwd:' mount-path mpath || return 1 local locdir remote mpoint for locdir remote in $mpath; do   # To be clever here we would look for the shortest matching path   # and work our way down.   if [[ $dir = ${locdir%%:*}(|/*) ]]; then     mpoint=${locdir#*:}     case $remote in       ((#b)sshfs:(*))       if ! sshfs -o workaround=rename $match[1] $mpoint; then         # Bad mount: it probably complained, but let's be clear. print "$0: attempt to mount $remote for $locdir failed." >&2 return 2       fi       # Success / failure depending on whether path is now provided.       # To be clever (see above) could loop further.       [[ -e $dir ]]       ;;       (*)       # Incorrect configuration, so return noisily.       print "$0: method ${remote%%:*} not handled" >&2       return 2       ;;     esac   fi done # Final test in case we found something that might be a mount point. # If we couldn't mount it but this is the directory being referred to, # assume it's OK. [[ -e $dir ]]