[ditz-talk] [PATCH] Add support shell completion (zsh for now).
Jeff Balogh
its.jeff.balogh at gmail.com
Fri Apr 11 02:33:32 EDT 2008
Nicolas Pouillard wrote:
> Note: patch pushed on my repo-clone as well.
>
> ---
> bin/ditz | 14 +++++++++++++-
> contrib/completion/_ditz.zsh | 29 +++++++++++++++++++++++++++++
> lib/operator.rb | 15 ++++++++++++++-
> 3 files changed, 56 insertions(+), 2 deletions(-)
> create mode 100644 contrib/completion/_ditz.zsh
>
> diff --git a/bin/ditz b/bin/ditz
> index 0b042df..4b85d0a 100755
> --- a/bin/ditz
> +++ b/bin/ditz
> @@ -1,5 +1,18 @@
> #!/usr/bin/env ruby
>
> +# requires are splitted in two for efficiency reasons
> +# ditz should be really fast when using it for
> +# completion.
> +require 'operator'
> +
> +op = Ditz::Operator.new
> +
> +# a secret option for shell completion
> +if ARGV.include? '--commands'
> + puts op.class.operations.map { |name, _| name }
> + exit 0
> +end
> +
> require 'rubygems'
> require 'fileutils'
> require 'trollop'; include Trollop
> @@ -17,7 +30,6 @@ $opts = options do
> end
>
> cmd = ARGV.shift or die "expecting a ditz command"
> -op = Ditz::Operator.new
> dir = $opts[:issue_dir]
>
> case cmd # some special cases not handled by Ditz::Operator
> diff --git a/contrib/completion/_ditz.zsh b/contrib/completion/_ditz.zsh
> new file mode 100644
> index 0000000..656860f
> --- /dev/null
> +++ b/contrib/completion/_ditz.zsh
> @@ -0,0 +1,29 @@
> +#compdef ditz
> +
> +ME=ditz
> +COMMANDS=--commands
> +OPTIONS='<options>'
> +
> +if (($CURRENT == 2)); then
> + # We're completing the first word after the tool: the command.
> + _wanted command expl "$ME command" \
> + compadd -- $( "$ME" "$COMMANDS" )
> +else
> + # Find the options/files/URL/etc. for the current command by using the tool
> itself.
> + case "${words[$CURRENT]}"; in
> + -*)
> + _wanted args expl "Arguments for $ME ${words[2]}" \
> + compadd -- $( "$ME" "${words[2]}" "$OPTIONS" ; _files )
> + ;;
> + ht*|ft*)
> + _arguments '*:URL:_urls'
> + ;;
> + /*|./*|\~*|../*)
> + _arguments '*:file:_files'
> + ;;
> + *)
> + _wanted args expl "Arguments for $ME ${words[2]}" \
> + compadd -- $( "$ME" "${words[2]}" "$OPTIONS" )
> + ;;
> + esac
> +fi
> diff --git a/lib/operator.rb b/lib/operator.rb
> index 74c9507..74ce0b0 100644
> --- a/lib/operator.rb
> +++ b/lib/operator.rb
> @@ -59,10 +59,12 @@ class Operator
> command = "command '#{method_to_op method}'"
> built_args = @operations[method][:args_spec].map do |spec|
> val = args.shift
> + generate_choices(project, method, spec) if val == '<options>'
> case spec
> when :issue
> raise Error, "#{command} requires an issue name" unless val
> - project.issue_for(val) or raise Error, "no issue with name #{val}"
> + valr = val.sub(/\A(\w+-\d+)_.*$/,'\1')
> + project.issue_for(valr) or raise Error, "no issue with name #{val}"
> when :release
> raise Error, "#{command} requires a release name" unless val
> project.release_for(val) or raise Error, "no release with name
> #{val}"
> @@ -75,9 +77,20 @@ class Operator
> val # no translation for other types
> end
> end
> + generate_choices(project, method, nil) if args.include? '<options>'
> raise Error, "too many arguments for #{command}" unless args.empty?
> built_args
> end
> +
> + def generate_choices project, method, spec
> + case spec
> + when :issue
> + puts project.issues.map { |i| "#{i.name}_#{i.title.gsub(/\W+/, '-')}" }
> + when :release, :maybe_release
> + puts project.releases.map { |r| r.name }
> + end
> + exit 0
> + end
> end
>
> def do op, project, config, args
This is *very* useful. Thanks!
More information about the ditz-talk
mailing list