From: Steve Hancock Date: Fri, 5 Jun 2020 02:06:41 +0000 (-0700) Subject: added option --logical-padding or -lop, see git#29 X-Git-Tag: 20200619~16 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=b69ec87a5c61de55f115bcc7061bd893f9b420ec;p=perltidy.git added option --logical-padding or -lop, see git#29 --- diff --git a/CHANGES.md b/CHANGES.md index ea121a66..c9381b72 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,10 @@ ## 2020 01 10.01 + - Added a parameter --logical-padding or -lop to allow logical padding + to be turned off. Requested by git #29. This flag is on by default. + The man pages have examples. + - Added a parameter -kpit=n to control spaces inside of parens following certain keywords, requested in git#26. This flag is off by default. @@ -27,17 +31,26 @@ separately. - Added --character-encoding=guess or -guess to have perltidy guess - if a file is encoded as -utf8 or some older single-byte encoding. This - is useful when processing a mixture of file types, such as utf8 and - latin-1. Also, specific encodings of input files other than utf8 may - now be given, for example --character-encoding=euc-jp. For a - description of the guessing method see the man pages. + if a file (or other input stream) is encoded as -utf8 or some + older single-byte encoding. This is useful when processing a mixture + of file types, such as utf8 and latin-1. Please Note: The default encoding has been set to be 'guess' instead of 'none'. I do not like to change defaults, but this seems like - the right choice, since it should make perltidy work properly with both - older latin-1 and newer utf8 files. I have done extensive testing and - so far haven't found any problems. + the best choice, since it should make perltidy work properly with both + utf8 files and older latin-1 files. The guess mode uses Encode::Guess, + which is included in standard perl distributions, and only tries to + guess if a file is utf8 or not, never any other encoding. If the guess is + utf8, and if the file successfully decodes as utf8, then it the encoding + is assumed to be utf8. Otherwise, no encoding is assumed. + I have done extensive testing and have not detected any problems with + this guess method. If you do not want to use this new default guess mode, + or have a problem with it, you can set --character-encoding=none + (the previous default) or --character-encoding=utf8 (if you deal + with utf8 files). + + - Specific encodings of input files other than utf8 may now be given, for + example --character-encoding=euc-jp. - Fix for git#22, Preserve function signature on a single line. An unwanted line break was being introduced when a closing signature paren diff --git a/MANIFEST b/MANIFEST index cc8c9c51..015ced2d 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,4 +1,5 @@ .pre-commit-hooks.yaml +bbs.t bin/perltidy BUGS.md CHANGES.md @@ -22,6 +23,7 @@ examples/lextest examples/perlcomment.pl examples/perllinetype.pl examples/perlmask.pl +examples/perltidy.DEBUG examples/perltidy_okw.pl examples/perltidyrc_dump.pl examples/perlxmltok.pl @@ -53,7 +55,8 @@ Makefile.PL MANIFEST This list of files pm2pl README.md -t/filter_example.t.SKIP +t/atee.t +t/filter_example.t t/snippets1.t t/snippets10.t t/snippets11.t @@ -63,7 +66,11 @@ t/snippets14.t t/snippets15.t t/snippets16.t t/snippets17.t +t/snippets18.t +t/snippets19.t t/snippets2.t +t/snippets20.t +t/snippets21.t t/snippets3.t t/snippets4.t t/snippets5.t @@ -77,3 +84,4 @@ t/testsa.t t/testss.t t/testwide.pl.src t/testwide.t +t/testwide.t.tdy diff --git a/bin/perltidy b/bin/perltidy index 2a9577c9..e3160f5a 100755 --- a/bin/perltidy +++ b/bin/perltidy @@ -1210,6 +1210,56 @@ For example, the commands C<-kpitl="if else while" -kpit=2> will cause the just the spaces inside parens following 'if', 'else', and 'while' keywords to follow the tightness value indicated by the B<-kpit=2> flag. +=item B<-lop> or B<--logical-padding> + +In the following example some extra space has been inserted on the second +line between the two open parens. This extra space is called "logical padding" +and is intended to help align similar things vertically in some logical +or ternary expressions. + + # perltidy [default formatting] + $same = + ( ( $aP eq $bP ) + && ( $aS eq $bS ) + && ( $aT eq $bT ) + && ( $a->{'title'} eq $b->{'title'} ) + && ( $a->{'href'} eq $b->{'href'} ) ); + +Note that this is considered to be a different operation from "vertical +alignment" because space at just one line is being adjusted, whereas in +"vertical alignment" the spaces at all lines are being adjusted. So it sort of +a local version of vertical alignment. + +Here is an example involving a ternary operator: + + # perltidy [default formatting] + $bits = + $top > 0xffff ? 32 + : $top > 0xff ? 16 + : $top > 1 ? 8 + : 1; + +This behavior is controlled with the flag B<--logical-padding>, which is set +'on' by default. If it is not desired it can be turned off using +B<--nological-padding> or B<-nlop>. The above two examples become, with +B<-nlop>: + + # perltidy -nlop + $same = + ( ( $aP eq $bP ) + && ( $aS eq $bS ) + && ( $aT eq $bT ) + && ( $a->{'title'} eq $b->{'title'} ) + && ( $a->{'href'} eq $b->{'href'} ) ); + + # perltidy -nlop + $bits = + $top > 0xffff ? 32 + : $top > 0xff ? 16 + : $top > 1 ? 8 + : 1; + + =item Trimming whitespace around C quotes B<-tqw> or B<--trim-qw> provide the default behavior of trimming @@ -1220,16 +1270,16 @@ multi-line C quotes to be left unchanged. This option will not normally be necessary, but was added for testing purposes, because in some versions of perl, trimming C quotes changes the syntax tree. -=item B<-sbq=n> or B<--space-backslash-quote=n> +=item b<-sbq=n> or b<--space-backslash-quote=n> -Lines like +lines like $str1=\"string1"; $str2=\'string2'; can confuse syntax highlighters unless a space is included between the backslash and the single or double quotation mark. -This can be controlled with the value of B as follows: +this can be controlled with the value of b as follows: -sbq=0 means no space between the backslash and quote -sbq=1 means follow the example of the source code diff --git a/docs/ChangeLog.html b/docs/ChangeLog.html index 094d0071..a789e486 100644 --- a/docs/ChangeLog.html +++ b/docs/ChangeLog.html @@ -2,7 +2,14 @@

