irb 1.7.1 → 1.13.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.document +1 -1
  3. data/Gemfile +10 -1
  4. data/README.md +265 -20
  5. data/Rakefile +13 -10
  6. data/doc/irb/irb.rd.ja +1 -3
  7. data/irb.gemspec +2 -1
  8. data/lib/irb/cmd/nop.rb +3 -52
  9. data/lib/irb/color.rb +4 -2
  10. data/lib/irb/command/backtrace.rb +17 -0
  11. data/lib/irb/command/base.rb +62 -0
  12. data/lib/irb/command/break.rb +17 -0
  13. data/lib/irb/command/catch.rb +17 -0
  14. data/lib/irb/command/chws.rb +40 -0
  15. data/lib/irb/command/context.rb +16 -0
  16. data/lib/irb/{cmd → command}/continue.rb +3 -3
  17. data/lib/irb/command/debug.rb +71 -0
  18. data/lib/irb/{cmd → command}/delete.rb +3 -3
  19. data/lib/irb/command/disable_irb.rb +19 -0
  20. data/lib/irb/command/edit.rb +63 -0
  21. data/lib/irb/command/exit.rb +18 -0
  22. data/lib/irb/{cmd → command}/finish.rb +3 -3
  23. data/lib/irb/command/force_exit.rb +18 -0
  24. data/lib/irb/command/help.rb +83 -0
  25. data/lib/irb/command/history.rb +45 -0
  26. data/lib/irb/command/info.rb +17 -0
  27. data/lib/irb/command/internal_helpers.rb +27 -0
  28. data/lib/irb/{cmd → command}/irb_info.rb +7 -7
  29. data/lib/irb/{cmd → command}/load.rb +23 -8
  30. data/lib/irb/{cmd → command}/ls.rb +42 -19
  31. data/lib/irb/{cmd → command}/measure.rb +18 -17
  32. data/lib/irb/{cmd → command}/next.rb +3 -3
  33. data/lib/irb/command/pushws.rb +65 -0
  34. data/lib/irb/command/show_doc.rb +51 -0
  35. data/lib/irb/command/show_source.rb +74 -0
  36. data/lib/irb/{cmd → command}/step.rb +3 -3
  37. data/lib/irb/command/subirb.rb +123 -0
  38. data/lib/irb/{cmd → command}/whereami.rb +3 -5
  39. data/lib/irb/command.rb +23 -0
  40. data/lib/irb/completion.rb +133 -102
  41. data/lib/irb/context.rb +182 -66
  42. data/lib/irb/debug/ui.rb +103 -0
  43. data/lib/irb/{cmd/debug.rb → debug.rb} +53 -59
  44. data/lib/irb/default_commands.rb +265 -0
  45. data/lib/irb/easter-egg.rb +16 -6
  46. data/lib/irb/ext/change-ws.rb +6 -8
  47. data/lib/irb/ext/{history.rb → eval_history.rb} +7 -7
  48. data/lib/irb/ext/loader.rb +4 -4
  49. data/lib/irb/ext/multi-irb.rb +5 -5
  50. data/lib/irb/ext/tracer.rb +12 -51
  51. data/lib/irb/ext/use-loader.rb +6 -8
  52. data/lib/irb/ext/workspaces.rb +10 -34
  53. data/lib/irb/frame.rb +1 -1
  54. data/lib/irb/help.rb +3 -3
  55. data/lib/irb/helper_method/base.rb +16 -0
  56. data/lib/irb/helper_method/conf.rb +11 -0
  57. data/lib/irb/helper_method.rb +29 -0
  58. data/lib/irb/{ext/save-history.rb → history.rb} +20 -58
  59. data/lib/irb/init.rb +154 -58
  60. data/lib/irb/input-method.rb +238 -203
  61. data/lib/irb/inspector.rb +3 -3
  62. data/lib/irb/lc/error.rb +1 -11
  63. data/lib/irb/lc/help-message +4 -0
  64. data/lib/irb/lc/ja/error.rb +1 -11
  65. data/lib/irb/lc/ja/help-message +13 -0
  66. data/lib/irb/locale.rb +2 -2
  67. data/lib/irb/nesting_parser.rb +13 -3
  68. data/lib/irb/notifier.rb +1 -1
  69. data/lib/irb/output-method.rb +2 -8
  70. data/lib/irb/pager.rb +91 -0
  71. data/lib/irb/ruby-lex.rb +391 -471
  72. data/lib/irb/ruby_logo.aa +43 -0
  73. data/lib/irb/source_finder.rb +139 -0
  74. data/lib/irb/statement.rb +80 -0
  75. data/lib/irb/version.rb +3 -3
  76. data/lib/irb/workspace.rb +24 -4
  77. data/lib/irb/ws-for-case-2.rb +1 -1
  78. data/lib/irb/xmp.rb +3 -3
  79. data/lib/irb.rb +1232 -604
  80. data/man/irb.1 +7 -0
  81. metadata +60 -32
  82. data/lib/irb/cmd/backtrace.rb +0 -21
  83. data/lib/irb/cmd/break.rb +0 -21
  84. data/lib/irb/cmd/catch.rb +0 -21
  85. data/lib/irb/cmd/chws.rb +0 -36
  86. data/lib/irb/cmd/edit.rb +0 -61
  87. data/lib/irb/cmd/help.rb +0 -23
  88. data/lib/irb/cmd/info.rb +0 -21
  89. data/lib/irb/cmd/pushws.rb +0 -45
  90. data/lib/irb/cmd/show_cmds.rb +0 -39
  91. data/lib/irb/cmd/show_doc.rb +0 -48
  92. data/lib/irb/cmd/show_source.rb +0 -113
  93. data/lib/irb/cmd/subirb.rb +0 -66
  94. data/lib/irb/extend-command.rb +0 -356
  95. data/lib/irb/src_encoding.rb +0 -7
