* lib/optparse.rb: shell completion support for zsh. based on

<http://d.hatena.ne.jp/rubikitch/20071002/zshcomplete>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29834 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2010-11-19 12:07:09 +00:00
Родитель 67f3280cfe
Коммит 91c0ff4f7d
4 изменённых файлов: 105 добавлений и 1 удалений

Просмотреть файл

@ -1,4 +1,7 @@
Fri Nov 19 20:26:51 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
Fri Nov 19 21:07:06 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/optparse.rb: shell completion support for zsh. based on
<http://d.hatena.ne.jp/rubikitch/20071002/zshcomplete>
* lib/optparse.rb: shell completion support for bash.

Просмотреть файл

@ -441,6 +441,24 @@ class OptionParser
(long.first || short.first).sub(/\A-+(?:\[no-\])?/, '')
end
def compsys(sdone, ldone) # :nodoc:
sopts, lopts, s = [], [], nil
@short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
@long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
return if sopts.empty? and lopts.empty? # completely hidden
(sopts+lopts).each do |opt|
# "(-x -c -r)-l[left justify]" \
if opt =~ /^--\[no-\](.+)$/
o = $1
yield("--#{o}", desc.join(""))
yield("--no-#{o}", desc.join(""))
else
yield("#{opt}", desc.join(""))
end
end
end
#
# Switch that takes no arguments.
#
@ -679,6 +697,14 @@ class OptionParser
end
to
end
def compsys(*args, &block) # :nodoc:
list.each do |opt|
if opt.respond_to?(:compsys)
opt.compsys(*args, &block)
end
end
end
end
#
@ -725,6 +751,24 @@ class OptionParser
DefaultList.short['-'] = Switch::NoArgument.new {}
DefaultList.long[''] = Switch::NoArgument.new {throw :terminate}
COMPSYS_HEADER = <<'XXX' # :nodoc:
typeset -A opt_args
local context state line
_arguments -s -S \
XXX
def compsys(to, name = File.basename($0)) # :nodoc:
to << "#compdef #{name}\n"
to << COMPSYS_HEADER
visit(:compsys, {}, {}) {|o, d|
to << %Q[ "#{o}[#{d.gsub(/\"/, '\"')}]" \\\n]
}
to << " '*:file:_files' && return 0\n"
end
#
# Default options for ARGV, which never appear in option summary.
#
@ -737,11 +781,16 @@ class OptionParser
# --help=complete=WORD
# Shows candidates for command line completion.
#
# --help=zshcomplete[=NAME:FILE]
# Creates zsh completion file.
#
Officious['help'] = proc do |parser|
Switch::OptionalArgument.new do |arg|
case arg
when /\Acomplete=(.*)/
puts parser.candidate($1)
when /\Azshcomplete(?:=(.+))?/
parser.compsys(STDOUT, $1)
else
puts parser.help
end

30
misc/rb_optparse.zsh Normal file
Просмотреть файл

@ -0,0 +1,30 @@
#!/bin/zsh
# Completion for zsh:
# (based on <http://d.hatena.ne.jp/rubikitch/20071002/zshcomplete>)
#
# (1) install this file,
#
# (2) load the script, and
# . ~/.zsh.d/rb_optparse.zsh
#
# (3) geneate completion files once.
# generate-complete-function/ruby/optparse COMMAND1
# generate-complete-function/ruby/optparse COMMAND2
#
generate-complete-function/ruby/optparse ()
{
local cmpl="_${1:t}"
mkdir -p "${ZSH_COMPLETION_DIR-$HOME/.zsh.d/Completion}"
$1 --help=zshcomplete="${1:t}" > "${ZSH_COMPLETION_DIR-$HOME/.zsh.d/Completion}/$comp"
if [[ $(type -w "$cmpl") == "${cmpl}: function" ]]; then
unfunction "$cmpl"
autoload -U "$cmpl}"
else
compinit "$cmpl"
fi
}
for cmd in "$@"; do
generate-complete-function/ruby/optparse "$cmd"
done

Просмотреть файл

@ -0,0 +1,22 @@
require 'test/unit'
require 'optparse'
class TestOptionParser < Test::Unit::TestCase
end
class TestOptionParser::BashCompletion < Test::Unit::TestCase
def setup
@opt = OptionParser.new
@opt.define("-z", "zzz") {}
@opt.define("--foo") {}
@opt.define("--bar=BAR") {}
@opt.define("--for=TYPE", [:hello, :help, :zot]) {}
end
def test_compsys
compsys = @opt.compsys("", "zshcompsys")
assert_match(/\"-z\[zzz\]\"/, compsys)
assert_match(/\"--foo\[\]\"/, compsys)
assert_match(/\"--bar\[\]\"/, compsys)
assert_match(/\"--for\[\]\"/, compsys)
end
end