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
 

Reply via email to