emonti-wxirb 1.0.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/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
|
+
|