fxri 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,165 +1,165 @@
1
- # Copyright (c) 2005 Martin Ankerl
2
- class Search_Engine
3
- def initialize(gui, data)
4
- @gui = gui
5
- @data = data
6
- @search_thread = nil
7
- end
8
-
9
- # Executed whenever a search criteria changes to update the packet list.
10
- def on_search
11
- # restart current search
12
- @end_time = Time.now + $cfg.search_delay
13
- @restart_search = true
14
- @gui.search_label.enabled = false
15
- return if @search_thread && @search_thread.status
16
-
17
- @search_thread = Thread.new(@search_thread) do
18
- begin
19
- @gui.search_label.enabled = false
20
- # wait untill deadline
21
- while (t = (@end_time - Time.now)) > 0
22
- sleep(t)
23
- end
24
-
25
- @data.gui_mutex.synchronize do
26
- # the thread has to use the gui mutex inside
27
- @restart_search = false
28
-
29
- match_data = get_match_data
30
-
31
- # remove all items
32
- @gui.packet_list.dirty_clear
33
-
34
- # add all items that match the search criteria
35
- status_text_deadline = Time.now + $cfg.status_line_update_interval
36
- @data.items.each do |item|
37
- #item.parent = @gui.packet_list if match?(item, match_data)
38
- if match?(item, match_data)
39
- item.show
40
- now = Time.now
41
- if now > status_text_deadline
42
- update_search_status_text
43
- status_text_deadline = now + $cfg.status_line_update_interval
44
- end
45
- end
46
- break if @restart_search
47
- end
48
- update_search_status_text
49
-
50
- if (@gui.packet_list.numItems > 0)
51
- @gui.packet_list.setCurrentItem(0)
52
- @gui.packet_list.selectItem(0)
53
- @gui.main.show_info(@gui.packet_list.getItem(0).packet_item.data)
54
- end
55
- @gui.search_label.enabled = true
56
-
57
- end # synchronize
58
- end while @restart_search# || match_data != @gui.search_field.text.downcase.split
59
- end #thread.new
60
- end
61
-
62
- def get_match_data
63
- str_to_match_data(@gui.search_field.text)
64
- end
65
-
66
- # Converts a string into a match_data representation.
67
- def str_to_match_data(str, index=0)
68
- words = [ ]
69
- exclude = [ ]
70
- is_exclude = false
71
-
72
- while str[index]
73
- case str[index]
74
- when ?", ?'
75
- word, index = get_word(str, index+1, str[index])
76
- unless word.empty?
77
- if is_exclude
78
- exclude.push word
79
- is_exclude = false
80
- else
81
- words.push word
82
- end
83
- end
84
-
85
- when 32 # space
86
- is_exclude = false
87
-
88
- =begin
89
- when ?>
90
- min, index = get_word(str, index+1)
91
- min = @gui.logic.size_to_nr(min)
92
-
93
- when ?<
94
- max, index = get_word(str, index+1)
95
- max = @gui.logic.size_to_nr(max)
96
- =end
97
- when ?-
98
- is_exclude = true
99
-
100
- else
101
- word, index = get_word(str, index)
102
- if is_exclude
103
- exclude.push word
104
- is_exclude = false
105
- else
106
- words.push word
107
- end
108
- end
109
-
110
- index += 1
111
- end
112
-
113
- # check if word has upcase letters
114
- words.collect! do |w|
115
- [w, /[A-Z]/.match(w)!=nil]
116
- end
117
- exclude.collect! do |w|
118
- [w, /[A-Z]/.match(w)!=nil]
119
- end
120
- [words, exclude]
121
- end
122
-
123
- def get_word(str, index, delim=32) # 32==space
124
- word = ""
125
- c = str[index]
126
- while (c && c != delim)
127
- word += c.chr
128
- index += 1
129
- c = str[index]
130
- end
131
- [word, index]
132
- end
133
-
134
- # Update the text for the number of displayed packs.
135
- def update_search_status_text
136
- @gui.search_label.text = sprintf($cfg.text.search, @gui.packet_list.numItems, @data.items.size)
137
- end
138
-
139
- # Find out if item is matched by current search criteria.
140
- def match?(item, match_data)
141
- words, exclude, min, max = match_data
142
-
143
- # check text that has to be there
144
- searchable, sortable_downcase, sortable_normal = item.sortable(0)
145
- words.each do |match_str, is_sensitive|
146
- if is_sensitive
147
- return false unless sortable_normal.include?(match_str)
148
- else
149
- return false unless sortable_downcase.include?(match_str)
150
- end
151
- end
152
-
153
- # check text not allowed to be there
154
- exclude.each do |match_str, is_sensitive|
155
- if is_sensitive
156
- return false if sortable_normal.include?(match_str)
157
- else
158
- return false if sortable_downcase.include?(match_str)
159
- end
160
- end
161
-
162
- # each check ok
163
- true
164
- end
165
- end
1
+ # Copyright (c) 2005 Martin Ankerl
2
+ class Search_Engine
3
+ def initialize(gui, data)
4
+ @gui = gui
5
+ @data = data
6
+ @search_thread = nil
7
+ end
8
+
9
+ # Executed whenever a search criteria changes to update the packet list.
10
+ def on_search
11
+ # restart current search
12
+ @end_time = Time.now + $cfg.search_delay
13
+ @restart_search = true
14
+ @gui.search_label.enabled = false
15
+ return if @search_thread && @search_thread.status
16
+
17
+ @search_thread = Thread.new(@search_thread) do
18
+ begin
19
+ @gui.search_label.enabled = false
20
+ # wait untill deadline
21
+ while (t = (@end_time - Time.now)) > 0
22
+ sleep(t)
23
+ end
24
+
25
+ @data.gui_mutex.synchronize do
26
+ # the thread has to use the gui mutex inside
27
+ @restart_search = false
28
+
29
+ match_data = get_match_data
30
+
31
+ # remove all items
32
+ @gui.packet_list.dirty_clear
33
+
34
+ # add all items that match the search criteria
35
+ status_text_deadline = Time.now + $cfg.status_line_update_interval
36
+ @data.items.each do |item|
37
+ #item.parent = @gui.packet_list if match?(item, match_data)
38
+ if match?(item, match_data)
39
+ item.show
40
+ now = Time.now
41
+ if now > status_text_deadline
42
+ update_search_status_text
43
+ status_text_deadline = now + $cfg.status_line_update_interval
44
+ end
45
+ end
46
+ break if @restart_search
47
+ end
48
+ update_search_status_text
49
+
50
+ if (@gui.packet_list.numItems > 0)
51
+ @gui.packet_list.setCurrentItem(0)
52
+ @gui.packet_list.selectItem(0)
53
+ @gui.main.show_info(@gui.packet_list.getItem(0).packet_item.data)
54
+ end
55
+ @gui.search_label.enabled = true
56
+
57
+ end # synchronize
58
+ end while @restart_search# || match_data != @gui.search_field.text.downcase.split
59
+ end #thread.new
60
+ end
61
+
62
+ def get_match_data
63
+ str_to_match_data(@gui.search_field.text)
64
+ end
65
+
66
+ # Converts a string into a match_data representation.
67
+ def str_to_match_data(str, index=0)
68
+ words = [ ]
69
+ exclude = [ ]
70
+ is_exclude = false
71
+
72
+ while str[index]
73
+ case str[index]
74
+ when ?", ?'
75
+ word, index = get_word(str, index+1, str[index])
76
+ unless word.empty?
77
+ if is_exclude
78
+ exclude.push word
79
+ is_exclude = false
80
+ else
81
+ words.push word
82
+ end
83
+ end
84
+
85
+ when 32 # space
86
+ is_exclude = false
87
+
88
+ =begin
89
+ when ?>
90
+ min, index = get_word(str, index+1)
91
+ min = @gui.logic.size_to_nr(min)
92
+
93
+ when ?<
94
+ max, index = get_word(str, index+1)
95
+ max = @gui.logic.size_to_nr(max)
96
+ =end
97
+ when ?-
98
+ is_exclude = true
99
+
100
+ else
101
+ word, index = get_word(str, index)
102
+ if is_exclude
103
+ exclude.push word
104
+ is_exclude = false
105
+ else
106
+ words.push word
107
+ end
108
+ end
109
+
110
+ index += 1
111
+ end
112
+
113
+ # check if word has upcase letters
114
+ words.collect! do |w|
115
+ [w, /[A-Z]/.match(w)!=nil]
116
+ end
117
+ exclude.collect! do |w|
118
+ [w, /[A-Z]/.match(w)!=nil]
119
+ end
120
+ [words, exclude]
121
+ end
122
+
123
+ def get_word(str, index, delim=32) # 32==space
124
+ word = ""
125
+ c = str[index]
126
+ while (c && c != delim)
127
+ word += c.chr
128
+ index += 1
129
+ c = str[index]
130
+ end
131
+ [word, index]
132
+ end
133
+
134
+ # Update the text for the number of displayed packs.
135
+ def update_search_status_text
136
+ @gui.search_label.text = sprintf($cfg.text.search, @gui.packet_list.numItems, @data.items.size)
137
+ end
138
+
139
+ # Find out if item is matched by current search criteria.
140
+ def match?(item, match_data)
141
+ words, exclude, min, max = match_data
142
+
143
+ # check text that has to be there
144
+ searchable, sortable_downcase, sortable_normal = item.sortable(0)
145
+ words.each do |match_str, is_sensitive|
146
+ if is_sensitive
147
+ return false unless sortable_normal.include?(match_str)
148
+ else
149
+ return false unless sortable_downcase.include?(match_str)
150
+ end
151
+ end
152
+
153
+ # check text not allowed to be there
154
+ exclude.each do |match_str, is_sensitive|
155
+ if is_sensitive
156
+ return false if sortable_normal.include?(match_str)
157
+ else
158
+ return false if sortable_downcase.include?(match_str)
159
+ end
160
+ end
161
+
162
+ # each check ok
163
+ true
164
+ end
165
+ end
@@ -1,400 +1,401 @@
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
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
+ # Not needed; fxri already does that
14
+ #require "fox16"
15
+ require "irb"
16
+ require "singleton"
17
+ require "English"
18
+
19
+ include Fox
20
+
21
+ STDOUT.sync = true
22
+
23
+ class FXIRBInputMethod < IRB::StdioInputMethod
24
+
25
+ attr_accessor :print_prompt, :gets_mode
26
+
27
+ def initialize
28
+ super
29
+ @history = 1
30
+ @begin = nil
31
+ @print_prompt = true
32
+ @end = nil
33
+ @continued_from = nil
34
+ @gets_mode = false
35
+ end
36
+
37
+ def gets
38
+ if @gets_mode
39
+ return FXIrb.instance.get_line
40
+ end
41
+
42
+ if (a = @prompt.match(/(\d+)[>*]/))
43
+ level = a[1].to_i
44
+ else
45
+ level = 0
46
+ end
47
+
48
+ if level > 0
49
+ @continued_from ||= @line_no
50
+ elsif @continued_from
51
+ merge_last(@line_no-@continued_from+1)
52
+ @continued_from = nil
53
+ end
54
+
55
+ if @print_prompt
56
+ print @prompt
57
+
58
+ #indentation
59
+ print " "*level
60
+ end
61
+
62
+ str = FXIrb.instance.get_line
63
+
64
+ @line_no += 1
65
+ @history = @line_no + 1
66
+ @line[@line_no] = str
67
+
68
+ str
69
+ end
70
+
71
+ # merge a block spanning several lines into one \n-separated line
72
+ def merge_last(i)
73
+ return unless i > 1
74
+ range = -i..-1
75
+ @line[range] = @line[range].map {|l| l.chomp}.join("\n")
76
+ @line_no -= (i-1)
77
+ @history -= (i-1)
78
+ end
79
+
80
+ def prevCmd
81
+ return "" if @gets_mode
82
+
83
+ if @line_no > 0
84
+ @history -= 1 unless @history <= 1
85
+ return line(@history)
86
+ end
87
+ return ""
88
+ end
89
+
90
+ def nextCmd
91
+ return "" if @gets_mode
92
+
93
+ if (@line_no > 0) && (@history < @line_no)
94
+ @history += 1
95
+ return line(@history)
96
+ end
97
+ return ""
98
+ end
99
+
100
+ end
101
+
102
+ module IRB
103
+
104
+ def IRB.start_in_fxirb(im)
105
+ if RUBY_VERSION < "1.7.3"
106
+ IRB.initialize(nil)
107
+ IRB.parse_opts
108
+ IRB.load_modules
109
+ else
110
+ IRB.setup(nil)
111
+ end
112
+
113
+ irb = Irb.new(nil, im)
114
+
115
+ @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
116
+ @CONF[:MAIN_CONTEXT] = irb.context
117
+ trap("SIGINT") do
118
+ irb.signal_handle
119
+ end
120
+
121
+ class << irb.context.workspace.main
122
+ def gets
123
+ inp = IRB.conf[:MAIN_CONTEXT].io
124
+ inp.gets_mode = true
125
+ retval = IRB.conf[:MAIN_CONTEXT].io.gets
126
+ inp.gets_mode = false
127
+ retval
128
+ end
129
+ end
130
+
131
+ catch(:IRB_EXIT) do
132
+ irb.eval_input
133
+ end
134
+ print "\n"
135
+
136
+ end
137
+
138
+ end
139
+
140
+
141
+ class FXIrb < FXText
142
+ include Singleton
143
+ include Responder
144
+
145
+ attr_reader :input
146
+
147
+ def FXIrb.init(p, tgt, sel, opts)
148
+ unless @__instance__
149
+ Thread.critical = true
150
+ begin
151
+ @__instance__ ||= new(p, tgt, sel, opts)
152
+ ensure
153
+ Thread.critical = false
154
+ end
155
+ end
156
+ return @__instance__
157
+ end
158
+
159
+ def initialize(p, tgt, sel, opts)
160
+ FXMAPFUNC(SEL_KEYRELEASE, 0, "onKeyRelease")
161
+ FXMAPFUNC(SEL_KEYPRESS, 0, "onKeyPress")
162
+ FXMAPFUNC(SEL_LEFTBUTTONPRESS,0,"onLeftBtnPress")
163
+ FXMAPFUNC(SEL_MIDDLEBUTTONPRESS,0,"onMiddleBtnPress")
164
+ FXMAPFUNC(SEL_LEFTBUTTONRELEASE,0,"onLeftBtnRelease")
165
+
166
+ super
167
+ setFont(FXFont.new(FXApp.instance, "lucida console", 9))
168
+ @anchor = 0
169
+ end
170
+
171
+ def create
172
+ super
173
+ setFocus
174
+ # IRB initialization
175
+ @inputAdded = 0
176
+ @input = IO.pipe
177
+ $DEFAULT_OUTPUT = self
178
+
179
+ @im = FXIRBInputMethod.new
180
+ @irb = Thread.new {
181
+ IRB.start_in_fxirb(@im)
182
+ self.crash
183
+ }
184
+
185
+
186
+ @multiline = false
187
+
188
+ @exit_proc = lambda {exit}
189
+ end
190
+
191
+ def on_exit(&block)
192
+ @exit_proc = block
193
+ end
194
+
195
+ def crash
196
+ instance_eval(&@exit_proc)
197
+ end
198
+
199
+ def onKeyRelease(sender, sel, event)
200
+ case event.code
201
+ when Fox::KEY_Return, Fox::KEY_KP_Enter
202
+ newLineEntered
203
+ end
204
+ return 1
205
+ end
206
+
207
+ def onKeyPress(sender,sel,event)
208
+ case event.code
209
+ when Fox::KEY_Return, Fox::KEY_KP_Enter
210
+ setCursorPos(getLength)
211
+ super
212
+ when Fox::KEY_Up,Fox::KEY_KP_Up
213
+ str = extractText(@anchor, getCursorPos-@anchor)
214
+ if str =~ /\n/
215
+ @multiline = true
216
+ super
217
+ setCursorPos(@anchor+1) if getCursorPos < @anchor
218
+ else
219
+ history(:prev) unless @multiline
220
+ end
221
+ when Fox::KEY_Down,Fox::KEY_KP_Down
222
+ str = extractText(getCursorPos, getLength - getCursorPos)
223
+ if str =~ /\n/
224
+ @multiline = true
225
+ super
226
+ else
227
+ history(:next) unless @multiline
228
+ end
229
+ when Fox::KEY_Left,Fox::KEY_KP_Left
230
+ if getCursorPos > @anchor
231
+ super
232
+ end
233
+ when Fox::KEY_Delete,Fox::KEY_KP_Delete,Fox::KEY_BackSpace
234
+ if getCursorPos > @anchor
235
+ super
236
+ end
237
+ when Fox::KEY_Home, Fox::KEY_KP_Home
238
+ setCursorPos(@anchor)
239
+ when Fox::KEY_End, Fox::KEY_KP_End
240
+ setCursorPos(getLength)
241
+ when Fox::KEY_Page_Up, Fox::KEY_KP_Page_Up
242
+ history(:prev)
243
+ when Fox::KEY_Page_Down, Fox::KEY_KP_Page_Down
244
+ history(:next)
245
+ when Fox::KEY_bracketright
246
+ #auto-dedent if the } or ] is on a line by itself
247
+ if (emptyline? or (getline == "en")) and indented?
248
+ dedent
249
+ end
250
+ super
251
+ when Fox::KEY_u
252
+ if (event.state & CONTROLMASK) != 0
253
+ str = extractText(getCursorPos, getLength - getCursorPos)
254
+ rmline
255
+ appendText(str)
256
+ setCursorPos(@anchor)
257
+ end
258
+ super
259
+ when Fox::KEY_k
260
+ if (event.state & CONTROLMASK) != 0
261
+ str = extractText(@anchor, getCursorPos-@anchor)
262
+ rmline
263
+ appendText(str)
264
+ setCursorPos(getLength)
265
+ end
266
+ super
267
+ when Fox::KEY_d
268
+ if (event.state & CONTROLMASK) != 0
269
+ #Ctrl - D
270
+ rmline
271
+ appendText("exit")
272
+ newLineEntered
273
+ else
274
+ # test for 'end' so we can dedent
275
+ if (getline == "en") and indented?
276
+ dedent
277
+ end
278
+ end
279
+ super
280
+ else
281
+ super
282
+ end
283
+ end
284
+
285
+ def dedent
286
+ str = getline
287
+ @anchor -= 2
288
+ rmline
289
+ appendText(str)
290
+ setCursorPos(getLength)
291
+ end
292
+
293
+ def history(dir)
294
+ str = (dir == :prev) ? @im.prevCmd.chomp : @im.nextCmd.chomp
295
+ if str != ""
296
+ removeText(@anchor, getLength-@anchor)
297
+ write(str)
298
+ end
299
+ end
300
+
301
+ def getline
302
+ extractText(@anchor, getLength-@anchor)
303
+ end
304
+
305
+ def rmline
306
+ str = getline
307
+ removeText(@anchor, getLength-@anchor)
308
+ str
309
+ end
310
+
311
+ def emptyline?
312
+ getline == ""
313
+ end
314
+
315
+ def indented?
316
+ extractText(@anchor-2, 2) == " "
317
+ end
318
+
319
+ def onLeftBtnPress(sender,sel,event)
320
+ @store_anchor = @anchor
321
+ setFocus
322
+ super
323
+ end
324
+
325
+ def onLeftBtnRelease(sender,sel,event)
326
+ super
327
+ @anchor = @store_anchor
328
+ setCursorPos(@anchor)
329
+ setCursorPos(getLength)
330
+ end
331
+
332
+ def onMiddleBtnPress(sender,sel,event)
333
+ pos=getPosAt(event.win_x,event.win_y)
334
+ if pos >= @anchor
335
+ super
336
+ end
337
+ end
338
+
339
+ def newLineEntered
340
+ if getLength-@anchor > 0
341
+ processCommandLine(extractText(@anchor, getLength-@anchor))
342
+ else
343
+ # Probably wrong, but might work
344
+ processCommandLine(extractText(@anchor, getLength))
345
+ end
346
+ end
347
+
348
+ def processCommandLine(cmd)
349
+ @multiline = false
350
+ lines = cmd.split(/\n/)
351
+ lines.each {|i|
352
+ @input[1].puts i
353
+ @inputAdded += 1
354
+ }
355
+ @im.print_prompt = false
356
+ while (@inputAdded > 0) do
357
+ @irb.run
358
+ end
359
+ @im.merge_last(lines.length)
360
+ @im.print_prompt = true
361
+ end
362
+
363
+ def sendCommand(cmd)
364
+ setCursorPos(getLength)
365
+ makePositionVisible(getLength) unless isPosVisible(getLength)
366
+ cmd += "\n"
367
+ appendText(cmd)
368
+ processCommandLine(cmd)
369
+ end
370
+
371
+ def write(obj)
372
+ str = obj.to_s
373
+ appendText(str)
374
+ setCursorPos(getLength)
375
+ makePositionVisible(getLength) unless isPosVisible(getLength)
376
+ return str.length
377
+ end
378
+
379
+ def get_line
380
+ @anchor = getLength
381
+ if @inputAdded == 0
382
+ Thread.stop
383
+ end
384
+ @inputAdded -= 1
385
+ return @input[0].gets
386
+ end
387
+ end
388
+
389
+ # Stand alone run
390
+ if __FILE__ == $0
391
+ application = FXApp.new("FXIrb", "ruby")
392
+ application.threadsEnabled = true
393
+ Thread.abort_on_exception = true
394
+ application.init(ARGV)
395
+ window = FXMainWindow.new(application, "FXIrb", nil, nil, DECOR_ALL, 0, 0, 580, 500)
396
+ fxirb = FXIrb.init(window, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP|TEXT_SHOWACTIVE)
397
+ application.create
398
+ window.show(PLACEMENT_SCREEN)
399
+ fxirb.on_exit {exit}
400
+ application.run
401
+ end