utils 0.0.39 → 0.0.40

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.
@@ -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