mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-10-31 18:10:56 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			505 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			505 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| #compdef darcs
 | |
| 
 | |
| # EXTENDED_GLOB is required fr pattern backreferences.
 | |
| setopt EXTENDED_GLOB
 | |
| 
 | |
| local DARCS=$words[1]
 | |
| 
 | |
| # test whether to hide short options from completion
 | |
| autoload is-at-least
 | |
| local hide_short
 | |
| if zstyle -s ":completion:${curcontext}" hide-shortopts hide_short; then
 | |
|   case $hide_short in
 | |
|     true|yes|on|1) hide_short='!' ;;
 | |
|     *) hide_short='' ;;
 | |
|   esac
 | |
| else
 | |
|   is-at-least 4.1 || hide_short='!'
 | |
| fi
 | |
| 
 | |
| 
 | |
| 
 | |
| _darcs_main() {
 | |
| # Based on section 6.8 of _A User's Guide to the Z-Shell_ by Peter Stephenson.
 | |
| # Also based on the tla completion module by Jason McCarty. How do I credit
 | |
| # this?
 | |
| local DARCS=$words[1]
 | |
| local arguments
 | |
| local curcontext="$curcontext"
 | |
| 
 | |
| if (( CURRENT > 2 )); then
 | |
|     local cmd=${words[2]}
 | |
|     local var_cmd=cmd_${cmd//-/_}
 | |
|     curcontext="${curcontext%:*:*}:darcs-${cmd}:"
 | |
|     (( CURRENT-- ))
 | |
|     shift words
 | |
| 
 | |
|     local short long arg desc action
 | |
|     short=()
 | |
|     long=()
 | |
|     arg=()
 | |
|     desc=()
 | |
|     action=()   
 | |
|     arguments=()
 | |
|     
 | |
|     # Collect all help lines which have a leading space.
 | |
|     local input
 | |
|     input=(${(f)"$($DARCS $cmd -h)"})
 | |
|     input=(${input:#[^\ ]*})
 | |
|     local i
 | |
|     for (( i=1 ; i <= ${#input} ; i++ )); do
 | |
| 	# Assumption: the the argument descriptions from `darcs cmd -h` 
 | |
| 	# have the following format:
 | |
| 	# [spaces]<-f>[spaces][--flag]<=<spaces>argument>[spaces][description]
 | |
| 	[[ "$input[i]" = (#b)' '#(-?|)' '#([^' ']#|)' '#(--[^=' ']#)(=([^' ']#)|)' '#(*) ]] \
 | |
| 		|| _message -e messages "cannot parse command help output." || return 1
 | |
| 
 | |
| 	short[i]="$match[1]"
 | |
| 	long[i]="$match[3]"
 | |
| 	arg[i]="$match[5]"
 | |
| 	desc[i]="$match[6]"
 | |
| 	desc[i]="${${desc[i]//\[/\\[}//\]/\\]}" # escape brackets	
 | |
| 
 | |
| 	case $arg[i] in
 | |
| 	DIRECTORY)
 | |
| 	  action[i]='_files -/' ;;
 | |
| 	FILE|FILENAME|IDFILE|KEYS)
 | |
| 	  action[i]='_files' ;;
 | |
| 	USERNAME)
 | |
| 	  action[i]='_users' ;;
 | |
| 	EMAIL|FROM)
 | |
| 	  action[i]='_email_addresses' ;;
 | |
| 	*)
 | |
|  	  action[i]='' ;;
 | |
|  	esac
 | |
|     done
 | |
|     
 | |
|     # Compute the exludes for _arguments
 | |
| 
 | |
|     local excluded short_excluded long_excluded k
 | |
| 
 | |
|     for (( i=1 ; i <= ${#input} ; i++ )); do
 | |
| 	excluded=()
 | |
| 	for opt (${=excludes[$long[i]]}); do
 | |
| 	    k=$long[(i)$opt]
 | |
| 	    excluded=($excluded $short[k] $long[k])
 | |
| 	done
 | |
| 
 | |
| 	# Generate arguments for _arguments.
 | |
| 	# Make long and short options mutually exclusive.
 | |
| 	short_excluded=($long[i] $excluded)
 | |
| 	long_excluded=($short[i] $excluded)
 | |
| 	[ $short[i] ] && arguments=("$arguments[@]"
 | |
| 	    "${hide_short}(${short_excluded})${short[i]}[${desc[i]}]${arg[i]:+:$arg[i]:$action[i]}")
 | |
| 	[ $long[i] ] && arguments=("$arguments[@]"
 | |
| 	    "(${long_excluded})${long[i]}${arg[i]:+=}[${desc[i]}]${arg[i]:+:$arg[i]:$action[i]}")
 | |
|     done
 | |
| 
 | |
|     arguments=("$arguments[@]" "${(@P)var_cmd-*:FILE:_files}")
 | |
| else
 | |
|     local hline
 | |
|     local -a cmdlist
 | |
|     _call_program help-commands darcs --help | while read -A hline; do
 | |
| 	(( ${#hline} < 2 )) && continue
 | |
| 	[[ $hline[1] == darcs ]] && continue
 | |
|  	[[ $hline[1] == Usage: ]] && continue
 | |
|  	[[ $hline[1] == Use ]] && continue
 | |
|  	cmdlist=( $cmdlist "${hline[1]}:${hline[2,-1]/(#b)([A-Z])(*)./${match[1]:l}$match[2]}" )
 | |
|      done
 | |
|     arguments=(':commands:(($cmdlist))')
 | |
| fi
 | |
| 
 | |
| _arguments -S -A '-*' \
 | |
|     "$arguments[@]"
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| #
 | |
| # Command argument definitions
 | |
| #
 | |
| local -a cmd_initialize cmd_get
 | |
| cmd_initialize=()
 | |
| cmd_get=(':repository:_files -/' ':new repository name:_files -/')
 | |
| 
 | |
| local -a cmd_add cmd_remove cmd_move cmd_replace
 | |
| cmd_add=('*:new files:_darcs_new_file_or_tree')
 | |
| cmd_remove=('*:existing controlled files:_darcs_controlled_files -e')
 | |
| cmd_move=('*:existing controlled files:_darcs_controlled_files -e')
 | |
| cmd_replace=(':old token:' ':new token:' '*:existing controlled files:_darcs_controlled_files -e')
 | |
| 
 | |
| local -a cmd_record cmd_pull cmd_push cmd_send cmd_apply
 | |
| cmd_record=('*:controlled files:_darcs_controlled_files')
 | |
| cmd_pull=(':repository:_darcs_repository_or_tree')
 | |
| cmd_push=(':repository:_darcs_repository_or_tree')
 | |
| cmd_send=(':repository:_darcs_repository_or_tree')
 | |
| cmd_apply=(':patch file:_files')
 | |
| 
 | |
| local -a cmd_whatsnew cmd_changes
 | |
| cmd_whatsnew=('*:controlled files:_darcs_controlled_files')
 | |
| cmd_changes=('*:controlled files:_darcs_controlled_files')
 | |
| 
 | |
| local -a cmd_tag cmd_setpref cmd_check cmd_optimize
 | |
| cmd_tag=()
 | |
| cmd_setpref=(':preference key:(test predist boringfile binaries)' ':value:_files')
 | |
| cmd_check=()
 | |
| cmd_optimize=()
 | |
| 
 | |
| local -a cmd_amend_record cmd_rollback cmd_unrecord cmd_unpull cmd_revert cmd_unrevert
 | |
| cmd_amend_record=('*:controlled files:_darcs_controlled_files')
 | |
| cmd_rollback=()
 | |
| cmd_unrecord=()
 | |
| cmd_unpull=()
 | |
| cmd_revert=('*:controlled files:_darcs_controlled_files')
 | |
| cmd_unrevert=()
 | |
| 
 | |
| local -a cmd_diff cmd_annotate
 | |
| cmd_diff=('*:controlled files:_darcs_controlled_files')
 | |
| cmd_annotate=('*:controlled files:_darcs_controlled_files')
 | |
| 
 | |
| local -a cmd_resolve cmd_dist cmd_trackdown cmd_repair
 | |
| cmd_resolve=()
 | |
| cmd_dist=()
 | |
| cmd_trackdown=(':initialization:' ':command:')
 | |
| cmd_repair=()
 | |
| 
 | |
| 
 | |
| #
 | |
| # Completion functions
 | |
| #
 | |
| 
 | |
| (( $+functions[_darcs_new_files] )) ||
 | |
| _darcs_new_files () {
 | |
|     local -a new_files
 | |
|     local -a local_files
 | |
|     local in_tree_head in_tree_tail
 | |
|     _darcs_make_tree_path in_tree_head in_tree_tail || return 1
 | |
|     new_files=(${(f)"$(cd $(_darcs_absolute_tree_root)/$in_tree_head; $DARCS whatsnew -sl .)"})  
 | |
|     new_files=(${${new_files:#[^a]*}//a /})
 | |
| 
 | |
|     local_files=()
 | |
|     for file ($new_files); do
 | |
| 	[[ $file:h = $in_tree_head && $file:t = ${in_tree_tail}* ]] && local_files+=$file:t
 | |
|     done
 | |
| 
 | |
|     compset -P '*/'
 | |
|     _description new_files expl "new files"
 | |
|     compadd "$expl[@]" "$local_files[@]"
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| # _darcs_controlled_files [-e|r] [-f|d]
 | |
| #
 | |
| # Adds controlled files to the completion. Can take either
 | |
| # -e or -r as flags which respectively only add the existing
 | |
| # files or the deleted files. Can take either -f or -d which
 | |
| # respectively add only the files or directories.
 | |
| (( $+functions[_darcs_controlled_files] )) ||
 | |
| _darcs_controlled_files() {
 | |
|     local abs_root=$(_darcs_absolute_tree_root)
 | |
|     local only_removed only_existing only_files only_dirs
 | |
|     zparseopts -E \
 | |
| 	'r=only_removed' 'e=only_existing' \
 | |
| 	'f=only_files' 'd=only_dirs'
 | |
| 
 | |
|     local in_tree_head in_tree_tail
 | |
|     _darcs_make_tree_path in_tree_head in_tree_tail
 | |
|     local recorded_dir="$abs_root/_darcs/current/$in_tree_head"
 | |
|     local -a controlled_files controlled_dirs existing_files existing_dirs 
 | |
|     local -a dir_display_strs removed_dir_display_strs
 | |
|     controlled_files=${(z)$(print $recorded_dir/$in_tree_tail*(.:t))}
 | |
|     controlled_dirs=${(z)$(print $recorded_dir/$in_tree_tail*(/:t))}
 | |
|     existing_files=() existing_dirs=()
 | |
|     removed_files=() removed_dirs=() 
 | |
|     dir_display_strs=() removed_dir_display_strs=()
 | |
|     local dir file
 | |
|     for dir ($controlled_dirs); do
 | |
| 	if [[ -e $abs_root/$in_tree_head/$dir ]]; then
 | |
| 	    existing_dirs+="$dir"
 | |
| 	    dir_display_strs+="$dir/"	
 | |
| 	else
 | |
| 	    removed_dirs+="$dir"
 | |
| 	    removed_dir_display_strs+="$dir/"
 | |
| 	fi
 | |
|     done
 | |
|     for file ($controlled_files); do
 | |
| 	if [[ -e $abs_root/$in_tree_head/$file ]]; then
 | |
| 	    existing_files+="$file"
 | |
| 	else
 | |
| 	    removed_files+="$file"
 | |
| 	fi
 | |
|     done
 | |
| 
 | |
|     compset -P '*/'
 | |
|     if (( ! ${#only_removed} )); then 
 | |
| 	_description controlled_files expl "existing revision controlled files"
 | |
| 	(( ! ${#only_dirs} )) && compadd "$expl[@]" $existing_files
 | |
| 	(( ! ${#only_files} )) \
 | |
| 	    && compadd "$expl[@]" -q -S / -d dir_display_strs -a -- existing_dirs
 | |
|     fi
 | |
|     if (( ! ${#only_existing} )); then
 | |
| 	_description removed_files expl "removed revision controlled files"
 | |
| 	(( ! ${#only_dirs} )) && compadd "$expl[@]" $removed_files
 | |
| 	(( ! ${#only_files} )) \
 | |
| 	    && compadd "$expl[@]" -q -S / -d removed_dir_display_strs -a -- removed_dirs
 | |
|     fi
 | |
| }
 | |
| 
 | |
| (( $+functions[_darcs_repositories] )) ||
 | |
| _darcs_repositories() {
 | |
|     local local_repos_path="$(_darcs_absolute_tree_root)/_darcs/prefs/repos"
 | |
|     local global_repos_path="$HOME/.darcs/repos"
 | |
|     local -a local_repos global_repos
 | |
|     local -a global_repos
 | |
|     [[ -e $local_repos_path ]] && cat $local_repos_path | read -A local_repos
 | |
|     [[ -e $global_repos_path ]] && cat $global_repos_path | read -A global_repos
 | |
|     local_repos=${local_repos:# #}
 | |
|     global_repos=${global_repos:# #}
 | |
|     _description repositories expl "repositories"
 | |
|     (( ${#local_repos} )) && compadd "$expl[@]" -- "$local_repos[@]"
 | |
|     (( ${#global_repos} )) && compadd "$expl[@]" -- "$global_repos[@]"
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| # Combination completion functions
 | |
| 
 | |
| (( $+functions[_darcs_new_file_or_tree] )) ||
 | |
| _darcs_new_file_or_tree() {
 | |
|     local base_dir=$( cd ${$(_darcs_repodir):-.}; pwd -P)
 | |
|     [[ -z $(_darcs_absolute_tree_root $base_dir) ]] && return 1
 | |
|     local -a ignored_files
 | |
|     ignored_files=(_darcs)
 | |
|     _alternative 'newfiles:new file:_darcs_new_files' \
 | |
| 		 "directories:tree:_path_files -/ -W$base_dir -Fignored_files"
 | |
| }
 | |
| 
 | |
| (( $+functions[_darcs_repository_or_tree] )) ||
 | |
| _darcs_repository_or_tree() {
 | |
|     local -a ignored_files
 | |
|     ignored_files=(_darcs)
 | |
|     _alternative 'repository:repository:_darcs_repositories' \
 | |
| 		 "directories:directories:_path_files -/ -Fignored_files"
 | |
| }
 | |
| 
 | |
| 
 | |
| #
 | |
| # Mutually exclusive options 
 | |
| #
 | |
| 
 | |
| typeset -A excludes
 | |
| excludes=(
 | |
| # Output
 | |
|     --summary                     '--no-summary'
 | |
|     --no-summary                  '--summary'
 | |
|     --context                     '          --xml-output --human-readable --unified'
 | |
|     --xml-output                  '--context              --human-readable --unified'
 | |
|     --human-readable              '--context --xml-output                  --unified'
 | |
|     --unified                     '--context --xml-output --human-readable          '
 | |
| 
 | |
| # Verbosity
 | |
|     --verbose                     '          --quiet --standard-verbosity'
 | |
|     --quiet                       '--verbose         --standard-verbosity'
 | |
|     --standard-verbosity          '--verbose --quiet                     '
 | |
| 
 | |
| # Traversal
 | |
|     --recursive                   '--not-recursive'
 | |
|     --not-recursive               '--recursive'
 | |
|     --look-for-adds               '--dont-look-for-adds'
 | |
|     --dont-look-for-adds          '--look-for-adds'
 | |
| 
 | |
| # Pattern
 | |
|     --from-match                  '             --from-patch --from-tag'
 | |
|     --from-patch                  '--from-match              --from-tag'
 | |
|     --from-tag                    '--from-patch --from-match           '
 | |
|     --to-match                    '           --to-patch -to-tag'
 | |
|     --to-patch                    '--to-match            -to-tag'
 | |
|     --to-tag                      '--to-match --to-patch        '
 | |
| 
 | |
| # Repository Properties
 | |
|     --plain-pristine-tree         '--no-pristine-tree'
 | |
|     --no-pristine-tree            '--plain-pristine-tree'
 | |
|     --parial                      '--complete'
 | |
|     --complete                    '--partial'
 | |
|     --compress                    '--dont-compress'
 | |
|     --dont-compress               '--compress'
 | |
|     --set-default                 '--no-set-default'
 | |
|     --no-set-default              '--set-default'
 | |
| 
 | |
| # Logs
 | |
|     --edit-long-comment           '--skip-long-comment --leave-test-directory'
 | |
|     --skip-long-comment           '--edit-long-comment --leave-test-directory'
 | |
|     --prompt-long-comment         '--edit-long-comment --skip-long-comment'
 | |
| 
 | |
| # Security
 | |
|     --sign                        '       --sign-as --sign-ssl --dont-sign'
 | |
|     --sign-as                     '--sign           --sign-ssl --dont-sign'
 | |
|     --sign-ssl                    '--sign --sign-as            --dont-sign'
 | |
|     --dont-sign                   '--sign --sign-as --sign-ssl            '
 | |
|     --verify                      '         --verify-ssl --no-verify'
 | |
|     --verify-ssl                  '--verify              --no-verify'
 | |
|     --no-verify                   '--verify --verify-ssl            '
 | |
|     --apply-as                    '--apply-as-myself'
 | |
|     --apply-as-myself             '--apply-as'
 | |
| 
 | |
| # Conflicts
 | |
|     --mark-conflicts              '--allow-conflicts --no-resolve-conflicts --dont-allow-conflicts'
 | |
|     --allow-conflicts             '--mark-conflicts --no-resolve-conflicts --dont-allow-conflicts'
 | |
|     --no-resolve-conflicts        '--mark-conflicts --allow-conflicts --dont-allow-conflicts'
 | |
|     --dont-allow-conflicts        '--mark-conflicts --allow-conflicts --no-resolve-conflicts '
 | |
| 
 | |
| # Test
 | |
|     --test                        '--no-test'
 | |
|     --no-test                     '--test'
 | |
|     --leave-test-directory        '--remove-test-directory'
 | |
|     --remove-test-directory       '--leave-test-directory'
 | |
| 
 | |
| # Misc
 | |
|     --force                       '--no-force'
 | |
|     --no-force                    '--force'
 | |
|     --ask-deps                    '--no-ask-deps'
 | |
|     --no-ask-deps                 '--ask-deps'
 | |
|     --date-trick                  '--no-date-trick'
 | |
|     --no-date-trick               '--date-trick'
 | |
|     --set-scripts-executable      '--dont-set-scripts-executable'
 | |
|     --dont-set-scripts-executable '--set-scripts-executable'
 | |
| )
 | |
| 
 | |
| 
 | |
| 
 | |
| #
 | |
| # Utility functions
 | |
| #
 | |
| 
 | |
| # _darcs_make_tree_path in_tree_head_name in_tree_tail_name path
 | |
| # Set in_tree_head_name in_tree_tail_name to the corresponding path
 | |
| # parts from inside the current darcs tree.
 | |
| _darcs_make_tree_path () {
 | |
|     [[ -z $3 || $3 = '.' ]] && 3=${PREFIX:-./}
 | |
|     local _in_tree=$(_darcs_path_from_root ${$(_darcs_repodir):-.}/$3)
 | |
|     [[ -z $_in_tree ]] && return 1
 | |
|     4='' 5=''
 | |
|     if [[ ${3[-1]} = / ]]; then 
 | |
| 	4=$_in_tree
 | |
|     else
 | |
| 	4=$_in_tree:h
 | |
| 	[[ $_in_tree:t != . ]] && 5=$_in_tree:t
 | |
|     fi
 | |
|     set -A "$1" "$4"
 | |
|     set -A "$2" "$5"
 | |
| }
 | |
| 
 | |
| _darcs_repodir () {
 | |
|     local index=$words[(i)--repodir*]
 | |
|     if (( index < CURRENT )); then
 | |
| 	if [[ $words[$index] = --repodir ]]; then
 | |
| 	    (( index++ ))
 | |
| 	    print $words[$index]
 | |
| 	else
 | |
| 	    print ${words[$index]#*=}
 | |
| 	fi
 | |
|     fi
 | |
| }
 | |
| 
 | |
| _darcs_absolute_tree_root () {
 | |
|     local root=$(_darcs_repodir)
 | |
|     [[ -z $root ]] && root=$(pwd -P)
 | |
|     while [[ ! $root -ef / ]]; do
 | |
| 	[[ -d $root/_darcs ]] && break
 | |
| 	root="$root/.."
 | |
|     done
 | |
|     [[ $root -ef / ]] || print $(cd $root; pwd -P)
 | |
| }
 | |
| 
 | |
| _darcs_tree_root () {
 | |
|     local abs=$(_darcs_absolute_tree_root)
 | |
|     local rel=$(_darcs_relative_path $abs $(pwd -P))
 | |
|     [[ -n $abs ]] && print $rel
 | |
| }
 | |
| 
 | |
| # _darcs_paths_from_root name paths
 | |
| # Sets name to the paths relative to the darcs tree root.
 | |
| # If no argument is given then the current directory
 | |
| # is assumed.
 | |
| _darcs_paths_from_root () {
 | |
|     local name=$1
 | |
|     abs=$(_darcs_absolute_tree_root)
 | |
|     [[ -z $abs ]] && set -A "$name" && return 1
 | |
|     shift
 | |
|     1=${1:=$PWD}
 | |
|     local -a subpaths
 | |
|     _darcs_filter_for_subpaths subpaths $abs $*
 | |
|     local i
 | |
|     for (( i=1; i<=${#subpaths}; i++ )); do
 | |
| 	[[ $subpaths[$i] != '.' ]] && subpaths[$i]="./$subpaths[$i]"
 | |
|     done
 | |
|     set -A "$name" "$subpaths[@]"
 | |
| }
 | |
| 
 | |
| _darcs_path_from_root() {
 | |
|     local path
 | |
|     _darcs_paths_from_root path $1
 | |
|     [[ -n $path ]] && print "$path"
 | |
| }
 | |
| 
 | |
| # _darcs_filter_for_in_dir name dir paths
 | |
| # Sets name to the relative paths from dir to the given paths which 
 | |
| # traverse dir. It ignores paths which are not in dir.
 | |
| _darcs_filter_for_subpaths () {
 | |
|     local name=$1 dir=$2 
 | |
|     shift 2
 | |
|     local p rel
 | |
|     local -a accepted_paths 
 | |
|     accepted_paths=()
 | |
|     for p; do
 | |
| 	rel=$(_darcs_path_difference $p $dir)
 | |
| 	[[ -n $rel ]] && accepted_paths+="$rel"
 | |
|     done
 | |
|     set -A "$name" "$accepted_paths[@]"
 | |
| }
 | |
| 
 | |
| # _darcs_path_difference p1 p2
 | |
| # Print the path from p2 to p1. If p2 is not an ancestor of p1 then it 
 | |
| # prints a blank string. If they point to the same directory then it returns
 | |
| # a single period. p2 needs to be a directory path.
 | |
| _darcs_path_difference () {
 | |
|     local diff=$(_darcs_relative_path $1 $2)
 | |
|     [[ ${diff%%/*} != .. ]] && print $diff || return 1
 | |
| }
 | |
| 
 | |
| 
 | |
| # Print the a relative path from the second directory to the first,
 | |
| # defaulting the second directory to $PWD if none is specified.
 | |
| # Taken from the zsh mailing list.
 | |
| _darcs_relative_path () {
 | |
|     2=${2:=$PWD}
 | |
|     [[ -d $2 && -d $1:h ]] || return 1
 | |
|     [[ ! -d $1 ]] && 3=$1:t 1=$1:h
 | |
|     1=$(cd $1; pwd -P)
 | |
|     2=$(cd $2; pwd -P)
 | |
|     [[ $1 -ef $2 ]] && print ${3:-.} && return
 | |
| 
 | |
|     local -a cur abs
 | |
|     cur=(${(s:/:)2})        # Split 'current' directory into cur
 | |
|     abs=(${(s:/:)1} $3)     # Split target directory into abs
 | |
| 
 | |
|     # Compute the length of the common prefix, or discover a subdiretory:
 | |
|     integer i=1
 | |
|     while [[ i -le $#abs && $abs[i] == $cur[i] ]]
 | |
|     do
 | |
| 	((++i > $#cur)) && print ${(j:/:)abs[i,-1]} && return
 | |
|     done
 | |
| 
 | |
|     2=${(j:/:)cur[i,-1]/*/..}       # Up to the common prefix directory and
 | |
|     1=${(j:/:)abs[i,-1]}            # down to the target directory or file
 | |
| 
 | |
|     print $2${1:+/$1}
 | |
| }
 | |
| 
 | |
| # Code to make sure _darcs is run when we load it
 | |
| _darcs_main "$@"
 | |
| 
 | |
| 
 | |
| 
 |