[ditz-talk] [PATCH] Add support shell completion (zsh for now).
Nicolas Pouillard
nicolas.pouillard at gmail.com
Wed Apr 9 19:55:17 EDT 2008
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
--
1.5.5.rc3
More information about the ditz-talk
mailing list