@@ -0,0 +1,16 @@
1
+ require "singleton"
2
+
3
+ module IRB
4
+ module HelperMethod
5
+ class Base
6
+ include Singleton
7
+
8
+ class << self
9
+ def description(description = nil)
10
+ @description = description if description
11
+ @description
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module IRB
2
+ module HelperMethod
3
+ class Conf < Base
4
+ description "Returns the current IRB context."
5
+
6
+ def execute
7
+ IRB.CurrentContext
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ require_relative "helper_method/base"
2
+
3
+ module IRB
4
+ module HelperMethod
5
+ @helper_methods = {}
6
+
7
+ class << self
8
+ attr_reader :helper_methods
9
+
10
+ def register(name, helper_class)
11
+ @helper_methods[name] = helper_class
12
+
13
+ if defined?(HelpersContainer)
14
+ HelpersContainer.install_helper_methods
15
+ end
16
+ end
17
+
18
+ def all_helper_methods_info
19
+ @helper_methods.map do |name, helper_class|
20
+ { display_name: name, description: helper_class.description }
21
+ end
22
+ end
23
+ end
24
+
25
+ # Default helper_methods
26
+ require_relative "helper_method/conf"
27
+ register(:conf, HelperMethod::Conf)
28
+ end
29
+ end
@@ -1,70 +1,23 @@
1
- # frozen_string_literal: false
2
- #
3
- # save-history.rb -
4
- # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
- #
1
+ require "pathname"
6
2
 
7
3
  module IRB
8
4
  module HistorySavingAbility # :nodoc:
