1 | #
|
---|
2 | # irb/extend-command.rb - irb extend command
|
---|
3 | # $Release Version: 0.9.5$
|
---|
4 | # $Revision: 11708 $
|
---|
5 | # $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
|
---|
6 | # by Keiju ISHITSUKA([email protected])
|
---|
7 | #
|
---|
8 | # --
|
---|
9 | #
|
---|
10 | #
|
---|
11 | #
|
---|
12 | module IRB
|
---|
13 | #
|
---|
14 | # IRB extended command
|
---|
15 | #
|
---|
16 | module ExtendCommandBundle
|
---|
17 | EXCB = ExtendCommandBundle
|
---|
18 |
|
---|
19 | NO_OVERRIDE = 0
|
---|
20 | OVERRIDE_PRIVATE_ONLY = 0x01
|
---|
21 | OVERRIDE_ALL = 0x02
|
---|
22 |
|
---|
23 | def irb_exit(ret = 0)
|
---|
24 | irb_context.exit(ret)
|
---|
25 | end
|
---|
26 |
|
---|
27 | def irb_context
|
---|
28 | IRB.CurrentContext
|
---|
29 | end
|
---|
30 |
|
---|
31 | @ALIASES = [
|
---|
32 | [:context, :irb_context, NO_OVERRIDE],
|
---|
33 | [:conf, :irb_context, NO_OVERRIDE],
|
---|
34 | [:irb_quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
|
---|
35 | [:exit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
|
---|
36 | [:quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
|
---|
37 | ]
|
---|
38 |
|
---|
39 | @EXTEND_COMMANDS = [
|
---|
40 | [:irb_current_working_workspace, :CurrentWorkingWorkspace, "irb/cmd/chws",
|
---|
41 | [:irb_print_working_workspace, OVERRIDE_ALL],
|
---|
42 | [:irb_cwws, OVERRIDE_ALL],
|
---|
43 | [:irb_pwws, OVERRIDE_ALL],
|
---|
44 | # [:irb_cww, OVERRIDE_ALL],
|
---|
45 | # [:irb_pww, OVERRIDE_ALL],
|
---|
46 | [:cwws, NO_OVERRIDE],
|
---|
47 | [:pwws, NO_OVERRIDE],
|
---|
48 | # [:cww, NO_OVERRIDE],
|
---|
49 | # [:pww, NO_OVERRIDE],
|
---|
50 | [:irb_current_working_binding, OVERRIDE_ALL],
|
---|
51 | [:irb_print_working_binding, OVERRIDE_ALL],
|
---|
52 | [:irb_cwb, OVERRIDE_ALL],
|
---|
53 | [:irb_pwb, OVERRIDE_ALL],
|
---|
54 | # [:cwb, NO_OVERRIDE],
|
---|
55 | # [:pwb, NO_OVERRIDE]
|
---|
56 | ],
|
---|
57 | [:irb_change_workspace, :ChangeWorkspace, "irb/cmd/chws",
|
---|
58 | [:irb_chws, OVERRIDE_ALL],
|
---|
59 | # [:irb_chw, OVERRIDE_ALL],
|
---|
60 | [:irb_cws, OVERRIDE_ALL],
|
---|
61 | # [:irb_cw, OVERRIDE_ALL],
|
---|
62 | [:chws, NO_OVERRIDE],
|
---|
63 | # [:chw, NO_OVERRIDE],
|
---|
64 | [:cws, NO_OVERRIDE],
|
---|
65 | # [:cw, NO_OVERRIDE],
|
---|
66 | [:irb_change_binding, OVERRIDE_ALL],
|
---|
67 | [:irb_cb, OVERRIDE_ALL],
|
---|
68 | [:cb, NO_OVERRIDE]],
|
---|
69 |
|
---|
70 | [:irb_workspaces, :Workspaces, "irb/cmd/pushws",
|
---|
71 | [:workspaces, NO_OVERRIDE],
|
---|
72 | [:irb_bindings, OVERRIDE_ALL],
|
---|
73 | [:bindings, NO_OVERRIDE]],
|
---|
74 | [:irb_push_workspace, :PushWorkspace, "irb/cmd/pushws",
|
---|
75 | [:irb_pushws, OVERRIDE_ALL],
|
---|
76 | # [:irb_pushw, OVERRIDE_ALL],
|
---|
77 | [:pushws, NO_OVERRIDE],
|
---|
78 | # [:pushw, NO_OVERRIDE],
|
---|
79 | [:irb_push_binding, OVERRIDE_ALL],
|
---|
80 | [:irb_pushb, OVERRIDE_ALL],
|
---|
81 | [:pushb, NO_OVERRIDE]],
|
---|
82 | [:irb_pop_workspace, :PopWorkspace, "irb/cmd/pushws",
|
---|
83 | [:irb_popws, OVERRIDE_ALL],
|
---|
84 | # [:irb_popw, OVERRIDE_ALL],
|
---|
85 | [:popws, NO_OVERRIDE],
|
---|
86 | # [:popw, NO_OVERRIDE],
|
---|
87 | [:irb_pop_binding, OVERRIDE_ALL],
|
---|
88 | [:irb_popb, OVERRIDE_ALL],
|
---|
89 | [:popb, NO_OVERRIDE]],
|
---|
90 |
|
---|
91 | [:irb_load, :Load, "irb/cmd/load"],
|
---|
92 | [:irb_require, :Require, "irb/cmd/load"],
|
---|
93 | [:irb_source, :Source, "irb/cmd/load",
|
---|
94 | [:source, NO_OVERRIDE]],
|
---|
95 |
|
---|
96 | [:irb, :IrbCommand, "irb/cmd/subirb"],
|
---|
97 | [:irb_jobs, :Jobs, "irb/cmd/subirb",
|
---|
98 | [:jobs, NO_OVERRIDE]],
|
---|
99 | [:irb_fg, :Foreground, "irb/cmd/subirb",
|
---|
100 | [:fg, NO_OVERRIDE]],
|
---|
101 | [:irb_kill, :Kill, "irb/cmd/subirb",
|
---|
102 | [:kill, OVERRIDE_PRIVATE_ONLY]],
|
---|
103 |
|
---|
104 | [:irb_help, :Help, "irb/cmd/help",
|
---|
105 | [:help, NO_OVERRIDE]],
|
---|
106 |
|
---|
107 | ]
|
---|
108 |
|
---|
109 | def self.install_extend_commands
|
---|
110 | for args in @EXTEND_COMMANDS
|
---|
111 | def_extend_command(*args)
|
---|
112 | end
|
---|
113 | end
|
---|
114 |
|
---|
115 | # aliases = [commans_alias, flag], ...
|
---|
116 | def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases)
|
---|
117 | case cmd_class
|
---|
118 | when Symbol
|
---|
119 | cmd_class = cmd_class.id2name
|
---|
120 | when String
|
---|
121 | when Class
|
---|
122 | cmd_class = cmd_class.name
|
---|
123 | end
|
---|
124 |
|
---|
125 | if load_file
|
---|
126 | eval %[
|
---|
127 | def #{cmd_name}(*opts, &b)
|
---|
128 | require "#{load_file}"
|
---|
129 | eval %[
|
---|
130 | def #{cmd_name}(*opts, &b)
|
---|
131 | ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)
|
---|
132 | end
|
---|
133 | ]
|
---|
134 | send :#{cmd_name}, *opts, &b
|
---|
135 | end
|
---|
136 | ]
|
---|
137 | else
|
---|
138 | eval %[
|
---|
139 | def #{cmd_name}(*opts, &b)
|
---|
140 | ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)
|
---|
141 | end
|
---|
142 | ]
|
---|
143 | end
|
---|
144 |
|
---|
145 | for ali, flag in aliases
|
---|
146 | @ALIASES.push [ali, cmd_name, flag]
|
---|
147 | end
|
---|
148 | end
|
---|
149 |
|
---|
150 | # override = {NO_OVERRIDE, OVERRIDE_PRIVATE_ONLY, OVERRIDE_ALL}
|
---|
151 | def install_alias_method(to, from, override = NO_OVERRIDE)
|
---|
152 | to = to.id2name unless to.kind_of?(String)
|
---|
153 | from = from.id2name unless from.kind_of?(String)
|
---|
154 |
|
---|
155 | if override == OVERRIDE_ALL or
|
---|
156 | (override == OVERRIDE_PRIVATE_ONLY) && !respond_to?(to) or
|
---|
157 | (override == NO_OVERRIDE) && !respond_to?(to, true)
|
---|
158 | target = self
|
---|
159 | (class<<self;self;end).instance_eval{
|
---|
160 | if target.respond_to?(to, true) &&
|
---|
161 | !target.respond_to?(EXCB.irb_original_method_name(to), true)
|
---|
162 | alias_method(EXCB.irb_original_method_name(to), to)
|
---|
163 | end
|
---|
164 | alias_method to, from
|
---|
165 | }
|
---|
166 | else
|
---|
167 | print "irb: warn: can't alias #{to} from #{from}.\n"
|
---|
168 | end
|
---|
169 | end
|
---|
170 |
|
---|
171 | def self.irb_original_method_name(method_name)
|
---|
172 | "irb_" + method_name + "_org"
|
---|
173 | end
|
---|
174 |
|
---|
175 | def self.extend_object(obj)
|
---|
176 | unless (class<<obj;ancestors;end).include?(EXCB)
|
---|
177 | super
|
---|
178 | for ali, com, flg in @ALIASES
|
---|
179 | obj.install_alias_method(ali, com, flg)
|
---|
180 | end
|
---|
181 | end
|
---|
182 | end
|
---|
183 |
|
---|
184 | install_extend_commands
|
---|
185 | end
|
---|
186 |
|
---|
187 | # extension support for Context
|
---|
188 | module ContextExtender
|
---|
189 | CE = ContextExtender
|
---|
190 |
|
---|
191 | @EXTEND_COMMANDS = [
|
---|
192 | [:eval_history=, "irb/ext/history.rb"],
|
---|
193 | [:use_tracer=, "irb/ext/tracer.rb"],
|
---|
194 | [:math_mode=, "irb/ext/math-mode.rb"],
|
---|
195 | [:use_loader=, "irb/ext/use-loader.rb"],
|
---|
196 | [:save_history=, "irb/ext/save-history.rb"],
|
---|
197 | ]
|
---|
198 |
|
---|
199 | def self.install_extend_commands
|
---|
200 | for args in @EXTEND_COMMANDS
|
---|
201 | def_extend_command(*args)
|
---|
202 | end
|
---|
203 | end
|
---|
204 |
|
---|
205 | def self.def_extend_command(cmd_name, load_file, *aliases)
|
---|
206 | Context.module_eval %[
|
---|
207 | def #{cmd_name}(*opts, &b)
|
---|
208 | Context.module_eval {remove_method(:#{cmd_name})}
|
---|
209 | require "#{load_file}"
|
---|
210 | send :#{cmd_name}, *opts, &b
|
---|
211 | end
|
---|
212 | for ali in aliases
|
---|
213 | alias_method ali, cmd_name
|
---|
214 | end
|
---|
215 | ]
|
---|
216 | end
|
---|
217 |
|
---|
218 | CE.install_extend_commands
|
---|
219 | end
|
---|
220 |
|
---|
221 | module MethodExtender
|
---|
222 | def def_pre_proc(base_method, extend_method)
|
---|
223 | base_method = base_method.to_s
|
---|
224 | extend_method = extend_method.to_s
|
---|
225 |
|
---|
226 | alias_name = new_alias_name(base_method)
|
---|
227 | module_eval %[
|
---|
228 | alias_method alias_name, base_method
|
---|
229 | def #{base_method}(*opts)
|
---|
230 | send :#{extend_method}, *opts
|
---|
231 | send :#{alias_name}, *opts
|
---|
232 | end
|
---|
233 | ]
|
---|
234 | end
|
---|
235 |
|
---|
236 | def def_post_proc(base_method, extend_method)
|
---|
237 | base_method = base_method.to_s
|
---|
238 | extend_method = extend_method.to_s
|
---|
239 |
|
---|
240 | alias_name = new_alias_name(base_method)
|
---|
241 | module_eval %[
|
---|
242 | alias_method alias_name, base_method
|
---|
243 | def #{base_method}(*opts)
|
---|
244 | send :#{alias_name}, *opts
|
---|
245 | send :#{extend_method}, *opts
|
---|
246 | end
|
---|
247 | ]
|
---|
248 | end
|
---|
249 |
|
---|
250 | # return #{prefix}#{name}#{postfix}<num>
|
---|
251 | def new_alias_name(name, prefix = "__alias_of__", postfix = "__")
|
---|
252 | base_name = "#{prefix}#{name}#{postfix}"
|
---|
253 | all_methods = instance_methods(true) + private_instance_methods(true)
|
---|
254 | same_methods = all_methods.grep(/^#{Regexp.quote(base_name)}[0-9]*$/)
|
---|
255 | return base_name if same_methods.empty?
|
---|
256 | no = same_methods.size
|
---|
257 | while !same_methods.include?(alias_name = base_name + no)
|
---|
258 | no += 1
|
---|
259 | end
|
---|
260 | alias_name
|
---|
261 | end
|
---|
262 | end
|
---|
263 | end
|
---|
264 |
|
---|