]> git.donarmstrong.com Git - perltidy.git/commitdiff
add -space-signature-paren=n, -ssp=n (see git #125)
authorSteve Hancock <perltidy@users.sourceforge.net>
Fri, 6 Oct 2023 14:32:22 +0000 (07:32 -0700)
committerSteve Hancock <perltidy@users.sourceforge.net>
Fri, 6 Oct 2023 14:32:22 +0000 (07:32 -0700)
15 files changed:
CHANGES.md
bin/perltidy
dev-bin/perltidy_random_setup.pl
lib/Perl/Tidy.pm
lib/Perl/Tidy/Formatter.pm
t/filter_example.t
t/snippets/expect/git125.def [new file with mode: 0644]
t/snippets/expect/git125.git125 [new file with mode: 0644]
t/snippets/expect/signature.def
t/snippets/git125.in [new file with mode: 0644]
t/snippets/git125.par [new file with mode: 0644]
t/snippets/packing_list.txt
t/snippets17.t
t/snippets28.t
t/snippets29.t [new file with mode: 0644]

index dfbfe9fe9fa9484a33c2d2f40106339f937b24cf..4cfd51f683c4d3f1b9a3f2aad7a2591deb965caa 100644 (file)
@@ -2,6 +2,24 @@
 
 ## 2023 09 12.02
 
+    - Added flag --space-signature-paren=n, or -ssp=n (issue git #125).
+      This flag works the same as the existing flag --space-prototype-paren=n
+      except that it applies to the space before the opening paren of a sub
+      signature instead of a sub prototype.  Previously, there was no control
+      over this (a space always occurred). For example, given the following
+      line:
+
+        sub circle( $xc, $yc, $rad );
+
+      The following results can now be obtained, according to the value of n:
+
+        sub circle( $xc, $yc, $rad );   # n=0 [no space]
+        sub circle( $xc, $yc, $rad );   # n=1 [default; same as input]
+        sub circle ( $xc, $yc, $rad );  # n=2 [space]
+
+      The spacing in previous versions of perltidy corresponded to n=2 (always
+      a space). The new default value, n=1, will produce a space if and only if       there was a space in the input text.
+
     - The dump-block-summary option can report an if-elsif-elsif-.. chain
       as a single line item with the notation -dbt='elsif3', for example,
       where the '3' is an integer which specifies the minimum number of elsif
index 63836aa3d4c1e1b93bc1c2feaa50ee8b87835e16..86c860b0d14cc99be6e42ba4fd033cdab30397b5 100755 (executable)
@@ -1599,6 +1599,28 @@ applying the different options would be:
         sub usage();    # n=1 [default; follows input]
         sub usage ();   # n=2 [space]
 
+=item B<-ssp=n>  or B<--space-signature-paren=n>
+
+This flag is analogous to the previous except that it applies to the space before the opening paren of a sub B<signature> rather than a sub B<prototype>.
+
+For example, consider the following line:
+
+      sub circle( $xc, $yc, $rad )
+
+This space before the opening paren can be controlled with integer B<n> which
+may have the value 0, 1, or 2 with these meanings:
+
+    -ssp=0 means no space before the paren
+    -ssp=1 means follow the example of the source code [DEFAULT]
+    -ssp=2 means always put a space before the paren
+
+The default is B<-ssp=1>, meaning that will be a space in the output if, and only if, there is one in the input.  Given the above line of code, the result of
+applying the different options would be:
+
+    sub circle( $xc, $yc, $rad )   # n=0 [no space]
+    sub circle( $xc, $yc, $rad )   # n=1 [default; same as input]
+    sub circle ( $xc, $yc, $rad )  # n=2 [space]
+
 =item B<-kpit=n> or B<--keyword-paren-inner-tightness=n>
 
 The space inside of an opening paren, which itself follows a certain keyword,
index 92443d64b86fc126849e1747de734b46a7b7828d..a3d0bb321c543d1f103bfa0326501e38c56c4725 100755 (executable)
@@ -1165,6 +1165,7 @@ EOM
             'keyword-group-blanks-after'  => [ 0, 2 ],
 
             'space-prototype-paren' => [ 0, 2 ],
+            'space-signature-paren' => [ 0, 2 ],
             'break-after-labels'    => [ 0, 2 ],
 
             'want-trailing-commas' => [ '0', '*', 'm', 'b', 'h', 'i', ' ' ],
index c1fc82ac6f2526f2c085f31d752ea8ada0623e03..5913e9212f07288df9b0f5627fc724f73f38d0fe 100644 (file)
@@ -3463,6 +3463,7 @@ sub generate_options {
     $add_option->( 'want-right-space',                          'wrs',   '=s' );
     $add_option->( 'want-trailing-commas',                      'wtc',   '=s' );
     $add_option->( 'space-prototype-paren',                     'spp',   '=i' );
+    $add_option->( 'space-signature-paren',                     'ssp',   '=i' );
     $add_option->( 'valign-code',                               'vc',    '!' );
     $add_option->( 'valign-block-comments',                     'vbc',   '!' );
     $add_option->( 'valign-side-comments',                      'vsc',   '!' );
@@ -3735,6 +3736,7 @@ sub generate_options {
         'keyword-group-blanks-after'  => [ 0, 2 ],
 
         'space-prototype-paren' => [ 0, 2 ],
+        'space-signature-paren' => [ 0, 2 ],
         'break-after-labels'    => [ 0, 2 ],
     );
 
@@ -3849,6 +3851,7 @@ sub generate_options {
       space-for-semicolon
       space-backslash-quote=1
       space-prototype-paren=1
+      space-signature-paren=1
       square-bracket-tightness=1
       square-bracket-vertical-tightness-closing=0
       square-bracket-vertical-tightness=0
index 94ed836aae4042406470c70bd3c04a235bded472..b2c4d700738aeeb45a5869b419da839628e5fd2e 100644 (file)
@@ -251,6 +251,7 @@ my (
     $rOpts_recombine,
     $rOpts_short_concatenation_item_length,
     $rOpts_space_prototype_paren,
+    $rOpts_space_signature_paren,
     $rOpts_stack_closing_block_brace,
     $rOpts_static_block_comments,
     $rOpts_add_missing_else,
@@ -2512,6 +2513,7 @@ sub initialize_global_option_vars {
     $rOpts_short_concatenation_item_length =
       $rOpts->{'short-concatenation-item-length'};
     $rOpts_space_prototype_paren     = $rOpts->{'space-prototype-paren'};
+    $rOpts_space_signature_paren     = $rOpts->{'space-signature-paren'};
     $rOpts_stack_closing_block_brace = $rOpts->{'stack-closing-block-brace'};
     $rOpts_static_block_comments     = $rOpts->{'static-block-comments'};
     $rOpts_add_missing_else          = $rOpts->{'add-missing-else'};
@@ -3035,6 +3037,27 @@ sub set_whitespace_flags {
 
     my %is_for_foreach = ( 'for' => 1, 'foreach' => 1 );
 
+    # function to return $ws for a signature paren following a sub
+    my $ws_signature_paren = sub {
+        my ($jj) = @_;
+        my $ws;
+        if ( $rOpts_space_signature_paren == 1 ) {
+
+            # is the previous token a blank?
+            my $have_blank = $rLL->[ $jj - 1 ]->[_TYPE_] eq 'b';
+
+            # or a newline?
+            $have_blank ||=
+              $rLL->[$jj]->[_LINE_INDEX_] != $rLL->[ $jj - 1 ]->[_LINE_INDEX_];
+
+            $ws = $have_blank ? WS_YES : WS_NO;
+        }
+        else {
+            $ws = $rOpts_space_signature_paren == 0 ? WS_NO : WS_YES;
+        }
+        return $ws;
+    };
+
     my $last_token = SPACE;
     my $last_type  = 'b';
 
@@ -3330,12 +3353,18 @@ sub set_whitespace_flags {
 
                 # Space between keyword and '('
                 elsif ( $last_type eq 'k' ) {
-                    $ws = WS_NO
-                      unless ( $rOpts_space_keyword_paren
-                        || $space_after_keyword{$last_token} );
 
-                    # Set inside space flag if requested
-                    set_container_ws_by_keyword( $last_token, $seqno );
+                    if ( $last_token eq 'sub' ) {
+                        $ws = $ws_signature_paren->($j);
+                    }
+                    else {
+                        $ws = WS_NO
+                          unless ( $rOpts_space_keyword_paren
+                            || $space_after_keyword{$last_token} );
+
+                        # Set inside space flag if requested
+                        set_container_ws_by_keyword( $last_token, $seqno );
+                    }
                 }
 
                 # Space between function and '('
@@ -3401,8 +3430,14 @@ sub set_whitespace_flags {
                 {
                     $ws = WS_NO;
                 }
+
+                # a paren after a sub definition starts signature
+                elsif ( $last_type eq 'S' ) {
+                    $ws = $ws_signature_paren->($j);
+                }
+
                 else {
-                    # ok - opening paren not covered by a special rule
+                    # no special rule for this opening paren type
                 }
             }
 
@@ -3418,7 +3453,10 @@ sub set_whitespace_flags {
             # keep space between 'sub' and '{' for anonymous sub definition,
             # be sure type = 'k' (added for c140)
             if ( $type eq '{' ) {
-                if ( $last_token eq 'sub' && $last_type eq 'k' ) {
+                if (   $last_token eq 'sub'
+                    && $last_type eq 'k'
+                    && $token ne '(' )
+                {
                     $ws = WS_YES;
                 }
 
index bdecf449f5270d18148ee596c3be2e07e518d698..1e7e8607c368c5c0d41b5d8c3d3aad067709b52a 100755 (executable)
@@ -48,7 +48,8 @@ ENDE
 my $output;
 my $stderr_string;
 my $errorfile_string;
-my $params = "";
+# -ssp=2 is needed to keep formatting unchanged with new -ssp parameter
+my $params = "-ssp=2";
 my $err    = Perl::Tidy::perltidy(
 
     #argv => '-npro',  # fix for RT#127679, avoid reading unwanted .perltidyrc
diff --git a/t/snippets/expect/git125.def b/t/snippets/expect/git125.def
new file mode 100644 (file)
index 0000000..9ef474b
--- /dev/null
@@ -0,0 +1,2 @@
+sub Add ( $x, $y );
+sub Sub( $x, $y );
diff --git a/t/snippets/expect/git125.git125 b/t/snippets/expect/git125.git125
new file mode 100644 (file)
index 0000000..1278116
--- /dev/null
@@ -0,0 +1,2 @@
+sub Add( $x, $y );
+sub Sub( $x, $y );
index b33d07e26355264b33586d103583c9dbd58f0102..e2d1e90189ec361143b6dce686f493089f6354c8 100644 (file)
@@ -1,12 +1,12 @@
 # git22: Preserve function signature on a single line
 # This behavior is controlled by 'sub weld_signature_parens'
 
-sub foo ( $x, $y = "abcd" ) {
+sub foo( $x, $y = "abcd" ) {
     $x . $y;
 }
 
 # do not break after closing do brace
-sub foo ( $x, $y = do { {} }, $z = 42, $w = do { "abcd" } ) {
+sub foo( $x, $y = do { {} }, $z = 42, $w = do { "abcd" } ) {
     $x . $y . $z;
 }
 
diff --git a/t/snippets/git125.in b/t/snippets/git125.in
new file mode 100644 (file)
index 0000000..9ef474b
--- /dev/null
@@ -0,0 +1,2 @@
+sub Add ( $x, $y );
+sub Sub( $x, $y );
diff --git a/t/snippets/git125.par b/t/snippets/git125.par
new file mode 100644 (file)
index 0000000..e8fd306
--- /dev/null
@@ -0,0 +1 @@
+-ssp=0
index 12afe1e277287cfd74a31265b1b520082eff068a..65ef0cbc0bc5878edeecfffb5cfe23e2097fca9b 100644 (file)
 ../snippets9.t rt98902.def
 ../snippets9.t rt98902.rt98902
 ../snippets9.t rt99961.def
+../snippets28.t        git125.def
+../snippets29.t        git125.git125
index 16e8fb644d9b40a6ed005a5527790726fa88400c..4abdf24c5503a91556f654c24c59ee6ac3f9c14c 100644 (file)
@@ -1054,12 +1054,12 @@ $i++;
 # git22: Preserve function signature on a single line
 # This behavior is controlled by 'sub weld_signature_parens'
 
-sub foo ( $x, $y = "abcd" ) {
+sub foo( $x, $y = "abcd" ) {
     $x . $y;
 }
 
 # do not break after closing do brace
-sub foo ( $x, $y = do { {} }, $z = 42, $w = do { "abcd" } ) {
+sub foo( $x, $y = do { {} }, $z = 42, $w = do { "abcd" } ) {
     $x . $y . $z;
 }
 
index 38e8b95da1242ce59b9d26260b7dbc0f5a1f211a..f9873fac95752b54c42c900bea46304df1da2d0a 100644 (file)
@@ -19,6 +19,7 @@
 #16 git124.def
 #17 c269.c269
 #18 c269.def
+#19 git125.def
 
 # To locate test #13 you can search for its name or the string '#13'
 
@@ -91,6 +92,11 @@ sub git124 {
         }
     ];
 }
+----------
+
+        'git125' => <<'----------',
+sub Add ( $x, $y );
+sub Sub( $x, $y );
 ----------
 
         'lrt' => <<'----------',
@@ -448,6 +454,15 @@ elsif ($zzzzz) {
 }
 #18...........
         },
+
+        'git125.def' => {
+            source => "git125",
+            params => "def",
+            expect => <<'#19...........',
+sub Add ( $x, $y );
+sub Sub( $x, $y );
+#19...........
+        },
     };
 
     my $ntests = 0 + keys %{$rtests};
diff --git a/t/snippets29.t b/t/snippets29.t
new file mode 100644 (file)
index 0000000..66c1c15
--- /dev/null
@@ -0,0 +1,107 @@
+# Created with: ./make_t.pl
+
+# Contents:
+#1 git125.git125
+
+# 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 = { 'git125' => "-ssp=0", };
+
+    ############################
+    # BEGIN SECTION 2: Sources #
+    ############################
+    $rsources = {
+
+        'git125' => <<'----------',
+sub Add ( $x, $y );
+sub Sub( $x, $y );
+----------
+    };
+
+    ####################################
+    # BEGIN SECTION 3: Expected output #
+    ####################################
+    $rtests = {
+
+        'git125.git125' => {
+            source => "git125",
+            params => "git125",
+            expect => <<'#1...........',
+sub Add( $x, $y );
+sub Sub( $x, $y );
+#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 "<<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";
+            }
+        }
+    }
+}