command-set 0.10.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|