Class: DenCli::Sub

Inherits:
Object
  • Object
show all
Defined in:
lib/dencli/sub.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, name, description, noshortaliases: nil, defined_in: nil) ⇒ Sub

Returns a new instance of Sub.



6
7
8
9
10
11
12
# File 'lib/dencli/sub.rb', line 6

def initialize parent, name, description, noshortaliases: nil, defined_in: nil
	#DenCli::assert_type self, __method__, :name, name, Symbol
	#DenCli::assert_type self, __method__, :parent, parent, DenCli, DenCli::Sub
	#DenCli::assert_type self, __method__, :description, description, String
	@parent, @name, @description, @subs, @aliases = parent, name, "-> #{description}", {}, {}
	@noshortaliases, @defined_in = ! ! noshortaliases, defined_in || Kernel.caller
end

Instance Attribute Details

#aliasesObject (readonly)

Returns the value of attribute aliases.



4
5
6
# File 'lib/dencli/sub.rb', line 4

def aliases
  @aliases
end

#defined_inObject (readonly)

Returns the value of attribute defined_in.



4
5
6
# File 'lib/dencli/sub.rb', line 4

def defined_in
  @defined_in
end

#descriptionObject (readonly)

Returns the value of attribute description.



4
5
6
# File 'lib/dencli/sub.rb', line 4

def description
  @description
end

#nameObject (readonly)

Returns the value of attribute name.



4
5
6
# File 'lib/dencli/sub.rb', line 4

def name
  @name
end

#parentObject (readonly)

Returns the value of attribute parent.



4
5
6
# File 'lib/dencli/sub.rb', line 4

def parent
  @parent
end

#subsObject (readonly)

Returns the value of attribute subs.



4
5
6
# File 'lib/dencli/sub.rb', line 4

def subs
  @subs
end

Class Method Details

._help_commands(output, subs) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/dencli/sub.rb', line 64

def _help_commands output, subs
	m = subs.map {|_name,c| x = c.usage.length; 25 < x ? 0 : x }.max
	subs.each do |_name, c|
		if 25 < c.usage.length
			output << "% -#{m}s\n#{' ' * m} " % [c.usage]
		else
			output << "% -#{m}s " % [c.usage]
		end
		n = m+2
		prefix = nil
		c.description.split( /\n/).each do |l|
			c = 0
			l.split( %r< >).each do |w|
				if prefix
					output << prefix
					prefix = nil
				end
				wl = w.length
				if 75 < c+wl
					output << "\n#{' ' * n}#{w}"
					c = n+2+wl
				else
					output << " #{w}"
					c += 1 + wl
				end
			end
			prefix = "\n#{' ' * n}"
		end
		output << "\n"
	end
	output
end

Instance Method Details

#[](name) ⇒ Object



16
# File 'lib/dencli/sub.rb', line 16

def []( name) @aliases[name&.to_s] end

#_full_cmd(post) ⇒ Object



14
# File 'lib/dencli/sub.rb', line 14

def _full_cmd( post) parent._full_cmd [@name]+post end

#_help(output, n = nil, *a) ⇒ Object



41
42
43
44
45
46
47
48
49
50
# File 'lib/dencli/sub.rb', line 41

def _help output, n = nil, *a
	if n.nil?
		output << "#{full_cmd.join ' '}: #{description}\n\n"
		self.class._help_commands output, @subs
	elsif has? n
		self[n]._help output, *a
	else
		raise DenCli::UnknownCommand, "unknown command: #{_full_cmd( [n])[1..-1].join ' '}, available for #{full_cmd[1..-1].join' '}: #{@subs.keys.join ' '}"
	end
end

#_usage(output) ⇒ Object



26
27
28
29
30
31
32
33
# File 'lib/dencli/sub.rb', line 26

def _usage output
	output << full_cmd.join( ' ')
	if @aliases.has_key? nil
		output << " [<command> ...]"
	else
		output << " <command> [...]"
	end
end

#call(*a) ⇒ Object



108
109
110
111
112
113
114
115
# File 'lib/dencli/sub.rb', line 108

def call *a
	n, *a = *a
	if has? n
		self[n].call *a
	else
		raise DenCli::UnknownCommand, "unknown command: #{_full_cmd( [n])[1..-1].join ' '}, available for #{full_cmd[1..-1].join' '}: #{@subs.keys.join ' '}"
	end
end

#cmd(name, description, min: nil, aliases: nil, defined_in: nil, &exe) ⇒ Object

Define a new command:

DenCli.new {|c|
  c.cmd( :hello, 'Greetings', &lambda {|| puts 'hello world' })
}

