[PATCH] bash URL completion

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH] bash URL completion

Gerlando Falauto
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!

bash_completion.diff (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] bash URL completion

Daniel Shahaf-2
http://subversion.apache.org/patches

Please send this to dev@!  (and follow the other suggestions too please
-- e.g., submit against trunk@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) )

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] bash URL completion

Nate
In reply to this post by Gerlando Falauto
Nice!  I was looking at doing the same thing!

Do you have the full completion code that you could post directly?  (not just the DIFF?)

Thanks in advance!

On Friday, July 27, 2012 at 3:31:51 AM UTC-6, Gerlando Falauto wrote:
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:

<a href="http://srv1/proj1" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fsrv1%2Fproj1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF3v3uHriVKOcrcC_YMOvarV6vsbA&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fsrv1%2Fproj1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF3v3uHriVKOcrcC_YMOvarV6vsbA&#39;;return true;">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!
Loading...