2020 01 10.01

-
- Added fix for git#25, improve vertical alignment for long lists with
+
- Added a parameter --logical-padding or -lop to allow logical padding
+  to be turned off.  Requested by git #29. This flag is on by default.
+  The man pages have examples.
+
+- Added a parameter -kpit=n to control spaces inside of parens following
+  certain keywords, requested in git#26. This flag is off by default.
+
+- Added fix for git#25, improve vertical alignment for long lists with
   varying numbers of items per line.
 
 - calls to the module Perl::Tidy can now capture any output produced
@@ -24,17 +31,26 @@
   separately.
 
 - Added --character-encoding=guess or -guess to have perltidy guess
-  if a file is encoded as -utf8 or some older single-byte encoding. This
-  is useful when processing a mixture of file types, such as utf8 and 
-  latin-1.  Also, specific encodings of input files other than utf8 may
-  now be given, for example --character-encoding=euc-jp.  For a
-  description of the guessing method see the man pages.
+  if a file (or other input stream) is encoded as -utf8 or some 
+  older single-byte encoding. This is useful when processing a mixture 
+  of file types, such as utf8 and latin-1.  
 
   Please Note: The default encoding has been set to be 'guess'
   instead of 'none'. I do not like to change defaults, but this seems like
-  the right choice, since it should make perltidy work properly with both
-  older latin-1 and newer utf8 files.  I have done extensive testing and
-  so far haven't found any problems.
+  the best choice, since it should make perltidy work properly with both
+  utf8 files and older latin-1 files.  The guess mode uses Encode::Guess,
+  which is included in standard perl distributions, and only tries to 
+  guess if a file is utf8 or not, never any other encoding.  If the guess is 
+  utf8, and if the file successfully decodes as utf8, then it the encoding 
+  is assumed to be utf8.  Otherwise, no encoding is assumed.
+  I have done extensive testing and have not detected any problems with
+  this guess method. If you do not want to use this new default guess mode,
+  or have a problem with it, you can set --character-encoding=none 
+  (the previous default) or --character-encoding=utf8 (if you deal
+  with utf8 files).
+
+- Specific encodings of input files other than utf8 may now be given, for
+  example --character-encoding=euc-jp.  
 
 - Fix for git#22, Preserve function signature on a single line. An
   unwanted line break was being introduced when a closing signature paren
diff --git a/docs/perltidy.html b/docs/perltidy.html
index bfb16504..7cb5d930 100644
--- a/docs/perltidy.html
+++ b/docs/perltidy.html
@@ -959,6 +959,48 @@
 
 

For example, the commands -kpitl="if else while" -kpit=2 will cause the just the spaces inside parens following 'if', 'else', and 'while' keywords to follow the tightness value indicated by the -kpit=2 flag.

+ +
-lop or --logical-padding
+
+ +