9
- end
10
-
11
- class Context
12
- def init_save_history# :nodoc:
13
- unless (class<<@io;self;end).include?(HistorySavingAbility)
14
- @io.extend(HistorySavingAbility)
15
- end
16
- end
17
-
18
- # A copy of the default <code>IRB.conf[:SAVE_HISTORY]</code>
19
- def save_history
20
- IRB.conf[:SAVE_HISTORY]
21
- end
22
-
23
- remove_method(:save_history=) if method_defined?(:save_history=)
24
- # Sets <code>IRB.conf[:SAVE_HISTORY]</code> to the given +val+ and calls
25
- # #init_save_history with this context.
26
- #
27
- # Will store the number of +val+ entries of history in the #history_file
28
- #
29
- # Add the following to your +.irbrc+ to change the number of history
30
- # entries stored to 1000:
31
- #
32
- # IRB.conf[:SAVE_HISTORY] = 1000
33
- def save_history=(val)
34
- IRB.conf[:SAVE_HISTORY] = val
35
- if val
36
- main_context = IRB.conf[:MAIN_CONTEXT]
37
- main_context = self unless main_context
38
- main_context.init_save_history
39
- end
40
- end
41
-
42
- # A copy of the default <code>IRB.conf[:HISTORY_FILE]</code>
43
- def history_file
44
- IRB.conf[:HISTORY_FILE]
5
+ def support_history_saving?
6
+ true
45
7
  end
46
8
 
47
- # Set <code>IRB.conf[:HISTORY_FILE]</code> to the given +hist+.
48
- def history_file=(hist)
49
- IRB.conf[:HISTORY_FILE] = hist
50
- end
51
- end
52
-
53
- module HistorySavingAbility # :nodoc:
54
- def HistorySavingAbility.extended(obj)
55
- IRB.conf[:AT_EXIT].push proc{obj.save_history}
56
- obj.load_history
57
- obj
9
+ def reset_history_counter
10
+ @loaded_history_lines = self.class::HISTORY.size
58
11
  end
59
12
 
60
13
  def load_history
61
- return unless self.class.const_defined?(:HISTORY)
62
14
  history = self.class::HISTORY
15
+
63
16
  if history_file = IRB.conf[:HISTORY_FILE]
64
17
  history_file = File.expand_path(history_file)
65
18
  end
66
19
  history_file = IRB.rc_file("_history") unless history_file
67
- if File.exist?(history_file)
20
+ if history_file && File.exist?(history_file)
68
21
  File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f|
69
22
  f.each { |l|
70
23
  l = l.chomp
@@ -82,14 +35,17 @@ module IRB
82
35
  end
83
36
 
84
37
  def save_history
85
- return unless self.class.const_defined?(:HISTORY)
86
- history = self.class::HISTORY
38
+ history = self.class::HISTORY.to_a
39
+
87
40
  if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) != 0
88
41
  if history_file = IRB.conf[:HISTORY_FILE]
89
42
  history_file = File.expand_path(history_file)
90
43
  end
91
44
  history_file = IRB.rc_file("_history") unless history_file
92
45
 
46
+ # When HOME and XDG_CONFIG_HOME are not available, history_file might be nil
47
+ return unless history_file
48
+
93
49
  # Change the permission of a file that already exists[BUG #7694]
94
50
  begin
95
51
  if File.stat(history_file).mode & 066 != 0
@@ -108,13 +64,19 @@ module IRB
108
64
  append_history = true
109
65
  end
110
66
 
67
+ pathname = Pathname.new(history_file)
68
+ unless Dir.exist?(pathname.dirname)
69
+ warn "Warning: The directory to save IRB's history file does not exist. Please double check `IRB.conf[:HISTORY_FILE]`'s value."
70
+ return
71
+ end
72
+
111
73
  File.open(history_file, (append_history ? 'a' : 'w'), 0o600, encoding: IRB.conf[:LC_MESSAGES]&.encoding) do |f|
112
- hist = history.map{ |l| l.split("\n").join("\\\n") }
74
+ hist = history.map{ |l| l.scrub.split("\n").join("\\\n") }
113
75
  unless append_history
114
76
  begin
115
77
  hist = hist.last(num) if hist.size > num and num > 0
