irb 1.1.0.pre.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +55 -0
  4. data/exe/irb +11 -0
  5. data/irb.gemspec +29 -0
  6. data/lib/irb.rb +855 -0
  7. data/lib/irb/cmd/chws.rb +34 -0
  8. data/lib/irb/cmd/fork.rb +39 -0
  9. data/lib/irb/cmd/help.rb +46 -0
  10. data/lib/irb/cmd/load.rb +67 -0
  11. data/lib/irb/cmd/nop.rb +39 -0
  12. data/lib/irb/cmd/pushws.rb +41 -0
  13. data/lib/irb/cmd/subirb.rb +43 -0
  14. data/lib/irb/color.rb +218 -0
  15. data/lib/irb/completion.rb +339 -0
  16. data/lib/irb/context.rb +459 -0
  17. data/lib/irb/ext/change-ws.rb +46 -0
  18. data/lib/irb/ext/history.rb +120 -0
  19. data/lib/irb/ext/loader.rb +129 -0
  20. data/lib/irb/ext/multi-irb.rb +265 -0
  21. data/lib/irb/ext/save-history.rb +117 -0
  22. data/lib/irb/ext/tracer.rb +72 -0
  23. data/lib/irb/ext/use-loader.rb +77 -0
  24. data/lib/irb/ext/workspaces.rb +67 -0
  25. data/lib/irb/extend-command.rb +328 -0
  26. data/lib/irb/frame.rb +81 -0
  27. data/lib/irb/help.rb +37 -0
  28. data/lib/irb/init.rb +312 -0
  29. data/lib/irb/input-method.rb +298 -0
  30. data/lib/irb/inspector.rb +142 -0
  31. data/lib/irb/lc/.document +4 -0
  32. data/lib/irb/lc/error.rb +32 -0
  33. data/lib/irb/lc/help-message +50 -0
  34. data/lib/irb/lc/ja/encoding_aliases.rb +11 -0
  35. data/lib/irb/lc/ja/error.rb +31 -0
  36. data/lib/irb/lc/ja/help-message +52 -0
  37. data/lib/irb/locale.rb +182 -0
  38. data/lib/irb/magic-file.rb +38 -0
  39. data/lib/irb/notifier.rb +232 -0
  40. data/lib/irb/output-method.rb +92 -0
  41. data/lib/irb/ruby-lex.rb +492 -0
  42. data/lib/irb/ruby-token.rb +267 -0
  43. data/lib/irb/slex.rb +282 -0
  44. data/lib/irb/src_encoding.rb +7 -0
  45. data/lib/irb/version.rb +17 -0
  46. data/lib/irb/workspace.rb +190 -0
  47. data/lib/irb/ws-for-case-2.rb +15 -0
  48. data/lib/irb/xmp.rb +170 -0
  49. metadata +133 -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,218 @@
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], 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], ALL],
49
+ on_qsymbols_beg: [[RED], ALL],
50
+ on_qwords_beg: [[RED], 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_tstring_beg: [[RED], ALL],
56
+ on_tstring_content: [[RED], ALL],
57
+ on_tstring_end: [[RED], ALL],
58
+ on_words_beg: [[RED], ALL],
59
+ on_parse_error: [[RED, REVERSE], ALL],
60
+ compile_error: [[RED, REVERSE], ALL],
61
+ }
62
+ rescue NameError
63
+ # Give up highlighting Ripper-incompatible older Ruby
64
+ TOKEN_SEQ_EXPRS = {}
65
+ end
66
+ private_constant :TOKEN_SEQ_EXPRS
67
+
68
+ class << self
69
+ def colorable?
70
+ $stdout.tty? && supported? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
71
+ end
72
+
73
+ def inspect_colorable?(obj)
74
+ case obj
75
+ when String, Symbol, Regexp, Integer, Float, FalseClass, TrueClass, NilClass
76
+ true
77
+ when Hash
78
+ obj.all? { |k, v| inspect_colorable?(k) && inspect_colorable?(v) }
79
+ when Array
80
+ obj.all? { |o| inspect_colorable?(o) }
81
+ when Range
82
+ inspect_colorable?(obj.begin) && inspect_colorable?(obj.end)
83
+ when Module
84
+ !obj.name.nil?
85
+ else
86
+ false
87
+ end
88
+ end
89
+
90
+ def clear
91
+ return '' unless colorable?
92
+ "\e[#{CLEAR}m"
93
+ end
94
+
95
+ def colorize(text, seq)
96
+ return text unless colorable?
97
+ seq = seq.map { |s| "\e[#{const_get(s)}m" }.join('')
98
+ "#{seq}#{text}#{clear}"
99
+ end
100
+
101
+ # If `complete` is false (code is incomplete), this does not warn compile_error.
102
+ # This option is needed to avoid warning a user when the compile_error is happening
103
+ # because the input is not wrong but just incomplete.
104
+ def colorize_code(code, complete: true)
105
+ return code unless colorable?
106
+
107
+ symbol_state = SymbolState.new
108
+ colored = +''
109
+ length = 0
110
+
111
+ scan(code, allow_last_error: !complete) do |token, str, expr|
112
+ in_symbol = symbol_state.scan_token(token)
113
+ str.each_line do |line|
114
+ line = Reline::Unicode.escape_for_print(line)
115
+ if seq = dispatch_seq(token, expr, line, in_symbol: in_symbol)
116
+ colored << seq.map { |s| "\e[#{s}m" }.join('')
117
+ colored << line.sub(/\Z/, clear)
118
+ else
119
+ colored << line
120
+ end
121
+ end
122
+ length += str.bytesize
123
+ end
124
+
125
+ # give up colorizing incomplete Ripper tokens
126
+ if length != code.bytesize
127
+ return Reline::Unicode.escape_for_print(code)
128
+ end
129
+
130
+ colored
131
+ end
132
+
133
+ private
134
+
135
+ # Ripper::Lexer::Elem#state is supported on Ruby 2.5+
136
+ def supported?
137
+ return @supported if defined?(@supported)
138
+ @supported = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
139
+ end
140
+
141
+ def scan(code, allow_last_error:)
142
+ pos = [1, 0]
143
+
144
+ lexer = Ripper::Lexer.new(code)
145
+ if lexer.respond_to?(:scan) # Ruby 2.7+
146
+ lexer.scan.each do |elem|
147
+ str = elem.tok
148
+ next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message
149
+ next if ([elem.pos[0], elem.pos[1] + str.bytesize] <=> pos) <= 0
150
+
151
+ str.each_line do |line|
152
+ if line.end_with?("\n")
153
+ pos[0] += 1
154
+ pos[1] = 0
155
+ else
156
+ pos[1] += line.bytesize
157
+ end
158
+ end
159
+
160
+ yield(elem.event, str, elem.state)
161
+ end
162
+ else
163
+ lexer.parse.each do |elem|
164
+ yield(elem.event, elem.tok, elem.state)
165
+ end
166
+ end
167
+ end
168
+
169
+ def dispatch_seq(token, expr, str, in_symbol:)
170
+ if token == :on_parse_error or token == :compile_error
171
+ TOKEN_SEQ_EXPRS[token][0]
172
+ elsif in_symbol
173
+ [YELLOW]
174
+ elsif TOKEN_KEYWORDS.fetch(token, []).include?(str)
175
+ [CYAN, BOLD]
176
+ elsif (seq, exprs = TOKEN_SEQ_EXPRS[token]; (expr & (exprs || 0)) != 0)
177
+ seq
178
+ else
179
+ nil
180
+ end
181
+ end
182
+ end
183
+
184
+ # A class to manage a state to know whether the current token is for Symbol or not.
185
+ class SymbolState
186
+ def initialize
187
+ # Push `true` to detect Symbol. `false` to increase the nest level for non-Symbol.
188
+ @stack = []
189
+ end
190
+
191
+ # Return true if the token is a part of Symbol.
192
+ def scan_token(token)
193
+ prev_state = @stack.last
194
+ case token
195
+ when :on_symbeg
196
+ @stack << true
197
+ when :on_ident, :on_op, :on_const, :on_ivar, :on_cvar, :on_gvar, :on_kw
198
+ if @stack.last # Pop only when it's Symbol
199
+ @stack.pop
200
+ return prev_state
201
+ end
202
+ when :on_tstring_beg
203
+ @stack << false
204
+ when :on_embexpr_beg
205
+ @stack << false
206
+ return prev_state
207
+ when :on_tstring_end # :on_tstring_end may close Symbol
208
+ @stack.pop
209
+ return prev_state
210
+ when :on_embexpr_end
211
+ @stack.pop
212
+ end
213
+ @stack.last
214
+ end
215
+ end
216
+ private_constant :SymbolState
217
+ end
218
+ end