katakata_irb 0.1.2 → 0.1.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.
@@ -1,216 +0,0 @@
1
- require 'irb'
2
- require_relative 'trex'
3
-
4
- module KatakataIrb::RubyLexPatch
5
- def self.patch_to_ruby_lex
6
- (RubyLex.instance_methods(false) - [:set_prompt, :process_continue, :check_code_block]).each { RubyLex.remove_method _1 }
7
- RubyLex.prepend self
8
- end
9
-
10
- def self.complete_tokens(code, context: nil)
11
- incomplete_tokens = RubyLex.ripper_lex_without_warning(code, context: context)
12
- KatakataIrb::TRex.interpolate_ripper_ignored_tokens(code, incomplete_tokens)
13
- end
14
-
15
- def calc_nesting_depth(opens)
16
- indent_level = 0
17
- nesting_level = 0
18
- opens.each_with_index do |t, index|
19
- case t.event
20
- when :on_heredoc_beg
21
- if opens[index + 1]&.event != :on_heredoc_beg
22
- if t.tok.start_with?('<<~')
23
- indent_level += 1
24
- else
25
- indent_level = 0
26
- end
27
- end
28
- when :on_tstring_beg, :on_regexp_beg, :on_symbeg
29
- indent_level += 1 if t.tok[0] == '%'
30
- when :on_embdoc_beg
31
- indent_level = 0
32
- else
33
- nesting_level += 1
34
- indent_level += 1
35
- end
36
- end
37
- [indent_level, nesting_level]
38
- end
39
-
40
- def process_indent_level(tokens)
41
- opens = KatakataIrb::TRex.parse(tokens)
42
- indent, _nesting = calc_nesting_depth(opens)
43
- indent * 2
44
- end
45
-
46
- def check_corresponding_token_depth(tokens, line_index)
47
- line_results = KatakataIrb::TRex.parse_line(tokens)
48
- result = line_results[line_index]
49
- return unless result
50
- _tokens, prev, opens, min_depth = result
51
- depth, = calc_nesting_depth(opens.take(min_depth))
52
- prev_depth, = calc_nesting_depth(prev)
53
- depth * 2 if depth < prev_depth
54
- end
55
-
56
- def ltype_from_open_tokens(opens)
57
- return nil if opens.empty?
58
- case opens.last.tok
59
- when ?`, /^<<[-~]?`/, /^%x.$/
60
- ?`
61
- when ?', /^<<[-~]?'/, /^%q.$/
62
- ?'
63
- when ?", /^<</, /^%.$/, /^%Q.$/
64
- ?"
65
- when ":'", ':"', ':', /^%s.$/
66
- ':'
67
- when /^%[iwIW].$/
68
- ']'
69
- when '/', /^%r.$/
70
- '/'
71
- end
72
- end
73
-
74
- def check_termination_in_prev_line(code, context: nil)
75
- tokens = self.class.ripper_lex_without_warning(code, context: context)
76
- last_newline_index = tokens.rindex { |t| t.tok.include?("\n") }
77
- index = (0...last_newline_index).reverse_each.find { |i| tokens[i].tok.include?("\n") }
78
- return false unless index
79
-
80
- last_line_tokens = tokens[(index + 1)..(tokens.size - 1)]
81
- first_token = last_line_tokens.find do |t|
82
- ![:on_sp, :on_ignored_sp, :on_comment].include?(t.event)
83
- end
84
-
85
- if first_token && first_token.state != Ripper::EXPR_DOT
86
- tokens_without_last_line = tokens[0..index]
87
- if check_termination(tokens_without_last_line)
88
- return last_line_tokens.map(&:tok).join
89
- end
90
- end
91
- false
92
- end
93
-
94
- def check_termination(tokens)
95
- opens = KatakataIrb::TRex.parse(tokens)
96
- opens.empty? && !process_continue(tokens)
97
- end
98
-
99
- def set_input(io, p = nil, context: nil, &block)
100
- @io = io
101
- if @io.respond_to?(:check_termination)
102
- @io.check_termination do |code|
103
- if Reline::IOGate.in_pasting?
104
- lex = RubyLex.new
105
- rest = lex.check_termination_in_prev_line(code, context: context)
106
- if rest
107
- Reline.delete_text
108
- rest.bytes.reverse_each do |c|
109
- Reline.ungetc(c)
110
- end
111
- true
112
- else
113
- false
114
- end
115
- else
116
- tokens = KatakataIrb::RubyLexPatch.complete_tokens(code, context: context)
117
- check_termination(tokens)
118
- end
119
- end
120
- end
121
- if @io.respond_to?(:dynamic_prompt)
122
- @io.dynamic_prompt do |lines|
123
- lines << '' if lines.empty?
124
- code = lines.map{ |l| l + "\n" }.join
125
- tokens = KatakataIrb::RubyLexPatch.complete_tokens code, context: context
126
- line_results = KatakataIrb::TRex.parse_line(tokens)
127
- continue = false
128
- tokens_until_line = []
129
- line_results.map.with_index do |(line_tokens, _prev_opens, next_opens), line_num_offset|
130
- line_tokens.each do |token, _s|
131
- tokens_until_line << token if token != tokens_until_line.last
132
- end
133
- unless (c = process_continue(tokens_until_line)).nil?
134
- continue = c
135
- end
136
- prompt next_opens, continue, line_num_offset
137
- end
138
- end
139
- end
140
-
141
- if p.respond_to?(:call)
142
- @input = p
143
- elsif block_given?
144
- @input = block
145
- else
146
- @input = Proc.new{@io.gets}
147
- end
148
- end
149
-
150
- def set_auto_indent(context)
151
- if @io.respond_to?(:auto_indent) and context.auto_indent_mode
152
- @io.auto_indent do |lines, line_index, byte_pointer, is_newline|
153
- if is_newline
154
- tokens = KatakataIrb::RubyLexPatch.complete_tokens(lines[0..line_index].join("\n"), context: context)
155
- process_indent_level tokens
156
- else
157
- code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
158
- last_line = lines[line_index]&.byteslice(0, byte_pointer)
159
- code += last_line if last_line
160
- tokens = KatakataIrb::RubyLexPatch.complete_tokens(code, context: context)
161
- check_corresponding_token_depth(tokens, line_index)
162
- end
163
- end
164
- end
165
- end
166
-
167
- def prompt(opens, continue, line_num_offset)
168
- ltype = ltype_from_open_tokens(opens)
169
- _indent, nesting_level = calc_nesting_depth(opens)
170
- @prompt.call(ltype, nesting_level, opens.any? || continue, @line_no + line_num_offset)
171
- end
172
-
173
- def store_prompt_to_irb(...)
174
- prompt(...) # TODO: do not use this. change the api. example: @input.call(prompt)
175
- end
176
-
177
- def readmultiline(context)
178
- if @io.respond_to? :check_termination
179
- store_prompt_to_irb [], false, 0
180
- @input.call
181
- else
182
- # nomultiline
183
- line = ''
184
- line_offset = 0
185
- store_prompt_to_irb [], false, 0
186
- loop do
187
- l = @input.call
188
- unless l
189
- return if line.empty?
190
- next
191
- end
192
- line << l
193
- tokens = KatakataIrb::RubyLexPatch.complete_tokens(line, context: context)
194
- _line_tokens, _prev_opens, next_opens = KatakataIrb::TRex.parse_line(tokens).last
195
- return line if next_opens.empty?
196
- line_offset += 1
197
- store_prompt_to_irb next_opens, true, line_offset
198
- end
199
- end
200
- end
201
-
202
- def each_top_level_statement(context = nil)
203
- loop do
204
- begin
205
- line = readmultiline(context)
206
- break unless line
207
- if line != "\n"
208
- line.force_encoding(@io.encoding)
209
- yield line, @line_no
210
- end
211
- @line_no += line.count("\n")
212
- rescue RubyLex::TerminateLineInput
213
- end
214
- end
215
- end
216
- end