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.
- checksums.yaml +4 -4
 - data/Gemfile.lock +8 -2
 - data/README.md +16 -26
 - data/bin/console +2 -7
 - data/katakata_irb.gemspec +2 -1
 - data/lib/katakata_irb/completor.rb +45 -6
 - data/lib/katakata_irb/{trex.rb → nesting_parser.rb} +54 -32
 - data/lib/katakata_irb/type_simulator.rb +25 -11
 - data/lib/katakata_irb/types.rb +15 -18
 - data/lib/katakata_irb/version.rb +1 -1
 - data/lib/katakata_irb.rb +5 -7
 - metadata +20 -16
 - data/exe/kirb +0 -11
 - data/lib/katakata_irb/reline_patch.rb +0 -43
 - data/lib/katakata_irb/reline_patches/escapeseq.patch +0 -45
 - data/lib/katakata_irb/reline_patches/fullwidth.patch +0 -200
 - data/lib/katakata_irb/reline_patches/indent.patch +0 -25
 - data/lib/katakata_irb/reline_patches/raw.patch +0 -95
 - data/lib/katakata_irb/reline_patches/scrollbar.patch +0 -43
 - data/lib/katakata_irb/reline_patches/wholelines.patch +0 -102
 - data/lib/katakata_irb/ruby_lex_patch.rb +0 -216
 
| 
         @@ -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
         
     |