about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--Completion/Unix/Command/_darcs533
2 files changed, 39 insertions, 501 deletions
diff --git a/ChangeLog b/ChangeLog
index e006e634d..565ba3543 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-07-02  Peter Stephenson  <pws@csr.com>
+
+	* Nicolas Pouillard: 27028: Completion/Unix/Command/_darcs: New
+	darcs completion; it's a lot shorter but apparently that's OK.
+
 2009-07-01  Peter Stephenson  <pws@csr.com>
 
 	* 27085: Doc/Zsh/mod_complist.yo, Src/Zle/complist.c:
@@ -11890,5 +11895,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4724 $
+* $Revision: 1.4725 $
 *****************************************************
diff --git a/Completion/Unix/Command/_darcs b/Completion/Unix/Command/_darcs
index 1d3414e45..d40ecda28 100644
--- a/Completion/Unix/Command/_darcs
+++ b/Completion/Unix/Command/_darcs
@@ -1,503 +1,36 @@
 #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 -z 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' ;;
-	URL)
-	  action[i]='_darcs_repository_or_tree' ;;
-	*)
- 	  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}")
+## Darcs completion snippet for zsh.
+##
+## Copyright (C) 2009  Nicolas Pouillard
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+
+if (($CURRENT == 2)); then
+  # We're completing the first word after "darcs" -- the command.
+  _wanted command expl 'darcs command' \
+    compadd -- $( darcs --commands )
 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] == [A-Z]* ]] && continue
- 	cmdlist=( $cmdlist "${hline[1]}:${hline[2,-1]/(#b)([A-Z])(*)./${match[1]:l}$match[2]}" )
-     done
-    arguments=(':commands:(($cmdlist))')
+  case "${words[$CURRENT]}"; in
+    # If it looks like an URL...
+    ht*|ft*)
+        _arguments '*:URL:_urls'
+        ;;
+    # If it looks like an explicit path...
+    /*|./*|\~*|../*)
+        _arguments '*:file:_files'
+        ;;
+    # Otherwise, let's ask darcs for all possible options
+    *)
+      _wanted args expl 'arg for darcs command' \
+        compadd -- $( darcs ${words[2]} --list-option )
+      ;;
+  esac
 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
-  [[ -e $local_repos_path ]] && local_repos=( $(<$local_repos_path) )
-  [[ -e $global_repos_path ]] && global_repos=( $(<$global_repos_path) )
-  _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 "$@"
-
-
-