[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [PATCH] bash URL completion

From: Daniel Shahaf <d.s_at_daniel.shahaf.name>
Date: Fri, 27 Jul 2012 23:46:18 +0100

http://subversion.apache.org/patches

Please send this to dev@! (and follow the other suggestions too please
-- e.g., submit against trunk_at_HEAD)

Gerlando Falauto wrote on Fri, Jul 27, 2012 at 11:31:51 +0200:
> Hi everyone,
>
> I strongly felt the urge to have some way of bash-completing URLS
> from the command line when doing checkouts, listing, cat (for
> README/REVNOTES files) and so on...
> I looked up the "tools/client-side/bash_completion" script only to
> realize it works for local (file:///) but not remote URLs.
> So I came up with the attached patch, which works for me (tested
> with bash 4.1.2, svn 1.6.11)
> The idea was (apart from adding sub-dir completion with a gross "svn
> ls" command) to (manually) list known repositories within a
> ~/.svn_repos file, one per line:
>
> http://srv1/proj1
> svn://srv2/proj2
>
> The reason behind this is that data cached in
> ~/.subversion/auth/svn.simple does not contain the full project URL
> (only the server name) and I could not find a way to get that
> information anywhere else.
>
> I known it would've made more sense to ask for advice *BEFORE*
> touching the code, but still... :-)
>
> Thanks in advance for your feedback!
> Gerlando
>
> P.S. I'm not subscribed to the list, so please Cc: me, thanks!

> diff --git a/svn-completion.bash b/svn-completion.bash
> index 12285f4..c2684b3 100644
> --- a/svn-completion.bash
> +++ b/svn-completion.bash
> @@ -35,6 +35,12 @@
>
> shopt -s extglob
>
> +function _debug()
> +{
> + # echo "$@" >> /tmp/svn-completion.debug
> + true
> +}
> +
> # Tree helper functions which only use bash, to ease readability.
>
> # look for value associated to key from stdin in K/V hash file format
> @@ -112,6 +118,53 @@ function _svn_lls()
> done
> }
>
> +# _svn_remotels currUrl proto
> +# e.g. currUrl = //server/project/dirprefix
> +# proto = http:
> +# list svn files/dirs (using svn ls) from a given path
> +# NOTE: this function outputs full URLs (except the protocol part), like
> +# //srv/proj/branches/ //srv/proj/tags/ //srv/proj/trunk/
> +function _svn_remotels()
> +{
> + local currUrl=$1
> + local proto=$2
> +
> + local fullUrl=$2$1
> + _debug "Trying to complete $opt"
> +
> + # HACK: fullUrl is something like http://srv/proj/ or http://srv/proj/ta
> + # so we add an X and get the dirname from there in order to see where we
> + # should run "svn ls" against (that is, http://srv/proj)
> + local urlDir=$(dirname "${fullUrl}X")/
> +
> + # now get the prefix part of the file (e.g. "ta" for "target.def")
> + # (this is used for local filtering)
> + local filepref=${fullUrl#${urlDir}}
> +
> + # This output prefix "//srv/proj/" will be re-added to the individual ls entries
> + # so to get something like a "full path" listing (except leading "protocol:")
> + local outurlDir=${urlDir#${proto}}
> +
> + _debug "prefix to be matched is $filepref"
> +
> + local files=()
> + local f=
> + svn ls --non-interactive $urlDir </dev/null 2>/dev/null | while IFS= read -r f
> + do
> + _debug -n "... $f:"
> + # if the filename matches the provided string, add it to the list
> + if [[ -z "$filepref" || $f == $filepref* ]]
> + then
> + _debug YES
> + echo "$outurlDir$f"
> + else
> + _debug NO
> + fi
> + done
> +
> + return 0
> +}
> +
> # This completion guides the command/option order along the one suggested
> # by "svn help", although other syntaxes are allowed.
> #
> @@ -395,9 +448,22 @@ _svn()
> fi
>
> # URL completion
> - if [[ $cmd == @(co|checkout|ls|list) && $stat = 'arg' && \
> + if [[ $cmd == @(co|checkout|ls|list|cat) && $stat = 'arg' && \
> $SVN_BASH_COMPL_EXT == *urls* ]]
> then
> + # whenever a colon (:) is present, bash will split it into three different parts:
> + # 1) http
> + # 2) :
> + # 3) //full/path/to
> + # So we need to reconstruct this
> + #FIXME this should be made more robust
> +
> + local prefixUrl=${COMP_WORDS[i-3]}${COMP_WORDS[i-2]} #http:
> + local currUrl=${COMP_WORDS[i-1]} #//srv-
> + local partUrl=${COMP_WORDS[i-3]}${COMP_WORDS[i-2]}${COMP_WORDS[i-1]}
> +
> + _debug partUrl=${partUrl} cur = ${cur}
> +
> # see about COMP_WORDBREAKS workaround in prop completion
> if [[ $cur == file:* ]]
> then
> @@ -405,27 +471,50 @@ _svn()
> local where=${cur/file:/}
> COMPREPLY=( $(compgen -d -S '/' -X '*/.*' -- $where ) )
> return
> - elif [[ $cur == *:* ]]
> + elif [[ $partUrl == *://*/* ]]
> then
> + local IFS=$'\n'
> + # Get the list of remote files (as full paths)
> + local results="$(_svn_remotels ${currUrl} ${prefixUrl} )"
> + COMPREPLY=( $(compgen -W "${results}" ))
> + _debug "...completion results are: ${COMPREPLY[@]}"
> + # Set output options:
> + # - nospace: DO NOT add a new space even if it's the only completion
> + # - filenames: remove common leading paths
> + compopt -o nospace -o filenames
> + return 0
> + elif [[ $partUrl == *:* ]]
> + then
> + _debug trying to get known urls
> # get known urls
> local urls= file=
> - for file in ~/.subversion/auth/svn.simple/* ; do
> - if [ -r $file ] ; then
> - local url=$(_svn_read_hashfile svn:realmstring < $file)
> - url=${url/*</}
> - url=${url/>*/}
> - urls="$urls $url"
> - fi
> +# for file in ~/.subversion/auth/svn.simple/* ; do
> +# if [ -r $file ] ; then
> +# local url=$(_svn_read_hashfile svn:realmstring < $file)
> +# url=${url/*</}
> +# url=${url/>*/}
> +# urls="$urls $url"
> +# fi
> +# done
> + for url in $(< ~/.svn_repos)
> + do
> + urls="$urls $url"
> done
> -
> + _debug "...known urls are: ${urls}"
> # only suggest/show possible suffixes
> - local prefix=${cur%:*} suffix=${cur#*:} c= choices=
> + local prefix=${partUrl%:*} suffix=${partUrl#*:} c= choices=
> +
> for c in $urls ; do
> + _debug "evaluating ${c} prefix=${prefix} suffix=${suffix}"
> [[ $c == $prefix:* ]] && choices="$choices ${c#*:}"
> done
> + _debug "choices is now ${choices}"
>
> - COMPREPLY=( $(compgen -W "$choices" -- $suffix ) )
> - return
> + COMPREPLY=( $(compgen -W "$choices" -- $cur ) )
> + # Set output options:
> + # - nospace: DO NOT add a new space even if it's the only completion
> + compopt -o nospace
> + return 0
> else
> # show schemas
> COMPREPLY=( $(compgen -W "$urlSchemas" -- $cur) )
Received on 2012-07-28 00:46:52 CEST

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.