command-set 0.10.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/command-set/command-set.rb +32 -1
- data/lib/command-set/command.rb +0 -45
- data/lib/command-set/dsl.rb +31 -19
- data/lib/command-set/interpreter/base.rb +7 -6
- data/lib/command-set/interpreter/text.rb +1 -0
- data/lib/command-set/results.rb +0 -4
- data/lib/command-set/standard-commands.rb +4 -4
- data/lib/command-set/structural.rb +2 -3
- metadata +3 -3
@@ -155,8 +155,8 @@ module Command
|
|
155
155
|
def initialize(name="")
|
156
156
|
@name = name
|
157
157
|
@command_list = { nil => RootCommand.setup(self, nil) {} }
|
158
|
+
@mode_commands = {}
|
158
159
|
@included_sets = []
|
159
|
-
@subject_template = nil
|
160
160
|
@documentation = ""
|
161
161
|
@prompt = nil
|
162
162
|
@arguments = []
|
@@ -220,12 +220,18 @@ module Command
|
|
220
220
|
@command_list.each_pair do |term, command|
|
221
221
|
command.each_command(path + [term], visitor)
|
222
222
|
end
|
223
|
+
return unless path.empty?
|
224
|
+
@mode_commands.each_pair do |term, command|
|
225
|
+
command.each_command([term], visitor)
|
226
|
+
end
|
223
227
|
end
|
224
228
|
|
225
229
|
def root_visit(terms, visitor)
|
226
230
|
next_hop = if(terms.empty?)
|
227
231
|
visitor.set_out_of_terms(self)
|
228
232
|
@command_list[nil]
|
233
|
+
elsif(visitor.command_path.empty?)
|
234
|
+
@mode_commands[terms.first] || @command_list[terms.first]
|
229
235
|
else
|
230
236
|
@command_list[terms.first]
|
231
237
|
end
|
@@ -307,10 +313,35 @@ module Command
|
|
307
313
|
|
308
314
|
alias short_docs documentation
|
309
315
|
|
316
|
+
def build_command(home, name_or_class, name_or_nil, block)
|
317
|
+
if Class === name_or_class && Command > name_or_class
|
318
|
+
if block.nil?
|
319
|
+
command = name_or_class.dup
|
320
|
+
name = command.name
|
321
|
+
else
|
322
|
+
name = name_or_nil.to_s
|
323
|
+
command = name_or_class.setup(self, name, &block)
|
324
|
+
end
|
325
|
+
else
|
326
|
+
if String === name_or_class or Symbol === name_or_class
|
327
|
+
name = name_or_class.to_s
|
328
|
+
else
|
329
|
+
raise RuntimeError, "#{name_or_class} is neither a Command class nor a name!"
|
330
|
+
end
|
331
|
+
command = Command.setup(name, &block)
|
332
|
+
end
|
333
|
+
|
334
|
+
home[name] = command
|
335
|
+
end
|
336
|
+
|
310
337
|
def command_list
|
311
338
|
return @command_list.dup
|
312
339
|
end
|
313
340
|
|
341
|
+
def mode_commands
|
342
|
+
return @mode_commands.dup
|
343
|
+
end
|
344
|
+
|
314
345
|
def command_names
|
315
346
|
return @command_list.keys.compact
|
316
347
|
end
|
data/lib/command-set/command.rb
CHANGED
@@ -33,51 +33,6 @@ module Command
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
=begin
|
37
|
-
#An abstraction of the lifecycle of a command. Allows invocations to be
|
38
|
-
#postponed temporarily, or for the command to be instantiated and still
|
39
|
-
#passed around. Client code should almost never need to see this class,
|
40
|
-
#so the methods aren't individually documented.
|
41
|
-
class CommandSetup
|
42
|
-
def initialize(cmd = [], args = {})
|
43
|
-
@task_id = nil
|
44
|
-
@args_hash = args
|
45
|
-
@terms = []
|
46
|
-
@command = cmd
|
47
|
-
@execution_context = nil
|
48
|
-
end
|
49
|
-
|
50
|
-
attr_accessor :task_id, :command, :args_hash, :terms
|
51
|
-
|
52
|
-
def class_resolution(command_set, path, subject)
|
53
|
-
return command_set.process_terms(path, subject)
|
54
|
-
end
|
55
|
-
|
56
|
-
def resolve_command_class(command_set, subject)
|
57
|
-
if @execution_context.nil? && Class === @command && Command > @command
|
58
|
-
@execution_context = TermProcessor.new(subject)
|
59
|
-
else
|
60
|
-
command_path = @command
|
61
|
-
@execution_context = class_resolution(command_set,
|
62
|
-
command_path,
|
63
|
-
subject)
|
64
|
-
@command = @execution_context.command_class
|
65
|
-
@args_hash = @execution_context.arg_hash.merge(@args_hash)
|
66
|
-
@terms = command_path
|
67
|
-
end
|
68
|
-
|
69
|
-
return @command
|
70
|
-
end
|
71
|
-
|
72
|
-
def command_instance(command_set, subject)
|
73
|
-
command_class = resolve_command_class(command_set, subject)
|
74
|
-
command = command_class.new(@execution_context, task_id)
|
75
|
-
command.consume_hash(@args_hash)
|
76
|
-
return command
|
77
|
-
end
|
78
|
-
end
|
79
|
-
=end
|
80
|
-
|
81
36
|
class AnchoredCommandSetup < CommandSetup
|
82
37
|
def initialize(command_set, cmd = [], args = {})
|
83
38
|
super(cmd, args)
|
data/lib/command-set/dsl.rb
CHANGED
@@ -21,6 +21,7 @@ Action:: utility functions within the command action block
|
|
21
21
|
#the new commands.
|
22
22
|
def include_commands(set, *commands)
|
23
23
|
new_commands = set.command_list
|
24
|
+
new_mode_commands = set.mode_commands
|
24
25
|
options = Hash === commands.first ? commands.shift : {}
|
25
26
|
|
26
27
|
commands.map!{|c| c.to_s}
|
@@ -28,9 +29,12 @@ Action:: utility functions within the command action block
|
|
28
29
|
new_commands.delete_if do |name,command|
|
29
30
|
not commands.include? name
|
30
31
|
end
|
32
|
+
new_mode_commands.delete_if do |name, command|
|
33
|
+
not commands.include? name
|
34
|
+
end
|
31
35
|
end
|
32
36
|
|
33
|
-
unless new_commands.empty?
|
37
|
+
unless new_commands.empty? and new_mode_commands.empty?
|
34
38
|
@included_sets << [set, options]
|
35
39
|
end
|
36
40
|
|
@@ -44,13 +48,17 @@ Action:: utility functions within the command action block
|
|
44
48
|
next unless CommandSet === command
|
45
49
|
@command_list[name].include_commands(command)
|
46
50
|
else
|
47
|
-
@command_list[name] = command
|
51
|
+
@command_list[name] = command
|
48
52
|
end
|
49
53
|
unless(options[:context].nil?)
|
50
54
|
@command_list[name] = ContextBoundary.new(@command_list[name],
|
51
55
|
options[:context])
|
52
56
|
end
|
53
57
|
end
|
58
|
+
|
59
|
+
new_mode_commands.each_pair do |name, command|
|
60
|
+
@mode_commands[name] = command
|
61
|
+
end
|
54
62
|
end
|
55
63
|
|
56
64
|
#If you've got a file dedicated to a set of commands, (and you really
|
@@ -96,32 +104,28 @@ Action:: utility functions within the command action block
|
|
96
104
|
# be a subclass of the class you passed in, which is great for a
|
97
105
|
# series of related commands.
|
98
106
|
def command(name_or_command_class, name_or_nil=nil, &block)
|
99
|
-
|
100
|
-
|
101
|
-
if Class === name_or_command_class && Command > name_or_command_class
|
102
|
-
if block.nil?
|
103
|
-
command = name_or_command_class.dup
|
104
|
-
name = command.name
|
105
|
-
else
|
106
|
-
name = name_or_nil.to_s
|
107
|
-
command = name_or_command_class.setup(self, name, &block)
|
108
|
-
end
|
109
|
-
elsif name_or_command_class.nil?
|
107
|
+
if name_or_command_class.nil?
|
110
108
|
command = @command_list[nil]
|
111
109
|
command.instance_eval(&block)
|
112
110
|
return
|
113
111
|
else
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
112
|
+
build_command(@command_list, name_or_command_class,
|
113
|
+
name_or_nil, block)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def command_alias(name, command)
|
118
|
+
if Array === command
|
119
|
+
command = find_command(command)
|
120
120
|
end
|
121
121
|
|
122
122
|
@command_list[name] = command
|
123
123
|
end
|
124
124
|
|
125
|
+
def mode_command(name_or_class, name_or_nil=nil, &block)
|
126
|
+
build_command(@mode_commands, name_or_class, name_or_nil, block)
|
127
|
+
end
|
128
|
+
|
125
129
|
#Defines a nested CommandSet. Commands within the nested set will be
|
126
130
|
#referenced by preceding them with the name of the set.
|
127
131
|
#DSL::CommandSetDefinition will be available within the block to be
|
@@ -606,6 +610,14 @@ Action:: utility functions within the command action block
|
|
606
610
|
subject.chain_of_command.unshift(setup)
|
607
611
|
end
|
608
612
|
|
613
|
+
def up(levels = 1)
|
614
|
+
return @nesting[-(levels+1)]
|
615
|
+
end
|
616
|
+
|
617
|
+
def root
|
618
|
+
return @nesting[0]
|
619
|
+
end
|
620
|
+
|
609
621
|
#:section: Miscellany
|
610
622
|
|
611
623
|
#Not normally called from within an #action block, this provides the
|
@@ -14,7 +14,7 @@ module Command
|
|
14
14
|
# #get_formatter, and #prompt_user
|
15
15
|
class BaseInterpreter
|
16
16
|
attr_accessor :out_io, :logger
|
17
|
-
attr_reader :subject, :command_set
|
17
|
+
attr_reader :subject, :command_set, :sub_modes
|
18
18
|
|
19
19
|
def initialize
|
20
20
|
@command_set=nil
|
@@ -51,7 +51,6 @@ module Command
|
|
51
51
|
@subject = subject
|
52
52
|
end
|
53
53
|
|
54
|
-
|
55
54
|
def command_set=(set)
|
56
55
|
@command_set = set
|
57
56
|
@subject = prep_subject(get_subject)
|
@@ -79,13 +78,13 @@ module Command
|
|
79
78
|
raise RuntimeError, "Sub-modes must be CommandSets!"
|
80
79
|
end
|
81
80
|
|
82
|
-
|
81
|
+
sub_modes.push([mode, mode.most_recent_args, nesting])
|
83
82
|
return nil
|
84
83
|
end
|
85
84
|
|
86
85
|
# The compliment to #push_mode. Removes the most recent command set.
|
87
86
|
def pop_mode
|
88
|
-
|
87
|
+
sub_modes.pop
|
89
88
|
return nil
|
90
89
|
end
|
91
90
|
|
@@ -94,8 +93,8 @@ module Command
|
|
94
93
|
#If your interpreter needs extra fields in the subject, alter
|
95
94
|
#subject_requirements to return an array of those fields.
|
96
95
|
def subject_requirements
|
97
|
-
return [:undo_stack, :interpreter_behavior,
|
98
|
-
:chain_of_command, :pause_decks]
|
96
|
+
return [:undo_stack, :interpreter, :interpreter_behavior,
|
97
|
+
:chain_of_command, :pause_decks, :mode_stack]
|
99
98
|
end
|
100
99
|
|
101
100
|
def get_subject
|
@@ -109,9 +108,11 @@ module Command
|
|
109
108
|
@command_set.add_defaults(subject)
|
110
109
|
subject.required_fields(subject_requirements())
|
111
110
|
subject.undo_stack = @undo_stack
|
111
|
+
subject.interpreter = self
|
112
112
|
subject.interpreter_behavior = @behavior
|
113
113
|
subject.chain_of_command = @commands_pending
|
114
114
|
subject.pause_decks = @pause_decks
|
115
|
+
subject.mode_stack = @sub_modes
|
115
116
|
return subject
|
116
117
|
end
|
117
118
|
|
@@ -2,6 +2,7 @@ require 'readline'
|
|
2
2
|
require 'command-set'
|
3
3
|
require 'dl/import'
|
4
4
|
require 'command-set/interpreter/base'
|
5
|
+
require 'command-set/formatter/strategy'
|
5
6
|
|
6
7
|
#This really locks text-interpreter down to Linux, maybe Unix-like
|
7
8
|
#platforms, I'm thinking. A more flexible way of doing this would rock,
|
data/lib/command-set/results.rb
CHANGED
@@ -84,7 +84,7 @@ module StdCmd
|
|
84
84
|
@@set = nil
|
85
85
|
def self.define_commands
|
86
86
|
return @@set ||= Command::CommandSet.define_commands do
|
87
|
-
|
87
|
+
mode_command Command::StandardCommand::Quit
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
@@ -94,7 +94,7 @@ module StdCmd
|
|
94
94
|
@@set = nil
|
95
95
|
def self.define_commands
|
96
96
|
return @@set ||= Command::CommandSet.define_commands do
|
97
|
-
|
97
|
+
mode_command("undo") do
|
98
98
|
doesnt_undo
|
99
99
|
action do
|
100
100
|
command=subject.undo_stack.get_undo
|
@@ -108,7 +108,7 @@ module StdCmd
|
|
108
108
|
EOH
|
109
109
|
end
|
110
110
|
|
111
|
-
|
111
|
+
mode_command("redo") do
|
112
112
|
doesnt_undo
|
113
113
|
action do
|
114
114
|
command=subject.undo_stack.get_redo
|
@@ -137,7 +137,7 @@ module StdCmd
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
-
|
140
|
+
mode_command(:exit) do
|
141
141
|
subject_methods :interpreter
|
142
142
|
doesnt_undo
|
143
143
|
|
@@ -66,7 +66,7 @@ module Command
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def term_without_hop(terms, node)
|
69
|
-
raise CommandException, "No such command #{terms.first}"
|
69
|
+
raise CommandException, "#{@command_path.join(" ")}: No such command #{terms.first}"
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -81,7 +81,6 @@ module Command
|
|
81
81
|
@set_nesting = []
|
82
82
|
end
|
83
83
|
|
84
|
-
|
85
84
|
attr_accessor :arg_hash, :terms, :subject,
|
86
85
|
:task_id, :command_class, :set_nesting
|
87
86
|
|
@@ -100,7 +99,7 @@ module Command
|
|
100
99
|
|
101
100
|
def term_without_hop(terms, node)
|
102
101
|
if CommandSet === node
|
103
|
-
raise CommandException, "No such command: #{terms.first}"
|
102
|
+
raise CommandException, "#{@command_path.join(" ")}: No such command: #{terms.first}"
|
104
103
|
end
|
105
104
|
end
|
106
105
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: command-set
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.10.
|
7
|
-
date: 2008-02-
|
6
|
+
version: 0.10.1
|
7
|
+
date: 2008-02-12 00:00:00 -08:00
|
8
8
|
summary: Framework for interactive programs focused around a DSL for commands
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -61,7 +61,7 @@ rdoc_options:
|
|
61
61
|
- --main
|
62
62
|
- Command
|
63
63
|
- --title
|
64
|
-
- command-set-0.10.
|
64
|
+
- command-set-0.10.1 RDoc
|
65
65
|
extra_rdoc_files:
|
66
66
|
- doc/README
|
67
67
|
- doc/GUIDED_TOUR
|