Blame | Last modification | View Log | RSS feed
# bash completion for the Mercurial distributed SCM# Docs:## If you source this file from your .bashrc, bash should be able to# complete a command line that uses hg with all the available commands# and options and sometimes even arguments.## Mercurial allows you to define additional commands through extensions.# Bash should be able to automatically figure out the name of these new# commands and their options. See below for how to define _hg_opt_foo# and _hg_cmd_foo functions to fine-tune the completion for option and# non-option arguments, respectively.### Notes about completion for specific commands:## - the completion function for the email command from the patchbomb# extension will try to call _hg_emails to get a list of e-mail# addresses. It's up to the user to define this function. For# example, put the addresses of the lists that you usually patchbomb# in ~/.patchbomb-to and the addresses that you usually use to send# the patchbombs in ~/.patchbomb-from and use something like this:## _hg_emails()# {# if [ -r ~/.patchbomb-$1 ]; then# cat ~/.patchbomb-$1# fi# }### Writing completion functions for additional commands:## If it exists, the function _hg_cmd_foo will be called without# arguments to generate the completion candidates for the hg command# "foo". If the command receives some arguments that aren't options# even though they start with a "-", you can define a function called# _hg_opt_foo to generate the completion candidates. If _hg_opt_foo# doesn't return 0, regular completion for options is attempted.## In addition to the regular completion variables provided by bash,# the following variables are also set:# - $hg - the hg program being used (e.g. /usr/bin/hg)# - $cmd - the name of the hg command being completed# - $cmd_index - the index of $cmd in $COMP_WORDS# - $cur - the current argument being completed# - $prev - the argument before $cur# - $global_args - "|"-separated list of global options that accept# an argument (e.g. '--cwd|-R|--repository')# - $canonical - 1 if we canonicalized $cmd before calling the function# 0 otherwise#shopt -s extglob_hg_commands(){local commandscommands="$("$hg" debugcomplete "$cur" 2>/dev/null)" || commands=""COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$commands' -- "$cur"))}_hg_paths(){local paths="$("$hg" paths 2>/dev/null | sed -e 's/ = .*$//')"COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$paths' -- "$cur"))}_hg_repos(){local ifor i in $(compgen -d -- "$cur"); dotest ! -d "$i"/.hg || COMPREPLY=(${COMPREPLY[@]:-} "$i")done}_hg_status(){local files="$("$hg" status -n$1 . 2>/dev/null)"local IFS=$'\n'COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))}_hg_tags(){local tags="$("$hg" tags -q 2>/dev/null)"local IFS=$'\n'COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$tags' -- "$cur"))}_hg_branches(){local branches="$("$hg" branches -q 2>/dev/null)"local IFS=$'\n'COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$branches' -- "$cur"))}# this is "kind of" ugly..._hg_count_non_option(){local i count=0local filters="$1"for ((i=1; $i<=$COMP_CWORD; i++)); doif [[ "${COMP_WORDS[i]}" != -* ]]; thenif [[ ${COMP_WORDS[i-1]} == @($filters|$global_args) ]]; thencontinueficount=$(($count + 1))fidoneecho $(($count - 1))}_hg(){local cur prev cmd cmd_index opts i# global options that receive an argumentlocal global_args='--cwd|-R|--repository'local hg="$1"local canonical=0COMPREPLY=()cur="$2"prev="$3"# searching for the command# (first non-option argument that doesn't follow a global option that# receives an argument)for ((i=1; $i<=$COMP_CWORD; i++)); doif [[ ${COMP_WORDS[i]} != -* ]]; thenif [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; thencmd="${COMP_WORDS[i]}"cmd_index=$ibreakfifidoneif [[ "$cur" == -* ]]; thenif [ "$(type -t "_hg_opt_$cmd")" = function ] && "_hg_opt_$cmd"; thenreturnfiopts=$("$hg" debugcomplete --options "$cmd" 2>/dev/null)COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur"))returnfi# global optionscase "$prev" in-R|--repository)_hg_paths_hg_reposreturn;;--cwd)# Stick with default bash completionreturn;;esacif [ -z "$cmd" ] || [ $COMP_CWORD -eq $i ]; then_hg_commandsreturnfi# try to generate completion candidates for whatever command the user typedlocal helpif _hg_command_specific; thenreturnfi# canonicalize the command name and try againhelp=$("$hg" help "$cmd" 2>/dev/null)if [ $? -ne 0 ]; then# Probably either the command doesn't exist or it's ambiguousreturnficmd=${help#hg }cmd=${cmd%%[$' \n']*}canonical=1_hg_command_specific}_hg_command_specific(){if [ "$(type -t "_hg_cmd_$cmd")" = function ]; then"_hg_cmd_$cmd"return 0fiif [ "$cmd" != status ] && [ "$prev" = -r ] || [ "$prev" == --rev ]; thenif [ $canonical = 1 ]; then_hg_tags_hg_branchesreturn 0elif [[ status != "$cmd"* ]]; then_hg_tags_hg_branchesreturn 0elsereturn 1fificase "$cmd" inhelp)_hg_commands;;export)if _hg_ext_mq_patchlist qapplied && [ "${COMPREPLY[*]}" ]; thenreturn 0fi_hg_tags_hg_branches;;manifest|update)_hg_tags_hg_branches;;pull|push|outgoing|incoming)_hg_paths_hg_repos;;paths)_hg_paths;;add)_hg_status "u";;merge)_hg_tags_hg_branches;;commit)_hg_status "mar";;remove)_hg_status "d";;forget)_hg_status "a";;diff)_hg_status "mar";;revert)_hg_status "mard";;clone)local count=$(_hg_count_non_option)if [ $count = 1 ]; then_hg_pathsfi_hg_repos;;debugindex|debugindexdot)COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.i" -- "$cur"));;debugdata)COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.d" -- "$cur"));;*)return 1;;esacreturn 0}complete -o bashdefault -o default -F _hg hg 2>/dev/null \|| complete -o default -F _hg hg# Completion for commands provided by extensions# bookmarks_hg_bookmarks(){local bookmarks="$("$hg" bookmarks --quiet 2>/dev/null )"local IFS=$'\n'COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$bookmarks' -- "$cur"))}_hg_cmd_bookmarks(){if [[ "$prev" = @(-d|--delete|-m|--rename) ]]; then_hg_bookmarksreturnfi}# mq_hg_ext_mq_patchlist(){local patchespatches=$("$hg" $1 2>/dev/null)if [ $? -eq 0 ] && [ "$patches" ]; thenCOMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$patches' -- "$cur"))return 0fireturn 1}_hg_ext_mq_queues(){local root=$("$hg" root 2>/dev/null)local nfor n in $(cd "$root"/.hg && compgen -d -- "$cur"); do# I think we're usually not interested in the regular "patches" queue# so just filter it.if [ "$n" != patches ] && [ -e "$root/.hg/$n/series" ]; thenCOMPREPLY=(${COMPREPLY[@]:-} "$n")fidone}_hg_cmd_qpop(){if [[ "$prev" = @(-n|--name) ]]; then_hg_ext_mq_queuesreturnfi_hg_ext_mq_patchlist qapplied}_hg_cmd_qpush(){if [[ "$prev" = @(-n|--name) ]]; then_hg_ext_mq_queuesreturnfi_hg_ext_mq_patchlist qunapplied}_hg_cmd_qgoto(){if [[ "$prev" = @(-n|--name) ]]; then_hg_ext_mq_queuesreturnfi_hg_ext_mq_patchlist qseries}_hg_cmd_qdelete(){local qcmd=qunappliedif [[ "$prev" = @(-r|--rev) ]]; thenqcmd=qappliedfi_hg_ext_mq_patchlist $qcmd}_hg_cmd_qfinish(){if [[ "$prev" = @(-a|--applied) ]]; thenreturnfi_hg_ext_mq_patchlist qapplied}_hg_cmd_qsave(){if [[ "$prev" = @(-n|--name) ]]; then_hg_ext_mq_queuesreturnfi}_hg_cmd_strip(){_hg_tags_hg_branches}_hg_cmd_qcommit(){local root=$("$hg" root 2>/dev/null)# this is run in a sub-shell, so we can't use _hg_statuslocal files=$(cd "$root/.hg/patches" 2>/dev/null &&"$hg" status -nmar 2>/dev/null)COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))}_hg_cmd_qfold(){_hg_ext_mq_patchlist qunapplied}_hg_cmd_qrename(){_hg_ext_mq_patchlist qseries}_hg_cmd_qheader(){_hg_ext_mq_patchlist qseries}_hg_cmd_qclone(){local count=$(_hg_count_non_option)if [ $count = 1 ]; then_hg_pathsfi_hg_repos}_hg_ext_mq_guards(){"$hg" qselect --series 2>/dev/null | sed -e 's/^.//'}_hg_cmd_qselect(){local guards=$(_hg_ext_mq_guards)COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$guards' -- "$cur"))}_hg_cmd_qguard(){local prefix=''if [[ "$cur" == +* ]]; thenprefix=+elif [[ "$cur" == -* ]]; thenprefix=-filocal ncur=${cur#[-+]}if ! [ "$prefix" ]; then_hg_ext_mq_patchlist qseriesreturnfilocal guards=$(_hg_ext_mq_guards)COMPREPLY=(${COMPREPLY[@]:-} $(compgen -P $prefix -W '$guards' -- "$ncur"))}_hg_opt_qguard(){local ifor ((i=cmd_index+1; i<=COMP_CWORD; i++)); doif [[ ${COMP_WORDS[i]} != -* ]]; thenif [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then_hg_cmd_qguardreturn 0fielif [ "${COMP_WORDS[i]}" = -- ]; then_hg_cmd_qguardreturn 0fidonereturn 1}# hbisect_hg_cmd_bisect(){local i subcmd# find the sub-commandfor ((i=cmd_index+1; i<=COMP_CWORD; i++)); doif [[ ${COMP_WORDS[i]} != -* ]]; thenif [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; thensubcmd="${COMP_WORDS[i]}"breakfifidoneif [ -z "$subcmd" ] || [ $COMP_CWORD -eq $i ] || [ "$subcmd" = help ]; thenCOMPREPLY=(${COMPREPLY[@]:-}$(compgen -W 'bad good help init next reset' -- "$cur"))returnficase "$subcmd" ingood|bad)_hg_tags_hg_branches;;esacreturn}# patchbomb_hg_cmd_email(){case "$prev" in-c|--cc|-t|--to|-f|--from|--bcc)# we need an e-mail address. let the user provide a function# to get themif [ "$(type -t _hg_emails)" = function ]; thenlocal arg=toif [[ "$prev" == @(-f|--from) ]]; thenarg=fromfilocal addresses=$(_hg_emails $arg)COMPREPLY=(${COMPREPLY[@]:-}$(compgen -W '$addresses' -- "$cur"))fireturn;;-m|--mbox)# fallback to standard filename completionreturn;;-s|--subject)# free form stringreturn;;esac_hg_tags_hg_branchesreturn}# gpg_hg_cmd_sign(){_hg_tags_hg_branches}# transplant_hg_cmd_transplant(){case "$prev" in-s|--source)_hg_paths_hg_reposreturn;;--filter)# standard filename completionreturn;;esac# all other transplant options values and command parameters are revisions_hg_tags_hg_branchesreturn}# shelve_hg_shelves(){local shelves="$("$hg" unshelve -l . 2>/dev/null)"local IFS=$'\n'COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$shelves' -- "$cur"))}_hg_cmd_shelve(){_hg_status "mard"}_hg_cmd_unshelve(){_hg_shelves}