fxri 0.3.3 → 0.3.4
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/bugs/fxri bug `concat' can't convert nil into Array (TypeError).eml +50 -0
- data/bugs/fxri with Ruby v1.8.5 via OneClickInstaller v1.8.5-21.eml +167 -0
- data/fxri +344 -319
- data/fxri-0.3.4.gem +0 -0
- data/fxri.gemspec +24 -24
- data/lib/Empty_Text_Field_Handler.rb +63 -63
- data/lib/FoxDisplayer.rb +148 -148
- data/lib/FoxTextFormatter.rb +274 -274
- data/lib/Globals.rb +50 -48
- data/lib/Icon_Loader.rb +35 -35
- data/lib/Packet_Item.rb +178 -178
- data/lib/Packet_List.rb +192 -192
- data/lib/Recursive_Open_Struct.rb +238 -233
- data/lib/RiManager.rb +159 -154
- data/lib/Search_Engine.rb +165 -165
- data/lib/fxirb-0.2.1/CHANGELOG +31 -0
- data/lib/fxirb-0.2.1/fxirb.rb +395 -0
- data/lib/fxirb.rb +400 -395
- metadata +24 -17
- data/fxri.kpf +0 -66
@@ -0,0 +1,31 @@
|
|
1
|
+
0.2.1 - Martin DeMello - 2005/04/13
|
2
|
+
* 'gets' implemented (with much help from Csaba Henk)
|
3
|
+
|
4
|
+
0.2.0 - Martin DeMello - 2005/04/10
|
5
|
+
* Multiline edit
|
6
|
+
* Settable on_exit proc
|
7
|
+
|
8
|
+
0.1.4 - Martin DeMello - 2005/02/19
|
9
|
+
* Minor code cleanup
|
10
|
+
* Dedentation on ], } or end
|
11
|
+
* Ctrl-D, Ctrl-U and Ctrl-K keys bound
|
12
|
+
|
13
|
+
0.1.3 - Martin DeMello - 2004/03/21
|
14
|
+
|
15
|
+
* Added ability to select text, and return the cursor to the proper position
|
16
|
+
* Changed font to Lucida Console
|
17
|
+
* Added indentation
|
18
|
+
|
19
|
+
0.1.2 - Frailis - 2003/01/10
|
20
|
+
|
21
|
+
* Fixed commands history
|
22
|
+
|
23
|
+
0.1.1 - Frailis - 2003/01/07
|
24
|
+
|
25
|
+
* Removed IOEmulate module because it redirects every "p" operation in a program which embeds FXIrb
|
26
|
+
|
27
|
+
0.1.0 - Frailis - 2003/01/02
|
28
|
+
|
29
|
+
* Tested on ruby 1.6.7 and 1.7.3
|
30
|
+
* Added commands history and terminal behaviour
|
31
|
+
|
@@ -0,0 +1,395 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
# TODO
|
4
|
+
# - handle user input redirection
|
5
|
+
# - readline
|
6
|
+
|
7
|
+
# Credits:
|
8
|
+
# - Initial linux version: Gilles Filippini
|
9
|
+
# - Initial windows port : Marco Frailis
|
10
|
+
# - Currently maintained and developed by
|
11
|
+
# Martin DeMello <martindemello@gmail.com>
|
12
|
+
|
13
|
+
require "fox12"
|
14
|
+
require "irb"
|
15
|
+
require "singleton"
|
16
|
+
require "English"
|
17
|
+
|
18
|
+
include Fox
|
19
|
+
|
20
|
+
STDOUT.sync = true
|
21
|
+
|
22
|
+
class FXIRBInputMethod < IRB::StdioInputMethod
|
23
|
+
|
24
|
+
attr_accessor :print_prompt, :gets_mode
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
super
|
28
|
+
@history = 1
|
29
|
+
@begin = nil
|
30
|
+
@print_prompt = true
|
31
|
+
@end = nil
|
32
|
+
@continued_from = nil
|
33
|
+
@gets_mode = false
|
34
|
+
end
|
35
|
+
|
36
|
+
def gets
|
37
|
+
if @gets_mode
|
38
|
+
return FXIrb.instance.get_line
|
39
|
+
end
|
40
|
+
|
41
|
+
if (a = @prompt.match(/(\d+)[>*]/))
|
42
|
+
level = a[1].to_i
|
43
|
+
else
|
44
|
+
level = 0
|
45
|
+
end
|
46
|
+
|
47
|
+
if level > 0
|
48
|
+
@continued_from ||= @line_no
|
49
|
+
elsif @continued_from
|
50
|
+
merge_last(@line_no-@continued_from+1)
|
51
|
+
@continued_from = nil
|
52
|
+
end
|
53
|
+
|
54
|
+
if @print_prompt
|
55
|
+
print @prompt
|
56
|
+
|
57
|
+
#indentation
|
58
|
+
print " "*level
|
59
|
+
end
|
60
|
+
|
61
|
+
str = FXIrb.instance.get_line
|
62
|
+
|
63
|
+
@line_no += 1
|
64
|
+
@history = @line_no + 1
|
65
|
+
@line[@line_no] = str
|
66
|
+
|
67
|
+
str
|
68
|
+
end
|
69
|
+
|
70
|
+
# merge a block spanning several lines into one \n-separated line
|
71
|
+
def merge_last(i)
|
72
|
+
return unless i > 1
|
73
|
+
range = -i..-1
|
74
|
+
@line[range] = @line[range].map {|l| l.chomp}.join("\n")
|
75
|
+
@line_no -= (i-1)
|
76
|
+
@history -= (i-1)
|
77
|
+
end
|
78
|
+
|
79
|
+
def prevCmd
|
80
|
+
return "" if @gets_mode
|
81
|
+
|
82
|
+
if @line_no > 0
|
83
|
+
@history -= 1 unless @history <= 1
|
84
|
+
return line(@history)
|
85
|
+
end
|
86
|
+
return ""
|
87
|
+
end
|
88
|
+
|
89
|
+
def nextCmd
|
90
|
+
return "" if @gets_mode
|
91
|
+
|
92
|
+
if (@line_no > 0) && (@history < @line_no)
|
93
|
+
@history += 1
|
94
|
+
return line(@history)
|
95
|
+
end
|
96
|
+
return ""
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
module IRB
|
102
|
+
|
103
|
+
def IRB.start_in_fxirb(im)
|
104
|
+
if RUBY_VERSION < "1.7.3"
|
105
|
+
IRB.initialize(nil)
|
106
|
+
IRB.parse_opts
|
107
|
+
IRB.load_modules
|
108
|
+
else
|
109
|
+
IRB.setup(nil)
|
110
|
+
end
|
111
|
+
|
112
|
+
irb = Irb.new(nil, im)
|
113
|
+
|
114
|
+
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
115
|
+
@CONF[:MAIN_CONTEXT] = irb.context
|
116
|
+
trap("SIGINT") do
|
117
|
+
irb.signal_handle
|
118
|
+
end
|
119
|
+
|
120
|
+
class << irb.context.workspace.main
|
121
|
+
def gets
|
122
|
+
inp = IRB.conf[:MAIN_CONTEXT].io
|
123
|
+
inp.gets_mode = true
|
124
|
+
retval = IRB.conf[:MAIN_CONTEXT].io.gets
|
125
|
+
inp.gets_mode = false
|
126
|
+
retval
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
catch(:IRB_EXIT) do
|
131
|
+
irb.eval_input
|
132
|
+
end
|
133
|
+
print "\n"
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
class FXIrb < FXText
|
141
|
+
include Singleton
|
142
|
+
include Responder
|
143
|
+
|
144
|
+
attr_reader :input
|
145
|
+
|
146
|
+
def FXIrb.init(p, tgt, sel, opts)
|
147
|
+
unless @__instance__
|
148
|
+
Thread.critical = true
|
149
|
+
begin
|
150
|
+
@__instance__ ||= new(p, tgt, sel, opts)
|
151
|
+
ensure
|
152
|
+
Thread.critical = false
|
153
|
+
end
|
154
|
+
end
|
155
|
+
return @__instance__
|
156
|
+
end
|
157
|
+
|
158
|
+
def initialize(p, tgt, sel, opts)
|
159
|
+
FXMAPFUNC(SEL_KEYRELEASE, 0, "onKeyRelease")
|
160
|
+
FXMAPFUNC(SEL_KEYPRESS, 0, "onKeyPress")
|
161
|
+
FXMAPFUNC(SEL_LEFTBUTTONPRESS,0,"onLeftBtnPress")
|
162
|
+
FXMAPFUNC(SEL_MIDDLEBUTTONPRESS,0,"onMiddleBtnPress")
|
163
|
+
FXMAPFUNC(SEL_LEFTBUTTONRELEASE,0,"onLeftBtnRelease")
|
164
|
+
|
165
|
+
super
|
166
|
+
setFont(FXFont.new(FXApp.instance, "lucida console", 9))
|
167
|
+
@anchor = 0
|
168
|
+
end
|
169
|
+
|
170
|
+
def create
|
171
|
+
super
|
172
|
+
setFocus
|
173
|
+
# IRB initialization
|
174
|
+
@inputAdded = 0
|
175
|
+
@input = IO.pipe
|
176
|
+
$DEFAULT_OUTPUT = self
|
177
|
+
|
178
|
+
@im = FXIRBInputMethod.new
|
179
|
+
@irb = Thread.new {
|
180
|
+
IRB.start_in_fxirb(@im)
|
181
|
+
self.crash
|
182
|
+
}
|
183
|
+
|
184
|
+
|
185
|
+
@multiline = false
|
186
|
+
|
187
|
+
@exit_proc = lambda {exit}
|
188
|
+
end
|
189
|
+
|
190
|
+
def on_exit(&block)
|
191
|
+
@exit_proc = block
|
192
|
+
end
|
193
|
+
|
194
|
+
def crash
|
195
|
+
instance_eval(&@exit_proc)
|
196
|
+
end
|
197
|
+
|
198
|
+
def onKeyRelease(sender, sel, event)
|
199
|
+
case event.code
|
200
|
+
when Fox::KEY_Return, Fox::KEY_KP_Enter
|
201
|
+
newLineEntered
|
202
|
+
end
|
203
|
+
return 1
|
204
|
+
end
|
205
|
+
|
206
|
+
def onKeyPress(sender,sel,event)
|
207
|
+
case event.code
|
208
|
+
when Fox::KEY_Return, Fox::KEY_KP_Enter
|
209
|
+
setCursorPos(getLength)
|
210
|
+
super
|
211
|
+
when Fox::KEY_Up,Fox::KEY_KP_Up
|
212
|
+
str = extractText(@anchor, getCursorPos-@anchor)
|
213
|
+
if str =~ /\n/
|
214
|
+
@multiline = true
|
215
|
+
super
|
216
|
+
setCursorPos(@anchor+1) if getCursorPos < @anchor
|
217
|
+
else
|
218
|
+
history(:prev) unless @multiline
|
219
|
+
end
|
220
|
+
when Fox::KEY_Down,Fox::KEY_KP_Down
|
221
|
+
str = extractText(getCursorPos, getLength - getCursorPos)
|
222
|
+
if str =~ /\n/
|
223
|
+
@multiline = true
|
224
|
+
super
|
225
|
+
else
|
226
|
+
history(:next) unless @multiline
|
227
|
+
end
|
228
|
+
when Fox::KEY_Left,Fox::KEY_KP_Left
|
229
|
+
if getCursorPos > @anchor
|
230
|
+
super
|
231
|
+
end
|
232
|
+
when Fox::KEY_Delete,Fox::KEY_KP_Delete,Fox::KEY_BackSpace
|
233
|
+
if getCursorPos > @anchor
|
234
|
+
super
|
235
|
+
end
|
236
|
+
when Fox::KEY_Home, Fox::KEY_KP_Home
|
237
|
+
setCursorPos(@anchor)
|
238
|
+
when Fox::KEY_End, Fox::KEY_KP_End
|
239
|
+
setCursorPos(getLength)
|
240
|
+
when Fox::KEY_Page_Up, Fox::KEY_KP_Page_Up
|
241
|
+
history(:prev)
|
242
|
+
when Fox::KEY_Page_Down, Fox::KEY_KP_Page_Down
|
243
|
+
history(:next)
|
244
|
+
when Fox::KEY_bracketright
|
245
|
+
#auto-dedent if the } or ] is on a line by itself
|
246
|
+
if (emptyline? or (getline == "en")) and indented?
|
247
|
+
dedent
|
248
|
+
end
|
249
|
+
super
|
250
|
+
when Fox::KEY_u
|
251
|
+
if (event.state & CONTROLMASK) != 0
|
252
|
+
str = extractText(getCursorPos, getLength - getCursorPos)
|
253
|
+
rmline
|
254
|
+
appendText(str)
|
255
|
+
setCursorPos(@anchor)
|
256
|
+
end
|
257
|
+
super
|
258
|
+
when Fox::KEY_k
|
259
|
+
if (event.state & CONTROLMASK) != 0
|
260
|
+
str = extractText(@anchor, getCursorPos-@anchor)
|
261
|
+
rmline
|
262
|
+
appendText(str)
|
263
|
+
setCursorPos(getLength)
|
264
|
+
end
|
265
|
+
super
|
266
|
+
when Fox::KEY_d
|
267
|
+
if (event.state & CONTROLMASK) != 0
|
268
|
+
#Ctrl - D
|
269
|
+
rmline
|
270
|
+
appendText("exit")
|
271
|
+
newLineEntered
|
272
|
+
else
|
273
|
+
# test for 'end' so we can dedent
|
274
|
+
if (getline == "en") and indented?
|
275
|
+
dedent
|
276
|
+
end
|
277
|
+
end
|
278
|
+
super
|
279
|
+
else
|
280
|
+
super
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def dedent
|
285
|
+
str = getline
|
286
|
+
@anchor -= 2
|
287
|
+
rmline
|
288
|
+
appendText(str)
|
289
|
+
setCursorPos(getLength)
|
290
|
+
end
|
291
|
+
|
292
|
+
def history(dir)
|
293
|
+
str = (dir == :prev) ? @im.prevCmd.chomp : @im.nextCmd.chomp
|
294
|
+
if str != ""
|
295
|
+
removeText(@anchor, getLength-@anchor)
|
296
|
+
write(str)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
def getline
|
301
|
+
extractText(@anchor, getLength-@anchor)
|
302
|
+
end
|
303
|
+
|
304
|
+
def rmline
|
305
|
+
str = getline
|
306
|
+
removeText(@anchor, getLength-@anchor)
|
307
|
+
str
|
308
|
+
end
|
309
|
+
|
310
|
+
def emptyline?
|
311
|
+
getline == ""
|
312
|
+
end
|
313
|
+
|
314
|
+
def indented?
|
315
|
+
extractText(@anchor-2, 2) == " "
|
316
|
+
end
|
317
|
+
|
318
|
+
def onLeftBtnPress(sender,sel,event)
|
319
|
+
@store_anchor = @anchor
|
320
|
+
setFocus
|
321
|
+
super
|
322
|
+
end
|
323
|
+
|
324
|
+
def onLeftBtnRelease(sender,sel,event)
|
325
|
+
super
|
326
|
+
@anchor = @store_anchor
|
327
|
+
setCursorPos(@anchor)
|
328
|
+
setCursorPos(getLength)
|
329
|
+
end
|
330
|
+
|
331
|
+
def onMiddleBtnPress(sender,sel,event)
|
332
|
+
pos=getPosAt(event.win_x,event.win_y)
|
333
|
+
if pos >= @anchor
|
334
|
+
super
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def newLineEntered
|
339
|
+
processCommandLine(extractText(@anchor, getLength-@anchor))
|
340
|
+
end
|
341
|
+
|
342
|
+
def processCommandLine(cmd)
|
343
|
+
@multiline = false
|
344
|
+
lines = cmd.split(/\n/)
|
345
|
+
lines.each {|i|
|
346
|
+
@input[1].puts i
|
347
|
+
@inputAdded += 1
|
348
|
+
}
|
349
|
+
@im.print_prompt = false
|
350
|
+
while (@inputAdded > 0) do
|
351
|
+
@irb.run
|
352
|
+
end
|
353
|
+
@im.merge_last(lines.length)
|
354
|
+
@im.print_prompt = true
|
355
|
+
end
|
356
|
+
|
357
|
+
def sendCommand(cmd)
|
358
|
+
setCursorPos(getLength)
|
359
|
+
makePositionVisible(getLength) unless isPosVisible(getLength)
|
360
|
+
cmd += "\n"
|
361
|
+
appendText(cmd)
|
362
|
+
processCommandLine(cmd)
|
363
|
+
end
|
364
|
+
|
365
|
+
def write(obj)
|
366
|
+
str = obj.to_s
|
367
|
+
appendText(str)
|
368
|
+
setCursorPos(getLength)
|
369
|
+
makePositionVisible(getLength) unless isPosVisible(getLength)
|
370
|
+
return str.length
|
371
|
+
end
|
372
|
+
|
373
|
+
def get_line
|
374
|
+
@anchor = getLength
|
375
|
+
if @inputAdded == 0
|
376
|
+
Thread.stop
|
377
|
+
end
|
378
|
+
@inputAdded -= 1
|
379
|
+
return @input[0].gets
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
# Stand alone run
|
384
|
+
if __FILE__ == $0
|
385
|
+
application = FXApp.new("FXIrb", "ruby")
|
386
|
+
application.threadsEnabled = true
|
387
|
+
Thread.abort_on_exception = true
|
388
|
+
application.init(ARGV)
|
389
|
+
window = FXMainWindow.new(application, "FXIrb", nil, nil, DECOR_ALL, 0, 0, 580, 500)
|
390
|
+
fxirb = FXIrb.init(window, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP|TEXT_SHOWACTIVE)
|
391
|
+
application.create
|
392
|
+
window.show(PLACEMENT_SCREEN)
|
393
|
+
fxirb.on_exit {exit}
|
394
|
+
application.run
|
395
|
+
end
|
data/lib/fxirb.rb
CHANGED
@@ -1,395 +1,400 @@
|
|
1
|
-
#! /usr/bin/env ruby
|
2
|
-
|
3
|
-
# TODO
|
4
|
-
# - handle user input redirection
|
5
|
-
# - readline
|
6
|
-
|
7
|
-
# Credits:
|
8
|
-
# - Initial linux version: Gilles Filippini
|
9
|
-
# - Initial windows port : Marco Frailis
|
10
|
-
# - Currently maintained and developed by
|
11
|
-
# Martin DeMello <martindemello@gmail.com>
|
12
|
-
|
13
|
-
require "
|
14
|
-
require "irb"
|
15
|
-
require "singleton"
|
16
|
-
require "English"
|
17
|
-
|
18
|
-
include Fox
|
19
|
-
|
20
|
-
STDOUT.sync = true
|
21
|
-
|
22
|
-
class FXIRBInputMethod < IRB::StdioInputMethod
|
23
|
-
|
24
|
-
attr_accessor :print_prompt, :gets_mode
|
25
|
-
|
26
|
-
def initialize
|
27
|
-
super
|
28
|
-
@history = 1
|
29
|
-
@begin = nil
|
30
|
-
@print_prompt = true
|
31
|
-
@end = nil
|
32
|
-
@continued_from = nil
|
33
|
-
@gets_mode = false
|
34
|
-
end
|
35
|
-
|
36
|
-
def gets
|
37
|
-
if @gets_mode
|
38
|
-
return FXIrb.instance.get_line
|
39
|
-
end
|
40
|
-
|
41
|
-
if (a = @prompt.match(/(\d+)[>*]/))
|
42
|
-
level = a[1].to_i
|
43
|
-
else
|
44
|
-
level = 0
|
45
|
-
end
|
46
|
-
|
47
|
-
if level > 0
|
48
|
-
@continued_from ||= @line_no
|
49
|
-
elsif @continued_from
|
50
|
-
merge_last(@line_no-@continued_from+1)
|
51
|
-
@continued_from = nil
|
52
|
-
end
|
53
|
-
|
54
|
-
if @print_prompt
|
55
|
-
print @prompt
|
56
|
-
|
57
|
-
#indentation
|
58
|
-
print " "*level
|
59
|
-
end
|
60
|
-
|
61
|
-
str = FXIrb.instance.get_line
|
62
|
-
|
63
|
-
@line_no += 1
|
64
|
-
@history = @line_no + 1
|
65
|
-
@line[@line_no] = str
|
66
|
-
|
67
|
-
str
|
68
|
-
end
|
69
|
-
|
70
|
-
# merge a block spanning several lines into one \n-separated line
|
71
|
-
def merge_last(i)
|
72
|
-
return unless i > 1
|
73
|
-
range = -i..-1
|
74
|
-
@line[range] = @line[range].map {|l| l.chomp}.join("\n")
|
75
|
-
@line_no -= (i-1)
|
76
|
-
@history -= (i-1)
|
77
|
-
end
|
78
|
-
|
79
|
-
def prevCmd
|
80
|
-
return "" if @gets_mode
|
81
|
-
|
82
|
-
if @line_no > 0
|
83
|
-
@history -= 1 unless @history <= 1
|
84
|
-
return line(@history)
|
85
|
-
end
|
86
|
-
return ""
|
87
|
-
end
|
88
|
-
|
89
|
-
def nextCmd
|
90
|
-
return "" if @gets_mode
|
91
|
-
|
92
|
-
if (@line_no > 0) && (@history < @line_no)
|
93
|
-
@history += 1
|
94
|
-
return line(@history)
|
95
|
-
end
|
96
|
-
return ""
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
module IRB
|
102
|
-
|
103
|
-
def IRB.start_in_fxirb(im)
|
104
|
-
if RUBY_VERSION < "1.7.3"
|
105
|
-
IRB.initialize(nil)
|
106
|
-
IRB.parse_opts
|
107
|
-
IRB.load_modules
|
108
|
-
else
|
109
|
-
IRB.setup(nil)
|
110
|
-
end
|
111
|
-
|
112
|
-
irb = Irb.new(nil, im)
|
113
|
-
|
114
|
-
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
115
|
-
@CONF[:MAIN_CONTEXT] = irb.context
|
116
|
-
trap("SIGINT") do
|
117
|
-
irb.signal_handle
|
118
|
-
end
|
119
|
-
|
120
|
-
class << irb.context.workspace.main
|
121
|
-
def gets
|
122
|
-
inp = IRB.conf[:MAIN_CONTEXT].io
|
123
|
-
inp.gets_mode = true
|
124
|
-
retval = IRB.conf[:MAIN_CONTEXT].io.gets
|
125
|
-
inp.gets_mode = false
|
126
|
-
retval
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
catch(:IRB_EXIT) do
|
131
|
-
irb.eval_input
|
132
|
-
end
|
133
|
-
print "\n"
|
134
|
-
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|
138
|
-
|
139
|
-
|
140
|
-
class FXIrb < FXText
|
141
|
-
include Singleton
|
142
|
-
include Responder
|
143
|
-
|
144
|
-
attr_reader :input
|
145
|
-
|
146
|
-
def FXIrb.init(p, tgt, sel, opts)
|
147
|
-
unless @__instance__
|
148
|
-
Thread.critical = true
|
149
|
-
begin
|
150
|
-
@__instance__ ||= new(p, tgt, sel, opts)
|
151
|
-
ensure
|
152
|
-
Thread.critical = false
|
153
|
-
end
|
154
|
-
end
|
155
|
-
return @__instance__
|
156
|
-
end
|
157
|
-
|
158
|
-
def initialize(p, tgt, sel, opts)
|
159
|
-
FXMAPFUNC(SEL_KEYRELEASE, 0, "onKeyRelease")
|
160
|
-
FXMAPFUNC(SEL_KEYPRESS, 0, "onKeyPress")
|
161
|
-
FXMAPFUNC(SEL_LEFTBUTTONPRESS,0,"onLeftBtnPress")
|
162
|
-
FXMAPFUNC(SEL_MIDDLEBUTTONPRESS,0,"onMiddleBtnPress")
|
163
|
-
FXMAPFUNC(SEL_LEFTBUTTONRELEASE,0,"onLeftBtnRelease")
|
164
|
-
|
165
|
-
super
|
166
|
-
setFont(FXFont.new(FXApp.instance, "lucida console", 9))
|
167
|
-
@anchor = 0
|
168
|
-
end
|
169
|
-
|
170
|
-
def create
|
171
|
-
super
|
172
|
-
setFocus
|
173
|
-
# IRB initialization
|
174
|
-
@inputAdded = 0
|
175
|
-
@input = IO.pipe
|
176
|
-
$DEFAULT_OUTPUT = self
|
177
|
-
|
178
|
-
@im = FXIRBInputMethod.new
|
179
|
-
@irb = Thread.new {
|
180
|
-
IRB.start_in_fxirb(@im)
|
181
|
-
self.crash
|
182
|
-
}
|
183
|
-
|
184
|
-
|
185
|
-
@multiline = false
|
186
|
-
|
187
|
-
@exit_proc = lambda {exit}
|
188
|
-
end
|
189
|
-
|
190
|
-
def on_exit(&block)
|
191
|
-
@exit_proc = block
|
192
|
-
end
|
193
|
-
|
194
|
-
def crash
|
195
|
-
instance_eval(&@exit_proc)
|
196
|
-
end
|
197
|
-
|
198
|
-
def onKeyRelease(sender, sel, event)
|
199
|
-
case event.code
|
200
|
-
when Fox::KEY_Return, Fox::KEY_KP_Enter
|
201
|
-
newLineEntered
|
202
|
-
end
|
203
|
-
return 1
|
204
|
-
end
|
205
|
-
|
206
|
-
def onKeyPress(sender,sel,event)
|
207
|
-
case event.code
|
208
|
-
when Fox::KEY_Return, Fox::KEY_KP_Enter
|
209
|
-
setCursorPos(getLength)
|
210
|
-
super
|
211
|
-
when Fox::KEY_Up,Fox::KEY_KP_Up
|
212
|
-
str = extractText(@anchor, getCursorPos-@anchor)
|
213
|
-
if str =~ /\n/
|
214
|
-
@multiline = true
|
215
|
-
super
|
216
|
-
setCursorPos(@anchor+1) if getCursorPos < @anchor
|
217
|
-
else
|
218
|
-
history(:prev) unless @multiline
|
219
|
-
end
|
220
|
-
when Fox::KEY_Down,Fox::KEY_KP_Down
|
221
|
-
str = extractText(getCursorPos, getLength - getCursorPos)
|
222
|
-
if str =~ /\n/
|
223
|
-
@multiline = true
|
224
|
-
super
|
225
|
-
else
|
226
|
-
history(:next) unless @multiline
|
227
|
-
end
|
228
|
-
when Fox::KEY_Left,Fox::KEY_KP_Left
|
229
|
-
if getCursorPos > @anchor
|
230
|
-
super
|
231
|
-
end
|
232
|
-
when Fox::KEY_Delete,Fox::KEY_KP_Delete,Fox::KEY_BackSpace
|
233
|
-
if getCursorPos > @anchor
|
234
|
-
super
|
235
|
-
end
|
236
|
-
when Fox::KEY_Home, Fox::KEY_KP_Home
|
237
|
-
setCursorPos(@anchor)
|
238
|
-
when Fox::KEY_End, Fox::KEY_KP_End
|
239
|
-
setCursorPos(getLength)
|
240
|
-
when Fox::KEY_Page_Up, Fox::KEY_KP_Page_Up
|
241
|
-
history(:prev)
|
242
|
-
when Fox::KEY_Page_Down, Fox::KEY_KP_Page_Down
|
243
|
-
history(:next)
|
244
|
-
when Fox::KEY_bracketright
|
245
|
-
#auto-dedent if the } or ] is on a line by itself
|
246
|
-
if (emptyline? or (getline == "en")) and indented?
|
247
|
-
dedent
|
248
|
-
end
|
249
|
-
super
|
250
|
-
when Fox::KEY_u
|
251
|
-
if (event.state & CONTROLMASK) != 0
|
252
|
-
str = extractText(getCursorPos, getLength - getCursorPos)
|
253
|
-
rmline
|
254
|
-
appendText(str)
|
255
|
-
setCursorPos(@anchor)
|
256
|
-
end
|
257
|
-
super
|
258
|
-
when Fox::KEY_k
|
259
|
-
if (event.state & CONTROLMASK) != 0
|
260
|
-
str = extractText(@anchor, getCursorPos-@anchor)
|
261
|
-
rmline
|
262
|
-
appendText(str)
|
263
|
-
setCursorPos(getLength)
|
264
|
-
end
|
265
|
-
super
|
266
|
-
when Fox::KEY_d
|
267
|
-
if (event.state & CONTROLMASK) != 0
|
268
|
-
#Ctrl - D
|
269
|
-
rmline
|
270
|
-
appendText("exit")
|
271
|
-
newLineEntered
|
272
|
-
else
|
273
|
-
# test for 'end' so we can dedent
|
274
|
-
if (getline == "en") and indented?
|
275
|
-
dedent
|
276
|
-
end
|
277
|
-
end
|
278
|
-
super
|
279
|
-
else
|
280
|
-
super
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
def dedent
|
285
|
-
str = getline
|
286
|
-
@anchor -= 2
|
287
|
-
rmline
|
288
|
-
appendText(str)
|
289
|
-
setCursorPos(getLength)
|
290
|
-
end
|
291
|
-
|
292
|
-
def history(dir)
|
293
|
-
str = (dir == :prev) ? @im.prevCmd.chomp : @im.nextCmd.chomp
|
294
|
-
if str != ""
|
295
|
-
removeText(@anchor, getLength-@anchor)
|
296
|
-
write(str)
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
def getline
|
301
|
-
extractText(@anchor, getLength-@anchor)
|
302
|
-
end
|
303
|
-
|
304
|
-
def rmline
|
305
|
-
str = getline
|
306
|
-
removeText(@anchor, getLength-@anchor)
|
307
|
-
str
|
308
|
-
end
|
309
|
-
|
310
|
-
def emptyline?
|
311
|
-
getline == ""
|
312
|
-
end
|
313
|
-
|
314
|
-
def indented?
|
315
|
-
extractText(@anchor-2, 2) == " "
|
316
|
-
end
|
317
|
-
|
318
|
-
def onLeftBtnPress(sender,sel,event)
|
319
|
-
@store_anchor = @anchor
|
320
|
-
setFocus
|
321
|
-
super
|
322
|
-
end
|
323
|
-
|
324
|
-
def onLeftBtnRelease(sender,sel,event)
|
325
|
-
super
|
326
|
-
@anchor = @store_anchor
|
327
|
-
setCursorPos(@anchor)
|
328
|
-
setCursorPos(getLength)
|
329
|
-
end
|
330
|
-
|
331
|
-
def onMiddleBtnPress(sender,sel,event)
|
332
|
-
pos=getPosAt(event.win_x,event.win_y)
|
333
|
-
if pos >= @anchor
|
334
|
-
super
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
def newLineEntered
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
@
|
352
|
-
|
353
|
-
|
354
|
-
@im.print_prompt =
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
application.
|
392
|
-
|
393
|
-
|
394
|
-
application
|
395
|
-
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
# TODO
|
4
|
+
# - handle user input redirection
|
5
|
+
# - readline
|
6
|
+
|
7
|
+
# Credits:
|
8
|
+
# - Initial linux version: Gilles Filippini
|
9
|
+
# - Initial windows port : Marco Frailis
|
10
|
+
# - Currently maintained and developed by
|
11
|
+
# Martin DeMello <martindemello@gmail.com>
|
12
|
+
|
13
|
+
require "fox16"
|
14
|
+
require "irb"
|
15
|
+
require "singleton"
|
16
|
+
require "English"
|
17
|
+
|
18
|
+
include Fox
|
19
|
+
|
20
|
+
STDOUT.sync = true
|
21
|
+
|
22
|
+
class FXIRBInputMethod < IRB::StdioInputMethod
|
23
|
+
|
24
|
+
attr_accessor :print_prompt, :gets_mode
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
super
|
28
|
+
@history = 1
|
29
|
+
@begin = nil
|
30
|
+
@print_prompt = true
|
31
|
+
@end = nil
|
32
|
+
@continued_from = nil
|
33
|
+
@gets_mode = false
|
34
|
+
end
|
35
|
+
|
36
|
+
def gets
|
37
|
+
if @gets_mode
|
38
|
+
return FXIrb.instance.get_line
|
39
|
+
end
|
40
|
+
|
41
|
+
if (a = @prompt.match(/(\d+)[>*]/))
|
42
|
+
level = a[1].to_i
|
43
|
+
else
|
44
|
+
level = 0
|
45
|
+
end
|
46
|
+
|
47
|
+
if level > 0
|
48
|
+
@continued_from ||= @line_no
|
49
|
+
elsif @continued_from
|
50
|
+
merge_last(@line_no-@continued_from+1)
|
51
|
+
@continued_from = nil
|
52
|
+
end
|
53
|
+
|
54
|
+
if @print_prompt
|
55
|
+
print @prompt
|
56
|
+
|
57
|
+
#indentation
|
58
|
+
print " "*level
|
59
|
+
end
|
60
|
+
|
61
|
+
str = FXIrb.instance.get_line
|
62
|
+
|
63
|
+
@line_no += 1
|
64
|
+
@history = @line_no + 1
|
65
|
+
@line[@line_no] = str
|
66
|
+
|
67
|
+
str
|
68
|
+
end
|
69
|
+
|
70
|
+
# merge a block spanning several lines into one \n-separated line
|
71
|
+
def merge_last(i)
|
72
|
+
return unless i > 1
|
73
|
+
range = -i..-1
|
74
|
+
@line[range] = @line[range].map {|l| l.chomp}.join("\n")
|
75
|
+
@line_no -= (i-1)
|
76
|
+
@history -= (i-1)
|
77
|
+
end
|
78
|
+
|
79
|
+
def prevCmd
|
80
|
+
return "" if @gets_mode
|
81
|
+
|
82
|
+
if @line_no > 0
|
83
|
+
@history -= 1 unless @history <= 1
|
84
|
+
return line(@history)
|
85
|
+
end
|
86
|
+
return ""
|
87
|
+
end
|
88
|
+
|
89
|
+
def nextCmd
|
90
|
+
return "" if @gets_mode
|
91
|
+
|
92
|
+
if (@line_no > 0) && (@history < @line_no)
|
93
|
+
@history += 1
|
94
|
+
return line(@history)
|
95
|
+
end
|
96
|
+
return ""
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
module IRB
|
102
|
+
|
103
|
+
def IRB.start_in_fxirb(im)
|
104
|
+
if RUBY_VERSION < "1.7.3"
|
105
|
+
IRB.initialize(nil)
|
106
|
+
IRB.parse_opts
|
107
|
+
IRB.load_modules
|
108
|
+
else
|
109
|
+
IRB.setup(nil)
|
110
|
+
end
|
111
|
+
|
112
|
+
irb = Irb.new(nil, im)
|
113
|
+
|
114
|
+
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
115
|
+
@CONF[:MAIN_CONTEXT] = irb.context
|
116
|
+
trap("SIGINT") do
|
117
|
+
irb.signal_handle
|
118
|
+
end
|
119
|
+
|
120
|
+
class << irb.context.workspace.main
|
121
|
+
def gets
|
122
|
+
inp = IRB.conf[:MAIN_CONTEXT].io
|
123
|
+
inp.gets_mode = true
|
124
|
+
retval = IRB.conf[:MAIN_CONTEXT].io.gets
|
125
|
+
inp.gets_mode = false
|
126
|
+
retval
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
catch(:IRB_EXIT) do
|
131
|
+
irb.eval_input
|
132
|
+
end
|
133
|
+
print "\n"
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
class FXIrb < FXText
|
141
|
+
include Singleton
|
142
|
+
include Responder
|
143
|
+
|
144
|
+
attr_reader :input
|
145
|
+
|
146
|
+
def FXIrb.init(p, tgt, sel, opts)
|
147
|
+
unless @__instance__
|
148
|
+
Thread.critical = true
|
149
|
+
begin
|
150
|
+
@__instance__ ||= new(p, tgt, sel, opts)
|
151
|
+
ensure
|
152
|
+
Thread.critical = false
|
153
|
+
end
|
154
|
+
end
|
155
|
+
return @__instance__
|
156
|
+
end
|
157
|
+
|
158
|
+
def initialize(p, tgt, sel, opts)
|
159
|
+
FXMAPFUNC(SEL_KEYRELEASE, 0, "onKeyRelease")
|
160
|
+
FXMAPFUNC(SEL_KEYPRESS, 0, "onKeyPress")
|
161
|
+
FXMAPFUNC(SEL_LEFTBUTTONPRESS,0,"onLeftBtnPress")
|
162
|
+
FXMAPFUNC(SEL_MIDDLEBUTTONPRESS,0,"onMiddleBtnPress")
|
163
|
+
FXMAPFUNC(SEL_LEFTBUTTONRELEASE,0,"onLeftBtnRelease")
|
164
|
+
|
165
|
+
super
|
166
|
+
setFont(FXFont.new(FXApp.instance, "lucida console", 9))
|
167
|
+
@anchor = 0
|
168
|
+
end
|
169
|
+
|
170
|
+
def create
|
171
|
+
super
|
172
|
+
setFocus
|
173
|
+
# IRB initialization
|
174
|
+
@inputAdded = 0
|
175
|
+
@input = IO.pipe
|
176
|
+
$DEFAULT_OUTPUT = self
|
177
|
+
|
178
|
+
@im = FXIRBInputMethod.new
|
179
|
+
@irb = Thread.new {
|
180
|
+
IRB.start_in_fxirb(@im)
|
181
|
+
self.crash
|
182
|
+
}
|
183
|
+
|
184
|
+
|
185
|
+
@multiline = false
|
186
|
+
|
187
|
+
@exit_proc = lambda {exit}
|
188
|
+
end
|
189
|
+
|
190
|
+
def on_exit(&block)
|
191
|
+
@exit_proc = block
|
192
|
+
end
|
193
|
+
|
194
|
+
def crash
|
195
|
+
instance_eval(&@exit_proc)
|
196
|
+
end
|
197
|
+
|
198
|
+
def onKeyRelease(sender, sel, event)
|
199
|
+
case event.code
|
200
|
+
when Fox::KEY_Return, Fox::KEY_KP_Enter
|
201
|
+
newLineEntered
|
202
|
+
end
|
203
|
+
return 1
|
204
|
+
end
|
205
|
+
|
206
|
+
def onKeyPress(sender,sel,event)
|
207
|
+
case event.code
|
208
|
+
when Fox::KEY_Return, Fox::KEY_KP_Enter
|
209
|
+
setCursorPos(getLength)
|
210
|
+
super
|
211
|
+
when Fox::KEY_Up,Fox::KEY_KP_Up
|
212
|
+
str = extractText(@anchor, getCursorPos-@anchor)
|
213
|
+
if str =~ /\n/
|
214
|
+
@multiline = true
|
215
|
+
super
|
216
|
+
setCursorPos(@anchor+1) if getCursorPos < @anchor
|
217
|
+
else
|
218
|
+
history(:prev) unless @multiline
|
219
|
+
end
|
220
|
+
when Fox::KEY_Down,Fox::KEY_KP_Down
|
221
|
+
str = extractText(getCursorPos, getLength - getCursorPos)
|
222
|
+
if str =~ /\n/
|
223
|
+
@multiline = true
|
224
|
+
super
|
225
|
+
else
|
226
|
+
history(:next) unless @multiline
|
227
|
+
end
|
228
|
+
when Fox::KEY_Left,Fox::KEY_KP_Left
|
229
|
+
if getCursorPos > @anchor
|
230
|
+
super
|
231
|
+
end
|
232
|
+
when Fox::KEY_Delete,Fox::KEY_KP_Delete,Fox::KEY_BackSpace
|
233
|
+
if getCursorPos > @anchor
|
234
|
+
super
|
235
|
+
end
|
236
|
+
when Fox::KEY_Home, Fox::KEY_KP_Home
|
237
|
+
setCursorPos(@anchor)
|
238
|
+
when Fox::KEY_End, Fox::KEY_KP_End
|
239
|
+
setCursorPos(getLength)
|
240
|
+
when Fox::KEY_Page_Up, Fox::KEY_KP_Page_Up
|
241
|
+
history(:prev)
|
242
|
+
when Fox::KEY_Page_Down, Fox::KEY_KP_Page_Down
|
243
|
+
history(:next)
|
244
|
+
when Fox::KEY_bracketright
|
245
|
+
#auto-dedent if the } or ] is on a line by itself
|
246
|
+
if (emptyline? or (getline == "en")) and indented?
|
247
|
+
dedent
|
248
|
+
end
|
249
|
+
super
|
250
|
+
when Fox::KEY_u
|
251
|
+
if (event.state & CONTROLMASK) != 0
|
252
|
+
str = extractText(getCursorPos, getLength - getCursorPos)
|
253
|
+
rmline
|
254
|
+
appendText(str)
|
255
|
+
setCursorPos(@anchor)
|
256
|
+
end
|
257
|
+
super
|
258
|
+
when Fox::KEY_k
|
259
|
+
if (event.state & CONTROLMASK) != 0
|
260
|
+
str = extractText(@anchor, getCursorPos-@anchor)
|
261
|
+
rmline
|
262
|
+
appendText(str)
|
263
|
+
setCursorPos(getLength)
|
264
|
+
end
|
265
|
+
super
|
266
|
+
when Fox::KEY_d
|
267
|
+
if (event.state & CONTROLMASK) != 0
|
268
|
+
#Ctrl - D
|
269
|
+
rmline
|
270
|
+
appendText("exit")
|
271
|
+
newLineEntered
|
272
|
+
else
|
273
|
+
# test for 'end' so we can dedent
|
274
|
+
if (getline == "en") and indented?
|
275
|
+
dedent
|
276
|
+
end
|
277
|
+
end
|
278
|
+
super
|
279
|
+
else
|
280
|
+
super
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def dedent
|
285
|
+
str = getline
|
286
|
+
@anchor -= 2
|
287
|
+
rmline
|
288
|
+
appendText(str)
|
289
|
+
setCursorPos(getLength)
|
290
|
+
end
|
291
|
+
|
292
|
+
def history(dir)
|
293
|
+
str = (dir == :prev) ? @im.prevCmd.chomp : @im.nextCmd.chomp
|
294
|
+
if str != ""
|
295
|
+
removeText(@anchor, getLength-@anchor)
|
296
|
+
write(str)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
def getline
|
301
|
+
extractText(@anchor, getLength-@anchor)
|
302
|
+
end
|
303
|
+
|
304
|
+
def rmline
|
305
|
+
str = getline
|
306
|
+
removeText(@anchor, getLength-@anchor)
|
307
|
+
str
|
308
|
+
end
|
309
|
+
|
310
|
+
def emptyline?
|
311
|
+
getline == ""
|
312
|
+
end
|
313
|
+
|
314
|
+
def indented?
|
315
|
+
extractText(@anchor-2, 2) == " "
|
316
|
+
end
|
317
|
+
|
318
|
+
def onLeftBtnPress(sender,sel,event)
|
319
|
+
@store_anchor = @anchor
|
320
|
+
setFocus
|
321
|
+
super
|
322
|
+
end
|
323
|
+
|
324
|
+
def onLeftBtnRelease(sender,sel,event)
|
325
|
+
super
|
326
|
+
@anchor = @store_anchor
|
327
|
+
setCursorPos(@anchor)
|
328
|
+
setCursorPos(getLength)
|
329
|
+
end
|
330
|
+
|
331
|
+
def onMiddleBtnPress(sender,sel,event)
|
332
|
+
pos=getPosAt(event.win_x,event.win_y)
|
333
|
+
if pos >= @anchor
|
334
|
+
super
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def newLineEntered
|
339
|
+
if getLength-@anchor > 0
|
340
|
+
processCommandLine(extractText(@anchor, getLength-@anchor))
|
341
|
+
else
|
342
|
+
# Probably wrong, but might work
|
343
|
+
processCommandLine(extractText(@anchor, getLength))
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
def processCommandLine(cmd)
|
348
|
+
@multiline = false
|
349
|
+
lines = cmd.split(/\n/)
|
350
|
+
lines.each {|i|
|
351
|
+
@input[1].puts i
|
352
|
+
@inputAdded += 1
|
353
|
+
}
|
354
|
+
@im.print_prompt = false
|
355
|
+
while (@inputAdded > 0) do
|
356
|
+
@irb.run
|
357
|
+
end
|
358
|
+
@im.merge_last(lines.length)
|
359
|
+
@im.print_prompt = true
|
360
|
+
end
|
361
|
+
|
362
|
+
def sendCommand(cmd)
|
363
|
+
setCursorPos(getLength)
|
364
|
+
makePositionVisible(getLength) unless isPosVisible(getLength)
|
365
|
+
cmd += "\n"
|
366
|
+
appendText(cmd)
|
367
|
+
processCommandLine(cmd)
|
368
|
+
end
|
369
|
+
|
370
|
+
def write(obj)
|
371
|
+
str = obj.to_s
|
372
|
+
appendText(str)
|
373
|
+
setCursorPos(getLength)
|
374
|
+
makePositionVisible(getLength) unless isPosVisible(getLength)
|
375
|
+
return str.length
|
376
|
+
end
|
377
|
+
|
378
|
+
def get_line
|
379
|
+
@anchor = getLength
|
380
|
+
if @inputAdded == 0
|
381
|
+
Thread.stop
|
382
|
+
end
|
383
|
+
@inputAdded -= 1
|
384
|
+
return @input[0].gets
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
# Stand alone run
|
389
|
+
if __FILE__ == $0
|
390
|
+
application = FXApp.new("FXIrb", "ruby")
|
391
|
+
application.threadsEnabled = true
|
392
|
+
Thread.abort_on_exception = true
|
393
|
+
application.init(ARGV)
|
394
|
+
window = FXMainWindow.new(application, "FXIrb", nil, nil, DECOR_ALL, 0, 0, 580, 500)
|
395
|
+
fxirb = FXIrb.init(window, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP|TEXT_SHOWACTIVE)
|
396
|
+
application.create
|
397
|
+
window.show(PLACEMENT_SCREEN)
|
398
|
+
fxirb.on_exit {exit}
|
399
|
+
application.run
|
400
|
+
end
|