In the following example some extra space has been inserted on the second line between the two open parens. This extra space is called "logical padding" and is intended to help align similar things vertically in some logical or ternary expressions.

+ +
    # perltidy [default formatting] 
+    $same =
+      (      ( $aP eq $bP )
+          && ( $aS eq $bS )
+          && ( $aT eq $bT )
+          && ( $a->{'title'} eq $b->{'title'} )
+          && ( $a->{'href'} eq $b->{'href'} ) );
+ +

Note that this is considered to be a different operation from "vertical alignment" because space at just one line is being adjusted, whereas in "vertical alignment" the spaces at all lines are being adjusted. So it sort of a local version of vertical alignment.

+ +

Here is an example involving a ternary operator:

+ +
    # perltidy [default formatting] 
+    $bits =
+        $top > 0xffff ? 32
+      : $top > 0xff   ? 16
+      : $top > 1      ? 8
+      :                 1;
+ +

This behavior is controlled with the flag --logical-padding, which is set 'on' by default. If it is not desired it can be turned off using --nological-padding or -nlop. The above two examples become, with -nlop:

+ +
    # perltidy -nlop
+    $same =
+      ( ( $aP eq $bP )
+          && ( $aS eq $bS )
+          && ( $aT eq $bT )
+          && ( $a->{'title'} eq $b->{'title'} )
+          && ( $a->{'href'} eq $b->{'href'} ) );
+
+    # perltidy -nlop
+    $bits =
+      $top > 0xffff ? 32
+      : $top > 0xff ? 16
+      : $top > 1    ? 8
+      :               1;
+
Trimming whitespace around qw quotes
@@ -968,17 +1010,17 @@

-ntqw or --notrim-qw cause leading and trailing whitespace around multi-line qw quotes to be left unchanged. This option will not normally be necessary, but was added for testing purposes, because in some versions of perl, trimming qw quotes changes the syntax tree.

-
-sbq=n or --space-backslash-quote=n
+
b<-sbq=n> or b<--space-backslash-quote=n>
-

Lines like

+

lines like

       $str1=\"string1";
        $str2=\'string2';

can confuse syntax highlighters unless a space is included between the backslash and the single or double quotation mark.

-

This can be controlled with the value of n as follows:

+

this can be controlled with the value of b<n> as follows:

    -sbq=0 means no space between the backslash and quote
     -sbq=1 means follow the example of the source code