# ./prog hello
hello world

name should be a string/symbol. It will be converted to string. If provided, aliases must be a list of different aliases. Except of nil, any alias will be converted to string. nil is an alias for a default command for sub-commands, but interactive shells.

DenCli.new {|c|
  c.sub( :greetings, 'Hello, Welcome, ...') do |s|
    s.cmd( :hello, 'A simple Hello', aliases: %w[hello-world hello_world], &lambda {|| puts 'Hello World' })
    s.cmd( :welcome, 'More gracefull', aliases: [nil, 'welcome-world', :hello_world], &lambda {|| puts 'Welcome World' })
  }
}

# ./prog greetings
Welcome World
# ./prog greetings welcome
Welcome World
# ./prog greetings hello
Hello World


187
188
189
# File 'lib/dencli/sub.rb', line 187

def cmd name, description, min: nil, aliases: nil, defined_in: nil, &exe
	_add name, min, DenCli::CMD.new( self, name, description, exe, defined_in || Kernel.caller.first), aliases
end

#commands {|name, _self| ... } ⇒ Object

Yields:

Yield Parameters:

  • _self (DenCli::Sub)

    the object that the method was called on



52
53
54
55
# File 'lib/dencli/sub.rb', line 52

def commands &exe
	yield name, self
	@subs.each {|k, c| c.commands &exe }
end

#complete(*pre, str) ⇒ Object



191
192
193
194
195
196
197
198
199
# File 'lib/dencli/sub.rb', line 191

def complete *pre, str
	if pre.empty?
		@subs.keys.grep /\A#{Regexp.escape str}/
	elsif sub = @subs[pre[0]]
		sub.complete *pre[1..-1], str
	else
		$stdout.print "\a"
	end
end

#full_cmdObject



15
# File 'lib/dencli/sub.rb', line 15

def full_cmd() _full_cmd [] end

#goto(*a) ⇒ Object



98
99
100
101
102
103
104
105
106
# File 'lib/dencli/sub.rb', line 98

def goto *a
	return self  if a.empty?
	n, *a = *a
	if has? n
		self[n].goto *a
	else
		raise DenCli::UnknownCommand, "unknown command: #{_full_cmd( [n])[1..-1].join ' '}, available for #{full_cmd[1..-1].join' '}: #{@subs.keys.join ' '}"
	end
end

#has?(name) ⇒ Boolean

Returns:

  • (Boolean)


17
# File 'lib/dencli/sub.rb', line 17

def has?( name) @aliases.has_key? name&.to_s end

#help(n = nil, *a, output: nil) ⇒ Object



35
36
37
38
39
# File 'lib/dencli/sub.rb', line 35

def help n = nil, *a, output: nil
	output ||= ''
	_help output, n, *a
	output
end

#help_commands(output: nil) ⇒ Object



57
58
59
60
61
# File 'lib/dencli/sub.rb', line 57

def help_commands output: nil
	output ||= ''
	self.class._help_commands output, subs.map {|_,c| c}
	output
end

#inspectObject



201
202
203
204
205
206
# File 'lib/dencli/sub.rb', line 201

def inspect
	"#<%s:0x%x %s @name=%p @description=%p @subs={%s} @aliases={%s} @parent=<%s:0x%x %s>>" % [
		self.class.name, self.object_id, self.full_cmd,
		@name, @description, @subs.keys.join(', '), @aliases.keys.join(', '), @parent.class.name, @parent.class.object_id, @parent.full_cmd
	]
end

#sub(name, description, min: nil, aliases: nil, noshortaliases: nil, defined_in: nil, &exe) ⇒ Object

Define a new sub-menu:

DenCli.new {|c|
  c.sub( 'sub-command') {|s|
    s.cmd( :hello, 'Greetings', &lambda {|| puts 'hello world' })
  }
}

# ./prog sub-command hello

name should be a string/symbol. It will be converted to string. If provided, aliases must be a list of different aliases. It will be converted to string.



156
157
158
159
# File 'lib/dencli/sub.rb', line 156

def sub name, description, min: nil, aliases: nil, noshortaliases: nil, defined_in: nil, &exe
	r = _add name.to_s, min, DenCli::Sub.new( self, name, description, noshortaliases: noshortaliases, defined_in: defined_in || Kernel.caller.first), aliases
	block_given? ? yield( r) : r
end

#usage(output: nil) ⇒ Object



20
21
22
23
24
# File 'lib/dencli/sub.rb', line 20

def usage output: nil
	output ||= ''
	_usage output
	output
end