dencli/lib/dencli.rb

95 lines
1.8 KiB
Ruby
Executable file

require 'optparse'
class DenCli
class UsageError < ::RuntimeError
end
class UnknownCommand < UsageError
end
require_relative 'dencli/cmd'
require_relative 'dencli/sub'
require_relative 'dencli/interactive'
require_relative 'dencli/version'
class <<self
# Helper Function for generate Regular Expressions of string,
# which matches all strings which has parts fron beginning of the given string.
# `n("abc")` would produce: `/(?:a|ab|abc)/`
# You can define a minimum length to match:
# `n("abcdef",4)` => `/abcd(?:|e|ef)/`
def n s, min = nil
min ||= 1
/#{s.length <= min ?
Regexp.quote(s) :
"#{Regexp.quote s[0...min]}#{
s[min...-1].
reverse.
each_char.
reduce( "#{Regexp.quote s[-1]}?") {|f,n|
"(?:#{Regexp.quote n}#{f})?"
}
}"
}/
end
# Wraps `n(s,min=)` in a full matching RegExp with ending `\0`:
# `r("abc")` would produce: `/\A(?:a|ab|abc)\0\z/`
# You can define a minimum length to match:
# `r("abcdef",4)` => `/\aabcd(?:|e|ef)\0\z/`
def r s, min = nil
/\A#{n s, min}\0\z/
end
# Generates a list of aliases for given `cmd`:
# `g(:abc)` => `["a", "ab", "abc"]`
# `g(:abcdef, 4)` => `["abcd", "abcde", "abcdef"]`
def gen_aliases cmd, min = nil
r = ((min||1)-1).upto cmd.length-1
if block_given?
r.each {|i| yield cmd[0..i] }
else
r.map {|i| cmd[0..i] }
end
end
alias g gen_aliases
end
attr_reader :subs
def initialize progname, description
@subs = Sub.new self, progname, description
end
def full_cmd
[]
end
def _full_cmd post
post
end
def sub *a, &exe
@subs.sub *a, &exe
end
def cmd *a, &exe
@subs.cmd *a, &exe
end
def call *a
@subs.call *a
end
def help *args
@subs.help *args
end
def [] k
@subs[k]
end
def interactive *args, **opts
Interactive.new self, *args, **opts
end
end