mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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:
parent
67f3280cfe
commit
91c0ff4f7d
4 changed files with 105 additions and 1 deletions
|
@ -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.
|
* lib/optparse.rb: shell completion support for bash.
|
||||||
|
|
||||||
|
|
|
@ -441,6 +441,24 @@ class OptionParser
|
||||||
(long.first || short.first).sub(/\A-+(?:\[no-\])?/, '')
|
(long.first || short.first).sub(/\A-+(?:\[no-\])?/, '')
|
||||||
end
|
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.
|
# Switch that takes no arguments.
|
||||||
#
|
#
|
||||||
|
@ -679,6 +697,14 @@ class OptionParser
|
||||||
end
|
end
|
||||||
to
|
to
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compsys(*args, &block) # :nodoc:
|
||||||
|
list.each do |opt|
|
||||||
|
if opt.respond_to?(:compsys)
|
||||||
|
opt.compsys(*args, &block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -725,6 +751,24 @@ class OptionParser
|
||||||
DefaultList.short['-'] = Switch::NoArgument.new {}
|
DefaultList.short['-'] = Switch::NoArgument.new {}
|
||||||
DefaultList.long[''] = Switch::NoArgument.new {throw :terminate}
|
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.
|
# Default options for ARGV, which never appear in option summary.
|
||||||
#
|
#
|
||||||
|
@ -737,11 +781,16 @@ class OptionParser
|
||||||
# --help=complete=WORD
|
# --help=complete=WORD
|
||||||
# Shows candidates for command line completion.
|
# Shows candidates for command line completion.
|
||||||
#
|
#
|
||||||
|
# --help=zshcomplete[=NAME:FILE]
|
||||||
|
# Creates zsh completion file.
|
||||||
|
#
|
||||||
Officious['help'] = proc do |parser|
|
Officious['help'] = proc do |parser|
|
||||||
Switch::OptionalArgument.new do |arg|
|
Switch::OptionalArgument.new do |arg|
|
||||||
case arg
|
case arg
|
||||||
when /\Acomplete=(.*)/
|
when /\Acomplete=(.*)/
|
||||||
puts parser.candidate($1)
|
puts parser.candidate($1)
|
||||||
|
when /\Azshcomplete(?:=(.+))?/
|
||||||
|
parser.compsys(STDOUT, $1)
|
||||||
else
|
else
|
||||||
puts parser.help
|
puts parser.help
|
||||||
end
|
end
|
||||||
|
|
30
misc/rb_optparse.zsh
Normal file
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
|
22
test/optparse/test_zsh_completion.rb
Normal file
22
test/optparse/test_zsh_completion.rb
Normal file
|
@ -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
|
Loading…
Add table
Reference in a new issue