summaryrefslogtreecommitdiff
path: root/Completion/Unix/Command/_darcs
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2009-07-02 09:00:45 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2009-07-02 09:00:45 +0000
commit7a1f580c036741585368086163ec24607c72c3a8 (patch)
treecf5fdba828fc03ce2bf7048baccf1b5741c20fde /Completion/Unix/Command/_darcs
parent55e4beb8d821400c3c989aa694548d5aed4a536c (diff)
downloadzsh-7a1f580c036741585368086163ec24607c72c3a8.tar.gz
zsh-7a1f580c036741585368086163ec24607c72c3a8.zip
Nicolas Pouillard: 27028: new darcs completion
Diffstat (limited to 'Completion/Unix/Command/_darcs')
-rw-r--r--Completion/Unix/Command/_darcs533
1 files changed, 33 insertions, 500 deletions
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 "$@"
-
-
-