From: Steve Hancock Date: Fri, 31 Dec 2021 15:46:29 +0000 (-0800) Subject: add parameters -vxl=s and -vil=s X-Git-Tag: 20211029.05~12 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=63a4eedeb47cc27c9a511145f55236e77287be56;p=perltidy.git add parameters -vxl=s and -vil=s --- diff --git a/bin/perltidy b/bin/perltidy index 3c4f40e5..62b0f3b2 100755 --- a/bin/perltidy +++ b/bin/perltidy @@ -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 + +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. For example, the following would prevent alignment at B<=> and B: + + --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 diff --git a/lib/Perl/Tidy.pm b/lib/Perl/Tidy.pm index 17e1c599..335ed86b 100644 --- a/lib/Perl/Tidy.pm +++ b/lib/Perl/Tidy.pm @@ -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 diff --git a/lib/Perl/Tidy/Formatter.pm b/lib/Perl/Tidy/Formatter.pm index 1f5ddf91..7de526f2 100644 --- a/lib/Perl/Tidy/Formatter.pm +++ b/lib/Perl/Tidy/Formatter.pm @@ -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. diff --git a/lib/Perl/Tidy/VerticalAligner.pm b/lib/Perl/Tidy/VerticalAligner.pm index aaa1e14c..a4326fd3 100644 --- a/lib/Perl/Tidy/VerticalAligner.pm +++ b/lib/Perl/Tidy/VerticalAligner.pm @@ -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;