diff --git a/lib/Perl/Tidy.pm b/lib/Perl/Tidy.pm
index 8f55ea03..32929006 100644
--- a/lib/Perl/Tidy.pm
+++ b/lib/Perl/Tidy.pm
@@ -1988,6 +1988,7 @@ sub generate_options {
     $add_option->( 'delete-semicolons',                         'dsm',   '!' );
     $add_option->( 'keyword-paren-inner-tightness',             'kpit',  '=i' );
     $add_option->( 'keyword-paren-inner-tightness-list',        'kpitl', '=s' );
+    $add_option->( 'logical-padding',                           'lop',   '!' );
     $add_option->( 'nospace-after-keyword',                     'nsak',  '=s' );
     $add_option->( 'nowant-left-space',                         'nwls',  '=s' );
     $add_option->( 'nowant-right-space',                        'nwrs',  '=s' );
@@ -2283,6 +2284,7 @@ sub generate_options {
       iterations=1
       keep-old-blank-lines=1
       keyword-paren-inner-tightness=1
+      logical-padding
       long-block-line-count=8
       look-for-autoloader
       look-for-selfloader
diff --git a/lib/Perl/Tidy/Formatter.pm b/lib/Perl/Tidy/Formatter.pm
index eb5d1359..e723bc93 100644
--- a/lib/Perl/Tidy/Formatter.pm
+++ b/lib/Perl/Tidy/Formatter.pm
@@ -10362,7 +10362,8 @@ sub send_lines_to_vertical_aligner {
 
     $self->undo_ci( $ri_first, $ri_last );
 
-    $self->set_logical_padding( $ri_first, $ri_last );
+    $self->set_logical_padding( $ri_first, $ri_last )
+      if ( $rOpts->{'logical-padding'} );
 
     # loop to prepare each line for shipment
     my $in_comma_list;
diff --git a/t/snippets/expect/lop.def b/t/snippets/expect/lop.def
new file mode 100644
index 00000000..e8777483
--- /dev/null
+++ b/t/snippets/expect/lop.def
@@ -0,0 +1,17 @@
+# logical padding examples
+$same =
+  (      ( $aP eq $bP )
+      && ( $aS eq $bS )
+      && ( $aT eq $bT )
+      && ( $a->{'title'} eq $b->{'title'} )
+      && ( $a->{'href'} eq $b->{'href'} ) );
+
+$bits =
+    $top > 0xffff ? 32
+  : $top > 0xff   ? 16
+  : $top > 1      ? 8
+  :                 1;
+
+lc(      $self->mime_attr('content-type')
+      || $self->{MIH_DefaultType}
+      || 'text/plain' );
diff --git a/t/snippets/expect/lop.lop b/t/snippets/expect/lop.lop
new file mode 100644
index 00000000..e9ce0a54
--- /dev/null
+++ b/t/snippets/expect/lop.lop
@@ -0,0 +1,17 @@
+# logical padding examples
+$same =
+  ( ( $aP eq $bP )
+      && ( $aS eq $bS )
+      && ( $aT eq $bT )
+      && ( $a->{'title'} eq $b->{'title'} )
+      && ( $a->{'href'} eq $b->{'href'} ) );
+
+$bits =
+  $top > 0xffff ? 32
+  : $top > 0xff ? 16
+  : $top > 1    ? 8
+  :               1;
+
+lc( $self->mime_attr('content-type')
+      || $self->{MIH_DefaultType}
+      || 'text/plain' );
diff --git a/t/snippets/lop.in b/t/snippets/lop.in
new file mode 100644
index 00000000..283b1b9c
--- /dev/null
+++ b/t/snippets/lop.in
@@ -0,0 +1,17 @@
+# logical padding examples
+$same =
+  (      ( $aP eq $bP )
+      && ( $aS eq $bS )
+      && ( $aT eq $bT )
+      && ( $a->{'title'} eq $b->{'title'} )
+      && ( $a->{'href'} eq $b->{'href'} ) );
+
+$bits =
+    $top > 0xffff ? 32
+  : $top > 0xff   ? 16
+  : $top > 1      ? 8
+  :                 1;
+
+lc( $self->mime_attr('content-type')
+        || $self->{MIH_DefaultType}
+        || 'text/plain' );
diff --git a/t/snippets/lop.par b/t/snippets/lop.par
new file mode 100644
index 00000000..42e74ada
--- /dev/null
+++ b/t/snippets/lop.par
@@ -0,0 +1 @@
+-nlop
diff --git a/t/snippets/packing_list.txt b/t/snippets/packing_list.txt
index f68982d6..41c88a8d 100644
--- a/t/snippets/packing_list.txt
+++ b/t/snippets/packing_list.txt
@@ -390,3 +390,5 @@
 ../snippets9.t	rt98902.def
 ../snippets9.t	rt98902.rt98902
 ../snippets9.t	rt99961.def
+../snippets20.t	lop.def
+../snippets21.t	lop.lop
diff --git a/t/snippets20.t b/t/snippets20.t
index 7d55f2a8..d911e714 100644
--- a/t/snippets20.t
+++ b/t/snippets20.t
@@ -19,6 +19,7 @@
 #16 kpitl.def
 #17 kpitl.kpitl
 #18 hanging_side_comments3.def
+#19 lop.def
 
 # To locate test #13 you can search for its name or the string '#13'
 
@@ -154,6 +155,26 @@ return ( $r**$n ) * ( pi**( $n / 2 ) ) / ( sqrt(pi) * factorial( 2 * ( int( $n
 );
 ----------
 
+        'lop' => <<'----------',
+# logical padding examples
+$same =
+  (      ( $aP eq $bP )
+      && ( $aS eq $bS )
+      && ( $aT eq $bT )
+      && ( $a->{'title'} eq $b->{'title'} )
+      && ( $a->{'href'} eq $b->{'href'} ) );
+
+$bits =
+    $top > 0xffff ? 32
+  : $top > 0xff   ? 16
+  : $top > 1      ? 8
+  :                 1;
+
+lc( $self->mime_attr('content-type')
+        || $self->{MIH_DefaultType}
+        || 'text/plain' );
+----------
+
         'outdent' => <<'----------',
         my $i;
       LOOP: while ( $i =  ) {
@@ -600,6 +621,30 @@ return ( $r**$n ) *
     }
 #18...........
         },
+
+        'lop.def' => {
+            source => "lop",
+            params => "def",
+            expect => <<'#19...........',
+# logical padding examples
+$same =
+  (      ( $aP eq $bP )
+      && ( $aS eq $bS )
+      && ( $aT eq $bT )
+      && ( $a->{'title'} eq $b->{'title'} )
+      && ( $a->{'href'} eq $b->{'href'} ) );
+
+$bits =
+    $top > 0xffff ? 32
+  : $top > 0xff   ? 16
+  : $top > 1      ? 8
+  :                 1;
+
+lc(      $self->mime_attr('content-type')
+      || $self->{MIH_DefaultType}
+      || 'text/plain' );
+#19...........
+        },
     };
 
     my $ntests = 0 + keys %{$rtests};
diff --git a/t/snippets21.t b/t/snippets21.t
new file mode 100644
index 00000000..6edfb8d2
--- /dev/null
+++ b/t/snippets21.t
@@ -0,0 +1,137 @@
+# Created with: ./make_t.pl
+
+# Contents:
+#1 lop.lop
+
+# To locate test #13 you can search for its name or the string '#13'
+
+use strict;
+use Test::More;
+use Carp;
+use Perl::Tidy;
+my $rparams;
+my $rsources;
+my $rtests;
+
+BEGIN {
+
+    ###########################################
+    # BEGIN SECTION 1: Parameter combinations #
+    ###########################################
+    $rparams = { 'lop' => "-nlop", };
+
+    ############################
+    # BEGIN SECTION 2: Sources #
+    ############################
+    $rsources = {
+
+        'lop' => <<'----------',
+# logical padding examples
+$same =
+  (      ( $aP eq $bP )
+      && ( $aS eq $bS )
+      && ( $aT eq $bT )
+      && ( $a->{'title'} eq $b->{'title'} )
+      && ( $a->{'href'} eq $b->{'href'} ) );
+
+$bits =
+    $top > 0xffff ? 32
+  : $top > 0xff   ? 16
+  : $top > 1      ? 8
+  :                 1;
+
+lc( $self->mime_attr('content-type')
+        || $self->{MIH_DefaultType}
+        || 'text/plain' );
+----------
+    };
+
+    ####################################
+    # BEGIN SECTION 3: Expected output #
+    ####################################
+    $rtests = {
+
+        'lop.lop' => {
+            source => "lop",
+            params => "lop",
+            expect => <<'#1...........',
+# logical padding examples
+$same =
+  ( ( $aP eq $bP )
+      && ( $aS eq $bS )
+      && ( $aT eq $bT )
+      && ( $a->{'title'} eq $b->{'title'} )
+      && ( $a->{'href'} eq $b->{'href'} ) );
+
+$bits =
+  $top > 0xffff ? 32
+  : $top > 0xff ? 16
+  : $top > 1    ? 8
+  :               1;
+
+lc( $self->mime_attr('content-type')
+      || $self->{MIH_DefaultType}
+      || 'text/plain' );
+#1...........
+        },
+    };
+
+    my $ntests = 0 + keys %{$rtests};
+    plan tests => $ntests;
+}
+
+###############
+# EXECUTE TESTS
+###############
+
+foreach my $key ( sort keys %{$rtests} ) {
+    my $output;
+    my $sname  = $rtests->{$key}->{source};
+    my $expect = $rtests->{$key}->{expect};
+    my $pname  = $rtests->{$key}->{params};
+    my $source = $rsources->{$sname};
+    my $params = defined($pname) ? $rparams->{$pname} : "";
+    my $stderr_string;
+    my $errorfile_string;
+    my $err = Perl::Tidy::perltidy(
+        source      => \$source,
+        destination => \$output,
+        perltidyrc  => \$params,
+        argv        => '',             # for safety; hide any ARGV from perltidy
+        stderr      => \$stderr_string,
+        errorfile => \$errorfile_string,    # not used when -se flag is set
+    );
+    if ( $err || $stderr_string || $errorfile_string ) {
+        print STDERR "Error output received for test '$key'\n";
+        if ($err) {
+            print STDERR "An error flag '$err' was returned\n";
+            ok( !$err );
+        }
+        if ($stderr_string) {
+            print STDERR "---------------------\n";
+            print STDERR "<>\n$stderr_string\n";
+            print STDERR "---------------------\n";
+            ok( !$stderr_string );
+        }
+        if ($errorfile_string) {
+            print STDERR "---------------------\n";
+            print STDERR "<<.ERR file>>\n$errorfile_string\n";
+            print STDERR "---------------------\n";
+            ok( !$errorfile_string );
+        }
+    }
+    else {
+        if ( !is( $output, $expect, $key ) ) {
+            my $leno = length($output);
+            my $lene = length($expect);
+            if ( $leno == $lene ) {
+                print STDERR
+"#> Test '$key' gave unexpected output.  Strings differ but both have length $leno\n";
+            }
+            else {
+                print STDERR
+"#> Test '$key' gave unexpected output.  String lengths differ: output=$leno, expected=$lene\n";
+            }
+        }
+    }
+}