#compdef osc # modified from _svn # reset _cache_osc_status array after use # add completion for diff # add completion for log _osc () { local curcontext="$curcontext" state line expl ret=1 _arguments -C \ '(-)--help[print help information]' \ '(- *)--version[print client version information]' \ '1: :->cmds' \ '*:: :->args' && ret=0 if [[ -n $state ]] && (( ! $+_osc_cmds )); then typeset -gHA _osc_cmds _osc_cmds=( ${=${(f)${"$(LC_ALL=C _call_program commands osc help)"#l#*Available subcommands:}}/(#s)[[:space:]]#(#b)([a-z]##)[[:space:]]#(\([a-z, ?]##\))#/$match[1] :$match[1]${match[2]:+:${${match[2]//[(),]}// /:}}:} ) fi case $state in cmds) _wanted commands expl 'osc command' _osc_commands && ret=0 ;; args) local cmd args usage typeset -gHA _cache_osc_status typeset -gHA _cache_osc_modifiedfiles typeset -gHA _cache_osc_repos cmd="${${(k)_osc_cmds[(R)*:$words[1]:*]}:-${(k)_osc_cmds[(i):$words[1]:]}}" if (( $#cmd )); then curcontext="${curcontext%:*:*}:osc-${cmd}:" usage=${${(M)${(f)"$(LC_ALL=C _call_program options osc help $cmd)"}:#usage:*}#usage:*$cmd] } args=( ${=${${${(M)${(f)"$(LC_ALL=C _call_program options osc help $cmd)"##*Valid options:}:#* :*}%% #:*}/ arg/:arg:}/(#b)-([[:alpha:]]) \[--([a-z-]##)\](:arg:)#/(--$match[2])-$match[1]$match[3] (-$match[1])--$match[2]$match[3]} ) case $cmd in; add) args+=( '*:file:_files -g "*(^e:_osc_controlled:)"' ) ;; commit) args+=( '*:file:_files -g "*(e:_osc_status:)"' ) _cache_osc_status=() ;; delete) args+=( '*:file:_files -g ".osc(/e:_osc_deletedfiles:)"' ) ;; diff) args+=( '*:file:_files -g "*(e:_osc_modifiedfiles:)"' ) _cache_osc_modifiedfiles=() ;; help) args+=( '*::sub command:_osc_commands' ) ;; log) args+=( '*::sub repos:_osc_repos' ) #_cache_osc_repos=() ;; build) args+=( '*::sub repos:_osc_repos' ) #_cache_osc_repos=() ;; # revert) # args+=( # '*:file:_files -g "(.osc|*)(/e:_osc_deletedfiles:,e:_osc_status:)"' # ) # ;; *) case $usage in *(SRC|DST|TARGET|URL*PATH)*) args+=( '*: : _alternative "files:file:_files" "urls:URL:_osc_urls"' ) ;; *URL*) args+=( ':URL:_osc_urls' ) ;; *PATH*) args+=( '*:file:_files' ) ;; esac ;; esac _arguments "$args[@]" && ret=0 else _message "unknown osc command: $words[1]" fi ;; esac return ret } (( $+functions[_osc_controlled] )) || _osc_controlled() { [[ -f ${(M)REPLY##*/}.osc/${REPLY##*/} ]] } (( $+functions[_osc_deletedfiles] )) || _osc_deletedfiles() { # Typical usage would be _files -g '.osc(/e:_osc_deletedfiles:)' local cont controlled reply=( ) [[ $REPLY = (*/|).osc ]] || return controlled=( $REPLY/*~$REPLY/_*(N:t) ) for cont in ${controlled}; do [[ -e $REPLY:h/$cont ]] || reply+=( ${REPLY%.osc}$cont ) done } (( $+functions[_osc_modifiedfiles] )) || _osc_modifiedfiles() { local dir=$REPLY:h local pat="${1:-([M]|?M)}" if (( ! $+_cache_osc_modifiedfiles[$dir] )); then _cache_osc_modifiedfiles[$dir]="$(_call_program files osc status $dir)" fi (( ${(M)#${(f)_cache_osc_modifiedfiles[$dir]}:#(#s)${~pat}*$REPLY} )) } (( $+functions[_osc_status] )) || _osc_status() { local dir=$REPLY:h local pat="${1:-([ADMR~]|?M)}" if [ $dir = "." ]; then dir=$PWD fi if (( ! $+_cache_osc_status[$dir] )); then _cache_osc_status[$dir]="$(_call_program files osc status $dir)" else fi (( ${(M)#${(f)_cache_osc_status[$dir]}:#(#s)${~pat}*$REPLY} )) } (( $+functions[_osc_urls] )) || _osc_urls() { local expl if [[ -prefix *: ]]; then _urls else compset -S '[^:]*' _wanted url-schemas expl 'URL schema' compadd -S '' - \ file:// http:// https:// osc:// osc+ssh:// fi } (( $+functions[_osc_commands] )) || _osc_commands() { compadd "$@" -k _osc_cmds || compadd "$@" ${(s.:.)_osc_cmds} } (( $+functions[_osc_repos] )) || _osc_repos() { local dir=$REPLY:h local tmp if [ $dir = "." ]; then dir=$PWD fi if (( ! $+_cache_osc_repos[$dir] )); then _cache_osc_repos[$dir]="$(_call_program repos osc repos)" fi tmp=() for line in ${(f)_cache_osc_repos[$dir]}; do line=($=line) tmp+=$line done compadd $tmp } _osc "$@"