116
78
  rescue RangeError # bignum too big to convert into `long'
117
- # Do nothing because the bignum should be treated as inifinity
79
+ # Do nothing because the bignum should be treated as infinity
118
80
  end
119
81
  end
120
82
  f.puts(hist)
data/lib/irb/init.rb CHANGED
@@ -1,10 +1,50 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/init.rb - irb initialize module
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
5
  #
6
6
 
7
7
  module IRB # :nodoc:
8
+ @CONF = {}
9
+ @INITIALIZED = false
10
+ # Displays current configuration.
11
+ #
12
+ # Modifying the configuration is achieved by sending a message to IRB.conf.
13
+ #
14
+ # See IRB@Configuration for more information.
15
+ def IRB.conf
16
+ @CONF
17
+ end
18
+
19
+ def @CONF.inspect
20
+ array = []
21
+ for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
22
+ case k
23
+ when :MAIN_CONTEXT, :__TMP__EHV__
24
+ array.push format("CONF[:%s]=...myself...", k.id2name)
25
+ when :PROMPT
26
+ s = v.collect{
27
+ |kk, vv|
28
+ ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
29
+ format(":%s=>{%s}", kk.id2name, ss.join(", "))
30
+ }
31
+ array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
32
+ else
33
+ array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
34
+ end
35
+ end
36
+ array.join("\n")
37
+ end
38
+
39
+ # Returns the current version of IRB, including release version and last
40
+ # updated date.
41
+ def IRB.version
42
+ format("irb %s (%s)", @RELEASE_VERSION, @LAST_UPDATE_DATE)
43
+ end
44
+
45
+ def IRB.initialized?
46
+ !!@INITIALIZED
47
+ end
8
48
 
9
49
  # initialize config
10
50
  def IRB.setup(ap_path, argv: ::ARGV)
@@ -12,22 +52,22 @@ module IRB # :nodoc:
12
52
  IRB.init_error
13
53
  IRB.parse_opts(argv: argv)
14
54
  IRB.run_config
55
+ IRB.validate_config
15
56
  IRB.load_modules
16
57
 
17
58
  unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]
18
59
  fail UndefinedPromptMode, @CONF[:PROMPT_MODE]
19
60
  end
61
+ @INITIALIZED = true
20
62
  end
21
63
 
22
64
  # @CONF default setting
23
65
  def IRB.init_config(ap_path)
24
- # class instance variables
25
- @TRACER_INITIALIZED = false
26
-
27
66
  # default configurations
28
67
  unless ap_path and @CONF[:AP_NAME]
29
68
  ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb")
30
69
  end
70
+ @CONF[:VERSION] = version
31
71
  @CONF[:AP_NAME] = File::basename(ap_path, ".rb")
32
72
 
33
73
  @CONF[:IRB_NAME] = "irb"
@@ -40,11 +80,13 @@ module IRB # :nodoc:
40
80
  @CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod)
41
81
  @CONF[:USE_COLORIZE] = (nc = ENV['NO_COLOR']).nil? || nc.empty?
42
82
  @CONF[:USE_AUTOCOMPLETE] = ENV.fetch("IRB_USE_AUTOCOMPLETE", "true") != "false"
83
+ @CONF[:COMPLETOR] = ENV.fetch("IRB_COMPLETOR", "regexp").to_sym
43
84
  @CONF[:INSPECT_MODE] = true
44
85
  @CONF[:USE_TRACER] = false
45
86
  @CONF[:USE_LOADER] = false
46
87
  @CONF[:IGNORE_SIGINT] = true
47
88
  @CONF[:IGNORE_EOF] = false
89
+ @CONF[:USE_PAGER] = true
48
90
  @CONF[:EXTRA_DOC_DIRS] = []
49
91
  @CONF[:ECHO] = nil
50
92
  @CONF[:ECHO_ON_ASSIGNMENT] = nil
