Hello, this patch works for svn ls and svn merge now. I'm not sure if it makes sense for other commands, however it is a separate function an can be used easily for other commands as well.
_svn_lls() looks broken for me because ${dn}.svn/text-base/${fn}.svn-base doesn't exist any more I suggest to enable SVN_BASH_COMPL_EXT=urls by default since nobody reads a documentation and enables it. greetings, Chris Am Dienstag, 18. August 2015, 13:51:58 schrieb Julian Foad: > Christian Ferbar wrote: > > new version. This patch are my current changes for "svn ls" only. > > Thanks, Chris. This looks much better already. (I haven't tried it.) > > > I need some feedback concerning: > > > > -> how to deal with svn error messages written to stderr, for example: > > svn ls svn+ssh://svn.something.com/<tab><tab>u...@svn.something.com's > > password: > > > > this happens when you forget to do ssh-add > > I suggest it should simply not provide any completions that cannot be > obtained without further input. Use --non-interactive so that > Subversion does not prompt for passwords. Prevent any stderr output > being printed to the console (maybe use "2> /dev/null"). Then make > sure the script behaves OK (just returning no completions) when > Subversion returns an error. You might need to look for a non-zero > exit code explicitly, but maybe not: it might be enough to just try > parsing the stdout and if there is no recognizable stdout then you get > no resulting completions. > > > -> in bash >= 4 they changed COMP_WORDS. The Line will be split at : as > > well, so "file:/something" are 3 array items. Nobody would use subversion > > 1.9 with bash 3 ... probably. I will drop bash 3 statements, for example: > > > > if [[ $cur == file:* ]] > > > > ok? > > Dropping support for Bash 3 sounds OK to me, if it is difficult to > keep it working. Especially good if only the URL completion depends on > Bash 4 and all the rest of the existing kinds of completion keep > working with Bash 3. > > >> Please can URL completion work on full URLs as well as on relative URLs? > > for SVN LS this is done: > > > > 1. svn ls tabtab -> ^/ file:/// http:// https:// > > svn:// svn+ssh:// > > 2. svn ls svn+ssh://tabtab -> will look at the ~/.ssh/known_hosts > > 3. svn ls http[s]://tabtab -> lookup in > > ~/.subversion/simple-auth - should still be working > > 4. svn ls proto://server/tabtab or ^/tabtab -> autocomplete via "svn ls" > > Excellent, that looks like the sort of thing I was hoping for. > > - Julian
Index: tools/client-side/bash_completion =================================================================== --- tools/client-side/bash_completion (Revision 1696324) +++ tools/client-side/bash_completion (Arbeitskopie) @@ -84,6 +84,7 @@ done } +# broken since svn 1.7 | FIXME: change to svn status -v ? # _svn_lls (dir|file|all) files... # list svn-managed files from list # some 'svn status --all-files' would be welcome here? @@ -106,6 +107,93 @@ done } +# try to complete TARGET +# 1. [nothing] lists available protocols +# 2. svn+ssh:// lists servers from .ssh/known_hosts +# 3. http[s]:// lists already used svn servers +# 4. file:// lists files from dir +# 5. ^/ or protocol except file:/ triggers svn ls +# this code expects bash 4, $cur is split by : too +# +# $1 'all' | 'remote_only' +# return true if found something +function _svn_complete_target() { + # this needs to be enabled + if [[ $SVN_BASH_COMPL_EXT == *urls* ]] ; then + : + else + echo "svn_complete_target disabled [$SVN_BASH_COMPL_EXT]" + return 1 + fi + + # echo -e "\n_svn_complete_target: [$cur] 1:[${COMP_WORDS[COMP_CWORD]}] 2:[${COMP_WORDS[COMP_CWORD-1]}] 3:[${COMP_WORDS[COMP_CWORD-2]}] | [${COMP_WORDS[@]}] [$COMP_WORDBREAKS]" + local prefix=${COMP_WORDS[COMP_CWORD-2]} + local colon=${COMP_WORDS[COMP_CWORD-1]} + # see about COMP_WORDBREAKS workaround in prop completion + if [[ $prefix == "file" && "$colon" == ":" ]] + then + # file completion for file:// urls + COMPREPLY=( $(compgen -d -S '/' -X '*/.*' -- $cur ) ) + return + elif [[ ( $1 == "all" && $cur == ^/* ) || ( "$colon" == ":" && $cur == //*/* ) ]] + then # we already hava a protocoll and host: autocomplete for svn ls ^/bla | svn ls remote_url | svn checkout remote_url + local p + if [ "$colon" == ":" ] ; then + p="$prefix$colon" + fi + if [[ $cur =~ ((.*/)([^/]*)) ]] # url = everything up to the last / + then + local url="${BASH_REMATCH[2]}" + local path="${BASH_REMATCH[3]}" + local remote_files="$(svn ls --non-interactive "$p$url" 2> /dev/null )" + COMPREPLY=( $(compgen -P "$url" -W "$remote_files" -- "$path" ) ) + compopt -o nospace + return 0 + fi + elif [[ "$colon" == ":" ]] + then + # get known servers + # svn+ssh:// + if [[ $prefix == "svn+ssh" && $cur =~ (^//(.*)) ]] ; then + local server_start=${BASH_REMATCH[2]} + # debian & suse: /usr/share/bash-completion/bash_completion + local suffix=/ + _known_hosts_real -p // "$server_start" + else + 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 + done + + # only suggest/show possible suffixes + local suffix=$cur c= choices= + for c in $urls ; do + [[ $c == $prefix:* ]] && choices="$choices ${c#*:}" + done + + COMPREPLY=( $(compgen -W "$choices" -- $suffix ) ) + fi + compopt -o nospace + return + else + # show schemas + if [ $1 == 'all' ] ; then + COMPREPLY=( $(compgen -W "^/ $urlSchemas" -- $cur) ) + else + COMPREPLY=( $(compgen -W "$urlSchemas" -- $cur) ) + fi + compopt -o nospace + return + fi + #echo "nothing found" + return 1 +} + # This completion guides the command/option order along the one suggested # by "svn help", although other syntaxes are allowed. # @@ -389,42 +477,12 @@ fi # URL completion - if [[ $cmd == @(co|checkout|ls|list) && $stat = 'arg' && \ - $SVN_BASH_COMPL_EXT == *urls* ]] + if [[ $cmd == @(co|checkout|ls|list) && $stat = 'arg' ]] then - # see about COMP_WORDBREAKS workaround in prop completion - if [[ $cur == file:* ]] - then - # file completion for file:// urls - local where=${cur/file:/} - COMPREPLY=( $(compgen -d -S '/' -X '*/.*' -- $where ) ) - return - elif [[ $cur == *:* ]] - then - # 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 - done - - # only suggest/show possible suffixes - local prefix=${cur%:*} suffix=${cur#*:} c= choices= - for c in $urls ; do - [[ $c == $prefix:* ]] && choices="$choices ${c#*:}" - done - - COMPREPLY=( $(compgen -W "$choices" -- $suffix ) ) - return + if [[ $cmd == @(ls|list) ]] ; then + _svn_complete_target 'all' && return else - # show schemas - COMPREPLY=( $(compgen -W "$urlSchemas" -- $cur) ) - compopt -o nospace - return + _svn_complete_target 'remote_only' && return fi fi @@ -449,11 +507,15 @@ compopt -o nospace return 0 fi + # this part is broken with bash 4 URL contains https only elif [[ $URL == */branches/* && $here == */trunk* && \ ! $hasReintegrateOpt && $cur = '' && $stat = 'arg' ]] ; then # force --reintegrate only if the current word is empty COMPREPLY=( $(compgen -W '--reintegrate' -- $cur ) ) return 0 + # autocomplete for svn merge ^/bla + else + _svn_complete_target 'all' && return fi fi