]> git.donarmstrong.com Git - perltidy.git/commitdiff
do not align equals across change in continuation indentation
authorSteve Hancock <perltidy@users.sourceforge.net>
Sat, 12 Dec 2020 15:08:50 +0000 (07:08 -0800)
committerSteve Hancock <perltidy@users.sourceforge.net>
Sat, 12 Dec 2020 15:08:50 +0000 (07:08 -0800)
lib/Perl/Tidy/Formatter.pm
lib/Perl/Tidy/VerticalAligner.pm
lib/Perl/Tidy/VerticalAligner/Line.pm

index a76085955fe95da5443383afc280c4c7ad222665..6e27ccfed6de7e2fc950e88df057adf92d1195ab 100644 (file)
@@ -16952,6 +16952,7 @@ sub send_lines_to_vertical_aligner {
         $rvalign_hash->{break_alignment_before}    = $break_alignment_before;
         $rvalign_hash->{break_alignment_after}     = $break_alignment_after;
         $rvalign_hash->{Kend}                      = $Kend_code;
+        $rvalign_hash->{ci_level}                  = $ci_levels_to_go[$ibeg];
 
         my $vao = $self->[_vertical_aligner_object_];
         $vao->valign_input($rvalign_hash);
index c4c4be734208cb35c7fd2b74e9f84b33beb195d6..fd9a3ba4df30dcd053bde437e48b9ac510ecc3c9 100644 (file)
@@ -411,6 +411,7 @@ sub valign_input {
     my $break_alignment_before    = $rline_hash->{break_alignment_before};
     my $break_alignment_after     = $rline_hash->{break_alignment_after};
     my $Kend                      = $rline_hash->{Kend};
+    my $ci_level                  = $rline_hash->{ci_level};
 
     # The index '$Kend' is a value which passed along with the line text to sub
     # 'write_code_line' for a convergence check.
@@ -701,6 +702,7 @@ EOM
             is_forced_break           => $is_forced_break,
             end_group                 => $break_alignment_after,
             Kend                      => $Kend,
+            ci_level                  => $ci_level,
         }
     );
 
@@ -2630,10 +2632,18 @@ EOM
             my ( $i_eq_l, $tok_eq_l, $pat_eq_l ) = @{ $equals_info[$jl] };
             my ( $i_eq_r, $tok_eq_r, $pat_eq_r ) = @{ $equals_info[$jr] };
             if ( defined($i_eq_l) && defined($i_eq_r) ) {
-                if (   $tok_eq_l eq $tok_eq_r
+
+                # Also, do not align equals across a change in ci level
+                my $ci_jump = $rnew_lines->[$jl]->get_ci_level() !=
+                  $rnew_lines->[$jr]->get_ci_level();
+
+                if (
+                       $tok_eq_l eq $tok_eq_r
                     && $i_eq_l == 0
                     && $i_eq_r == 0
-                    && substr( $pat_eq_l, 0, 1 ) ne substr( $pat_eq_r, 0, 1 ) )
+                    && ( substr( $pat_eq_l, 0, 1 ) ne substr( $pat_eq_r, 0, 1 )
+                        || $ci_jump )
+                  )
                 {
                     $rnew_lines->[$jl]->set_end_group(1);
                 }
@@ -3630,6 +3640,8 @@ sub Dump_tree_groups {
     my %is_assignment;
     my %is_good_alignment;
 
+    use constant TEST_MARGINAL_EQ_ALIGNMENT => 0;
+
     BEGIN {
 
         my @q = qw(
@@ -3691,6 +3703,7 @@ sub Dump_tree_groups {
         my $raw_tokb = "";    # first token seen at group level
         my $jfirst_bad;
         my $line_ending_fat_comma;    # is last token just a '=>' ?
+        my $j0_eq_pad;
 
         for ( my $j = 0 ; $j < $jmax_1 - 1 ; $j++ ) {
             my ( $raw_tok, $lev, $tag, $tok_count ) =
@@ -3711,6 +3724,11 @@ sub Dump_tree_groups {
             if ( $j == 0 ) {
                 $pad += $line_1->get_leading_space_count() -
                   $line_0->get_leading_space_count();
+
+                # Remember the pad at a leading equals
+                if ( $raw_tok eq '=' && $lev == $group_level ) {
+                    $j0_eq_pad = $pad;
+                }
             }
 
             if ( $pad < 0 )        { $pad     = -$pad }
@@ -3746,8 +3764,6 @@ sub Dump_tree_groups {
 
         $is_marginal = 1 if ( $is_marginal == 0 && $line_ending_fat_comma );
 
-        if ( !defined($jfirst_bad) ) { $jfirst_bad = $jmax_1 - 1; }
-
         # Turn off the "marginal match" flag in some cases...
         # A "marginal match" occurs when the alignment tokens agree
         # but there are differences in the other tokens (patterns).
@@ -3871,9 +3887,35 @@ sub Dump_tree_groups {
                 }
             }
         }
-        if ( $is_marginal && $imax_align > $jfirst_bad - 1 ) {
+
+        ##if ( !defined($jfirst_bad) ) { $jfirst_bad = $jmax_1 - 1; }
+
+        # For a marginal match, only keep matches before the first 'bad' match
+        if (   $is_marginal
+            && defined($jfirst_bad)
+            && $imax_align > $jfirst_bad - 1 )
+        {
             $imax_align = $jfirst_bad - 1;
         }
+
+        # FIXME: This is a future update, postponed until the variable 'CI' is
+        # available for each line so that two lines with different CI values
+        # can be rejected.
+
+        # Two marginal match lines with leading '=' lie at the
+        # boundary of good and bad alignment, so we only align if the pad
+        # distance is small.  There is no perfect value, but 3 or 4 spaces
+        # seems to be a fairly good
+        # compromise.
+        if (   TEST_MARGINAL_EQ_ALIGNMENT
+            && $imax_align < 0
+            && defined($j0_eq_pad)
+            && $j0_eq_pad >= -4
+            && $j0_eq_pad <= 4 )
+        {
+            $imax_align = 0;
+        }
+
         return ( $is_marginal, $imax_align );
     }
 }
index b7ddcfe9ab328d7928c19c19cc88391c5aad262f..bf77f9855e53959263461edf897f5a1423ceea2e 100644 (file)
@@ -32,6 +32,7 @@ BEGIN {
         _is_forced_break_           => $i++,
         _end_group_                 => $i++,
         _Kend_                      => $i++,
+        _ci_level_                  => $i++,
     };
 }
 
@@ -83,6 +84,7 @@ EOM
         $self->[_is_forced_break_]           = $ri->{is_forced_break};
         $self->[_end_group_]                 = $ri->{end_group};
         $self->[_Kend_]                      = $ri->{Kend};
+        $self->[_ci_level_]                  = $ri->{ci_level};
 
         $self->[_ralignments_] = [];
 
@@ -97,6 +99,7 @@ EOM
     sub get_rpatterns      { return $_[0]->[_rpatterns_] }
     sub get_indentation    { return $_[0]->[_indentation_] }
     sub get_Kend           { return $_[0]->[_Kend_] }
+    sub get_ci_level       { return $_[0]->[_ci_level_] }
 
     sub get_j_terminal_match {
         return $_[0]->[_j_terminal_match_];