irb 1.1.0.pre.4

Sign up to get free protection for your applications and to get access to all the features.
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