]> git.donarmstrong.com Git - perltidy.git/commitdiff
add parameters -vxl=s and -vil=s
authorSteve Hancock <perltidy@users.sourceforge.net>
Fri, 31 Dec 2021 15:46:29 +0000 (07:46 -0800)
committerSteve Hancock <perltidy@users.sourceforge.net>
Fri, 31 Dec 2021 15:46:29 +0000 (07:46 -0800)
bin/perltidy
lib/Perl/Tidy.pm
lib/Perl/Tidy/Formatter.pm
lib/Perl/Tidy/VerticalAligner.pm

index 3c4f40e529e44e6d8cf0ba9f52f783e5ee169145..62b0f3b2c932c49bd8dd321cfe928135e4cc3385 100755 (executable)
@@ -4184,6 +4184,35 @@ excess of the maximum line length.  If this occurs, the entire group of
 comments will remain aligned and be outdented by the same amount.  This coordinated
 alignment will not occur if B<-nvbc> is set.  The default is B<-vbc>.
 
+=item B<Finer alignment control with --valign-exclusion-list=s or -vxl=s and --valign-inclusion-list=s or -vil=s>
+
+More detailed control of alignment types is available with these two parameters.
+Most of the alignments in typical programs occur at one of the tokens ',' '=',
+and '=>', but many others are possible.  The complete list of token types where
+vertical alignment can occur is:
+
+  = **= += *= &= <<= &&= -= /= |= >>= ||= //= .= %= ^= x=
+  { ( ? : , ; => && || ~~ !~~ =~ !~ // <=> ->
+  if unless and or err for foreach while until
+
+These alignments are all enabled by default, but they can be selectively disabled by including one or more of these tokens in the list B<valign-exclusion-list=s>.  For example, the following would prevent alignment at B<=> and B<if>:
+
+  --valign-exclusion-list='= if'
+
+If it is simpler to specify only the token types which are to be aligned, use the special symbol B<*> for this list and include the types which are to be aligned in the list of B<--valign-inclusion-list>. For example,
+the following parameters enable alignment only at commas and 'fat commas':
+
+  --valign-exclusion-list='*'
+  --valign-inclusion-list=', =>'
+
+These parameter lists should consist of space-separated tokens from the above
+list of possible alignment tokens.  If an unrecognized parameter appears, it is
+simply ignored. And if a parameter is entered in both lists (it should
+not), then the exclusion list has priority.
+
+Note that control of side comment alignment is not done with these parameters but
+rather with the B<--valign-side_comments> listed above.
+
 =back
 
 =head2 Other Controls
index 17e1c5994d2484dd4450fe4b35bf7fc7d0f997d5..335ed86b68f805849e2f9502af1ccee044c341ef 100644 (file)
@@ -777,6 +777,7 @@ EOM
 
     Perl::Tidy::Formatter::check_options($rOpts);
     Perl::Tidy::Tokenizer::check_options($rOpts);
+    Perl::Tidy::VerticalAligner::check_options($rOpts);
     if ( $rOpts->{'format'} eq 'html' ) {
         Perl::Tidy::HtmlWriter->check_options($rOpts);
     }
@@ -2314,6 +2315,8 @@ sub generate_options {
     $add_option->( 'valign-code',                               'vc',    '!' );
     $add_option->( 'valign-block-comments',                     'vbc',   '!' );
     $add_option->( 'valign-side-comments',                      'vsc',   '!' );
+    $add_option->( 'valign-exclusion-list',                     'vxl',   '=s' );
+    $add_option->( 'valign-inclusion-list',                     'vil',   '=s' );
 
     ########################################
     $category = 4;    # Comment controls
index 1f5ddf9133a2ad6cc1102874952f0e344144400f..7de526f2708a26e6a932e619404b8a67b79b622f 100644 (file)
@@ -22422,6 +22422,13 @@ EOM
                     elsif ( $i > $i_elsif_open && $i < $i_elsif_close ) {
 
                     }
+
+                    # and ignore any tokens which have leading padded spaces
+                    # example: perl527/lop.t
+                    elsif ( substr( $alignment_type, 0, 1 ) eq ' ' ) {
+
+                    }
+
                     else {
                         $ralignment_type_to_go->[$i] = $alignment_type;
                         $ralignment_hash_by_line->[$line]->{$i} =
@@ -23601,6 +23608,10 @@ sub pad_token {
                         if ( $token eq '(' ) {
                             $name = $self->make_paren_name($i);
                         }
+
+                        # name cannot be '.', so change to something else if so
+                        if ( $name eq '.' ) { $name = 'dot' }
+
                         $container_name{$depth} = "+" . $name;
 
                         # Make the container name even more unique if necessary.
index aaa1e14c7645c8c66b90bf92515968f837eed7d5..a4326fd3e162b967b614484a6761af886763db2d 100644 (file)
@@ -172,7 +172,50 @@ BEGIN {
     };
 
     DEBUG_TABS && $debug_warning->('TABS');
+}
+
+# GLOBAL variables
+my (
+
+    %valign_control_hash,
+    $valign_control_default,
+
+);
+
+sub check_options {
+
+    # This routine is called to check the user-supplied run parameters
+    # and to configure the control hashes to them.
+    my ($rOpts) = @_;
+
+    %valign_control_hash    = ();
+    $valign_control_default = 1;
+
+    if ( $rOpts->{'valign-inclusion-list'} ) {
+        my @list = split /\s+/, $rOpts->{'valign-inclusion-list'};
+        @valign_control_hash{@list} = (1) x scalar(@list);
+    }
 
+    # Note that the -vxl list is done after -vil, so -vxl has priority
+    # in the event of duplicate entries.
+    if ( $rOpts->{'valign-exclusion-list'} ) {
+        my @list = split /\s+/, $rOpts->{'valign-exclusion-list'};
+        @valign_control_hash{@list} = (0) x scalar(@list);
+    }
+
+    # '$valign_control_default' applies to types not in the hash:
+    # - If a '*' was entered then set it to be that default type
+    # - Otherwise, leave it set it to 1
+    if ( defined( $valign_control_hash{'*'} ) ) {
+        $valign_control_default = $valign_control_hash{'*'};
+    }
+
+    # Side comments are controlled separately and must be removed if specified
+    if ( defined( $valign_control_hash{'#'} ) ) {
+        delete $valign_control_hash{'#'};
+    }
+
+    return;
 }
 
 sub new {
@@ -1225,6 +1268,7 @@ sub check_fit {
     my $rfield_lengths      = $new_line->get_rfield_lengths();
     my $padding_available   = $old_line->get_available_space_on_right();
     my $jmax_old            = $old_line->get_jmax();
+    my $rtokens_old         = $old_line->get_rtokens();
 
     # Safety check ... only lines with equal array sizes should arrive here
     # from sub check_match.  So if this error occurs, look at recent changes in
@@ -1257,11 +1301,31 @@ EOM
             $pad += $leading_space_count;
         }
 
-        # Keep going if this field does not need any space.
-        next if $pad < 0;
+        # Give up if not enough space is available
+        my $revert = $pad > $padding_available;
+
+        # Apply any user-defined vertical alignment controls in top-down sweep
+        if (  !$revert
+            && $j < $jmax
+            && %valign_control_hash )
+        {
 
-        # See if it needs too much space.
-        if ( $pad > $padding_available ) {
+            # FIXME: This call is a little inefficient; need to do profiling
+            # to see if it should be avoided.
+            my $tok = $rtokens_old->[$j];
+            my ( $raw_tok, $lev, $tag, $tok_count ) =
+              decode_alignment_token($tok);
+
+            my $align_ok = $valign_control_hash{$raw_tok};
+            $align_ok = $valign_control_default unless defined($align_ok);
+
+            if ( !$align_ok && $pad != 0 ) {
+                $revert = 1;
+            }
+        }
+
+        # Revert to the starting state if does not fit
+        if ($revert) {
 
             ################################################
             # Line does not fit -- revert to starting state
@@ -1272,6 +1336,9 @@ EOM
             return;
         }
 
+        # Keep going if this field does not need any space.
+        next if ( $pad < 0 );
+
         # make room for this field
         $old_line->increase_field_width( $j, $pad );
         $padding_available -= $pad;
@@ -2225,6 +2292,21 @@ sub sweep_left_to_right {
                       && $col > $col_want + $short_pad * $factor;
                 }
 
+                # Apply user-defined vertical alignment controls in l-r sweep
+                if ( !$is_big_gap && %valign_control_hash ) {
+
+                    my $align_ok = $valign_control_hash{$raw_tok};
+                    $align_ok = $valign_control_default
+                      unless defined($align_ok);
+
+                    # Note that the following definition of $pad is not the
+                    # total pad because we are working at group boundaries. But
+                    # we can still see if it is zero or not.
+                    if ( !$align_ok && $col_want != $col ) {
+                        $is_big_gap = 1;
+                    }
+                }
+
                 # if match is limited by gap size, stop aligning at this level
                 if ($is_big_gap) {
                     $blocking_level[$ng] = $lev - 1;