emonti-wxirb 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +173 -0
- data/bin/wxirb +14 -0
- data/lib/wxirb.rb +393 -0
- metadata +64 -0
data/README.rdoc
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
|
2
|
+
= WxIRB
|
3
|
+
|
4
|
+
This is a GUI "irb-alike" console based on WxRuby. I wrote this because I
|
5
|
+
needed a better way to prototype and debug my wxruby applications as I was
|
6
|
+
developing them. WxIRB puts you "inside" a Wx::App.run event loop, which
|
7
|
+
lets you easily play with window objects during run-time.
|
8
|
+
|
9
|
+
This is mostly just a port of why_the_lucky_stiff's Shoes GUI irb example to
|
10
|
+
wxruby with the addition of a command history and a few other convenience
|
11
|
+
methods added in the window classes.
|
12
|
+
|
13
|
+
Credit to Why.
|
14
|
+
See: http://github.com/why/shoes/blob/master/samples/expert-irb.rb
|
15
|
+
|
16
|
+
== Installation
|
17
|
+
|
18
|
+
WxIRB is available as a gem from github.
|
19
|
+
|
20
|
+
gem sources -a http://gems.github.com #(you only have to do this once)
|
21
|
+
sudo gem install wxirb
|
22
|
+
|
23
|
+
Or you can install it manually:
|
24
|
+
|
25
|
+
git clone git://github.com/emonti/wxirb.git
|
26
|
+
sudo cp wxirb/lib/wxirb.rb /usr/lib/ruby/1.8/site_ruby/1.8 # or wherever
|
27
|
+
sudo cp wxirb/bin/wxirb /usr/local/bin # or wherever
|
28
|
+
|
29
|
+
== Keyboard Interaction
|
30
|
+
|
31
|
+
WxIRB is designed to allow you to edit multi-line ruby statements in the
|
32
|
+
input window. The keyboard commands in the input text area are what you'
|
33
|
+
d expect in a multi-line text-box with some additional special keyboard
|
34
|
+
modifiers:
|
35
|
+
|
36
|
+
* ENTER : runs a statement through the mock IRB object. (what you'd expect)
|
37
|
+
* META+ENTER : sends a newline inside the window instead of running a command
|
38
|
+
* META+UP-ARROW : scroll up in history
|
39
|
+
* META+DOWN-ARROW : scroll down in history
|
40
|
+
|
41
|
+
WxIRB does not have a "run" button. Thank goodness!
|
42
|
+
|
43
|
+
The output text area is read-only from the UI. Tabbing focus from the output
|
44
|
+
text area should land you back in the input text area.
|
45
|
+
|
46
|
+
|
47
|
+
== Interacting with the WxIRB Window Objects
|
48
|
+
|
49
|
+
When running wx_irb.rb directly a global variable named '$wxirb' is created
|
50
|
+
for you which holds a reference to the WxIRB::BaseFrame window you are using.
|
51
|
+
|
52
|
+
This is done so you can easily access the UI frame object and children from
|
53
|
+
within the actual interface. A few convenience methods and accessors are
|
54
|
+
exposed this way:
|
55
|
+
|
56
|
+
* '$wxirb.clear' lets you clear the output window
|
57
|
+
|
58
|
+
* '$wxirb.history' returns the command history object (basically an array)
|
59
|
+
|
60
|
+
* '$wxirb.histdump(s=0, e=-1)' prints the history to the output text area.
|
61
|
+
to the output text area. Takes optional start and indexes for viewing just
|
62
|
+
a slice of the history array.
|
63
|
+
|
64
|
+
* '$wxirb.set_binding(bind)' sets the object binding to 'bind' which is used
|
65
|
+
when running eval() on user input. See also, 'Object Binding'.
|
66
|
+
|
67
|
+
|
68
|
+
== WxIRB CommandHistory
|
69
|
+
|
70
|
+
WxIRB maintains a persistent history log. The WxIRB history uses a separate
|
71
|
+
file from IRB which is defined by WxIRB::CommandHistory::HISTFILE. It is
|
72
|
+
actually just a YAMLized array.
|
73
|
+
|
74
|
+
By default, this is $HOME/.wxirb_history (no way of 'convenient' way of
|
75
|
+
configuring this right now)
|
76
|
+
|
77
|
+
History is implemented in the WxIRB::CommandHistory class. This is basically
|
78
|
+
an array with a few convenience methods and accessors:
|
79
|
+
|
80
|
+
* 'hpos' is an accessor to the history array position.
|
81
|
+
|
82
|
+
* 'prev' moves hpos back one and returns the history value at that position
|
83
|
+
|
84
|
+
* 'next' does the same thing, but forward
|
85
|
+
|
86
|
+
* '<<' is an override for the Array superclass that just updates the history
|
87
|
+
position variable.
|
88
|
+
|
89
|
+
* 'save!' saves current history to the persistent history file
|
90
|
+
|
91
|
+
* 'save' saves to the persistent history file only if the history has changed.
|
92
|
+
(this is used for an evt_idle event handler by the input text window)
|
93
|
+
|
94
|
+
* 'clear' empties the history array and persistent history file
|
95
|
+
|
96
|
+
|
97
|
+
== Output to WxIRB
|
98
|
+
|
99
|
+
The WxIRB::BaseFrame object also has an 'output' accessor which returns a
|
100
|
+
reference to the OutputTextCtrl text window half of the display. This object
|
101
|
+
has a few methods to make it usable (in duck-typing cases) as an IO object.
|
102
|
+
Note: This doesn't actually inherit from or implement all of IO class, however.
|
103
|
+
|
104
|
+
* '<<' outputs to the output window
|
105
|
+
|
106
|
+
* 'puts' prints directly to the output text area like 'IO.puts' and returns
|
107
|
+
nil.
|
108
|
+
|
109
|
+
* 'print' prints directly to the output text area like 'IO.print'
|
110
|
+
and returns nil.
|
111
|
+
|
112
|
+
* 'write' prints directly to the output text area like 'IO.write' and returns
|
113
|
+
the number of bytes written.
|
114
|
+
|
115
|
+
* Note: write, print, and puts all use brown text to differentiate from other
|
116
|
+
output.
|
117
|
+
|
118
|
+
* 'close', 'closed?' and 'flush' are also all defined but just emulate an
|
119
|
+
IO object with their return values. Other than that, they do nothing.
|
120
|
+
|
121
|
+
|
122
|
+
== Object Binding
|
123
|
+
|
124
|
+
Originally, WxIRB just ran 'eval' using the TOPLEVEL_BINDING (aka main)
|
125
|
+
This is how you usually run IRB. However, it may be desirable to instantiate
|
126
|
+
a wxirb console bound to a different namespace for debugging specific objects
|
127
|
+
and whatnot. So a few ways to manage bindings were added.
|
128
|
+
|
129
|
+
* WxIRB::BaseFrame.new now accepts an optional binding parameter. For example:
|
130
|
+
|
131
|
+
>> WxIRB::BaseFrame.new(nil, :binding => TOPLEVEL_BINDING)
|
132
|
+
|
133
|
+
By default, new WxIRB::BaseFrame objects will bind to themselves. Meaning,
|
134
|
+
commands will run in the scope of the WxIRB::BaseFrame scope itself.
|
135
|
+
TOPLEVEL_BINDING makes the scope 'main'.
|
136
|
+
|
137
|
+
When running 'wxirb.rb' directly, you will start with TOPLEVEL_BINDING, but
|
138
|
+
you can use the 'set_binding' method of $wxirb to change the binding on the
|
139
|
+
fly.
|
140
|
+
|
141
|
+
* As mentioned above, WxIRB::BaseFrame also has an instance method called
|
142
|
+
set_binding. This method lets you change WxIRB's binding on the fly.
|
143
|
+
Here's a short example from inside WxIRB running 'wxirb.rb' directly:
|
144
|
+
|
145
|
+
>> self
|
146
|
+
=> main
|
147
|
+
>> $wxirb
|
148
|
+
=> #<WxIRB::BaseFrame:0x51e8c0>
|
149
|
+
>> $wxirb.set_binding $wxirb.instance_eval { binding }
|
150
|
+
=> #<Binding:0x17235fe8>
|
151
|
+
>> self
|
152
|
+
=> #<WxIRB::BaseFrame:0x51e8c0>
|
153
|
+
>> @output
|
154
|
+
=> #<WxIRB::InputTextCtrl:0x51d5b0>
|
155
|
+
>> @output.puts "hello self"
|
156
|
+
hello self
|
157
|
+
=> nil
|
158
|
+
>> set_binding TOPLEVEL_BINDING
|
159
|
+
=> #<Binding:0x296d0>
|
160
|
+
>> self
|
161
|
+
=> main
|
162
|
+
|
163
|
+
|
164
|
+
== BUGS
|
165
|
+
|
166
|
+
* Running statements gets slow when the Output window gets very full. Not
|
167
|
+
really sure why this is, but running 'wxirb.clear' periodically helps.
|
168
|
+
|
169
|
+
* An effort is made to rescue most exceptions, but sometimes wxirb will
|
170
|
+
close due to an un-handled exception. Regular 'irb' does this too
|
171
|
+
sometimes... so I don't feel too bad.
|
172
|
+
|
173
|
+
|
data/bin/wxirb
ADDED
data/lib/wxirb.rb
ADDED
@@ -0,0 +1,393 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
begin
|
3
|
+
require 'rubygems'
|
4
|
+
rescue LoadError
|
5
|
+
end
|
6
|
+
require 'wx'
|
7
|
+
require 'yaml'
|
8
|
+
require 'irb/ruby-lex'
|
9
|
+
require 'stringio'
|
10
|
+
|
11
|
+
# This class is stolen almost verbatim from why_the_lucky_stiff's Shoes
|
12
|
+
# example. (http://github.com/why/shoes/blob/master/samples/expert-irb.rb)
|
13
|
+
# He gets all the credit.
|
14
|
+
class MimickIRB < RubyLex
|
15
|
+
attr_accessor :started
|
16
|
+
|
17
|
+
class Continue < StandardError; end
|
18
|
+
class Empty < StandardError; end
|
19
|
+
|
20
|
+
def initialize(bind=TOPLEVEL_BINDING)
|
21
|
+
set_binding(bind)
|
22
|
+
super()
|
23
|
+
set_input(StringIO.new)
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_binding(bind)
|
27
|
+
if bind.is_a? Binding
|
28
|
+
@bind = bind
|
29
|
+
else
|
30
|
+
raise "Invalid binding #{bind.inspect}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def run(str)
|
35
|
+
obj = nil
|
36
|
+
@io << str
|
37
|
+
@io.rewind
|
38
|
+
unless l = lex
|
39
|
+
raise Empty if @line == ''
|
40
|
+
else
|
41
|
+
case l.strip
|
42
|
+
when "reset"
|
43
|
+
@line = ""
|
44
|
+
else
|
45
|
+
@line << l << "\n"
|
46
|
+
if @ltype or @continue or @indent > 0
|
47
|
+
raise Continue
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
unless @line.empty?
|
52
|
+
obj = eval @line, @bind, "(irb)", @line_no
|
53
|
+
end
|
54
|
+
@line_no += @line.scan(/\n/).length
|
55
|
+
@line = ''
|
56
|
+
@exp_line_no = @line_no
|
57
|
+
|
58
|
+
@indent = 0
|
59
|
+
@indent_stack = []
|
60
|
+
|
61
|
+
$stdout.rewind
|
62
|
+
output = $stdout.read
|
63
|
+
$stdout.truncate(0)
|
64
|
+
$stdout.rewind
|
65
|
+
[output, obj]
|
66
|
+
rescue Object => e
|
67
|
+
case e when Empty, Continue
|
68
|
+
else @line = ""
|
69
|
+
end
|
70
|
+
raise e
|
71
|
+
ensure
|
72
|
+
set_input(StringIO.new)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
# Docs say there's a KeyEvent.cmd_down which is platform independent.
|
78
|
+
# But they LIE so we create our own...
|
79
|
+
class Wx::KeyEvent
|
80
|
+
case Wx::PLATFORM
|
81
|
+
when "WXMAC"
|
82
|
+
def inputmod_down; meta_down; end
|
83
|
+
when "WXMSW"
|
84
|
+
def inputmod_down; alt_down; end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
module WxIRB
|
90
|
+
# WxIRB maintains a persistent history log. The WxIRB history uses a separate
|
91
|
+
# file from IRB which is defined by WxIRB::CommandHistory::HISTFILE. It is
|
92
|
+
# actually just a YAMLized array.
|
93
|
+
#
|
94
|
+
# By default, the file is $HOME/.wxirb_history (no 'convenient' way of
|
95
|
+
# configuring this right now aside from changing the constant)
|
96
|
+
#
|
97
|
+
# History is implemented in the WxIRB::CommandHistory class. This is
|
98
|
+
# basically just an Array with a few convenience methods and accessors.
|
99
|
+
class CmdHistory < Array
|
100
|
+
# an accessor to the history array position.
|
101
|
+
attr_accessor :hpos
|
102
|
+
|
103
|
+
# location of the persistent history file
|
104
|
+
HISTFILE = "#{ENV["HOME"]}/.wxirb_history"
|
105
|
+
|
106
|
+
# Initializes a CommandHistory object and loads persistent history
|
107
|
+
# from the file specified in HISTFILE
|
108
|
+
def initialize(*opts)
|
109
|
+
super(*opts)
|
110
|
+
@hpos = nil
|
111
|
+
begin
|
112
|
+
self.replace YAML.load_file(HISTFILE)
|
113
|
+
@hpos = self.size-1
|
114
|
+
rescue
|
115
|
+
STDERR.puts "Note - error restoring history: #{$!.inspect}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# moves hpos back one and returns the history value at that position
|
120
|
+
def prev
|
121
|
+
return nil if self.empty?
|
122
|
+
val = self[@hpos].to_s
|
123
|
+
@hpos -= 1 unless @hpos == 0
|
124
|
+
return val
|
125
|
+
end
|
126
|
+
|
127
|
+
# moves hpos forward one and returns the history value at that position
|
128
|
+
def next
|
129
|
+
if not self.empty? and @hpos != self.size-1
|
130
|
+
@hpos += 1
|
131
|
+
self[@hpos].to_s
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# An override for the Array superclass that just updates the history
|
136
|
+
# position variable. This also ensures that history elements are appended
|
137
|
+
# as strings.
|
138
|
+
def << (val)
|
139
|
+
@hpos = self.size
|
140
|
+
@changed=true
|
141
|
+
super(val.to_s)
|
142
|
+
end
|
143
|
+
|
144
|
+
# empties the history array and persistent history file
|
145
|
+
def clear
|
146
|
+
self.replace([])
|
147
|
+
self.save!
|
148
|
+
end
|
149
|
+
|
150
|
+
# saves current history to the persistent history file
|
151
|
+
def save!
|
152
|
+
ret=nil
|
153
|
+
begin
|
154
|
+
ret=File.open(HISTFILE, "w") {|f| f.write(self.to_yaml) }
|
155
|
+
rescue Errno::ENOENT
|
156
|
+
STDERR.puts "Error: couldn't save history - #{$!}"
|
157
|
+
end
|
158
|
+
@changed=nil
|
159
|
+
ret
|
160
|
+
end
|
161
|
+
|
162
|
+
# saves to the persistent history file only if the history has changed.
|
163
|
+
# (this is used for an evt_idle event handler by the input text window)
|
164
|
+
def save(force=false)
|
165
|
+
return nil unless @changed or force
|
166
|
+
self.save!
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
# Keyboard commands in the input text area are what you'd expect in a
|
172
|
+
# multi-line textbox with some additional special keyboard modifiers.
|
173
|
+
# See InputTextCtrl#on_char
|
174
|
+
class InputTextCtrl < Wx::TextCtrl
|
175
|
+
attr_accessor :history
|
176
|
+
include Wx
|
177
|
+
STYLE = TE_PROCESS_TAB|TE_PROCESS_ENTER|WANTS_CHARS|TE_MULTILINE
|
178
|
+
|
179
|
+
def initialize(parent, output, mirb)
|
180
|
+
super(parent, :style => STYLE)
|
181
|
+
@history = CmdHistory.new
|
182
|
+
@output = output
|
183
|
+
|
184
|
+
@stdout_save = $stdout
|
185
|
+
$stdout = StringIO.new
|
186
|
+
@mirb = mirb
|
187
|
+
evt_idle :on_idle
|
188
|
+
evt_char :on_char
|
189
|
+
|
190
|
+
@font = Wx::Font.new(10, Wx::MODERN, Wx::NORMAL, Wx::NORMAL)
|
191
|
+
set_default_style Wx::TextAttr.new(Wx::BLACK, Wx::WHITE, @font)
|
192
|
+
|
193
|
+
paint do |dc|
|
194
|
+
b_height = dc.get_text_extent("@", @font)[1] * 4
|
195
|
+
cache_best_size Wx::Size.new(self.size.width, b_height)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Fires on Wx::IdleEvent - saves persistent history if history has changed
|
200
|
+
def on_idle(evt)
|
201
|
+
history.save
|
202
|
+
end
|
203
|
+
|
204
|
+
# Fires on text input events.
|
205
|
+
# Implements a few special keyboard handlers
|
206
|
+
# * META+ENTER : sends a newline inside the input window instead of
|
207
|
+
# actually running a command
|
208
|
+
# * META+UP-ARROW : scroll up in history
|
209
|
+
# * META+DOWN-ARROW : scroll down in history
|
210
|
+
def on_char(evt)
|
211
|
+
k = evt.key_code
|
212
|
+
mflag = evt.modifiers
|
213
|
+
|
214
|
+
if [MOD_NONE, MOD_SHIFT].include?(mflag) and (0x20..0x7f).include?(k)
|
215
|
+
evt.skip()
|
216
|
+
return
|
217
|
+
end
|
218
|
+
|
219
|
+
case k
|
220
|
+
when K_RETURN
|
221
|
+
if evt.inputmod_down
|
222
|
+
# multi-line command uses meta-down-arrow for newline
|
223
|
+
self.write_text("\n")
|
224
|
+
else
|
225
|
+
@history << self.value
|
226
|
+
run self.value
|
227
|
+
self.clear
|
228
|
+
end
|
229
|
+
return
|
230
|
+
when (evt.inputmod_down and K_UP)
|
231
|
+
if hist=history.prev
|
232
|
+
self.value = hist
|
233
|
+
self.set_insertion_point_end
|
234
|
+
return
|
235
|
+
end
|
236
|
+
when (evt.inputmod_down and K_DOWN)
|
237
|
+
if hist=history.next
|
238
|
+
self.value = hist
|
239
|
+
self.set_insertion_point_end
|
240
|
+
return
|
241
|
+
else
|
242
|
+
self.clear
|
243
|
+
end
|
244
|
+
end
|
245
|
+
evt.skip()
|
246
|
+
end
|
247
|
+
|
248
|
+
# Runs a command through the mock irb class, handles display details.
|
249
|
+
def run(cmd)
|
250
|
+
(lines = cmd.split(/\r?\n/)).each_index do |idx|
|
251
|
+
begin
|
252
|
+
line = lines[idx] + "\n"
|
253
|
+
@output.default_style = Wx::TextAttr.new(Wx::BLUE)
|
254
|
+
@output << ">> #{line}"
|
255
|
+
|
256
|
+
out, obj = @mirb.run(line)
|
257
|
+
@output.default_style = Wx::TextAttr.new(Wx::BLACK)
|
258
|
+
@output << out
|
259
|
+
@output.default_style = Wx::TextAttr.new(Wx::Colour.new(100,100,100))
|
260
|
+
@output << "=> #{obj.inspect}\n"
|
261
|
+
rescue MimickIRB::Empty
|
262
|
+
rescue MimickIRB::Continue
|
263
|
+
if idx == lines.size-1
|
264
|
+
@output.default_style = Wx::TextAttr.new(Wx::LIGHT_GREY)
|
265
|
+
@output << "...\n"
|
266
|
+
end
|
267
|
+
rescue Exception => se
|
268
|
+
@output.default_style = Wx::TextAttr.new(Wx::RED)
|
269
|
+
@output << (se.inspect + "\n" + se.backtrace.join("\n") + "\n")
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
|
276
|
+
# The output textbox.
|
277
|
+
# This object has a few methods to make it usable (in duck-typing cases) as
|
278
|
+
# an IO object. This doesn't actually inherit or implement from the IO
|
279
|
+
# class, however.
|
280
|
+
class OutputTextCtrl < Wx::TextCtrl
|
281
|
+
include Wx
|
282
|
+
STYLE = TE_READONLY|TE_MULTILINE|TE_RICH|TE_RICH2|TE_CHARWRAP
|
283
|
+
|
284
|
+
def initialize(parent)
|
285
|
+
super(parent, :style => STYLE)
|
286
|
+
|
287
|
+
font = Wx::Font.new(10, Wx::MODERN, Wx::NORMAL, Wx::NORMAL)
|
288
|
+
set_default_style Wx::TextAttr.new(Wx::BLACK, Wx::WHITE, font)
|
289
|
+
|
290
|
+
@io_style=Wx::TextAttr.new(Wx::Colour.new(180, 104, 52))
|
291
|
+
end
|
292
|
+
|
293
|
+
#----------------------------------------------------------------------
|
294
|
+
# some methods (as i think of/need them) to make it possible to use
|
295
|
+
# the output text area as a fake IO object
|
296
|
+
#----------------------------------------------------------------------
|
297
|
+
|
298
|
+
# '<<' outputs to the output window
|
299
|
+
alias :<< :append_text
|
300
|
+
|
301
|
+
# 'close', 'closed?' and 'flush' are also all defined but just emulate
|
302
|
+
# an IO object with their return values. Other than that, they do nothing.
|
303
|
+
def close ; nil; end
|
304
|
+
def closed? ; false ; end
|
305
|
+
def flush; self; end
|
306
|
+
|
307
|
+
# prints directly to the output text area like 'IO.print'
|
308
|
+
# and returns nil.
|
309
|
+
def print(*args)
|
310
|
+
set_default_style @io_style
|
311
|
+
self << args.flatten.join
|
312
|
+
nil
|
313
|
+
end
|
314
|
+
|
315
|
+
# Displays directly to the output text area like 'IO.puts' and returns nil.
|
316
|
+
def puts(*args)
|
317
|
+
set_default_style @io_style
|
318
|
+
self << args.flatten.map do |o|
|
319
|
+
s=o.to_s
|
320
|
+
(s[-1,1]=="\n") ? s : s + "\n"
|
321
|
+
end.join
|
322
|
+
nil
|
323
|
+
end
|
324
|
+
|
325
|
+
# Displays directly to the output text area like 'IO.write' and returns
|
326
|
+
# the number of bytes written.
|
327
|
+
def write(dat)
|
328
|
+
set_default_style @io_style
|
329
|
+
out = dat.to_s
|
330
|
+
self << out
|
331
|
+
out.size
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
# This window object is parent to the Input and Output text areas. It
|
336
|
+
# provides a sliding splitter control between the top and bottom text boxes.
|
337
|
+
class TerminalSplitter < Wx::SplitterWindow
|
338
|
+
def initialize(parent)
|
339
|
+
super(parent, :style => Wx::SP_LIVE_UPDATE)
|
340
|
+
self.set_sash_gravity(1.0)
|
341
|
+
evt_splitter_dclick self, :on_dclick
|
342
|
+
end
|
343
|
+
|
344
|
+
def on_dclick(evt)
|
345
|
+
set_sash_position(- @bottom.best_size.height)
|
346
|
+
end
|
347
|
+
|
348
|
+
def split_horizontally(top, bottom, pos=nil)
|
349
|
+
@top ||= top
|
350
|
+
@bottom ||= bottom
|
351
|
+
minsz = @bottom.best_size.height
|
352
|
+
set_minimum_pane_size(minsz) # this also prevents unsplitting.
|
353
|
+
pos ||= - minsz
|
354
|
+
super(@top, @bottom, pos)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
|
359
|
+
# Parent and top-level window for all the wxirb controls.
|
360
|
+
class BaseFrame < Wx::Frame
|
361
|
+
attr_reader :output, :input
|
362
|
+
|
363
|
+
def initialize(parent, opts={})
|
364
|
+
bind = (opts.delete(:binding) || binding)
|
365
|
+
@mirb=MimickIRB.new(bind)
|
366
|
+
|
367
|
+
opts[:title] ||= "WxIRB"
|
368
|
+
super(parent, opts)
|
369
|
+
|
370
|
+
@splitter = TerminalSplitter.new(self)
|
371
|
+
@output = OutputTextCtrl.new(@splitter)
|
372
|
+
@input = InputTextCtrl.new(@splitter, @output, @mirb)
|
373
|
+
@splitter.split_horizontally(@output, @input)
|
374
|
+
@input.set_focus()
|
375
|
+
end
|
376
|
+
|
377
|
+
# Allow our binding to be changed on the fly
|
378
|
+
def set_binding(bind); @mirb.set_binding(bind); end
|
379
|
+
|
380
|
+
# Clears the output window
|
381
|
+
def clear; @output.clear ; end
|
382
|
+
|
383
|
+
# Returns the window's command history object (see WxIRB::CommandHistory)
|
384
|
+
def history; @input.history ; end
|
385
|
+
|
386
|
+
# Prints the history to the output text area. Takes optional start and
|
387
|
+
# end position indexes for viewing just a slice of the history array.
|
388
|
+
def histdump(s=0, e=-1)
|
389
|
+
puts self.history[s..e]
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: emonti-wxirb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Monti
|
8
|
+
autorequire: wxirb
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-02-13 00:00:00 -08:00
|
13
|
+
default_executable: wxirb
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: wxruby
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.9.9
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: emonti@matasano.com
|
27
|
+
executables:
|
28
|
+
- wxirb
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.rdoc
|
33
|
+
files:
|
34
|
+
- README.rdoc
|
35
|
+
- bin/wxirb
|
36
|
+
- lib/wxirb.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://www.matasano.com
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.2.0
|
60
|
+
signing_key:
|
61
|
+
specification_version: 2
|
62
|
+
summary: A GUI IRB-like console based on WxRuby
|
63
|
+
test_files: []
|
64
|
+
|