1#compdef tla 2 3autoload -z is-at-least 4local TLA=$words[1] 5local tla_version 6local hide_short 7 8# ask the user which version of tla this is 9if ! zstyle -s ":completion:${curcontext}" tla-version tla_version; then 10 # ask tla instead 11 tla_version="$($TLA --version)" 12 if [[ "${${(f)tla_version}[1]}" == The\ GNU\ Arch\ Revision\ Control\ System\ \(tla\)\ (#b)([0-9.]##) ]]; then 13 tla_version="$match[1]" 14 else 15 tla_version="${${$($TLA --version)#tla tla-}%% from regexps.com*}" 16 [[ $tla_version == *[a-zA-Z]* ]] && tla_version=1.3 # tla doesn't know 17 fi 18fi 19 20# test whether to hide short options from completion 21if zstyle -s ":completion:${curcontext}" hide-shortopts hide_short; then 22 case $hide_short in 23 true|yes|on|1) hide_short='!' ;; 24 *) hide_short='' ;; 25 esac 26fi 27 28# completion functions 29 30(( $+functions[_tla_archives] )) || 31_tla_archives () { _arch_archives tla "$@" } 32 33(( $+functions[_tla_categories] )) || 34_tla_categories () { _arch_namespace tla 1 "$argv[@]" } 35 36(( $+functions[_tla_branches] )) || 37_tla_branches () {_arch_namespace tla 2 "$argv[@]" } 38 39(( $+functions[_tla_versions] )) || 40_tla_versions () { _arch_namespace tla 3 "$argv[@]" } 41 42(( $+functions[_tla_revisions] )) || 43_tla_revisions () { _arch_namespace tla 4 "$argv[@]" } 44 45(( $+functions[_tla_local_revisions] )) || 46_tla_local_revisions () { 47 local expl1 expl2 tree_version=`$TLA tree-version` 48 _description -V applied-patches expl1 "patches from this version" 49 _description -V other-patches expl2 "patches from other versions" 50 compadd "$expl1[@]" `$TLA logs` 51 compadd "$expl2[@]" `$TLA logs --full $($TLA log-versions | grep -v $tree_version)` 52 # This is incredibly slow. 53 # Should complete based on -A, -R, -d 54} 55 56(( $+functions[_tla_config] )) || 57_tla_config () { 58 59 # zsh 4.1.1+ is recommended; 4.0.6 gives the error below when doing 60 # tla build-config e<TAB> 61 # _path_files:322: no matches found: configs//e/.(/) 62 # whereas 4.1.1 completes correctly 63 64 local configdir root ret=1 n expl 65 66 n=$opt_args[(i)(-d|--dir)] 67 [[ -n "$n" ]] && configdir=$opt_args[$n] 68 root="$(_call_program tla $TLA tree-root ${configdir} 2>&1)" 69 if (( $? )); then 70 _message -e messages "Error: $root" 71 return $ret 72 fi 73 74 if [[ -d "$root/configs" ]]; then 75 configdir=("$root/configs") 76 _description files expl '%Bconfig file%b' 77 _files -W configdir "$expl[@]" && ret=0 78 else 79 _message -e messages "No configs/ directory in tree whose root is $root" 80 fi 81 return $ret 82} 83 84(( $+functions[_tla_limit] )) || 85_tla_limit () { #presently only does push-mirror style limits 86 [[ $words[$CURRENT] == *@* ]] && return 1 87 88 local expl archive 89 archive=${words[(r)*@*]:-$($TLA my-default-archive 2> /dev/null)} 90 if [ $archive ]; then 91 92 if [[ $PREFIX != *--* ]]; then 93 _description -V categories expl "categories in $archive" 94 compadd -q -S -- "$expl[@]" `$TLA categories -A $archive` 95 else 96 _tla_namespace_branches 3 97 fi 98 fi 99} 100 101(( $+functions[_tla_tree_or_rev] )) || 102_tla_tree_or_rev () { 103 _alternative 'trees:tree:_files -/' 'revisions:revision:_tla_revisions' 104} 105 106(( $+functions[_tla_libraries] )) || 107_tla_libraries () { 108 local libraries expl 109 libraries=($(_call_program tla $TLA my-revision-library)) 110 _description -V libraries expl "revision libraries" 111 compadd "$expl[@]" -a libraries 112} 113 114(( $+functions[_tla_my_revision_library] )) || 115_tla_my_revision_library () { 116 if [[ -n $words[(r)-d] ]] || [[ -n $words[(r)--delete] ]]; then 117 _tla_libraries 118 else 119 _files -/ 120 fi 121} 122 123(( $+functions[_tla_log_versions] )) || 124_tla_log_versions () { 125 local logs expl 126 if is-at-least 1.1 $tla_version; then 127 logs=($(_call_program tla $TLA log-versions)) 128 else 129 logs=($(_call_program tla $TLA logs)) 130 fi 131 _description -V versions expl "log versions" 132 compadd "$expl[@]" -a logs 133} 134 135# command argument definitions 136# commands with different versions 137 138local cmd_register_archive cmd_archives cmd_ls_archives cmd_redo 139local cmd_redo_changes cmd_changes cmd_what_changed cmd_categories 140local cmd_branches cmd_versions cmd_cacherev cmd_logs cmd_log_versions 141local cmd_log_ls cmd_update cmd_join_branch cmd_replay cmd_deltapatch 142local cmd_delta_patch cmd_apply_delta cmd_sync_tree cmd_make_sync_tree 143local cmd_delta cmd_revdelta cmd_library_categories cmd_library_branches 144local cmd_library_versions cmd_library_revisions 145local cmd_archive_register 146 147cmd_log_ls=('*:version:_tla_log_versions') 148cmd_log_versions=() 149# the options should only complete items that are in the tree 150 151if is-at-least 1.1 $tla_version; then 152 cmd_register_archive=('::archive:_tla_archives' ':location:_files -/') 153 cmd_archive_register=($cmd_register_archive) 154 cmd_archives=('::regex:') 155 cmd_redo=('::changeset:_files -/') 156 cmd_changes=('::revision:_tla_revisions' 157 # ':separator:(--)' '*::limit:_files' 158 #don't understand the limit usage 159 ) 160 cmd_categories=('::archive:_tla_archives') 161 cmd_branches=('::category:_tla_categories') 162 cmd_versions=('::branch:_tla_branches') 163 cmd_cacherev=('::revision:_tla_revisions') 164 #should only complete non-cached revisions 165 166 cmd_logs=($cmd_log_ls) 167 cmd_update=('::revision:_tla_revisions') 168 cmd_join_branch=(':revision:_tla_revisions') 169 #should only complete continuation revisions 170 171 cmd_replay=('*::revision:_tla_revisions') 172 cmd_deltapatch=(':FROM:_tla_tree_or_rev' ':TO:_tla_tree_or_rev') 173 cmd_sync_tree=(':revision:_tla_revisions') 174 cmd_delta=(':FROM:_tla_tree_or_rev' ':TO:_tla_tree_or_rev' '::DEST:_files -/') 175 cmd_library_categories=('::archive:_tla_archives --library') 176 cmd_library_branches=('::category:_tla_categories --library') 177 cmd_library_versions=('::branch:_tla_branches --library') 178 cmd_library_revisions=('::version:_tla_versions --library') 179else 180 cmd_register_archive=(':archive:_tla_archives' ':location:_files -/') 181 cmd_archives=() 182 cmd_redo=() 183 cmd_changes=('::revision:_tla_revisions') 184 cmd_categories=() 185 cmd_branches=(':category:_tla_categories') 186 cmd_versions=(':branch:_tla_branches') 187 cmd_cacherev=(':revision:_tla_revisions' '::dir:_files -/') 188 cmd_logs=($cmd_log_versions) 189 cmd_update=(':dir:_files -/' '::newdir:_files -/' 190 '::revision:_tla_revisions') 191 cmd_join_branch=(':dir:_files -/' '::newdir:_files -/' 192 ':revision:_tla_revisions') 193 cmd_replay=(':dir:_files -/' '::newdir:_files -/' '::revision:_tla_revisions') 194 cmd_deltapatch=(':FROM:_tla_tree_or_rev' ':TO:_tla_tree_or_rev' 195 ':UPON:_tla_tree_or_rev' '::DEST:_files -/') 196 cmd_sync_tree=(':dir:_files -/' '::newdir:_files -/' 197 ':revision:_tla_revisions') 198 cmd_delta=(':FROM:_tla_tree_or_rev' ':TO:_tla_tree_or_rev') 199 cmd_library_categories=() 200 cmd_library_branches=(':category:_tla_categories --library') 201 cmd_library_versions=(':branch:_tla_branches --library') 202 cmd_library_revisions=(':version:_tla_versions --library') 203fi 204 205cmd_ls_archives=($cmd_archives) 206cmd_redo_changes=($cmd_redo) 207cmd_what_changed=($cmd_changes) 208cmd_delta_patch=($cmd_deltapatch) 209cmd_apply_delta=($cmd_deltapatch) 210cmd_make_sync_tree=($cmd_sync_tree) 211cmd_revdelta=($cmd_delta) 212 213# commands the same in all versions 214 215local cmd_help 216cmd_help=() 217 218local cmd_my_id 219cmd_my_id=('::id-string:') 220 221local cmd_my_default_archive 222cmd_my_default_archive=('::archive:_tla_archives') 223 224local cmd_whereis_archive 225cmd_whereis_archive=(':archive:_tla_archives') 226 227local cmd_init_tree 228cmd_init_tree=('::version:_tla_versions') 229 230local cmd_tree_root 231cmd_tree_root=('::directory:_files -/') 232 233local cmd_tree_version 234cmd_tree_version=('::directory:_files -/') 235 236local cmd_set_tree_version 237cmd_set_tree_version=(':version:_tla_versions') 238 239local cmd_build_config cmd_buildcfg 240cmd_build_config=(':config:_tla_config') 241cmd_buildcfg=($cmd_build_config) 242 243local cmd_cat_config cmd_catcfg cmd_cfgcat 244cmd_cat_config=(':config:_tla_config') 245cmd_catcfg=($cmd_cat_config) 246cmd_cfgcat=($cmd_cat_config) 247 248local cmd_undo cmd_undo_changes 249cmd_undo=('::revision:_tla_revisions') 250cmd_undo_changes=($cmd_undo) 251 252local cmd_file_diffs 253cmd_file_diffs=(':file:_files' '::revision:_tla_revisions') 254 255local cmd_file_find 256cmd_file_find=(':file:_files' '::revision:_tla_revisions') 257 258local cmd_inventory cmd_srcfind 259cmd_inventory=('::separator:(--)' '*:directory:_files -/') 260cmd_srcfind=($cmd_inventory) 261 262local cmd_tree_lint cmd_lint 263cmd_tree_lint=('::directory:_files -/') 264cmd_lint=($cmd_tree_lint) 265 266local cmd_id cmd_invtag 267cmd_id=('*:file:_files') 268cmd_invtag=($cmd_id) 269 270local cmd_id_tagging_method cmd_tagging_method methods 271cmd_id_tagging_method=('::tagging method:(($methods))') 272methods=( 273 'names:use naming conventions only' 274 'implicit:use naming conventions but permit for inventory tags' 275 'tagline:use naming conventions but permit for inventory tags' 276 'explicit:require explicit designation of source' 277) 278cmd_tagging_method=($cmd_id_tagging_method) 279 280local cmd_add cmd_add_id cmd_add_tag 281cmd_add=('*:files to add:_files') 282cmd_add_id=($cmd_add) 283cmd_add_tag=($cmd_add) 284 285local cmd_delete cmd_delete_id cmd_delete_tag 286cmd_delete=('*:files to delete:_files') 287cmd_delete_id=($cmd_delete) 288cmd_delete_tag=($cmd_delete) 289 290local cmd_move cmd_move_id cmd_move_tag 291cmd_move_id=(':old name:_files' ':new name:_files') 292cmd_move_id=($cmd_move) 293cmd_move_tag=($cmd_move) 294#would be nice not to offer dirs for newname if oldname is a file, and 295#vice versa 296 297local cmd_mv 298cmd_mv=('*:file:_files') 299# not really right, but close enough 300 301local cmd_default_id cmd_explicit_default cmd_default_tag 302cmd_default_id=('::TAG-PREFIX:') 303cmd_explicit_default=($cmd_default_id) 304cmd_default_tag=($cmd_default_id) 305 306local cmd_tagging_defaults cmd_id_tagging_defaults 307cmd_tagging_defaults=() 308cmd_id_tagging_defaults=($cmd_tagging_defaults) 309 310local cmd_changeset cmd_mkpatch 311cmd_changeset=( 312 ':ORIG:_files -/' 313 ':MOD:_files -/' 314 ':DEST:_files -/' 315 '*:files:_files' 316) 317cmd_mkpatch=("$cmd_changeset[@]") 318 319local cmd_dopatch cmd_do_changeset cmd_apply_changeset 320cmd_dopatch=(':changeset:_files -/' ':target:_files -/') 321cmd_do_changeset=($cmd_dopatch) 322cmd_apply_changeset=($cmd_dopatch) 323 324local cmd_show_changeset 325cmd_show_changeset=('::changeset:_files -/') 326 327local cmd_make_archive 328cmd_make_archive=('::name:' ':location:_files -/') 329 330local cmd_archive_setup 331cmd_archive_setup=('*:versions:_tla_branches --trailing-dashes') 332 333local cmd_make_category 334cmd_make_category=(':category:_tla_archives -S /') 335 336local cmd_make_branch 337cmd_make_branch=(':branch:_tla_categories --trailing-dashes') 338 339local cmd_make_version 340cmd_make_version=(':version:_tla_branches --trailing-dashes') 341 342local cmd_import cmd_imprev 343cmd_import=('::version:_tla_versions') 344cmd_imprev=($cmd_import) 345 346local cmd_commit cmd_cmtrev 347cmd_commit=('::version:_tla_versions' ':separator:(--)' '*:files:_files') 348cmd_cmtrev=($cmd_commit) 349 350local cmd_get cmd_getrev 351cmd_get=(':revision:_tla_revisions' '::directory:_files -/') 352cmd_getrev=($cmd_get) 353 354local cmd_get_patch cmd_get_changeset 355cmd_get_patch=(':revision:_tla_revisions' '::dir:_files -/') 356cmd_get_changeset=($cmd_get_patch) 357 358local cmd_lock_revision 359cmd_lock_revision=(':revision:_tla_revisions') 360 361local cmd_push_mirror cmd_archive_mirror 362cmd_push_mirror=( 363 '::FROM or MINE:_tla_archives' 364 '::TO:_tla_archives' 365 '::LIMIT:_tla_limit' 366) 367cmd_archive_mirror=($cmd_push_mirror) 368 369local cmd_revisions 370cmd_revisions=('::version:_tla_versions') 371 372local cmd_ancestry 373cmd_ancestry=('::revision:_tla_revisions') 374 375local cmd_ancestry_graph 376cmd_ancestry_graph=('::revision:_tla_revisions') 377 378local cmd_cat_archive_log 379cmd_cat_archive_log=(':revision:_tla_revisions') 380 381local cmd_cachedrevs 382cmd_cachedrevs=(':version:_tla_versions') 383 384local cmd_uncacherev 385cmd_uncacherev=(':revision:_tla_revisions' '::dir:_files -/') 386 387local cmd_archive_meta_info 388cmd_archive_meta_info=(':item-name:((name\:foo mirror\:bar))') 389 390local cmd_archive_snapshot 391cmd_archive_snapshot=(':dir:_files -/' '::limit:_tla_revisions') 392 393local cmd_archive_version 394cmd_archive_version=() 395 396local cmd_archive_fixup 397cmd_archive_fixup=() 398 399local cmd_make_log 400cmd_make_log=('::version:_tla_versions') 401 402local cmd_add_log cmd_add_log_version 403cmd_add_log=(':version:_tla_versions') 404cmd_add_log_version=($cmd_add_log) 405 406local cmd_remove_log cmd_remove_log_version 407cmd_remove_log=(':version:_tla_log_versions') 408cmd_remove_log_version=($cmd_remove_log) 409 410local cmd_abrowse 411cmd_abrowse=('::LIMIT:_tla_revisions') 412 413local cmd_cat_log 414cmd_cat_log=(':revision-spec:_tla_local_revisions') 415 416local cmd_changelog 417cmd_changelog=('::version:_tla_versions') 418 419local cmd_log_for_merge 420cmd_log_for_merge=('::version:_tla_versions') 421 422local cmd_merges 423cmd_merges=(':INTO:_tla_revisions' '::FROM:_tla_revisions') 424 425local cmd_new_merges 426cmd_new_merges=('::version:_tla_versions') 427 428local cmd_tag cmd_tagrev cmd_branch 429cmd_tag=(':SOURCE-REVISION:_tla_revisions' ':TAG-VERSION:_tla_versions') 430cmd_tagrev=($cmd_tag) 431cmd_branch=($cmd_tag) 432 433local cmd_star_merge 434cmd_star_merge=(':FROM:_tla_revisions') 435 436local cmd_missing cmd_whats_missing 437cmd_missing=('::revision:_tla_revisions') 438cmd_whats_missing=($cmd_missing) 439 440local cmd_pristines cmd_ls_pristines 441cmd_pristines=('::limit:_tla_revisions') 442cmd_ls_pristines=($cmd_pristines) 443 444local cmd_lock_pristine 445cmd_lock_pristine=(':revision:_tla_revisions') 446 447local cmd_add_pristine 448cmd_add_pristine=(':revision:_tla_revisions') 449 450local cmd_find_pristine 451cmd_find_pristine=(':revision:_tla_revisions') 452 453local cmd_my_revision_library cmd_library_dir 454cmd_my_revision_library=(':library:_tla_my_revision_library') 455cmd_library_dir=($my_revision_library) 456 457local cmd_library_find 458cmd_library_find=(':revision:_tla_revisions --library') 459 460local cmd_library_add 461cmd_library_add=(':revision:_tla_revisions --exclude-library-revisions') 462 463local cmd_library_remove 464cmd_library_remove=(':revision:_tla_revisions --library') 465 466local cmd_library_archives 467cmd_library_archives=() 468 469local cmd_library_log 470cmd_library_log=(':revision:_tla_revisions --library') 471 472local cmd_library_file 473cmd_library_file=(':file:_files' ':revision:_tla_revisions --library') 474 475local cmd_grab 476cmd_grab=(':location:_files') 477 478local cmd_parse_package_name 479cmd_parse_package_name=(':name:') 480 481local cmd_valid_package_name 482cmd_valid_package_name=(':name:') 483 484local cmd_library_config 485cmd_library_config=(':library:_tla_libraries') 486 487local cmd_rbrowse 488cmd_rbrowse=('::regular expression:') 489 490local cmd_rm 491cmd_rm=('*:file:_files') 492 493local cmd_escape 494cmd_escape=(':string:') 495 496local cmd_diff 497cmd_diff=('::revision:_tla_revisions') 498 499local cmd_export 500cmd_export=(':revision:_tla_revisions' ':dir:_files -/') 501 502#mutually exclusive options 503 504local -A excludes 505excludes=( 506# This first line means that if --output was given, don't complete 507# --no-output or --keep. The converse is not true. 508--output '--no-output --keep' 509--no-output --output 510 511--silent ' --quiet --report --verbose --debug' 512--quiet '--silent --report --verbose --debug' 513--report '--silent --quiet --verbose --debug' 514--verbose '--silent --quiet --report --debug' 515--debug '--silent --quiet --report --verbose ' 516 517--sparse --non-sparse 518--non-sparse --sparse 519 520--files ' --directories --both' 521--directories '--files --both' 522--both '--files --directories ' 523 524--mirror --mirror-from 525--mirror-from --mirror 526 527--no-cached --cached-tags 528--cached-tags --no-cached 529 530--non-greedy --greedy 531--greedy --non-greedy 532) 533 534_tla_main () { 535 typeset -A opt_args 536 local arguments 537 if (( CURRENT > 2 )); then 538 local cmd=${words[2]} 539 local var_cmd=cmd_${cmd//-/_} 540 curcontext="${curcontext%:*:*}:tla-$cmd:" 541 (( CURRENT-- )) 542 shift words 543 544 arguments=() 545 local input 546 input=(${${(M)${(f)"$($TLA $cmd -h)"}:# *}# }) 547 548 local i j=1 549 local short long arg desc action 550 short=() 551 long=() 552 arg=() 553 desc=() 554 action=() 555 for (( i=1 ; i <= ${#input} ; i++ )); do 556 [[ "$input[i]" != *[^\ ]* ]] && continue # stupid blank lines 557 short[j]="${${${input[i]}[1,2]}#--}" 558 long[j]="${${input[i]#-?, }%% *}" 559 560 arg[j]="${${${input[i]%% *}##* }##-*}" 561 [[ $long[j] == --archive ]] && arg[j]=ARCHIVE # tla doesn't mention this 562 563 desc[j]="${input[i]##* }" 564 if [[ "$input[i+1]" == \ *[^\ ]* ]]; then # description continues 565 (( i++ )) 566 desc[j]="$desc[j] ${input[i]##* }" 567 fi 568 [[ "$short[j]" == -[hHV] ]] && continue 569 desc[j]="${${desc[j]//\[/\\[}//\]/\\]}" # escape brackets 570 571 case $arg[j] in 572 DIR|PATCH-DIR|DEST|OUTPUT|PATH) 573 action[j]='_files -/' ;; 574 FILES|FILE|SNAP-FILE) 575 action[j]='_files' ;; 576 MASTER|MASTER-SOURCE|ARCHIVE) 577 action[j]='_tla_archives' ;; 578 CATEGORY) 579 action[j]='_tla_categories' ;; 580 BRANCH) 581 action[j]='_tla_branches' ;; 582 VERSION) 583 action[j]='_tla_versions' ;; 584 CFG) 585 action[j]='_tla_configs' ;; 586 LIB) 587 action[j]='_tla_libraries' ;; 588# PATCH,FILE) # not sure how to complete this 589# action[j]='_tla_patch_file' ;; 590 *) 591 action[j]='' ;; 592 esac 593 594 (( j++ )) 595 596 done 597 598 local excluded k 599 for (( i = 1 ; i < j ; i++ )); do 600 excluded=($short[i] $long[i]) 601 foreach opt (${=excludes[$long[i]]}) 602 k=$long[(i)$opt] 603 excluded=($excluded $short[k] $long[k]) 604 #excludes matching short options too :-) 605 end 606 607 608 # generate arguments to _arguments ;-) 609 # make long and short options mutually exclusive 610 [ $short[i] ] && arguments=("$arguments[@]" 611 "${hide_short}(${excluded})${short[i]}[${desc[i]}]${arg[i]:+:$arg[i]:$action[i]}") 612 [ $long[i] ] && arguments=("$arguments[@]" 613 "(${excluded})${long[i]}[${desc[i]}]${arg[i]:+:$arg[i]:$action[i]}") 614 done 615 616 arguments=("$arguments[@]" "${(@P)var_cmd-*:FILE:_files}") 617 else 618 local help 619 local -U cmds 620 help=(${(f)"$($TLA help)"}) 621 cmds=(${${${${(M)help:#* :*}/ #: #/:}%% ##}## #}) 622 arguments=(':commands:(($cmds))') 623 fi 624 _arguments -S -A '-*' \ 625 {"${hide_short}(: -)-V",'(: -)--version'}'[display version]' \ 626 {"${hide_short}(: -)-h",'(: -)--help'}'[display help]' \ 627 '(: -)-H[display verbose help]' \ 628 "$arguments[@]" 629} 630 631_tla_main "$@" 632