#compdef mtn # -*-sh-*- # # ZSH Completion for Monotone # # Author: Joel Reed # Last changed by: Thomas Moschny # # # Installing into /usr/share/zsh/site-functions: # # (1) If that directory is not already present in $fpath, add the line # "fpath=(/usr/share/zsh/site-functions $fpath)" to either your # system wide zshrc, or user ~/.zshrc. # # (2) Copy $MONOTONE/contrib/monotone.zsh_completion (this file) to # /usr/share/zsh/site-functions/_mtn # # Alternatively, you can install this file as _mtn into some directory # in your home (e.g. ~/.zsh), and add that directory to the $fpath. # # redefine _mtn. _mtn() { local extra _arguments -s : \ '--confdir=[set location of configuration directory]:dir:_files -/'\ {'(--db)-d+','(-d)--db='}'[set name of database]:file:_files'\ '--debug[print debug log to stderr while running]'\ '--dump=[file to dump debugging log to, on failure]:file:_files'\ {'-h','--help'}'[display help message]'\ '--ignore-suspend-certs[do not ignore revisions marked as suspended]'\ {'(--key)-k+','(-k)--key='}'[set key for signatures]:keys keys:_mtn_keys'\ '--keydir=[set location of key store]:dir:_files -/'\ '--log=[file to write the log to]:file:_files'\ '--norc[do not load ~/.monotone/monotonerc or _MTN/monotonerc lua files]'\ '--nostd[do not load standard lua hooks]'\ '--quiet[suppress log and progress messages]'\ '--rcfile=[load extra rc file]:file:_files'\ '--reallyquiet[suppress warning, verbose, informational and progress messages]'\ '--root=[limit search for working copy to specified root]:dir:_files -/'\ '--ssh-sign=[sign with ssh-agent]:ssh_sign:(yes no check)'\ '--ticker=[set ticker style]:style:(count dot none)'\ '(- *)--version[print version number, then exit]'\ {'-@+','--xargs='}'[insert command line arguments taken from the given file]:file:_files'\ '*::monotone command:_mtn_command' } # define monotone command dispatch function. (( $+functions[_mtn_command] )) || _mtn_command() { (( $+_mtn_cmds )) || _mtn_cmds=( add annotate approve asciik attr au automate cat cert checkout ci clone co comment commit complete cvs_import db diff disapprove drop dropkey explicit_merge fdiff fload fmerge genkey get_roster heads help identify import list log ls merge merge_into_dir merge_into_workspace migrate_workspace mkdir mv passphrase pivot_root pluck privkey propagate pubkey pull push rcs_import read refresh_inodeprints rename revert rm serve set setup show_conflicts ssh_agent_add ssh_agent_export status suspend sync tag testresult trusted unset update version ) local cmd="$words[1]" if (( CURRENT == 1 )); then _describe -t commands 'monotone command' _mtn_cmds else local curcontext="$curcontext" if [[ -n $cmd ]]; then curcontext="${curcontext%:*:*}:mtn-${cmd}:" _call_function ret _mtn_$cmd || _message 'no more arguments' else _message "unknown monotone command: $cmd" fi return ret fi } # define completion functions for each monotone command (( $+functions[_mtn_add] )) || _mtn_add() { _arguments -s : \ '--unknown[add unknown files from workspace]'\ '*:file to add:_mtn_files_unknown' } (( $+functions[_mtn_annotate] )) || _mtn_annotate() { _arguments -s : \ {'(--revision)-r+','(-r)--revision='}'[select revision id for operation]:revision:_mtn_selector_or_revision'\ '--revs-only[annotate using full revision ids only]'\ '(*)*:file to annotate:_mtn_files_known' } (( $+functions[_mtn_approve] )) || _mtn_approve() { _arguments -s : \ {'(--branch)-b+','(-b)--branch='}'[select branch cert for operation]:branch:_mtn_branches'\ '(*)*:revision:_mtn_selector_or_revision' } # missing: asciik (( $+functions[_mtn_attr] )) || _mtn_attr() { if (( CURRENT == 2 )); then compadd -- set get drop elif (( CURRENT == 3 )); then # fixme: should differentiate between set, get and drop compadd -- $(mtn automate attributes) else local fname="$words[3]" compadd -- $(mtn automate attributes $fname) fi } (( $+functions[_mtn_au] )) || _mtn_au() { _mtn_automate } (( $+functions[_mtn_automate] )) || _mtn_automate() { (( $+_mtn_automate_cmds )) || _mtn_automate_cmds=( ancestors ancestry_difference branches cert certs children common_ancestors content_diff db_get db_set descendents drop_attribute erase_ancestors genkey get_attributes get_base_revision_id get_content_changed get_corresponding_path get_current_revision_id get_file get_file_of get_manifest_of get_option get_revision graph heads identify interface_version inventory keys leaves packet_for_fdata packet_for_fdelta packet_for_rdata packets_for_certs parents put_file put_revision roots select set_attribute stdio tags toposort ) if (( CURRENT == 2 )) ; then compadd -a _mtn_automate_cmds fi } (( $+functions[_mtn_cat] )) || _mtn_cat() { _arguments -s : \ {'(--revision)-r+','(-r)--revision='}'[select revision id for operation]:revision:_mtn_selector_or_revision'\ '*:file to cat:_mtn_files_known' } (( $+functions[_mtn_cert] )) || _mtn_cert() { _arguments -s : \ '1:revision:_mtn_selector_or_revision'\ '2:certname: '\ '3:certval: ' } (( $+functions[_mtn_checkout] )) || _mtn_checkout() { _arguments -s : \ {'(--branch)-b+','(-b)--branch='}'[select branch cert for operation]:branch:_mtn_branches'\ {'(--revision)-r+','(-r)--revision='}'[select revision id for operation]:revision:_mtn_selector_or_revision'\ '(*)*:directory for checkout: ' } (( $+functions[_mtn_ci] )) || _mtn_ci() { _mtn_commit } # missing: clone (( $+functions[_mtn_co] )) || _mtn_co() { _mtn_checkout } (( $+functions[_mtn_comment] )) || _mtn_comment() { _arguments -s : \ '1:revision:_mtn_selector_or_revision'\ '2:comment: ' } (( $+functions[_mtn_commit] )) || _mtn_commit() { _arguments -s : \ {'(--branch)-b+','(-b)--branch='}'[select branch cert for operation]:branch:_mtn_branches'\ {'(--message)-m+','(-m)--message='}'[set commit changelog message]:message: '\ '--message-file=[set filename containing commit changelog message]:file:_files'\ '--date=[override date/time for commit]:date: '\ '--author=[override author for commit]:author: '\ '--depth=[limit the number of levels of directories to descend]:depth'\ '--exclude=[leave out anything described by its argument]:file:_mtn_files_known'\ '*:files to commit:_mtn_files_changed' } (( $+functions[_mtn_complete] )) || _mtn_complete() { _arguments -s : \ '1:what to complete:(file key manifest revision)'\ '2:partial id: ' } (( $+functions[_mtn_cvs_import] )) || _mtn_cvs_import() { _arguments : \ '*:file:_files' } (( $+functions[_mtn_db] )) || _mtn_db() { (( $+_mtn_db_cmds )) || _mtn_db_cmds=( changesetify check dump execute info init kill_branch_certs_locally kill_rev_locally kill_tag_locally load migrate regenerate_caches rosterify set_epoch version ) if (( CURRENT == 2 )) ; then compadd -a _mtn_db_cmds fi } (( $+functions[_mtn_diff] )) || _mtn_diff() { _arguments -s : \ {'(--revision)-r+','(-r)--revision='}'[select revision id for operation]:revision:_mtn_selector_or_revision'\ '--depth=[limit the number of levels of directories to descend]:depth: '\ '--exclude=[leave out anything described by its argument]:file:_mtn_files_known'\ {'(--unified)-u','(-u)--unified'}'[use unified diff format]'\ {'(--contex)-c','(-c)--contex'}'[use context diff format]'\ '--external[use external diff hook for generating diffs]'\ '--diff-args=[argument to pass external diff hook]:arg: '\ {'-no-show-encloser','--no-show-c-function'}'[do not show the function containing each block of changes]'\ '*:files to diff:_mtn_files_changed' } (( $+functions[_mtn_disapprove] )) || _mtn_disapprove() { _arguments -s : \ {'(--branch)-b+','(-b)--branch='}'[select branch cert for operation]:branch:_mtn_branches'\ '(*)*:revision to disapprove:_mtn_selector_or_revision' } (( $+functions[_mtn_drop] )) || _mtn_drop() { _arguments -s : \ {'(--execute)-e','(-e)--execute'}'[perform the associated file operation]'\ '--missing[perform the operations for files missing from workspace]'\ {'(--recursive)-R','(-R)--recursive'}'[also operate on the contents of any listed directories]'\ '*:entries to drop:_mtn_files_known' } (( $+functions[_mtn_dropkey] )) || _mtn_dropkey() { _mtn_keys } (( $+functions[_mtn_explicit_merge] )) || _mtn_explicit_merge() { _arguments -s : \ '1:left revision:_mtn_selector_or_revision'\ '2:right revision:_mtn_selector_or_revision'\ '3:dest branch:_mtn_branches' } # missing: fdiff # missing: fload # missing: fmerge # missing: genkey # missing: get_roster (( $+functions[_mtn_heads] )) || _mtn_heads() { _arguments -s : \ {'(--branch)-b+','(-b)--branch='}'[select branch cert for operation]:branch:_mtn_branches' } # missing: help # missing: identify # missing: import (( $+functions[_mtn_list] )) || _mtn_list() { (( $+_mtn_ls_cmds )) || _mtn_ls_cmds=( certs keys branches epochs tags vars known unknown ignored missing changed ) if (( CURRENT == 2 )) ; then compadd -a _mtn_ls_cmds fi } (( $+functions[_mtn_log] )) || _mtn_log() { _arguments -s : \ {'(--revision)-r+','(-r)--revision='}'[select revision id for operation]:revision:_mtn_selector_or_revision'\ '--last=[limit log output to the last number of entries]:last: ' \ '--next=[limit log output to the next number of entries]:next: ' \ '--brief[print a brief version of the normal output]'\ '--diffs[print diffs along with logs]'\ '--no-merges[exclude merges when printing logs]'\ '--no-files[exclude files when printing logs]'\ '*:restriction for log:_mtn_files_known' } (( $+functions[_mtn_ls] )) || _mtn_ls() { _mtn_list } (( $+functions[_mtn_merge] )) || _mtn_merge() { _arguments -s : \ {'(--branch)-b+','(-b)--branch='}'[select branch cert for operation]:branch:_mtn_branches'\ '--date=[override date/time for commit]:date: '\ '--author=[override author for commit]:author: ' } # missing: merge_into_dir # missing: merge_into_workspace (( $+functions[_mtn_mkdir] )) || _mtn_mkdir() { _arguments -s : \ '--no-respect-ignore[do not ignore any files]'\ '*:directory to create: ' } (( $+functions[_mtn_mv] )) || _mtn_mv() { _mtn_rename } # missing: passphrase # missing: pivot_root # missing: pluck # missing: privkey (( $+functions[_mtn_propagate] )) || _mtn_propagate() { _arguments -s : \ {'(--message)-m+','(-m)--message='}'[set commit changelog message]:message: '\ '--message-file=[set filename containing commit changelog message]:file:_files'\ '--date=[override date/time for commit]:date: '\ '--author=[override author for commit]:author: '\ '1:source branch:_mtn_branches'\ '2:dest branch:_mtn_branches'\ } # missing: pubkey (( $+functions[_mtn_pull] )) || _mtn_pull() { _arguments -s : \ '--set-default[use the current arguments as the future default]'\ '--exclude=[leave out anything described by its argument]:exclude: ' } (( $+functions[_mtn_push] )) || _mtn_push() { _mtn_sync } (( $+functions[_mtn_rcs_import] )) || _mtn_rcs_import() { _arguments -s : \ {'(--branch)-b+','(-b)--branch='}'[select branch cert for operation]:branch:_mtn_branches'\ '*:files to import:_files' } # missing: read # missing: refresh_inodeprints (( $+functions[_mtn_rename] )) || _mtn_rename() { _arguments -s : \ {'(--execute)-e','(-e)--execute'}'[perform the associated file operation]'\ '*:files to rename:_mtn_files_known' } (( $+functions[_mtn_revert] )) || _mtn_revert() { _arguments -s : \ '--depth=[limit the number of levels of directories to descend]:depth: '\ '--exclude=[leave out anything described by its argument]:file:_mtn_files_known'\ '--missing[perform the operations for files missing from workspace]'\ '*:files to revert:_mtn_files_changed' } (( $+functions[_mtn_rm] )) || _mtn_rm() { _mtn_drop } (( $+functions[_mtn_serve] )) || _mtn_serve() { _arguments -s : \ '--pid-file=[record process id of server]:file:_files'\ '--exclude=[leave out anything described by its argument]:exclude: '\ '--bind=[address:port to listen on]:bind: '\ '--stdio[serve netsync on stdio]'\ '--no-transport-auth[disable transport authentication]'\ '*:pattern: ' } # missing: set # missing: setup # missing: show_conflicts # missing: ssh_agent_add # missing: ssh_agent_export (( $+functions[_mtn_status] )) || _mtn_status() { _arguments -s : \ '--depth=[limit the number of levels of directories to descend]:depth: '\ '--exclude=[leave out anything described by its argument]:file:_mtn_files_known'\ '*:file:_mtn_files_known' } # missing: suspend (( $+functions[_mtn_sync] )) || _mtn_sync() { _arguments -s : \ '--set-default[use the current arguments as the future default]'\ '--exclude=[leave out anything described by its argument]:exclude: '\ '--key-to-push=[push the specified key]:key: ' } (( $+functions[_mtn_tag] )) || _mtn_tag() { _arguments -s : \ '1:revision to tag:_mtn_selector_or_revision'\ '(1)*:tagname: ' } (( $+functions[_mtn_result] )) || _mtn_testresult() { _arguments -s : \ '1:revision:_mtn_selector_or_revision'\ '2:result:(pass fail true false yes no 1 0)' } # missing: trusted # missing: unset (( $+functions[_mtn_update] )) || _mtn_update() { _arguments -s : \ {'(--branch)-b+','(-b)--branch='}'[select branch cert for operation]:branch:_mtn_branches'\ {'(--revision)-r+','(-r)--revision='}'[select revision id for operation]:revision:_mtn_selector_or_revision' } (( $+functions[_mtn_version] )) || _mtn_version() { _arguments -s : \ '--full[print detailed version number]' } # define completion functions for files maintained by monotone. (( $+functions[_mtn_files_unknown] )) || _mtn_files_unknown() { _mtn_files "unknown" } (( $+functions[_mtn_files_changed] )) || _mtn_files_changed() { _mtn_files "changed" } (( $+functions[_mtn_files_known] )) || _mtn_files_known() { _mtn_files "known" } (( $+functions[_mtn_files] )) || _mtn_files() { # "mtn ls --depth=0 foo ." should output the names of directories # containing suppressed matches local prefix=${PREFIX}X local rcwd="$(_mtn_rcwd)" local -a list list=( ${${${(f)"$(mtn ls $1 ${prefix:h} 2>/dev/null)"}#$rcwd}#/} ) compadd -f -a list } (( $+functions[_mtn_branches] )) || _mtn_branches() { compadd -- $(mtn ls branches 2>/dev/null) } (( $+functions[_mtn_tags] )) || _mtn_tags() { compadd -- ${(u)${(f)"$(mtn ls tags 2>/dev/null)"}%% *} } (( $+functions[_mtn_public_keys] )) || _mtn_public_keys() { compadd -- ${${${(@M)${(f)"$(mtn ls keys 2>/dev/null)"}:#*@*}#* }%%* *} } (( $+functions[_mtn_keys] )) || _mtn_keys() { if [[ -n $PREFIX ]]; then compadd -X "(prefix of a) key id" -n \ -- $(mtn complete key $PREFIX 2>/dev/null) fi } (( $+functions[_mtn_revisions] )) || _mtn_revisions() { if [[ -n $PREFIX ]]; then compadd -X "(prefix of a) revision id" -n \ -- $(mtn complete revision $PREFIX 2>/dev/null) fi } (( $+functions[_mtn_selectors] )) || _mtn_selectors() { _values -s / -S : selector \ '*b[branches]:branch:_mtn_branches' \ '*h[branch heads]:branch head:_mtn_branches' \ '*t[tags]:tag:_mtn_tags' \ '*a[authors]:author:_mtn_public_keys' \ '*d[date]:date:' \ '*e[earlier than]:date:' \ '*l[later than]:date:' \ '*i[revision id]:revision id:_mtn_revisions' \ '*p[parent of]:revision_id:_mtn_revisions' } (( $+functions[_mtn_selector_or_revision] )) || _mtn_selector_or_revision() { _alternative 'selector:selector:_mtn_selectors' \ 'revision:revision:_mtn_revisions' } # helper function, determines cwd relative to the root of the workspace (( $+functions[_mtn_rcwd] )) || _mtn_rcwd() { local current="$(pwd)" local base=$current while [[ "${base}" != "/" && ! -d "${base}/_MTN" ]]; do base=${base:h} done echo ${current#$base/} } _mtn "$@"