utils 0.0.39 → 0.0.40

Sign up to get free protection for your applications and to get access to all the features.
@@ -4021,15 +4021,15 @@ function! s:BufAbbreviations()
4021
4021
  Rabbrev coo[ cookies
4022
4022
  Rabbrev fl[ flash
4023
4023
  Rabbrev rr( render
4024
- Rabbrev ra( render :action\ =>\
4025
- Rabbrev rc( render :controller\ =>\
4026
- Rabbrev rf( render :file\ =>\
4027
- Rabbrev ri( render :inline\ =>\
4028
- Rabbrev rj( render :json\ =>\
4029
- Rabbrev rl( render :layout\ =>\
4030
- Rabbrev rp( render :partial\ =>\
4031
- Rabbrev rt( render :text\ =>\
4032
- Rabbrev rx( render :xml\ =>\
4024
+ Rabbrev ra( render :action\ =>\
4025
+ Rabbrev rc( render :controller\ =>\
4026
+ Rabbrev rf( render :file\ =>\
4027
+ Rabbrev ri( render :inline\ =>\
4028
+ Rabbrev rj( render :json\ =>\
4029
+ Rabbrev rl( render :layout\ =>\
4030
+ Rabbrev rp( render :partial\ =>\
4031
+ Rabbrev rt( render :text\ =>\
4032
+ Rabbrev rx( render :xml\ =>\
4033
4033
  endif
4034
4034
  if buffer.type_name('view','helper')
4035
4035
  Rabbrev dotiw distance_of_time_in_words
@@ -4037,8 +4037,8 @@ function! s:BufAbbreviations()
4037
4037
  endif
4038
4038
  if buffer.type_name('controller')
4039
4039
  Rabbrev re( redirect_to
4040
- Rabbrev rea( redirect_to :action\ =>\
4041
- Rabbrev rec( redirect_to :controller\ =>\
4040
+ Rabbrev rea( redirect_to :action\ =>\
4041
+ Rabbrev rec( redirect_to :controller\ =>\
4042
4042
  Rabbrev rst( respond_to
4043
4043
  endif
4044
4044
  if buffer.type_name() ==# 'model' || buffer.type_name('model-arb')
@@ -4076,13 +4076,13 @@ function! s:BufAbbreviations()
4076
4076
  Rabbrev asre( assert_response
4077
4077
  Rabbrev art( assert_redirected_to
4078
4078
  endif
4079
- Rabbrev :a :action\ =>\
4079
+ Rabbrev :a :action\ =>\
4080
4080
  " hax
4081
- Rabbrev :c :co________\ =>\
4081
+ Rabbrev :c :co________\ =>\
4082
4082
  inoreabbrev <buffer> <silent> :c <C-R>=<SID>TheCWord()<CR>
4083
- Rabbrev :i :id\ =>\
4084
- Rabbrev :o :object\ =>\
4085
- Rabbrev :p :partial\ =>\
4083
+ Rabbrev :i :id\ =>\
4084
+ Rabbrev :o :object\ =>\
4085
+ Rabbrev :p :partial\ =>\
4086
4086
  Rabbrev logd( logger.debug
4087
4087
  Rabbrev logi( logger.info
4088
4088
  Rabbrev logw( logger.warn
data/lib/utils/editor.rb CHANGED
@@ -6,15 +6,26 @@ module Utils
6
6
 
7
7
  module SourceLocationExtension
8
8
  def source_location
9
+ filename = nil
10
+ linenumber = nil
9
11
  if respond_to?(:to_str)
10
12
  if (string = to_str) =~ FILE_LINENUMBER_REGEXP
11
- [ $1, $2.to_i ]
13
+ filename = $1
14
+ linenumber = $2.to_i
15
+ [ $1, linenumber ]
12
16
  else
13
- [ string, 1 ]
17
+ filename = string
14
18
  end
15
19
  else
16
- [ to_s, 1 ]
20
+ filename = to_s
17
21
  end
22
+ array = linenumber ? [ filename, linenumber ] : [ filename, 1 ]
23
+ array.singleton_class.instance_eval do
24
+ define_method(:filename) { filename }
25
+ define_method(:linenumber) { linenumber }
26
+ define_method(:to_s) { [ filename, linenumber ].compact * ':' }
27
+ end
28
+ array
18
29
  end
19
30
  end
20
31
 
@@ -38,6 +49,7 @@ module Utils
38
49
  alias wait? wait
39
50
 
40
51
  def vim
52
+ vim_in_path = [`which gvim`, `which vim`].map(&:chomp).find(&:full?)
41
53
  @vim ||=
42
54
  case `uname -s`
43
55
  when /\Adarwin/i
@@ -46,10 +58,10 @@ module Utils
46
58
  then
47
59
  File.join(path, 'Contents/MacOS/Vim')
48
60
  else
49
- 'vim'
61
+ vim_in_path
50
62
  end
51
63
  else
52
- 'vim'
64
+ vim_in_path
53
65
  end
54
66
  end
55
67
 
data/lib/utils/file_xt.rb CHANGED
@@ -1,5 +1,8 @@
1
+ require 'dslkit/polite'
2
+
1
3
  module Utils
2
4
  module FileXt
5
+ extend DSLKit::Concern
3
6
  include File::Constants
4
7
 
5
8
  SEEK_SET = File::SEEK_SET
@@ -30,12 +33,6 @@ module Utils
30
33
  end
31
34
  end
32
35
 
33
- def self.included(modul)
34
- modul.instance_eval do
35
- extend ClassMethods
36
- end
37
- end
38
-
39
36
  module ClassMethods
40
37
  def binary?(name)
41
38
  File.open(name, 'rb') { |f| f.binary? }
data/lib/utils/find.rb CHANGED
@@ -1,42 +1,146 @@
1
+ require 'pathname'
2
+
1
3
  module Utils
2
4
  module Find
3
- #
4
- # Calls the associated block with the name of every file and directory listed
5
- # as arguments, then recursively on their subdirectories, and so on.
6
- #
7
- # See the +Find+ module documentation for an example.
8
- #
9
- def find(*paths) # :yield: path
10
- paths.collect!{|d| d.dup}
11
- while file = paths.shift
12
- catch(:prune) do
13
- yield file.dup.taint
14
- next unless File.exist? file
5
+ class ConfigurableFinder
6
+ module PathExtension
7
+ attr_writer :finder
8
+
9
+ def file
10
+ tried = false
15
11
  begin
16
- if File.stat(file).directory? then
17
- d = Dir.open(file)
12
+ file = @finder.get_file(self)
13
+ if file
14
+ file.closed? and file.reopen
15
+ else
16
+ file = File.new(self)
17
+ @finder.add_file self, file
18
+ end
19
+ return file
20
+ rescue Errno::EMFILE
21
+ tried and raise
22
+ @finder.close_files
23
+ tried = true
24
+ retry
25
+ rescue Errno::ENOENT, Errno::EACCES
26
+ return
27
+ end
28
+ end
29
+
30
+ def pathname
31
+ Pathname.new(self)
32
+ end
33
+
34
+ def suffix
35
+ pathname.extname[1..-1]
36
+ end
37
+
38
+ def exist?
39
+ !!file
40
+ end
41
+
42
+ def stat
43
+ file and file.stat
44
+ end
45
+
46
+ def lstat
47
+ file and file.lstat
48
+ end
49
+ end
50
+
51
+ def initialize(opts = {})
52
+ @files = {}
53
+ opts[:suffix].full? { |s| @suffix = [*s] }
54
+ @follow_symlinks = opts.fetch(:follow_symlinks, false)
55
+ end
56
+
57
+ def include_suffix?(suffix)
58
+ @suffix.nil? || @suffix.include?(suffix)
59
+ end
60
+
61
+ def visit_file?(file)
62
+ suffix = File.extname(file).full?(:[], 1..-1) || ''
63
+ include_suffix?(suffix)
64
+ end
65
+
66
+ def prepare_file(file)
67
+ path = file.dup.taint
68
+ path.extend PathExtension
69
+ path.finder = self
70
+ path
71
+ end
72
+
73
+ def get_file(path)
74
+ @files[path]
75
+ end
76
+
77
+ def add_file(path, file)
78
+ @files[path] = file
79
+ self
80
+ end
81
+
82
+ def close_files
83
+ @files.each_value do |f|
84
+ f.closed? or f.close
85
+ end
86
+ nil
87
+ end
88
+
89
+ def stat(file)
90
+ @follow_symlinks ? file.stat : file.lstat
91
+ end
92
+
93
+ def find(*paths, &block)
94
+ block_given? or return enum_for(__method__, *paths)
95
+
96
+ paths.map! do |d|
97
+ File.exist?(d) or raise Errno::ENOENT
98
+ d.dup
99
+ end
100
+
101
+ while file = paths.shift
102
+ catch(:prune) do
103
+ file = prepare_file(file)
104
+ visit_file?(file) and yield file
105
+ begin
106
+ s = stat(file) or next
107
+ rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
108
+ next
109
+ end
110
+ if s.directory? then
18
111
  begin
19
- for f in d
20
- next if f == "." or f == ".."
21
- if File::ALT_SEPARATOR and file =~ /^(?:[\/\\]|[A-Za-z]:[\/\\]?)$/ then
22
- f = file + f
23
- elsif file == "/" then
24
- f = "/" + f
25
- else
26
- f = File.join(file, f)
27
- end
28
- paths.unshift f.untaint
29
- end
30
- ensure
31
- d.close
112
+ tried = false
113
+ fs = Dir.entries(file)
114
+ rescue Errno::EMFILE
115
+ tried and raise
116
+ close_files
117
+ tried = true
118
+ retry
119
+ rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
120
+ next
121
+ end
122
+ fs.sort!
123
+ fs.reverse_each do |f|
124
+ next if f == "." or f == ".."
125
+ f = File.join(file, f)
126
+ paths.unshift f.untaint
32
127
  end
33
128
  end
34
- rescue Errno::ENOENT, Errno::EACCES
35
129
  end
36
130
  end
37
131
  end
38
132
  end
39
133
 
134
+ # Calls the associated block with the name of every file and directory
135
+ # listed as arguments, then recursively on their subdirectories, and so on.
136
+ #
137
+ # See the +Find+ module documentation for an example.
138
+ #
139
+ def find(*paths, &block) # :yield: path
140
+ paths, options = paths.extract_last_argument_options
141
+ ConfigurableFinder.new(options).find(*paths, &block)
142
+ end
143
+
40
144
  #
41
145
  # Skips the current file or directory, restarting the loop with the next
42
146
  # entry. If the current file is a directory, that directory will not be
data/lib/utils/finder.rb CHANGED
@@ -36,8 +36,8 @@ class Utils::Finder
36
36
  end
37
37
 
38
38
  def attempt_match?(path)
39
- stat = File.stat(path)
40
- stat.symlink? and stat = File.lstat(path)
39
+ stat = path.stat
40
+ stat.symlink? and stat = path.lstat
41
41
  if @only_directory
42
42
  stat.directory?
43
43
  elsif @directory
@@ -54,10 +54,10 @@ class Utils::Finder
54
54
  pathes = []
55
55
  find(*@roots) do |filename|
56
56
  begin
57
- bn, s = File.basename(filename), File.stat(filename)
57
+ bn, s = filename.pathname.basename, filename.stat
58
58
  if s.directory? && @config.discover.prune?(bn)
59
59
  $DEBUG and warn "Pruning #{filename.inspect}."
60
- Utils::Find.prune
60
+ prune
61
61
  end
62
62
  if s.file? && @config.discover.skip?(bn)
63
63
  $DEBUG and warn "Skipping #{filename.inspect}."
@@ -73,7 +73,7 @@ class Utils::Finder
73
73
  @suffixes = @args['I'].ask_and_send(:split, /[\s,]+/).to_a
74
74
  pathes = pathes.map! do |path, dir, file|
75
75
  if @suffixes.full?
76
- @suffixes.include?(File.extname(file)[1..-1]) or next
76
+ @suffixes.include?(path.suffix) or next
77
77
  end
78
78
  if do_match = attempt_match?(path) and $DEBUG
79
79
  warn "Attempt match of #{path.inspect}"
data/lib/utils/grepper.rb CHANGED
@@ -6,6 +6,7 @@ class ::File
6
6
  end
7
7
 
8
8
  class Utils::Grepper
9
+ include Utils::Find
9
10
  include Utils::Patterns
10
11
  include Term::ANSIColor
11
12
 
@@ -71,9 +72,11 @@ class Utils::Grepper
71
72
  bn, s = File.basename(filename), File.stat(filename)
72
73
  if s.directory? && @config.search.prune?(bn)
73
74
  $DEBUG and warn "Pruning #{filename.inspect}."
74
- Utils::Find.prune
75
+ prune
75
76
  end
76
- if s.file? && !@config.search.skip?(bn) && (!@name_pattern || @name_pattern.match(bn))
77
+ if s.file? && !@config.search.skip?(bn) &&
78
+ (!@name_pattern || @name_pattern.match(bn))
79
+ then
77
80
  File.open(filename, 'rb') do |file|
78
81
  if file.binary? != true
79
82
  $DEBUG and warn "Matching #{filename.inspect}."
@@ -147,8 +150,8 @@ class Utils::Grepper
147
150
  def search
148
151
  @suffixes = @args['I'].ask_and_send(:split, /[\s,]+/).to_a
149
152
  for dir in @roots
150
- Utils::Find.find(dir) do |filename|
151
- if @suffixes.empty? || @suffixes.include?(File.extname(filename)[1..-1])
153
+ find(dir) do |filename|
154
+ if @suffixes.empty? || @suffixes.include?(filename.suffix)
152
155
  match(filename)
153
156
  end
154
157
  end
data/lib/utils/irb.rb ADDED
@@ -0,0 +1,507 @@
1
+ require 'tins/xt'
2
+ require 'irb/completion'
3
+ require 'enumerator'
4
+ require 'pp'
5
+ require_maybe 'ap'
6
+ if Readline.respond_to?(:point) && Readline.respond_to?(:line_buffer)
7
+ require 'pry-editline'
8
+ end
9
+ require 'utils'
10
+ $editor = Utils::Editor.new
11
+ $pager = ENV['PAGER'] || 'less -r'
12
+
13
+ if IRB.conf[:PROMPT]
14
+ IRB.conf[:PROMPT][:CUSTOM] = {
15
+ :PROMPT_I => ">> ",
16
+ :PROMPT_N => ">> ",
17
+ :PROMPT_S => "%l> ",
18
+ :PROMPT_C => "+> ",
19
+ :RETURN => " # => %s\n"
20
+ }
21
+ IRB.conf[:PROMPT_MODE] = :CUSTOM
22
+ end
23
+
24
+ module Utils
25
+ module IRB
26
+
27
+ module Shell
28
+ require 'fileutils'
29
+ include FileUtils
30
+ require 'utils/find'
31
+ include Utils::Find
32
+
33
+ # Start _ri_ for +pattern+. If +pattern+ is not string like, call it with
34
+ # pattern.class.name as argument.
35
+ def ri(*patterns)
36
+ patterns.map! { |p| p.respond_to?(:to_str) ? p.to_str : p.class.name }
37
+ system "ri #{patterns.map { |p| "'#{p}'" } * ' '} | #{$pager}"
38
+ end
39
+
40
+ # Restart this irb.
41
+ def irb_restart
42
+ exec $0
43
+ end
44
+
45
+ # Return all instance methods of obj's class.
46
+ def irb_all_class_instance_methods(obj)
47
+ methods = obj.class.instance_methods
48
+ irb_wrap_methods obj, methods
49
+ end
50
+
51
+ # Return instance methods of obj's class without the inherited/mixed in
52
+ # methods.
53
+ def irb_class_instance_methods(obj)
54
+ methods = obj.class.instance_methods(false)
55
+ irb_wrap_methods obj, methods
56
+ end
57
+
58
+ # Return all instance methods defined in module modul.
59
+ def irb_all_instance_methods(modul)
60
+ methods = modul.instance_methods
61
+ irb_wrap_methods modul, methods, true
62
+ end
63
+
64
+ # Return instance methods defined in module modul without the inherited/mixed
65
+ # in methods.
66
+ def irb_instance_methods(modul)
67
+ methods = modul.instance_methods(false)
68
+ irb_wrap_methods modul, methods, true
69
+ end
70
+
71
+ # Return all methods of obj (including obj's eigenmethods.)
72
+ def irb_all_methods(obj)
73
+ methods = obj.methods
74
+ irb_wrap_methods obj, methods
75
+ end
76
+
77
+ # Return instance methods of obj's class without the inherited/mixed in
78
+ # methods, but including obj's eigenmethods.
79
+ def irb_methods(obj)
80
+ methods = obj.class.ancestors[1..-1].inject(obj.methods) do |all, a|
81
+ all -= a.instance_methods
82
+ end
83
+ irb_wrap_methods obj, methods
84
+ end
85
+
86
+ # Return all eigen methods of obj.
87
+ def irb_eigen_methods(obj)
88
+ irb_wrap_methods obj, obj.methods(false)
89
+ end
90
+
91
+ def irb_wrap_methods(obj, methods, modul = false)
92
+ methods.map do |name|
93
+ MethodWrapper.new(obj, name, modul) rescue nil
94
+ end.compact.sort!
95
+ end
96
+
97
+ class WrapperBase
98
+ include Comparable
99
+
100
+ def initialize(name)
101
+ @name =
102
+ case
103
+ when name.respond_to?(:to_str)
104
+ name.to_str
105
+ when name.respond_to?(:to_sym)
106
+ name.to_sym.to_s
107
+ else
108
+ name.to_s
109
+ end
110
+ end
111
+
112
+ attr_reader :name
113
+
114
+ attr_reader :description
115
+
116
+ alias to_str name
117
+
118
+ alias inspect description
119
+
120
+ alias to_s description
121
+
122
+ def ==(name)
123
+ @name = name
124
+ end
125
+
126
+ alias eql? ==
127
+
128
+ def hash
129
+ @name.hash
130
+ end
131
+
132
+ def <=>(other)
133
+ @name <=> other.name
134
+ end
135
+ end
136
+
137
+ class MethodWrapper < WrapperBase
138
+ def initialize(obj, name, modul)
139
+ super(name)
140
+ if modul
141
+ @arity = obj.instance_method(name).arity
142
+ else
143
+ @arity = obj.method(name).arity
144
+ end
145
+ @description = "#@name(#@arity)"
146
+ end
147
+
148
+ attr_reader :arity
149
+ end
150
+
151
+ class ConstantWrapper < WrapperBase
152
+ def initialize(obj, name)
153
+ super(name)
154
+ @klass = obj.class
155
+ @description = "#@name:#@klass"
156
+ end
157
+
158
+ attr_reader :klass
159
+ end
160
+
161
+ # Return all the constants defined in +modul+.
162
+ def irb_constants(modul)
163
+ modul.constants.map { |c| ConstantWrapper.new(modul.const_get(c), c) }.sort
164
+ end
165
+
166
+ # Return all the subclasses of +klass+. TODO implement subclasses w/out rails
167
+ def irb_subclasses(klass)
168
+ klass.subclasses.map { |c| ConstantWrapper.new(eval(c), c) }.sort
169
+ end
170
+
171
+ unless Object.const_defined?(:Infinity)
172
+ Infinity = 1.0 / 0 # I like to define the infinite.
173
+ end
174
+
175
+ # Output all kinds of information about +obj+. If detailed is given output
176
+ # details about the methods (+ arity) in inheritance chain of +obj+ as well.
177
+ # * detailed as 0 output instance methods only of part 0 (the first) of the
178
+ # chain.
179
+ # * detailed as 1..2 output instance methods of +obj+ inherited from parts 1
180
+ # and 2 of the the chain.
181
+ def irb_info(obj, detailed = nil)
182
+ if Module === obj
183
+ modul = obj
184
+ klassp = Class === modul
185
+ if klassp
186
+ begin
187
+ allocated = modul.allocate
188
+ rescue TypeError
189
+ else
190
+ obj = allocated
191
+ end
192
+ end
193
+ else
194
+ modul = obj.class
195
+ end
196
+ inspected = obj.inspect
197
+ puts "obj = #{inspected.size > 40 ? inspected[0, 40] + '...' : inspected} is of class #{obj.class}."
198
+ am = irb_all_methods(obj).size
199
+ ms = irb_methods(obj).size
200
+ ems = irb_eigen_methods(obj).size
201
+ puts "obj: #{am} methods, #{ms} only local#{ems > 0 ? " (#{ems} eigenmethods),": ','} #{am - ms} inherited/mixed in."
202
+ acim = irb_all_class_instance_methods(obj).size
203
+ cim = irb_class_instance_methods(obj).size
204
+ puts "obj: #{acim} instance methods, #{cim} local, #{acim - cim} only inherited/mixed in."
205
+ if klassp
206
+ s = modul.superclass
207
+ puts "Superclass of #{modul}: #{s}"
208
+ end
209
+ a = []
210
+ ec = true
211
+ begin
212
+ a << (class << obj; self; end)
213
+ rescue TypeError
214
+ ec = false
215
+ end
216
+ a.concat modul.ancestors
217
+ if ec
218
+ puts "Ancestors of #{modul}: (#{a[0]},) #{a[1..-1].map { |k| "#{k}#{k == s ? '*' : ''}" } * ', '}"
219
+ else
220
+ puts "Ancestors of #{modul}: #{a[0..-1].map { |k| "#{k}#{k == s ? '*' : ''}" } * ', '}"
221
+ end
222
+ if Class === modul and detailed
223
+ if detailed.respond_to? :to_int
224
+ detailed = detailed..detailed
225
+ end
226
+ detailed.each do |i|
227
+ break if i >= a.size
228
+ k = a[i]
229
+ puts "#{k}:"
230
+ puts irb_wrap_methods(obj, k.instance_methods(false)).sort
231
+ end
232
+ end
233
+ nil
234
+ end
235
+
236
+ # Output *all* the irb_info about +obj+. You may need to buy a bigger screen for
237
+ # this or use:
238
+ # less { irb_fullinfo object }
239
+ def irb_fullinfo(obj)
240
+ irb_info obj, 0..Infinity
241
+ end
242
+
243
+ def capture_output(with_stderr = false)
244
+ return "missing block" unless block_given?
245
+ require 'tempfile'
246
+ begin
247
+ old_stdout, $stdout = $stdout, Tempfile.new('irb')
248
+ if with_stderr
249
+ old_stderr, $stderr = $stderr, $stdout
250
+ end
251
+ yield
252
+ ensure
253
+ $stdout, temp = old_stdout, $stdout
254
+ with_stderr and $stderr = old_stderr
255
+ end
256
+ temp.rewind
257
+ temp.read
258
+ end
259
+
260
+ # Use pager on the output of the commands given in the block.
261
+ def less(with_stderr = false, &block)
262
+ IO.popen($pager, 'w') do |f|
263
+ f.write capture_output(with_stderr, &block)
264
+ f.close_write
265
+ end
266
+ nil
267
+ end
268
+
269
+ def irb_time
270
+ s = Time.now
271
+ yield
272
+ d = Time.now - s
273
+ warn "Took %.3fs seconds." % d
274
+ d
275
+ end
276
+
277
+ def irb_time_tap
278
+ r = nil
279
+ irb_time { r = yield }
280
+ r
281
+ end
282
+
283
+ def irb_time_watch(duration = 1)
284
+ start = Time.now
285
+ pre = nil
286
+ loop do
287
+ cur = [ yield ].flatten
288
+ unless pre
289
+ pre = cur.map(&:to_f)
290
+ cur = [ yield ].flatten
291
+ end
292
+ expired = Time.now - start
293
+ diffs = cur.zip(pre).map { |c, p| c - p }
294
+ rates = diffs.map { |d| d / duration }
295
+ warn "#{expired} #{cur.zip(rates, diffs).map(&:inspect) * ' '} # / per sec."
296
+ pre = cur.map(&:to_f)
297
+ sleep duration
298
+ end
299
+ end
300
+
301
+ def irb_write(filename, text = nil)
302
+ File.secure_write filename, text, 'wb'
303
+ end
304
+
305
+ def irb_read(filename, chunk_size = 8_192)
306
+ if block_given?
307
+ File.open(filename) do |file|
308
+ until file.eof?
309
+ yield file.read(chunk_size)
310
+ end
311
+ end
312
+ else
313
+ IO.read filename
314
+ end
315
+ end
316
+
317
+ def irb_load!(*files)
318
+ files = files.map { |f| f.gsub(/(\.rb)?\Z/, '.rb') }
319
+ loaded = {}
320
+ for file in files
321
+ catch :found do
322
+ Find.find('.') do |f|
323
+ File.directory?(f) and next
324
+ md5_f = Utils::MD5.md5(f)
325
+ if f.end_with?(file) and !loaded[md5_f]
326
+ Kernel.load f
327
+ loaded[md5_f] = true
328
+ STDERR.puts "Loaded '#{f}'."
329
+ end
330
+ end
331
+ Find.find('.') do |f|
332
+ File.directory?(f) and next
333
+ md5_f = Utils::MD5.md5(f)
334
+ if f.end_with?(file) and !loaded[md5_f]
335
+ Kernel.load f
336
+ loaded[md5_f] = true
337
+ STDERR.puts "Loaded '#{f}'."
338
+ end
339
+ end
340
+ end
341
+ end
342
+ nil
343
+ end
344
+
345
+ def irb_edit(*files)
346
+ $editor.full?(:edit, *files)
347
+ end
348
+
349
+ # List contents of directory
350
+ def ls(*args)
351
+ puts `ls #{args.map { |x| "'#{x}'" } * ' '}`
352
+ end
353
+
354
+ if defined?(ActiveRecord::Base)
355
+ $logger = Logger.new(STDERR)
356
+ def irb_toggle_logging
357
+ require 'logger'
358
+ if ActiveRecord::Base.logger != $logger
359
+ $old_logger = ActiveRecord::Base.logger
360
+ ActiveRecord::Base.logger = $logger
361
+ true
362
+ else
363
+ ActiveRecord::Base.logger = $old_logger
364
+ false
365
+ end
366
+ end
367
+ end
368
+ end
369
+
370
+ module Module
371
+ # Start +ri+ for +module#pattern+, trying to find a method matching +pattern+
372
+ # for all modules in the ancestors chain of this module.
373
+ def ri(pattern = nil)
374
+ if pattern
375
+ pattern = pattern.to_sym.to_s if pattern.respond_to? :to_sym
376
+ ancestors.each do |a|
377
+ if method = a.instance_methods(false).find { |m| pattern === m }
378
+ a = Object if a == Kernel # ri seems to be confused
379
+ system "ri #{a}##{method} | #{$pager}"
380
+ end
381
+ end
382
+ else
383
+ system "ri #{self} | #{$pager}"
384
+ end
385
+ return
386
+ end
387
+ end
388
+
389
+ module Regexp
390
+ # Show the match of this Regexp on the +string+.
391
+ def show_match(string)
392
+ string =~ self ? "#{$`}<<#{$&}>>#{$'}" : "no match"
393
+ end
394
+ end
395
+
396
+ module String
397
+ # Pipe this string into +cmd+.
398
+ def |(cmd)
399
+ IO.popen(cmd, 'w+') do |f|
400
+ f.write self
401
+ f.close_write
402
+ return f.read
403
+ end
404
+ end
405
+
406
+ # Write this string into file +filename+.
407
+ def >>(filename)
408
+ File.secure_write(filename, self)
409
+ end
410
+ end
411
+
412
+ module Relation
413
+ def explain
414
+ connection.select_all("EXPLAIN #{to_sql}")
415
+ end
416
+ end
417
+ end
418
+ end
419
+
420
+ module IRB
421
+ class Context
422
+ def init_save_history
423
+ unless (class<<@io;self;end).include?(HistorySavingAbility)
424
+ @io.extend(HistorySavingAbility)
425
+ end
426
+ end
427
+
428
+ def save_history
429
+ IRB.conf[:SAVE_HISTORY]
430
+ end
431
+
432
+ def save_history=(val)
433
+ IRB.conf[:SAVE_HISTORY] = val
434
+ if val
435
+ main_context = IRB.conf[:MAIN_CONTEXT]
436
+ main_context = self unless main_context
437
+ main_context.init_save_history
438
+ end
439
+ end
440
+
441
+ def history_file
442
+ IRB.conf[:HISTORY_FILE]
443
+ end
444
+
445
+ def history_file=(hist)
446
+ IRB.conf[:HISTORY_FILE] = hist
447
+ end
448
+ end
449
+
450
+ module HistorySavingAbility
451
+ include Readline
452
+
453
+ def HistorySavingAbility.create_finalizer
454
+ at_exit do
455
+ if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0
456
+ if hf = IRB.conf[:HISTORY_FILE]
457
+ file = File.expand_path(hf)
458
+ end
459
+ file = IRB.rc_file("_history") unless file
460
+ open(file, 'w' ) do |f|
461
+ hist = HISTORY.to_a
462
+ f.puts(hist[-num..-1] || hist)
463
+ end
464
+ end
465
+ end
466
+ end
467
+
468
+ def HistorySavingAbility.extended(obj)
469
+ HistorySavingAbility.create_finalizer
470
+ obj.load_history
471
+ obj
472
+ end
473
+
474
+ def load_history
475
+ hist = IRB.conf[:HISTORY_FILE]
476
+ hist = IRB.rc_file("_history") unless hist
477
+ if File.exist?(hist)
478
+ open(hist) do |f|
479
+ f.each {|l| HISTORY << l.chomp}
480
+ end
481
+ end
482
+ end
483
+ end
484
+ end
485
+ IRB.conf[:SAVE_HISTORY] = 1000
486
+
487
+ if defined?(ActiveRecord::Relation)
488
+ class ActiveRecord::Relation
489
+ include Utils::IRB::Relation
490
+ end
491
+ end
492
+
493
+ class String
494
+ include Utils::IRB::String
495
+ end
496
+
497
+ class Object
498
+ include Utils::IRB::Shell
499
+ end
500
+
501
+ class Module
502
+ include Utils::IRB::Module
503
+ end
504
+
505
+ class Regexp
506
+ include Utils::IRB::Regexp
507
+ end