irb 1.1.0.pre.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +10 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +55 -0
  5. data/Rakefile +10 -0
  6. data/bin/console +6 -0
  7. data/bin/setup +6 -0
  8. data/doc/irb/irb-tools.rd.ja +184 -0
  9. data/doc/irb/irb.rd.ja +411 -0
  10. data/exe/irb +11 -0
  11. data/irb.gemspec +84 -0
  12. data/lib/irb.rb +870 -0
  13. data/lib/irb/cmd/chws.rb +34 -0
  14. data/lib/irb/cmd/fork.rb +39 -0
  15. data/lib/irb/cmd/help.rb +46 -0
  16. data/lib/irb/cmd/load.rb +67 -0
  17. data/lib/irb/cmd/nop.rb +39 -0
  18. data/lib/irb/cmd/pushws.rb +41 -0
  19. data/lib/irb/cmd/subirb.rb +43 -0
  20. data/lib/irb/color.rb +233 -0
  21. data/lib/irb/completion.rb +339 -0
  22. data/lib/irb/context.rb +458 -0
  23. data/lib/irb/ext/change-ws.rb +46 -0
  24. data/lib/irb/ext/history.rb +157 -0
  25. data/lib/irb/ext/loader.rb +129 -0
  26. data/lib/irb/ext/multi-irb.rb +265 -0
  27. data/lib/irb/ext/save-history.rb +117 -0
  28. data/lib/irb/ext/tracer.rb +72 -0
  29. data/lib/irb/ext/use-loader.rb +77 -0
  30. data/lib/irb/ext/workspaces.rb +67 -0
  31. data/lib/irb/extend-command.rb +328 -0
  32. data/lib/irb/frame.rb +81 -0
  33. data/lib/irb/help.rb +37 -0
  34. data/lib/irb/init.rb +312 -0
  35. data/lib/irb/input-method.rb +298 -0
  36. data/lib/irb/inspector.rb +142 -0
  37. data/lib/irb/lc/.document +4 -0
  38. data/lib/irb/lc/error.rb +32 -0
  39. data/lib/irb/lc/help-message +52 -0
  40. data/lib/irb/lc/ja/encoding_aliases.rb +11 -0
  41. data/lib/irb/lc/ja/error.rb +31 -0
  42. data/lib/irb/lc/ja/help-message +55 -0
  43. data/lib/irb/locale.rb +182 -0
  44. data/lib/irb/magic-file.rb +38 -0
  45. data/lib/irb/notifier.rb +232 -0
  46. data/lib/irb/output-method.rb +92 -0
  47. data/lib/irb/ruby-lex.rb +499 -0
  48. data/lib/irb/ruby_logo.aa +38 -0
  49. data/lib/irb/slex.rb +282 -0
  50. data/lib/irb/src_encoding.rb +7 -0
  51. data/lib/irb/version.rb +17 -0
  52. data/lib/irb/workspace.rb +181 -0
  53. data/lib/irb/ws-for-case-2.rb +15 -0
  54. data/lib/irb/xmp.rb +170 -0
  55. data/man/irb.1 +207 -0
  56. metadata +140 -0
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ # change-ws.rb -
4
+ # $Release Version: 0.9.6$
5
+ # $Revision$
6
+ # by Keiju ISHITSUKA(keiju@ruby-lang.org)
7
+ #
8
+ # --
9
+ #
10
+ #
11
+ #
12
+
13
+ require_relative "nop"
14
+ require_relative "../ext/change-ws"
15
+
16
+ # :stopdoc:
17
+ module IRB
18
+ module ExtendCommand
19
+
20
+ class CurrentWorkingWorkspace < Nop
21
+ def execute(*obj)
22
+ irb_context.main
23
+ end
24
+ end
25
+
26
+ class ChangeWorkspace < Nop
27
+ def execute(*obj)
28
+ irb_context.change_workspace(*obj)
29
+ irb_context.main
30
+ end
31
+ end
32
+ end
33
+ end
34
+ # :startdoc:
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ # fork.rb -
4
+ # $Release Version: 0.9.6 $
5
+ # $Revision$
6
+ # by Keiju ISHITSUKA(keiju@ruby-lang.org)
7
+ #
8
+ # --
9
+ #
10
+ #
11
+ #
12
+
13
+
14
+ # :stopdoc:
15
+ module IRB
16
+ module ExtendCommand
17
+ class Fork < Nop
18
+ def execute
19
+ pid = send ExtendCommand.irb_original_method_name("fork")
20
+ unless pid
21
+ class << self
22
+ alias_method :exit, ExtendCommand.irb_original_method_name('exit')
23
+ end
24
+ if block_given?
25
+ begin
26
+ yield
27
+ ensure
28
+ exit
29
+ end
30
+ end
31
+ end
32
+ pid
33
+ end
34
+ end
35
+ end
36
+ end
37
+ # :startdoc:
38
+
39
+
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ # help.rb - helper using ri
4
+ # $Release Version: 0.9.6$
5
+ # $Revision$
6
+ #
7
+ # --
8
+ #
9
+ #
10
+ #
11
+
12
+ require_relative "nop"
13
+
14
+ # :stopdoc:
15
+ module IRB
16
+ module ExtendCommand
17
+ class Help < Nop
18
+ def execute(*names)
19
+ require 'rdoc/ri/driver'
20
+ IRB::ExtendCommand::Help.const_set(:Ri, RDoc::RI::Driver.new)
21
+ rescue LoadError, SystemExit
22
+ IRB::ExtendCommand::Help.remove_method(:execute)
23
+ # raise NoMethodError in ensure
24
+ else
25
+ def execute(*names)
26
+ if names.empty?
27
+ Ri.interactive
28
+ return
29
+ end
30
+ names.each do |name|
31
+ begin
32
+ Ri.display_name(name.to_s)
33
+ rescue RDoc::RI::Error
34
+ puts $!.message
35
+ end
36
+ end
37
+ nil
38
+ end
39
+ nil
40
+ ensure
41
+ execute(*names)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ # :startdoc:
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ # load.rb -
4
+ # $Release Version: 0.9.6$
5
+ # $Revision$
6
+ # by Keiju ISHITSUKA(keiju@ruby-lang.org)
7
+ #
8
+ # --
9
+ #
10
+ #
11
+ #
12
+
13
+ require_relative "nop"
14
+ require_relative "../ext/loader"
15
+
16
+ # :stopdoc:
17
+ module IRB
18
+ module ExtendCommand
19
+ class Load < Nop
20
+ include IrbLoader
21
+
22
+ def execute(file_name, priv = nil)
23
+ return irb_load(file_name, priv)
24
+ end
25
+ end
26
+
27
+ class Require < Nop
28
+ include IrbLoader
29
+
30
+ def execute(file_name)
31
+
32
+ rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
33
+ return false if $".find{|f| f =~ rex}
34
+
35
+ case file_name
36
+ when /\.rb$/
37
+ begin
38
+ if irb_load(file_name)
39
+ $".push file_name
40
+ return true
41
+ end
42
+ rescue LoadError
43
+ end
44
+ when /\.(so|o|sl)$/
45
+ return ruby_require(file_name)
46
+ end
47
+
48
+ begin
49
+ irb_load(f = file_name + ".rb")
50
+ $".push f
51
+ return true
52
+ rescue LoadError
53
+ return ruby_require(file_name)
54
+ end
55
+ end
56
+ end
57
+
58
+ class Source < Nop
59
+ include IrbLoader
60
+ def execute(file_name)
61
+ source_file(file_name)
62
+ end
63
+ end
64
+ end
65
+
66
+ end
67
+ # :startdoc:
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ # nop.rb -
4
+ # $Release Version: 0.9.6$
5
+ # $Revision$
6
+ # by Keiju ISHITSUKA(keiju@ruby-lang.org)
7
+ #
8
+ # --
9
+ #
10
+ #
11
+ #
12
+ # :stopdoc:
13
+ module IRB
14
+ module ExtendCommand
15
+ class Nop
16
+
17
+
18
+ def self.execute(conf, *opts)
19
+ command = new(conf)
20
+ command.execute(*opts)
21
+ end
22
+
23
+ def initialize(conf)
24
+ @irb_context = conf
25
+ end
26
+
27
+ attr_reader :irb_context
28
+
29
+ def irb
30
+ @irb_context.irb
31
+ end
32
+
33
+ def execute(*opts)
34
+ #nop
35
+ end
36
+ end
37
+ end
38
+ end
39
+ # :startdoc:
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ # change-ws.rb -
4
+ # $Release Version: 0.9.6$
5
+ # $Revision$
6
+ # by Keiju ISHITSUKA(keiju@ruby-lang.org)
7
+ #
8
+ # --
9
+ #
10
+ #
11
+ #
12
+
13
+ require_relative "nop"
14
+ require_relative "../ext/workspaces"
15
+
16
+ # :stopdoc:
17
+ module IRB
18
+ module ExtendCommand
19
+ class Workspaces < Nop
20
+ def execute(*obj)
21
+ irb_context.workspaces.collect{|ws| ws.main}
22
+ end
23
+ end
24
+
25
+ class PushWorkspace < Workspaces
26
+ def execute(*obj)
27
+ irb_context.push_workspace(*obj)
28
+ super
29
+ end
30
+ end
31
+
32
+ class PopWorkspace < Workspaces
33
+ def execute(*obj)
34
+ irb_context.pop_workspace(*obj)
35
+ super
36
+ end
37
+ end
38
+ end
39
+ end
40
+ # :startdoc:
41
+
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: false
2
+ # multi.rb -
3
+ # $Release Version: 0.9.6$
4
+ # $Revision$
5
+ # by Keiju ISHITSUKA(keiju@ruby-lang.org)
6
+ #
7
+ # --
8
+ #
9
+ #
10
+ #
11
+
12
+ require_relative "nop"
13
+ require_relative "../ext/multi-irb"
14
+
15
+ # :stopdoc:
16
+ module IRB
17
+ module ExtendCommand
18
+ class IrbCommand < Nop
19
+ def execute(*obj)
20
+ IRB.irb(nil, *obj)
21
+ end
22
+ end
23
+
24
+ class Jobs < Nop
25
+ def execute
26
+ IRB.JobManager
27
+ end
28
+ end
29
+
30
+ class Foreground < Nop
31
+ def execute(key)
32
+ IRB.JobManager.switch(key)
33
+ end
34
+ end
35
+
36
+ class Kill < Nop
37
+ def execute(*keys)
38
+ IRB.JobManager.kill(*keys)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ # :startdoc:
@@ -0,0 +1,233 @@
1
+ # frozen_string_literal: true
2
+ require 'reline'
3
+ require 'ripper'
4
+
5
+ module IRB # :nodoc:
6
+ module Color
7
+ CLEAR = 0
8
+ BOLD = 1
9
+ UNDERLINE = 4
10
+ REVERSE = 7
11
+ RED = 31
12
+ GREEN = 32
13
+ YELLOW = 33
14
+ BLUE = 34
15
+ MAGENTA = 35
16
+ CYAN = 36
17
+
18
+ TOKEN_KEYWORDS = {
19
+ on_kw: ['nil', 'self', 'true', 'false', '__FILE__', '__LINE__'],
20
+ on_const: ['ENV'],
21
+ }
22
+ private_constant :TOKEN_KEYWORDS
23
+
24
+ # A constant of all-bit 1 to match any Ripper's state in #dispatch_seq
25
+ ALL = -1
26
+ private_constant :ALL
27
+
28
+ begin
29
+ # Following pry's colors where possible, but sometimes having a compromise like making
30
+ # backtick and regexp as red (string's color, because they're sharing tokens).
31
+ TOKEN_SEQ_EXPRS = {
32
+ on_CHAR: [[BLUE, BOLD], ALL],
33
+ on_backtick: [[RED, BOLD], ALL],
34
+ on_comment: [[BLUE, BOLD], ALL],
35
+ on_const: [[BLUE, BOLD, UNDERLINE], ALL],
36
+ on_embexpr_beg: [[RED], ALL],
37
+ on_embexpr_end: [[RED], ALL],
38
+ on_embvar: [[RED], ALL],
39
+ on_float: [[MAGENTA, BOLD], ALL],
40
+ on_gvar: [[GREEN, BOLD], ALL],
41
+ on_heredoc_beg: [[RED], ALL],
42
+ on_heredoc_end: [[RED], ALL],
43
+ on_ident: [[BLUE, BOLD], Ripper::EXPR_ENDFN],
44
+ on_imaginary: [[BLUE, BOLD], ALL],
45
+ on_int: [[BLUE, BOLD], ALL],
46
+ on_kw: [[GREEN], ALL],
47
+ on_label: [[MAGENTA], ALL],
48
+ on_label_end: [[RED, BOLD], ALL],
49
+ on_qsymbols_beg: [[RED, BOLD], ALL],
50
+ on_qwords_beg: [[RED, BOLD], ALL],
51
+ on_rational: [[BLUE, BOLD], ALL],
52
+ on_regexp_beg: [[RED, BOLD], ALL],
53
+ on_regexp_end: [[RED, BOLD], ALL],
54
+ on_symbeg: [[YELLOW], ALL],
55
+ on_symbols_beg: [[RED, BOLD], ALL],
56
+ on_tstring_beg: [[RED, BOLD], ALL],
57
+ on_tstring_content: [[RED], ALL],
58
+ on_tstring_end: [[RED, BOLD], ALL],
59
+ on_words_beg: [[RED, BOLD], ALL],
60
+ on_parse_error: [[RED, REVERSE], ALL],
61
+ compile_error: [[RED, REVERSE], ALL],
62
+ }
63
+ rescue NameError
64
+ # Give up highlighting Ripper-incompatible older Ruby
65
+ TOKEN_SEQ_EXPRS = {}
66
+ end
67
+ private_constant :TOKEN_SEQ_EXPRS
68
+
69
+ class << self
70
+ def colorable?
71
+ $stdout.tty? && supported? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
72
+ end
73
+
74
+ def inspect_colorable?(obj, seen: {})
75
+ case obj
76
+ when String, Symbol, Regexp, Integer, Float, FalseClass, TrueClass, NilClass
77
+ true
78
+ when Hash
79
+ without_circular_ref(obj, seen: seen) do
80
+ obj.all? { |k, v| inspect_colorable?(k, seen: seen) && inspect_colorable?(v, seen: seen) }
81
+ end
82
+ when Array
83
+ without_circular_ref(obj, seen: seen) do
84
+ obj.all? { |o| inspect_colorable?(o, seen: seen) }
85
+ end
86
+ when Range
87
+ inspect_colorable?(obj.begin, seen: seen) && inspect_colorable?(obj.end, seen: seen)
88
+ when Module
89
+ !obj.name.nil?
90
+ else
91
+ false
92
+ end
93
+ end
94
+
95
+ def clear
96
+ return '' unless colorable?
97
+ "\e[#{CLEAR}m"
98
+ end
99
+
100
+ def colorize(text, seq)
101
+ return text unless colorable?
102
+ seq = seq.map { |s| "\e[#{const_get(s)}m" }.join('')
103
+ "#{seq}#{text}#{clear}"
104
+ end
105
+
106
+ # If `complete` is false (code is incomplete), this does not warn compile_error.
107
+ # This option is needed to avoid warning a user when the compile_error is happening
108
+ # because the input is not wrong but just incomplete.
109
+ def colorize_code(code, complete: true)
110
+ return code unless colorable?
111
+
112
+ symbol_state = SymbolState.new
113
+ colored = +''
114
+ length = 0
115
+
116
+ scan(code, allow_last_error: !complete) do |token, str, expr|
117
+ in_symbol = symbol_state.scan_token(token)
118
+ str.each_line do |line|
119
+ line = Reline::Unicode.escape_for_print(line)
120
+ if seq = dispatch_seq(token, expr, line, in_symbol: in_symbol)
121
+ colored << seq.map { |s| "\e[#{s}m" }.join('')
122
+ colored << line.sub(/\Z/, clear)
123
+ else
124
+ colored << line
125
+ end
126
+ end
127
+ length += str.bytesize
128
+ end
129
+
130
+ # give up colorizing incomplete Ripper tokens
131
+ if length != code.bytesize
132
+ return Reline::Unicode.escape_for_print(code)
133
+ end
134
+
135
+ colored
136
+ end
137
+
138
+ private
139
+
140
+ def without_circular_ref(obj, seen:, &block)
141
+ return false if seen.key?(obj.object_id)
142
+ seen[obj.object_id] = true
143
+ block.call
144
+ ensure
145
+ seen.delete(obj.object_id)
146
+ end
147
+
148
+ # Ripper::Lexer::Elem#state is supported on Ruby 2.5+
149
+ def supported?
150
+ return @supported if defined?(@supported)
151
+ @supported = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
152
+ end
153
+
154
+ def scan(code, allow_last_error:)
155
+ pos = [1, 0]
156
+
157
+ verbose, $VERBOSE = $VERBOSE, nil
158
+ lexer = Ripper::Lexer.new(code)
159
+ if lexer.respond_to?(:scan) # Ruby 2.7+
160
+ lexer.scan.each do |elem|
161
+ str = elem.tok
162
+ next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
163
+ next if ([elem.pos[0], elem.pos[1] + str.bytesize] <=> pos) <= 0
164
+
165
+ str.each_line do |line|
166
+ if line.end_with?("\n")
167
+ pos[0] += 1
168
+ pos[1] = 0
169
+ else
170
+ pos[1] += line.bytesize
171
+ end
172
+ end
173
+
174
+ yield(elem.event, str, elem.state)
175
+ end
176
+ else
177
+ lexer.parse.each do |elem|
178
+ yield(elem.event, elem.tok, elem.state)
179
+ end
180
+ end
181
+ $VERBOSE = verbose
182
+ end
183
+
184
+ def dispatch_seq(token, expr, str, in_symbol:)
185
+ if token == :on_parse_error or token == :compile_error
186
+ TOKEN_SEQ_EXPRS[token][0]
187
+ elsif in_symbol
188
+ [YELLOW]
189
+ elsif TOKEN_KEYWORDS.fetch(token, []).include?(str)
190
+ [CYAN, BOLD]
191
+ elsif (seq, exprs = TOKEN_SEQ_EXPRS[token]; (expr & (exprs || 0)) != 0)
192
+ seq
193
+ else
194
+ nil
195
+ end
196
+ end
197
+ end
198
+
199
+ # A class to manage a state to know whether the current token is for Symbol or not.
200
+ class SymbolState
201
+ def initialize
202
+ # Push `true` to detect Symbol. `false` to increase the nest level for non-Symbol.
203
+ @stack = []
204
+ end
205
+
206
+ # Return true if the token is a part of Symbol.
207
+ def scan_token(token)
208
+ prev_state = @stack.last
209
+ case token
210
+ when :on_symbeg, :on_symbols_beg, :on_qsymbols_beg
211
+ @stack << true
212
+ when :on_ident, :on_op, :on_const, :on_ivar, :on_cvar, :on_gvar, :on_kw
213
+ if @stack.last # Pop only when it's Symbol
214
+ @stack.pop
215
+ return prev_state
216
+ end
217
+ when :on_tstring_beg
218
+ @stack << false
219
+ when :on_embexpr_beg
220
+ @stack << false
221
+ return prev_state
222
+ when :on_tstring_end # :on_tstring_end may close Symbol
223
+ @stack.pop
224
+ return prev_state
225
+ when :on_embexpr_end
226
+ @stack.pop
227
+ end
228
+ @stack.last
229
+ end
230
+ end
231
+ private_constant :SymbolState
232
+ end
233
+ end