@@ -356,6 +356,23 @@ def free_indent_token?(token)
356356    %i[ on_tstring_beg  on_backtick  on_regexp_beg  on_symbeg ] . include? ( token . event ) 
357357  end 
358358
359+   def  indent_difference ( lines ,  line_results ,  open_token ) 
360+     return  0  unless  open_token 
361+     loop  do 
362+       line_index  =  open_token . pos [ 0 ]  - 1 
363+       _tokens ,  prev_opens ,  _next_opens ,  min_depth  =  line_results [ line_index ] 
364+       indent_level ,  _nesting_level  =  calc_nesting_depth ( prev_opens . take ( min_depth ) ) 
365+       calculated_indent  =  2  * indent_level 
366+       open_token  =  prev_opens . last 
367+       if  !open_token  || ( open_token . event  != :on_heredoc_beg  && !free_indent_token? ( open_token ) ) 
368+         actual_indent  =  lines [ line_index ] [ /^ */ ] . size 
369+         return  actual_indent  - calculated_indent 
370+       elsif  open_token . event  == :on_heredoc_beg  && open_token . tok . match? ( /^<<[^-~]/ ) 
371+         return  0 
372+       end 
373+     end 
374+   end 
375+ 
359376  def  process_indent_level ( tokens ,  lines ,  line_index ,  is_newline ) 
360377    line_results  =  IRB ::NestingParser . parse_by_line ( tokens ) 
361378    result  =  line_results [ line_index ] 
@@ -374,10 +391,16 @@ def process_indent_level(tokens, lines, line_index, is_newline)
374391
375392    preserve_indent  =  lines [ line_index  - ( is_newline  ? 1  : 0 ) ] [ /^ */ ] . size 
376393
394+     # Calculates base indent for pasted code 
395+     # irb(main):001:1*     if 1 # Base indent is 4 
396+     # irb(main):002:1*       2 
397+     # irb(main):003:0>     end 
398+     base_indent  =  [ 0 ,  indent_difference ( lines ,  line_results ,  prev_opens . last ) ] . max 
399+ 
377400    if  free_indent_token? ( prev_opens . last ) 
378401      if  is_newline  && prev_opens . last . pos [ 0 ]  == line_index 
379402        # First newline inside free-indent token 
380-         indent 
403+         base_indent  +  indent 
381404      else 
382405        # Accept any number of indent inside free-indent token 
383406        preserve_indent 
@@ -395,21 +418,21 @@ def process_indent_level(tokens, lines, line_index, is_newline)
395418      if  prev_opens . size  < next_opens . size  || prev_opens . last  == next_opens . last 
396419        if  is_newline  && lines [ line_index ] . empty?  && line_results [ line_index  - 1 ] [ 1 ] . last  != prev_opens . last 
397420          # First line in heredoc 
398-           indent 
421+           tok . match? ( /^<<[-~]/ )  ?  base_indent  +  indent  :  indent 
399422        elsif  tok . match? ( /^<<~/ ) 
400423          # Accept extra indent spaces inside `<<~` heredoc 
401-           [ indent ,  preserve_indent ] . max 
424+           [ base_indent  +  indent ,  preserve_indent ] . max 
402425        else 
403426          # Accept any number of indent inside other heredoc 
404427          preserve_indent 
405428        end 
406429      else 
407430        # Heredoc close 
408431        prev_line_indent_level ,  _prev_line_nesting_level  =  calc_nesting_depth ( prev_opens ) 
409-         tok . match? ( /^<<[~-]/ )  ? 2  * ( prev_line_indent_level  - 1 )  : 0 
432+         tok . match? ( /^<<[~-]/ )  ? base_indent  +  2  * ( prev_line_indent_level  - 1 )  : 0 
410433      end 
411434    else 
412-       indent 
435+       base_indent  +  indent 
413436    end 
414437  end 
415438
0 commit comments