Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[SUBMIT] _ant completion function



Hello,

Here's my version of an _ant function for Ant completion support in
versions 1.3 to 1.5.

It's nearly 100% pure zsh with the exception that sed is called to strip
\r's from the output of ant -projecthelp which is a requirement when
running under Cygwin.  If anyone can tell me how to do that with within
zsh I'd appreciate it.  There's also a minor cosmetic issue in that the
default target is printed with a leading space.  The problem is I couldn't
figure out how to do a substitution while condtitionally removing a
trailing space.  Using ? or * didn't work for me to make a space optional.

So far, I've not found a build file that wasn't parsed correctly but then
I haven't done extensive testing either.

Suggested improvements
* Caching of targets on a per build file basis
* Enhance the -logger option with a menu of the standard logger classes
shipping with Ant while still allowing completion on a classname.
* A number of the options support completing on a classname.  However,
this doesn't work unless the class file is in a package under the current
directory.  It would be desirable to complete on any class in the
classpath.  Since Ant's classpath isn't exposed, the best guess would be
to use a classpath of $ANT_HOME/lib/*.jar.

Also, I should mention that Ant 1.5 ships with completion support for zsh
2.5 and up.  Someone wrote a Perl script (bin/complete-ant-cmd.pl) to
support completion for Bash.  I figured out how to get it to run from zsh
and documented it at the top of the script.  Unfortunately, this isn't
mentioned in Ant's documentation.  Although this completion support does
cache targets on a per build file basis, it's using the old completion
system.

-Bill
#compdef ant

local expl tmp match basedir file buildxml
local curcontext="$curcontext"
local context state line
typeset -A opt_args

_arguments \
    '-help[print help message]' \
    '-projecthelp[print project help information]' \
    '-version[print the version information and exit]' \
    '-diagnostics[print diagnostic information to aide in troubleshooting]' \
    '(-q)-quiet[be extra quiet]' \
    '(-quiet)-q[be extra quiet]' \
    '(-v)-verbose[be extra verbose]' \
    '(-verbose)-v[be extra verbose]' \
    '-debug[print debugging information]' \
    '-emacs[produce logging information without adornments]' \
    '(-l)-logfile[use given file for log]:log file:_files' \
    '(-logfile)-l[use given file for log]:log file:_files' \
    '-logger[class which is to perform logging]:classname:->class' \
    '*-listener[add an instance of class as a project listener]:classname:->class' \
    '(-f)-buildfile[use given build file]:build file:_files -g \*.xml' \
    '(-buildfile)-f[use given build file]:build file:_files -g \*.xml' \
    '-file[use given build file]:build file:_files -g \*.xml' \
    '-D[specify a property]:property:->property' \
    '-propertyfile[load all properties from file (-D overrides)]:property file:_files' \
    '-inputhandler[class which will handle input requests]:classname:->class' \
    '-find[search for build file towards the root of the filesystem]:build file:(build.xml)' \
    '*:targets:->targets' \
     && return 0

[[ -n "$state" ]] &&
case "$state" in

# copied from _java functon
property)
  if compset -P '*='; then
    _default
  else
    _message 'property name'
  fi
  ;;

# copied from _java functon
class)
  match=()
  compset -P '(#b)(*.)'
  basedir=${match[1]//.//}
  _alternative \
    'classes:class:compadd $basedir*.class(.:t:s/.class//)' \
    'packages:package:compadd -qS. $basedir*~$basedir*.*(/:t)'
  ;;

targets)
  #echo "curcontext: \"$curcontext\""
  #echo "words: \"$words[*]\"" > /tmp/_ant-buildargs.tmp
  # Detect any of -find, -buildfile, -file or -f options and save to run with 
  # -projecthelp.
  for arg in "$words[2,-1]"; do
    case $arg in
      (-find|-buildfile|-file|-f)
	buildxml="$arg"
	;;
      (*)
	if [[ -n $buildxml ]]; then
	  buildxml="$buildxml $arg"
	  break
	fi
	;;
    esac
  done
  #echo "$buildxml" >> /tmp/_ant-buildargs.tmp
  ##if _tags targets; then
  #if zstyle -t ":completion:${curcontext}:targets" call-command; then
    # Run ant -projecthelp also passing any of -find, -buildfile or -f options.
    # Parse output into an array of the format "target:description".
    # For the array to be set with correct argument boundaries, the entire
    # set statement needs to be eval'd.  On Cygwin, need to kill \r's output
    # from Java or parsing will fail.
    eval set -A tmp "$(_call_program targets "$words[1]" $buildxml -projecthelp |
        sed 's/\\r$//' |
      while read target desc
      do
      #local target desc default_target
      # This loop reads ant -projecthelp output from versions 1.3 to 1.5
	#target="${target:s@\\r@@}"
	ln="${target}:${desc}"
	[[ $target = "" ]] && continue  # skip blank lines
	case $ln in
	    (Buildfile:*)
		buildfile=$desc
	    ;;
	    (Default:target:*)
		# with version 1.5, target is on the same line
		default_target="${desc/target:/}"
		# versions 1.3 and 1.4 with default target on a separate line
		if [[ -z $default_target ]]; then
		    read junk
		    read default_target junk
		fi
		# Output target again indicating its the default one.
		print -n "'$default_target:(Default target) ' "
	    ;;
	    (Searching:*|Main:targets:|Subtargets::|BUILD:SUCCESSFUL|Total:time:*)
	    ;;
	    (*)
		# Return target and description
		print -n "'$ln ' "
	    ;;
	esac
      done
    )"
    ##fi
  #fi
# test array
#  tmp=(
#    'compile:Compile Application'
#    'jar:Build jar file (default)'
#    'dist:Create Distribution'
#    'clean:'
#  )
  _describe 'Targets' tmp --
  ;;

*)
  _message "unknown state: $state"
  ;;
esac


Messages sorted by: Reverse Date, Date, Thread, Author