@@ -58,35 +100,30 @@ module IRB # :nodoc:
58
100
  @CONF[:PROMPT] = {
59
101
  :NULL => {
60
102
  :PROMPT_I => nil,
61
- :PROMPT_N => nil,
62
103
  :PROMPT_S => nil,
63
104
  :PROMPT_C => nil,
64
105
  :RETURN => "%s\n"
65
106
  },
66
107
  :DEFAULT => {
67
- :PROMPT_I => "%N(%m):%03n:%i> ",
68
- :PROMPT_N => "%N(%m):%03n:%i> ",
69
- :PROMPT_S => "%N(%m):%03n:%i%l ",
70
- :PROMPT_C => "%N(%m):%03n:%i* ",
108
+ :PROMPT_I => "%N(%m):%03n> ",
109
+ :PROMPT_S => "%N(%m):%03n%l ",
110
+ :PROMPT_C => "%N(%m):%03n* ",
71
111
  :RETURN => "=> %s\n"
72
112
  },
73
113
  :CLASSIC => {
74
114
  :PROMPT_I => "%N(%m):%03n:%i> ",
75
- :PROMPT_N => "%N(%m):%03n:%i> ",
76
115
  :PROMPT_S => "%N(%m):%03n:%i%l ",
77
116
  :PROMPT_C => "%N(%m):%03n:%i* ",
78
117
  :RETURN => "%s\n"
79
118
  },
80
119
  :SIMPLE => {
81
120
  :PROMPT_I => ">> ",
82
- :PROMPT_N => ">> ",
83
121
  :PROMPT_S => "%l> ",
84
122
  :PROMPT_C => "?> ",
85
123
  :RETURN => "=> %s\n"
86
124
  },
87
125
  :INF_RUBY => {
88
- :PROMPT_I => "%N(%m):%03n:%i> ",
89
- :PROMPT_N => nil,
126
+ :PROMPT_I => "%N(%m):%03n> ",
90
127
  :PROMPT_S => nil,
91
128
  :PROMPT_C => nil,
92
129
  :RETURN => "%s\n",
@@ -94,7 +131,6 @@ module IRB # :nodoc:
94
131
  },
95
132
  :XMP => {
96
133
  :PROMPT_I => nil,
97
- :PROMPT_N => nil,
98
134
  :PROMPT_S => nil,
99
135
  :PROMPT_C => nil,
100
136
  :RETURN => " ==>%s\n"
@@ -157,10 +193,6 @@ module IRB # :nodoc:
157
193
  # Symbol aliases
158
194
  :'$' => :show_source,
159
195
  :'@' => :whereami,
160
- # Keyword aliases
161
- :break => :irb_break,
162
- :catch => :irb_catch,
163
- :next => :irb_next,
164
196
  }
165
197
  end
166
198
 
@@ -187,6 +219,7 @@ module IRB # :nodoc:
187
219
  added = [:TIME, IRB.conf[:MEASURE_PROC][:TIME], arg]
188
220
  end
189
221
  if added
222
+ IRB.conf[:MEASURE] = true
190
223
  found = IRB.conf[:MEASURE_CALLBACKS].find{ |m| m[0] == added[0] && m[2] == added[2] }
191
224
  if found
192
225
  # already added
@@ -207,6 +240,7 @@ module IRB # :nodoc:
207
240
  type_sym = type.upcase.to_sym
208
241
  IRB.conf[:MEASURE_CALLBACKS].reject!{ |t, | t == type_sym }
209
242
  end
243
+ IRB.conf[:MEASURE] = nil if IRB.conf[:MEASURE_CALLBACKS].empty?
210
244
  end
211
245
 
212
246
  def IRB.init_error
@@ -254,6 +288,8 @@ module IRB # :nodoc:
254
288
  end
255
289
  when "--noinspect"
256
290
  @CONF[:INSPECT_MODE] = false
291
+ when "--no-pager"
292
+ @CONF[:USE_PAGER] = false
257
293
  when "--singleline", "--readline", "--legacy"
258
294
  @CONF[:USE_SINGLELINE] = true
259
295
  when "--nosingleline", "--noreadline"
@@ -299,6 +335,10 @@ module IRB # :nodoc:
299
335
  @CONF[:USE_AUTOCOMPLETE] = true
300
336
  when "--noautocomplete"
301
337
  @CONF[:USE_AUTOCOMPLETE] = false
338
+ when "--regexp-completor"
339
+ @CONF[:COMPLETOR] = :regexp
340
+ when "--type-completor"
341
+ @CONF[:COMPLETOR] = :type
302
342
  when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
303
343
  opt = $1 || argv.shift
304
344
  prompt_mode = opt.upcase.tr("-", "_").intern
@@ -353,61 +393,73 @@ module IRB # :nodoc:
353
393
  $LOAD_PATH.unshift(*load_path)
354
394
  end
355
395
 
356
- # running config
396
+ # Run the config file
357
397
  def IRB.run_config
358
398
  if @CONF[:RC]
359
- begin
360
- load rc_file
361
- rescue LoadError, Errno::ENOENT
362
- rescue # StandardError, ScriptError
363
- print "load error: #{rc_file}\n"
364
- print $!.class, ": ", $!, "\n"
365
- for err in $@[0, $@.size - 2]
366
- print "\t", err, "\n"
367
- end
399
+ irbrc_files.each do |rc|
400
+ load rc
401
+ rescue StandardError, ScriptError => e
402
+ warn "Error loading RC file '#{rc}':\n#{e.full_message(highlight: false)}"
368
403
  end
369
404
  end
370
405
  end
371
406
 
372
407
  IRBRC_EXT = "rc"
373
- def IRB.rc_file(ext = IRBRC_EXT)
374
- if !@CONF[:RC_NAME_GENERATOR]
375
- rc_file_generators do |rcgen|
376
- @CONF[:RC_NAME_GENERATOR] ||= rcgen
377
- if File.exist?(rcgen.call(IRBRC_EXT))
378
- @CONF[:RC_NAME_GENERATOR] = rcgen
379
- break
380
- end
381
- end
408
+
409
+ def IRB.rc_file(ext)
410
+ prepare_irbrc_name_generators
411
+
412
+ # When irbrc exist in default location
413
+ if (rcgen = @existing_rc_name_generators.first)
414
+ return rcgen.call(ext)
382
415
  end
383
- case rc_file = @CONF[:RC_NAME_GENERATOR].call(ext)
384
- when String
385
- return rc_file
386
- else
387
- fail IllegalRCNameGenerator
416
+
417
+ # When irbrc does not exist in default location
418
+ rc_file_generators do |rcgen|
419
+ return rcgen.call(ext)
388
420
  end
421
+
422
+ # When HOME and XDG_CONFIG_HOME are not available
423
+ nil
424
+ end
425
+
426
+ def IRB.irbrc_files
427
+ prepare_irbrc_name_generators
428
+ @irbrc_files
389
429
  end
390
430
 
391
- # enumerate possible rc-file base name generators
392
- def IRB.rc_file_generators
393
- if irbrc = ENV["IRBRC"]
394
- yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
431
+ def IRB.validate_config
432
+ conf[:IRB_NAME] = conf[:IRB_NAME].to_s
433
+
434
+ irb_rc = conf[:IRB_RC]
435
+ unless irb_rc.nil? || irb_rc.respond_to?(:call)
436
+ raise_validation_error "IRB.conf[:IRB_RC] should be a callable object. Got #{irb_rc.inspect}."
437
+ end
438
+
439
+ back_trace_limit = conf[:BACK_TRACE_LIMIT]
440
+ unless back_trace_limit.is_a?(Integer)
441
+ raise_validation_error "IRB.conf[:BACK_TRACE_LIMIT] should be an integer. Got #{back_trace_limit.inspect}."
395
442
  end
396
- if xdg_config_home = ENV["XDG_CONFIG_HOME"]
397
- irb_home = File.join(xdg_config_home, "irb")
398
- if File.directory?(irb_home)
399
- yield proc{|rc| irb_home + "/irb#{rc}"}
443
+
444
+ prompt = conf[:PROMPT]
445
+ unless prompt.is_a?(Hash)
446
+ msg = "IRB.conf[:PROMPT] should be a Hash. Got #{prompt.inspect}."
447
+
448
+ if prompt.is_a?(Symbol)
449
+ msg += " Did you mean to set `IRB.conf[:PROMPT_MODE]`?"
400
450
  end
451
+
452
+ raise_validation_error msg
401
453
  end
402
- if home = ENV["HOME"]
403
- yield proc{|rc| home+"/.irb#{rc}"}
404
- yield proc{|rc| home+"/.config/irb/irb#{rc}"}
454
+
455
+ eval_history = conf[:EVAL_HISTORY]
456
+ unless eval_history.nil? || eval_history.is_a?(Integer)
457
+ raise_validation_error "IRB.conf[:EVAL_HISTORY] should be an integer. Got #{eval_history.inspect}."
405
458
  end
406
- current_dir = Dir.pwd
407
- yield proc{|rc| current_dir+"/.irb#{rc}"}
408
- yield proc{|rc| current_dir+"/irb#{rc.sub(/\A_?/, '.')}"}
409
- yield proc{|rc| current_dir+"/_irb#{rc}"}
410
- yield proc{|rc| current_dir+"/$irb#{rc}"}
459
+ end
460
+
461
+ def IRB.raise_validation_error(msg)
462
+ raise TypeError, msg, @irbrc_files
411
463
  end
412
464
 
413
465
  # loading modules
@@ -423,6 +475,50 @@ module IRB # :nodoc:
423
475
 
424
476
  class << IRB
425
477
  private
478
+
479
+ def prepare_irbrc_name_generators
480
+ return if @existing_rc_name_generators
481
+
482
+ @existing_rc_name_generators = []
483
+ @irbrc_files = []
484
+ rc_file_generators do |rcgen|
485
+ irbrc = rcgen.call(IRBRC_EXT)
486
+ if File.exist?(irbrc)
487
+ @irbrc_files << irbrc
488
+ @existing_rc_name_generators << rcgen
489
+ end
490
+ end
491
+ generate_current_dir_irbrc_files.each do |irbrc|
492
+ @irbrc_files << irbrc if File.exist?(irbrc)
493
+ end
494
+ @irbrc_files.uniq!
495
+ end
496
+
497
+ # enumerate possible rc-file base name generators
498
+ def rc_file_generators
499
+ if irbrc = ENV["IRBRC"]
500
+ yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
501
+ end
502
+ if xdg_config_home = ENV["XDG_CONFIG_HOME"]
503
+ irb_home = File.join(xdg_config_home, "irb")
504
+ if File.directory?(irb_home)
505
+ yield proc{|rc| irb_home + "/irb#{rc}"}
506
+ end
507
+ end
508
+ if home = ENV["HOME"]
509
+ yield proc{|rc| home+"/.irb#{rc}"}
510
+ if xdg_config_home.nil? || xdg_config_home.empty?
511
+ yield proc{|rc| home+"/.config/irb/irb#{rc}"}
512
+ end
513
+ end
514
+ end
515
+
516
+ # possible irbrc files in current directory
517
+ def generate_current_dir_irbrc_files
518
+ current_dir = Dir.pwd
519
+ %w[.irbrc irbrc _irbrc $irbrc].map { |file| "#{current_dir}/#{file}" }
520
+ end
521
+
426
522
  def set_encoding(extern, intern = nil, override: true)
427
523
  verbose, $VERBOSE = $VERBOSE, nil
428
524
  Encoding.default_external = extern unless extern.nil? || extern.empty?