## 2020 10 01.02
+ - implement request RT #133649, delete-old-newlines selectively. Two parameters,
+
+ -kbb=s or --keep-old-breakpoints-before=s, and
+ -kba=s or --keep-old-breakpoints-after=s
+
+ were added to request that old breakpoints be kept before or after
+ selected token types. For example, -kbb='=>' means that newlines before
+ fat commas should be kept.
+
- Fix git #44, fix exit status for assert-tidy/untidy. The exit status was
always 0 for --assert-tidy if the user had turned off all error messages with
the -quiet. This has been fixed.
controlled with -maxle=n, --maximum-level-errors=n. This means that if
the ending indentation differs from the starting indentation by more than
n levels, the file will be output verbatim. The default is n=1.
- To skip this check, set n=0.
+ To skip this check, set n=-1 or set n to a large number.
+
+ - A related new flag, --maximum-unexpected-errors=n, or -maxue=n, is available
+ but is off by default.
- Add flag -xci, --extended-continuation-indentation, regarding issue git #28
This flag causes continuation indentation to "extend" deeper into structures.
To prevent this, and thereby always form longer lines, use B<-nboa>.
+
+=item Keeping old breakpoints at specific token types
+
+Two command line parameters provide detailed control over whether
+perltidy should keep an old line break before or after a specific
+token type:
+
+B<-kbb=s> or B<--keep-old-breakpoints-before=s>, and
+
+B<-kba=s> or B<--keep-old-breakpoints-after=s>
+
+These parameters are each followed by a quoted string, B<s>, containing
+a list of token types (separated only by spaces). No more than one of each
+of these parameters should be specified, because repeating a
+command-line parameter always overwrites the previous one before
+perltidy ever sees it.
+
+For example, -kbb='=>' means that if an input line begins with a '=>' then the
+output script should also have a line break before that token.
+
+For example, given the script:
+
+ method 'foo'
+ => [ Int, Int ]
+ => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
+ # perltidy [default]
+ method 'foo' => [ Int, Int ] => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
+ # perltidy -kbb='=>'
+ method 'foo'
+ => [ Int, Int ]
+ => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
=item B<-iob>, B<--ignore-old-breakpoints>
Use this flag to tell perltidy to ignore existing line breaks to the
maximum extent possible. This will tend to produce the longest possible
containers, regardless of type, which do not exceed the line length
-limit.
+limit. But please note that this parameter has priority over all
+other parameters requesting that certain old breakpoints be kept.
=item B<-kis>, B<--keep-interior-semicolons>
B<--maximum-level-errors=n> or B<-maxle=n> specifies the maximum number of
indentation level errors are allowed before perltidy skips formatting and just
-outputs a file verbatim. The default is n=1. This means that if the final indentation
-of a script differs from the starting indentation by more than 1 levels, the file
-will be output verbatim. To avoid formatting if there are any indentation
-level errors use -maxle=0. To skip this check set n equal to a large number,
-such as n=100.
+outputs a file verbatim. The default is B<n=1>. This means that if the final
+indentation of a script differs from the starting indentation by more than 1
+levels, the file will be output verbatim. To avoid formatting if there are any
+indentation level errors use -maxle=0. To skip this check you can either set n
+equal to a large number, such as B<n=100>, or set B<n=-1>.
For example, the following script has level error of 3 and will be output verbatim
B<--maximum-unexpected-errors=n> or B<-maxue=n> specifies the maximum number of
unexpected tokenization errors are allowed before formatting is skipped and a
-script is output verbatim. This is off by default but can be turned on to
-avoid accidentally formatting something like an html file, for example. If the
-number of times the tokenizer found unexpected tokens is greater than the
-parameter n, the file will be output verbatim. To skip this check completely,
-set n equal to a large number or set n=0. The default is n=0 (skip this check)
-to avoid causing problems with scripts using extended syntaxes.
+script is output verbatim. The intention is to avoid accidentally formatting
+a non-perl script, such as an html file for example. This check can be turned
+off by setting B<n=0>.
+
+A recommended value is B<n=3>. However, the default is B<n=0> (skip this check)
+to avoid causing problems with scripts which have extended syntaxes.
B<-DEBUG> will write a file with extension F<.DEBUG> for each input file
showing the tokenization of all lines of code.
<ul id="index">
<li><a href="#Issues-fixed-after-release-20201001">Issues fixed after release 20201001</a></li>
<li><a href="#Issues-fixed-after-release-20200907">Issues fixed after release 20200907</a></li>
- <li><a href="#POD-ERRORS">POD ERRORS</a></li>
+ <li><a href="#Open-Issues">Open Issues</a></li>
</ul>
<h1 id="Issues-fixed-after-release-20201001">Issues fixed after release 20201001</h1>
<dl>
+<dt id="implement-request-RT-133649-added-parameters--kbb-s-and--kba-s"><b>implement request RT #133649, added parameters -kbb=s and -kba=s</b></dt>
+<dd>
+
+<p>These parameters request that old breakpoints be kept before or after selected token types. For example, -kbb='=>' means that newlines before fat commas should be kept. This was added 4 Nov 2020.</p>
+
+</dd>
+<dt id="added-parameters--maxue-n-and-maxle-n"><b>added parameters -maxue=n and maxle=n</b></dt>
+<dd>
+
+<p>These parameters had tentatively been hardwired in the tokenizer. Now the user can control them or turn the checks off altogether.</p>
+
+</dd>
+<dt id="Fix-problem-parsing"><b>Fix problem parsing '$$*'</b></dt>
+<dd>
+
+<p>In random testing, an error was encountered parsing the following line</p>
+
+<pre><code> $self->{"mod_id"}=($$*1001)%(10**(rand()*6));
+ ---^
+ found Number where operator expected (previous token underlined)</code></pre>
+
+<p>The line parsed correctly with a space between the '$$' and the '*'. The problem had to do with an error in some newer code for postfix dereferencing, and this was fixed on 2 Nov 2020, 'fix problem scanning '$$'; revise call to operator_expected', 49d993b.</p>
+
+</dd>
+<dt id="Update-for-git-44-fix-exit-status-for-assert-tidy-untidy"><b>Update for git #44, fix exit status for assert-tidy/untidy</b></dt>
+<dd>
+
+<p>The exit status was always 0 for --assert-tidy if the user had turned off error messages with -quiet. This was fixed by gluesys/master in 'fix exit status for assert-tidy/untidy options', 625d250.</p>
+
+</dd>
+<dt id="Fixed-problem-parsing-extruded-signature"><b>Fixed problem parsing extruded signature</b></dt>
+<dd>
+
+<p>A parsing error was encountered in a test parsing the following extruded signature:</p>
+
+<pre><code> sub foo2
+ (
+ $
+ first
+ ,
+ $
+ ,
+ $
+ third
+ )
+ {
+ return
+ "first=$first, third=$third"
+ ;
+ }</code></pre>
+
+<p>The second '$' combined with the ',' on the next line to form a punctuation variable. This was fixed 20 Oct 2020 in 'fixed problem parsing extruded signature', 9b454f6.</p>
+
+<p>The file parses correctly now, with formatted output</p>
+
+<pre><code> sub foo2 ( $first, $, $third ) {
+ return "first=$first, third=$third";
+ }</code></pre>
+
+</dd>
+<dt id="Fixed-several-uses-of-undefined-variables-found-in-testing"><b>Fixed several uses of undefined variables found in testing</b></dt>
+<dd>
+
+<p>Several instances of incorrect array indexing were found in testing and fixed. These each involved incorrectly indexing with index -1. They were found by placing undefs at the end of arrays. None of these was causing incorrect formatting. They were fixed 26 Oct 2020 in 'fixed several instances of incorrect array indexing', c60f694.</p>
+
+</dd>
+<dt id="Prevent-syntax-error-by-breaking-dashed-package-names"><b>Prevent syntax error by breaking dashed package names</b></dt>
+<dd>
+
+<p>In stress testing perltidy with the -extrude option, the following test snippet</p>
+
+<pre><code> use perl6-alpha;</code></pre>
+
+<p>was broken into sepate lines</p>
+
+<pre><code> use
+ perl6
+ -
+ alpha
+ ;</code></pre>
+
+<p>A rule was added to prevent breaking around a dash separating two barewords. Rerunning gives</p>
+
+<pre><code> use
+ perl6-alpha
+ ;</code></pre>
+
+<p>This was fixed 26 Oct 2020 in 'prevent breaking package names with trailing dashes', 9234be4.</p>
+
+</dd>
+<dt id="Prevent-syntax-error-by-breaking-dashed-barewords"><b>Prevent syntax error by breaking dashed barewords</b></dt>
+<dd>
+
+<p>In stress testing perltidy with the -extrude option, using the following test snippet</p>
+
+<pre><code> my %var;
+ {
+ $var{-y} = 1;
+ $var{-q} = 1;
+ $var{-qq} = 1;
+ $var{-m} = 1;
+ $var{y} = 1;
+ $var{q} = 1;
+ $var{qq} = 1;
+ $var{m} = 1;
+ }</code></pre>
+
+<p>a syntax error was created when newlines were placed before or after the dashes. It is necessary to always keep a dash on the same line with its surrounding tokens. A rule was added to do this. The new 'extruded' result for the above snippet is:</p>
+
+<pre><code> my%var
+ ;
+ {
+ $var{-y}
+ =
+ 1
+ ;
+ $var{-q}
+ =
+ 1
+ ;
+ $var{-qq}
+ =
+ 1
+ ;
+ $var{-m}
+ =
+ 1
+ ;
+ $var{y}
+ =
+ 1
+ ;
+ $var{q}
+ =
+ 1
+ ;
+ $var{qq}
+ =
+ 1
+ ;
+ $var{m}
+ =
+ 1
+ ;
+ }</code></pre>
+
+<p>This update was added 26 Oct 2020, 'prevent syntax error by breaking dashed barewords', e121cae.</p>
+
+</dd>
+<dt id="more-types-of-severe-errors-will-prevent-formatting"><b>more types of severe errors will prevent formatting</b></dt>
+<dd>
+
+<p>Files for which 'severe errors' are found have always been output verbatim rather than being formatted. The definition of 'severe error' has been expanded to include a final indentation level error greater than 1, more than 2 brace errors, and more than 3 "unexpected token type" parsing errors. The goal is to avoid formatting a non-perl script or a perl script with severe errors. So for example the following snippet has a level error of 2</p>
+
+<pre><code> {{{{
+ }}</code></pre>
+
+<p>was previously output with default parameters as</p>
+
+<pre><code> {
+ {
+ {
+ {}
+ }</code></pre>
+
+<p>along with an error message. But now it is just output verbatim as</p>
+
+<pre><code> {{{{
+ }}</code></pre>
+
+<p>along with an error message. This update was added 25 Oct 2020, 'avoid formatting files with more types of severe errors', 2a86f51.</p>
+
+</dd>
+<dt id="added-state-as-keyword"><b>added 'state' as keyword</b></dt>
+<dd>
+
+<p>A statement such as the following was generating an error message at the colon:</p>
+
+<pre><code> state $a : shared;</code></pre>
+
+<p>The problem was that 'state' was not in the list of keywords. This has been fixed and the line now parses without error. The 'state.t' test file for perl 5.31 now formats without error. This was added 18 Oct 2020 in "add 'state' as keyword", d73e15f.</p>
+
+</dd>
+<dt id="sub-signatures-no-longer-parsed-with-prototypes"><b>sub signatures no longer parsed with prototypes</b></dt>
+<dd>
+
+<p>Simple signatures (those without commas) were being parsed with code originally written for prototypes. This prevented them from being formatted with the usual formatting rules. This was changed so that all signatures are now formatted with the normal formatting rules. For example:</p>
+
+<pre><code> # Old, input and after formatting:
+ sub t123 ($list=wantarray) { $list ? "list" : "scalar" }
+
+ # New, after formatting
+ sub t123 ( $list = wantarray ) { $list ? "list" : "scalar" }</code></pre>
+
+<p>Notice that some spaces have been introduced within the signature. Previously the contents of the parens not changed unless the parens contained a list.</p>
+
+<p>This change introduced a problem parsing extended syntax within signatures which has been fixed. In the following snippet, the ':' caused a parsing error which was fixed.</p>
+
+<pre><code> # perltidy -sal='method'
+ method foo4 ( $class : $bar, $bubba ) { $class->bar($bar) }</code></pre>
+
+<p>The ':' here is given a type of 'A'. This may be used to change the spacing around it. For example:</p>
+
+<pre><code> # perltidy -sal='method' -nwls='A'
+ method foo4 ( $class: $bar, $bubba ) { $class->bar($bar) }</code></pre>
+
+<p>This update was added 18 Oct 2020, in 'format all signatures separately from prototypes', e6a10f3. The test file 'signatures.t' distributed with perl5.31 formats without error now.</p>
+
+</dd>
+<dt id="fix-parsing-problem-with"><b>fix parsing problem with $#</b></dt>
+<dd>
+
+<p>A problem with parsing variables of the form $# and $#array was found in testing and fixed. For most variables the leading sigil may be separated from the remaining part of the identifier by whitespace. An exception is for a variable beginning with '$#'. If there is any space between the '$' and '#' then the '#' starts a comment. So the following snippet is has valid syntax and is equivalent to $ans=40;</p>
+
+<pre><code> my $ #
+ #
+ ans = 40;</code></pre>
+
+<p>This was being misparsed and was fixed 17 Oct 2020, in 'fixed parsing error with spaces in $#' a079cdb.</p>
+
+</dd>
+<dt id="fix-missing-line-break-for-hash-of-subs-with-signatures"><b>fix missing line break for hash of subs with signatures</b></dt>
+<dd>
+
+<p>During testing the following error was found and fixed. Given the following input snippet:</p>
+
+<pre><code> get(
+ on_ready => sub ($worker) {
+ $on_ready->end;
+ return;
+ },
+ on_exit => sub ( $worker, $status ) { return; },
+ );</code></pre>
+
+<p>The resulting formatting was</p>
+
+<pre><code> get(
+ on_ready => sub ($worker) {
+ $on_ready->end;
+ return;
+ }, on_exit => sub ( $worker, $status ) { return; },
+ );</code></pre>
+
+<p>Notice that the break after the comma has been lost. The problem was traced to a short-cut taken by the code looking for one-line blocks. The unique circumstances in which this occured involved a hash of anonymous subs, one with a signature with multiple parameters and short enough to be a one-line block, as in the last sub definition line. This was fixed 17 Oct 2020 in 'fix missing line break for hash of subs with signatures', 51428db.</p>
+
+</dd>
+<dt id="fix-issues-with-prototype-and-signature-parsing"><b>fix issues with prototype and signature parsing</b></dt>
+<dd>
+
+<p>Problems with parsing prototypes and signatures were found during testing and fixed 17 Oct 2020 in 'fixed problem parsing multi-line signatures with comments', 017fd07. For example the following snippet was mis-parsed because of the hash mark.</p>
+
+<pre><code> sub test ( # comment )))
+ $x, $x) { $x+$y }</code></pre>
+
+<p>Complex signature expressions such as the following are now parsed without error:</p>
+
+<pre><code> sub t086
+ ( #foo)))
+ $ #foo)))
+ a #foo)))
+ ) #foo)))
+ { $a.$b }</code></pre>
+
+</dd>
+<dt id="improve-guess-for-pattern-or-division"><b>improve guess for pattern or division</b></dt>
+<dd>
+
+<p>The following line caused a tokenization error in which the two slashes were parsed as a pattern.</p>
+
+<pre><code> my $masksize = ceil( Opcode::opcodes / 8 ); # /</code></pre>
+
+<p>This problem was discovered in random testing. When a slash follows a bareword whose prototype is not known to perltidy, it has to guess whether the slash starts a pattern or is a division. The guessing logic was rewritten and improved 14 Oct 2020 in 'rewrote logic to guess if divide or pattern', afebe2f.</p>
+
+</dd>
+<dt id="fix--bos-to-keep-isolated-semicolon-breaks-after-block-braces"><b>fix -bos to keep isolated semicolon breaks after block braces</b></dt>
+<dd>
+
+<p>The flag <b>-bos</b>, or <b>--break-at-old-semicolon-breakpoints</b>, keeps breaks at old isolated semicolons. For example</p>
+
+<pre><code> $z = sqrt($x**2 + $y**2)
+ ;</code></pre>
+
+<p>In testing it was found not to be doing this after braces which require semicolons, such as 'do' and anonymous subs. This was fixed 12 Oct 2020 in 'fix -bos to work with semicolons after braces', 03ee7fc. For example</p>
+
+<pre><code> my $dist = sub {
+ $z = sqrt( $x**2 + $y**2 )
+ ;
+ }
+ ;</code></pre>
+
+</dd>
+<dt id="keep-break-after-use-overload"><b>keep break after 'use overload'</b></dt>
+<dd>
+
+<p>If a line break occurs after <b>use overload</b> then it will now be kept. Previously it was dropped. For example, this would be kept intact:</p>
+
+<pre><code> use overload
+ '+' => sub {
+ print length $_[2], "\n";
+ my ( $x, $y ) = _order(@_);
+ Number::Roman->new( int $x + $y );
+ },
+ '-' => sub {
+ my ( $x, $y ) = _order(@_);
+ Number::Roman->new( int $x - $y );
+ },
+ ...</code></pre>
+
+<p>This keeps the list from shifting to the right and can avoid problems in formatting the list with certain styles, including with the -xci flag. Fixed 12 Oct 2020 in 'keep break after use overload statement', 8485afa.</p>
+
+</dd>
+<dt id="added-flag--xci-to-improve-formatting-when--ci-and--i-are-equal-issue-git-28"><b>added flag -xci to improve formatting when -ci and -i are equal, issue git #28</b></dt>
+<dd>
+
+<p>This flag causes continuation indentation to "extend" deeper into structures. If you use <b>-ci=n</b> and <b>-i=n</b> with the same value of <b>n</b> you will probably want to set this flag. Since this is a fairly new flag, the default is <b>-nxci</b> to avoid disturbing existing formatting.</p>
+
+</dd>
<dt id="terminal-braces-not-indenting-correctly-with--bli-formatting-issue-git-40"><b>terminal braces not indenting correctly with -bli formatting, issue git #40</b></dt>
<dd>
</dd>
</dl>
-<h1 id="POD-ERRORS">POD ERRORS</h1>
+<h1 id="Open-Issues">Open Issues</h1>
-<p>Hey! <b>The above document had some coding errors, which are explained below:</b></p>
+<p>These are known issues which have not been fixed.</p>
<dl>
-<dt id="Around-line-3">Around line 3:</dt>
+<dt id="lexical-subs-not-fully-supported"><b>lexical subs not fully supported</b></dt>
<dd>
-<p>'=item' outside of any '=over'</p>
+<p>Basic parsing of lexical subs works but some aspects of lexical subs are not yet functional. One of these is that unlike regular subs, lexical subs can override names of builtin functions.</p>
+
+<p>First consider the following snippet</p>
+
+<pre><code> sub s {
+ my $arg=$_[0];
+ print "s called with arg $arg\n";
+ }
+ s(1);
+ s(2);</code></pre>
+
+<p>The 's' in the two last lines is the builtin s function, not the sub. Both perltidy and perl make the same assumption here. This program happens to still run but prints nothing. It will not run if the last semicolon is removed.</p>
+
+<p>Now consider the following snippet in which the sub has a preceding 'my'</p>
+
+<pre><code> use feature 'lexical_subs', 'signatures';
+ my sub s {
+ my $arg=$_[0];
+ print "s called with arg $arg\n";
+ }
+ s(1);
+ s(2);</code></pre>
+
+<p>The builtin function 's' is replaced by the sub s here, and the program runs. Perltidy will format this but it is assuming that the s in the two last lines are the builtin s function. If the last semicolon is removed, there will be an formatting error. So perltidy and perl make different assumptions in this case.</p>
+
+<p>Another issue is that perltidy does not yet remember the extent of the scope of a lexical sub.</p>
</dd>
-<dt id="Around-line-36">Around line 36:</dt>
+<dt id="issues-with-paren-less-calls"><b>issues with paren-less calls</b></dt>
<dd>
-<p>You forgot a '=back' before '=head1'</p>
+<p>Consider the following snippet:</p>
+
+<pre><code> use Test::More;
+ ok open($stdin, "<&", $1), 'open ... "<&", $magical_fileno', || _diag $!;</code></pre>
+
+<p>Note the unusual situation of a comma followed by an '||'. Perltidy will format this satisfactorally but it will write an error message. The syntax is correct, however. Perl knows the prototype of the 'ok' function, which is called here without parens, so the last comma marks the last arg and is needed to keep the || from attaching to the last arg.</p>
+
+<p>Full support of peren-less calls will probably never be implemented in perltidy because it would require that it parse all of the modules used to find the prototypes. This would make it impossible to run perltidy on small snippets of code from within an editor.</p>
+
+<p>The problem can be avoid if parens are used:</p>
+
+<pre><code> ok ( open($stdin, "<&", $1), 'open ... "<&", $magical_fileno') || _diag $!;</code></pre>
+
+</dd>
+<dt id="multiple-sub-paren-calls"><b>multiple sub paren calls</b></dt>
+<dd>
+
+<p>Perltidy currently flags as an error a closing paren followed by an opening paren, as in the following</p>
+
+<pre><code> $subsubs[0]()(0)</code></pre>
+
+<p>This syntax is ok. The example is from test 'current_sub.t' in perl5.31.</p>
</dd>
</dl>
<h1>Perltidy Change Log</h1>
-<h2>2020 10 01.01</h2>
+<h2>2020 10 01.02</h2>
-<pre><code>- Add flag -xci, --extended-continuation-indentation, regarding issue git #28
+<pre><code>- implement request RT #133649, delete-old-newlines selectively. Two parameters,
+
+ -kbb=s or --keep-old-breakpoints-before=s, and
+ -kba=s or --keep-old-breakpoints-after=s
+
+ were added to request that old breakpoints be kept before or after
+ selected token types. For example, -kbb='=>' means that newlines before
+ fat commas should be kept.
+
+- Fix git #44, fix exit status for assert-tidy/untidy. The exit status was
+ always 0 for --assert-tidy if the user had turned off all error messages with
+ the -quiet. This has been fixed.
+
+- Add flag -maxfs=n, --maximum-file-size-mb=n. This parameter is provided to
+ avoid causing system problems by accidentally attempting to format an
+ extremely large data file. The default is n=10. The command to increase
+ the limit to 20 MB for example would be -mfs=20. This only applies to
+ files specified by filename on the command line.
+
+- Skip formatting if there are too many indentation level errors. This is
+ controlled with -maxle=n, --maximum-level-errors=n. This means that if
+ the ending indentation differs from the starting indentation by more than
+ n levels, the file will be output verbatim. The default is n=1.
+ To skip this check, set n=-1 or set n to a large number.
+
+- A related new flag, --maximum-unexpected-errors=n, or -maxue=n, is available
+ but is off by default.
+
+- Add flag -xci, --extended-continuation-indentation, regarding issue git #28
+ This flag causes continuation indentation to "extend" deeper into structures.
+ Since this is a fairly new flag, the default is -nxci to avoid disturbing
+ existing formatting. BUT you will probably see some improved formatting
+ in complex data structures by setting this flag if you currently use -ci=n
+ and -i=n with the same value of 'n' (as is the case if you use -pbp,
+ --perl-best-practices, where n=4).
- Fix issue git #42, clarify how --break-at-old-logical-breakpoints works.
+ The man page was updated to note that it does not cause all logical breakpoints
+ to be replicated in the output file.
+
+- Fix issue git #41, typo in manual regarding -fsb.
-- Fix issue git #41, typo in manual regarding -fsb
+- Some problems with parsing complex multi-line sub signatures have been fixed.
- Fix issue git #40: when using the -bli option, a closing brace followed by
- a semicolon was not being indented.
+ a semicolon was not being indented. This applies to braces which require
+ semicolons, such as a 'do' block.
+
+- Added 'state' as a keyword.
+
+- This version is about 15% faster than previous versions due to some optimization work
+ using Devel::NYTProf.
+
+- Numerous minor issues that the average user would not encounter were found
+ and fixed. They can be seen in the more complete list of updates at
+
+ https://github.com/perltidy/perltidy/blob/master/local-docs/BugLog.pod
</code></pre>
<h2>2020 10 01</h2>
<pre><code>- Robustness of perltidy has been significantly improved. Updating is recommended. Continual
automated testing runs began about 1 Sep 2020 and numerous issues have been found and fixed.
Many involve references to uninitialized variables when perltidy is fed random text and random
- control parameters. A complete list is given in the file
-
- https://github.com/perltidy/perltidy/blob/master/local-docs/BugLog.pod
+ control parameters.
- Added the token '->' to the list of alignment tokens, as suggested in git
#39, so that it can be vertically aligned if a space is placed before them with -wls='->'.
<h1 id="VERSION">VERSION</h1>
-<p>This man page documents Perl::Tidy version 20201001.01</p>
+<p>This man page documents Perl::Tidy version 20201001.02</p>
<h1 id="LICENSE">LICENSE</h1>
<dt id="q---quiet"><b>-q</b>, <b>--quiet</b></dt>
<dd>
-<p>Deactivate error messages and syntax checking (for running under an editor).</p>
+<p>Deactivate error messages (for running under an editor).</p>
<p>For example, if you use a vi-style editor, such as vim, you may execute perltidy as a filter from within the editor using something like</p>
<dt id="ast---assert-tidy"><b>-ast</b>, <b>--assert-tidy</b></dt>
<dd>
-<p>This flag asserts that the input and output code streams are identical, or in other words that the input code is already 'tidy' according to the formatting parameters. If this is not the case, an error message noting this is produced. This error message will cause the process to return a non-zero exit code. The test for this is made by comparing an MD5 hash value for the input and output code streams. This flag has no other effect on the functioning of perltidy. This might be useful for certain code maintenance operations.</p>
+<p>This flag asserts that the input and output code streams are identical, or in other words that the input code is already 'tidy' according to the formatting parameters. If this is not the case, an error message noting this is produced. This error message will cause the process to return a non-zero exit code. The test for this is made by comparing an MD5 hash value for the input and output code streams. This flag has no other effect on the functioning of perltidy. This might be useful for certain code maintenance operations. Note: you will not see this message if you have error messages turned off with the -quiet flag.</p>
</dd>
<dt id="asu---assert-untidy"><b>-asu</b>, <b>--assert-untidy</b></dt>
next if $x == $y;
} } until $x++ > $z;</code></pre>
-<p>When this flag is set perltidy makes a preliminary pass through the file and identifies all nested pairs of containers. To qualify as a nested pair, the closing container symbols must be immediately adjacent. The opening symbols must either be adjacent, or, if the outer opening symbol is an opening paren, they may be separated by any single non-container symbol or something that looks like a function evaluation.</p>
+<p>When this flag is set perltidy makes a preliminary pass through the file and identifies all nested pairs of containers. To qualify as a nested pair, the closing container symbols must be immediately adjacent and the opening symbols must either (1) be adjacent as in the above example, or (2) have an anonymous sub declaration following an outer opening container symbol which is not a code block brace, or (3) have an outer opening paren separated from the inner opening symbol by any single non-container symbol or something that looks like a function evaluation, as illustrated in the next examples.</p>
<p>Any container symbol may serve as both the inner container of one pair and as the outer container of an adjacent pair. Consequently, any number of adjacent opening or closing symbols may join together in weld. For example, here are three levels of wrapped function calls:</p>
<p>To prevent this, and thereby always form longer lines, use <b>-nboa</b>.</p>
+</dd>
+<dt id="Keeping-old-breakpoints-at-specific-token-types">Keeping old breakpoints at specific token types</dt>
+<dd>
+
+<p>Two command line parameters provide detailed control over whether perltidy should keep an old line break before or after a specific token type:</p>
+
+<p><b>-kbb=s</b> or <b>--keep-old-breakpoints-before=s</b>, and</p>
+
+<p><b>-kba=s</b> or <b>--keep-old-breakpoints-after=s</b></p>
+
+<p>These parameters are each followed by a quoted string, <b>s</b>, containing a list of token types (separated only by spaces). No more than one of each of these parameters should be specified, because repeating a command-line parameter always overwrites the previous one before perltidy ever sees it.</p>
+
+<p>For example, -kbb='=>' means that if an input line begins with a '=>' then the output script should also have a line break before that token.</p>
+
+<p>For example, given the script:</p>
+
+<pre><code> method 'foo'
+ => [ Int, Int ]
+ => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
+ # perltidy [default]
+ method 'foo' => [ Int, Int ] => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
+ # perltidy -kbb='=>'
+ method 'foo'
+ => [ Int, Int ]
+ => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };</code></pre>
+
</dd>
<dt id="iob---ignore-old-breakpoints"><b>-iob</b>, <b>--ignore-old-breakpoints</b></dt>
<dd>
-<p>Use this flag to tell perltidy to ignore existing line breaks to the maximum extent possible. This will tend to produce the longest possible containers, regardless of type, which do not exceed the line length limit.</p>
+<p>Use this flag to tell perltidy to ignore existing line breaks to the maximum extent possible. This will tend to produce the longest possible containers, regardless of type, which do not exceed the line length limit. But please note that this parameter has priority over all other parameters requesting that certain old breakpoints be kept.</p>
</dd>
<dt id="kis---keep-interior-semicolons"><b>-kis</b>, <b>--keep-interior-semicolons</b></dt>
<p><b>--file-size-order</b> or <b>-fso</b> will cause files to be processed in order of increasing size, when multiple files are being processed. This is useful during program development, when large numbers of files with varying sizes are processed, because it can reduce virtual memory usage.</p>
+<p><b>--maximum-file-size-mb=n</b> or <b>-maxfs=n</b> specifies the maximum file size in megabytes that perltidy will attempt to format. This parameter is provided to avoid causing system problems by accidentally attempting to format an extremely large data file. Most perl scripts are less than about 2 MB in size. The integer <b>n</b> has a default value of 10, so perltidy will skip formatting files which have a size greater than 10 MB. The command to increase the limit to 20 MB for example would be</p>
+
+<pre><code> perltidy -maxfs=20</code></pre>
+
+<p>This only applies to files specified by filename on the command line.</p>
+
+<p><b>--maximum-level-errors=n</b> or <b>-maxle=n</b> specifies the maximum number of indentation level errors are allowed before perltidy skips formatting and just outputs a file verbatim. The default is <b>n=1</b>. This means that if the final indentation of a script differs from the starting indentation by more than 1 levels, the file will be output verbatim. To avoid formatting if there are any indentation level errors use -maxle=0. To skip this check you can either set n equal to a large number, such as <b>n=100</b>, or set <b>n=-1</b>.</p>
+
+<p>For example, the following script has level error of 3 and will be output verbatim</p>
+
+<pre><code> Input and default output:
+ {{{
+
+
+ perltidy -maxle=100
+ {
+ {
+ {</code></pre>
+
+<p><b>--maximum-unexpected-errors=n</b> or <b>-maxue=n</b> specifies the maximum number of unexpected tokenization errors are allowed before formatting is skipped and a script is output verbatim. The intention is to avoid accidentally formatting a non-perl script, such as an html file for example. This check can be turned off by setting <b>n=0</b>.</p>
+
+<p>A recommended value is <b>n=3</b>. However, the default is <b>n=0</b> (skip this check) to avoid causing problems with scripts which have extended syntaxes.</p>
+
<p><b>-DEBUG</b> will write a file with extension <i>.DEBUG</i> for each input file showing the tokenization of all lines of code.</p>
</dd>
<h1 id="VERSION">VERSION</h1>
-<p>This man page documents perltidy version 20201001.01</p>
+<p>This man page documents perltidy version 20201001.02</p>
<h1 id="BUG-REPORTS">BUG REPORTS</h1>
$add_option->( 'break-at-old-semicolon-breakpoints', 'bos', '!' );
$add_option->( 'break-at-old-ternary-breakpoints', 'bot', '!' );
$add_option->( 'break-at-old-attribute-breakpoints', 'boa', '!' );
+ $add_option->( 'keep-old-breakpoints-before', 'kbb', '=s' );
+ $add_option->( 'keep-old-breakpoints-after', 'kba', '=s' );
$add_option->( 'ignore-old-breakpoints', 'iob', '!' );
########################################
%right_bond_strength,
%left_bond_strength,
+ # Hashes for -kbb=s and -kba=s
+ %keep_break_before_type,
+ %keep_break_after_type,
+
# Initialized in check_options, modified by prepare_cuddled_block_types:
%want_one_line_block,
_save_logfile_ => $i++,
_maximum_level_ => $i++,
+ _rKrange_code_without_comments_ => $i++,
+ _rbreak_before_Kfirst_ => $i++,
+ _rbreak_after_Klast_ => $i++,
+
};
# Array index names for _this_batch_ (in above list)
$self->[_rspecial_side_comment_type_] = {};
$self->[_maximum_level_] = 0;
+ $self->[_rKrange_code_without_comments_] = [];
+ $self->[_rbreak_before_Kfirst_] = {};
+ $self->[_rbreak_after_Klast_] = {};
+
# This flag will be updated later by a call to get_save_logfile()
$self->[_save_logfile_] = defined($logger_object);
'?' => ':',
);
- if ( $rOpts->{'ignore-old-breakpoints'} ) {
+ # note any requested old line breaks to keep
+ %keep_break_before_type = ();
+ %keep_break_after_type = ();
+ if ( !$rOpts->{'ignore-old-breakpoints'} ) {
+
+ # FIXME: could check for valid types here.
+ # Invalid types are harmless but probably not intended.
+ my @types;
+ @types = ( split_words( $rOpts->{'keep-old-breakpoints-before'} ) );
+ @keep_break_before_type{@types} = (1) x scalar(@types);
+ @types = ( split_words( $rOpts->{'keep-old-breakpoints-after'} ) );
+ @keep_break_after_type{@types} = (1) x scalar(@types);
+ }
+ else {
if ( $rOpts->{'break-at-old-method-breakpoints'} ) {
Warn("Conflicting parameters: -iob and -bom; -bom will be ignored\n"
);
Warn("Conflicting parameters: -iob and -bos; -bos will be ignored\n"
);
}
+ if ( $rOpts->{'keep-old-breakpoints-before'} ) {
+ Warn("Conflicting parameters: -iob and -kbb; -kbb will be ignored\n"
+ );
+ }
+ if ( $rOpts->{'keep-old-breakpoints-after'} ) {
+ Warn("Conflicting parameters: -iob and -kba; -kba will be ignored\n"
+ );
+ }
# Note: there are additional parameters that can be made inactive by
# -iob, but they are on by default so we would generate excessive
# remains fixed for the rest of this iteration.
$self->respace_tokens();
+ $self->keep_old_line_breaks();
+
# Implement any welding needed for the -wn or -cb options
$self->weld_containers();
my $rLL = $self->[_rLL_];
my $Klimit = $self->[_Klimit_];
my $rlines = $self->[_rlines_];
+ my @Krange_code_without_comments;
# Re-construct the arrays of tokens associated with the original input lines
# since they have probably changed due to inserting and deleting blanks
$Kfirst = $K_array[0];
$Klast = $K_array[-1];
$Klast_out = $Klast;
+
+ # Save ranges of non-comment code. This will be used by
+ # sub keep_old_line_breaks.
+ if ( defined($Kfirst) && $rLL->[$Kfirst]->[_TYPE_] ne '#' ) {
+ push @Krange_code_without_comments, [ $Kfirst, $Klast ];
+ }
}
# It is only safe to trim the actual line text if the input
Fault("unexpected tokens at end of file when reconstructing lines");
}
+ $self->[_rKrange_code_without_comments_] = \@Krange_code_without_comments;
return;
}
+sub keep_old_line_breaks {
+
+ # Called once per file to find and mark any old line breaks which
+ # should be kept. We will be translating the input hashes into
+ # token indexes.
+ my ($self) = @_;
+
+ return unless ( %keep_break_before_type || %keep_break_after_type );
+
+ my $rLL = $self->[_rLL_];
+
+ my $rKrange_code_without_comments =
+ $self->[_rKrange_code_without_comments_];
+ my $rbreak_before_Kfirst = $self->[_rbreak_before_Kfirst_];
+ my $rbreak_after_Klast = $self->[_rbreak_after_Klast_];
+
+ foreach my $item ( @{$rKrange_code_without_comments} ) {
+ my ( $Kfirst, $Klast ) = @{$item};
+
+ my $typeb = $rLL->[$Kfirst]->[_TYPE_];
+ if ( $keep_break_before_type{$typeb} ) {
+ $rbreak_before_Kfirst->{$Kfirst} = 1;
+ }
+
+ my $typee = $rLL->[$Klast]->[_TYPE_];
+ if ( $keep_break_after_type{$typee} ) {
+ $rbreak_after_Klast->{$Klast} = 1;
+ }
+ }
+ return;
+}
+
sub weld_containers {
# Called once per file to do any welding operations requested by --weld*
# initialize closure variables
my $rK_range = $line_of_tokens->{_rK_range};
( $K_first, $K_last ) = @{$rK_range};
+
+ # remember original starting index in case it changes
+ my $K_first_true= $K_first;
+
$rLL = $self->[_rLL_];
$radjusted_levels = $self->[_radjusted_levels_];
$self->end_batch();
}
+ # Keep any requested breaks before this line. Note that we have to
+ # use the original K_first because it may have been reduced above
+ # to add a blank.
+ if ( $self->[_rbreak_before_Kfirst_]->{$K_first_true} ) {
+ destroy_one_line_block();
+ $self->end_batch();
+ }
+
# loop to process the tokens one-by-one
# We do not want a leading blank if the previous batch just got output
# if we are instructed to keep all old line breaks
|| !$rOpts->{'delete-old-newlines'}
+ # we have a request to keep a break after this line
+ || $self->[_rbreak_after_Klast_]->{$K_last}
+
# if this is a line of the form 'use overload'. A break here
# in the input file is a good break because it will allow
# the operators which follow to be formatted well. Without
# Set severe error flag if the level error is greater than 1.
# The formatter can function for any level error but it is probably
# best not to attempt formatting for a high level error.
- if ( $level_diff > $maxle ) {
+ if ( $maxle >= 0 && $level_diff > $maxle ) {
$severe_error = 1;
warning(<<EOM);
-Formatting will be skipped because level error '$level_diff' exceeds -maxle=$maxle; use -maxle=0 to force formatting
+Formatting will be skipped because level error '$level_diff' exceeds -maxle=$maxle; use -maxle=-1 to force formatting
EOM
}
}
=over 4
+=item B<implement request RT #133649, added parameters -kbb=s and -kba=s>
+
+These parameters request that old breakpoints be kept before or after
+selected token types. For example, -kbb='=>' means that newlines before
+fat commas should be kept. This was added 4 Nov 2020.
+
=item B<added parameters -maxue=n and maxle=n>
These parameters had tentatively been hardwired in the tokenizer.
--- /dev/null
+$this_env = join( "",
+ $before, $closures, $contents, ( $defenv ? '' : &balance_tags() ),
+ $reopens );
+$_ = $after;
+
+method 'foo1' => [ Int, Int ] => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+};
+
+method 'foo2' => [ Int, Int ] => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+};
+
--- /dev/null
+$this_env = join(
+ "", $before, $closures
+ , $contents
+ , ( $defenv ? '' : &balance_tags() )
+ , $reopens
+);
+$_ = $after;
+
+method 'foo1'
+ => [ Int, Int ]
+ => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
+method 'foo2' =>
+ [ Int, Int ] =>
+ sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
--- /dev/null
+$this_env = join("", $before, $closures
+ , $contents
+ , ($defenv ? '': &balance_tags())
+ , $reopens ); $_ = $after;
+
+method 'foo1'
+ => [ Int, Int ]
+ => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
+method 'foo2'=>
+ [ Int, Int ]=>
+ sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
--- /dev/null
+-kbb='=> ,' -kba='=>'
../snippets9.t rt98902.def
../snippets9.t rt98902.rt98902
../snippets9.t rt99961.def
+../snippets22.t kba1.def
+../snippets22.t kba1.kba1
#12 mangle4.mangle
#13 extrude5.def
#14 extrude5.extrude
+#15 kba1.def
+#16 kba1.kba1
# To locate test #13 you can search for its name or the string '#13'
'def' => "",
'extrude' => "--extrude",
'here_long' => "-l=33",
- 'mangle' => "--mangle",
- 'xci1' => "-xci",
- 'xci2' => "-pbp -nst -nse -xci",
+ 'kba1' => <<'----------',
+-kbb='=> ,' -kba='=>'
+----------
+ 'mangle' => "--mangle",
+ 'xci1' => "-xci",
+ 'xci2' => "-pbp -nst -nse -xci",
};
############################
FROM logins WHERE username='$user'
END_OF_SELECT
+----------
+
+ 'kba1' => <<'----------',
+$this_env = join("", $before, $closures
+ , $contents
+ , ($defenv ? '': &balance_tags())
+ , $reopens ); $_ = $after;
+
+method 'foo1'
+ => [ Int, Int ]
+ => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
+method 'foo2'=>
+ [ Int, Int ]=>
+ sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
----------
'mangle4' => <<'----------',
;
#14...........
},
+
+ 'kba1.def' => {
+ source => "kba1",
+ params => "def",
+ expect => <<'#15...........',
+$this_env = join( "",
+ $before, $closures, $contents, ( $defenv ? '' : &balance_tags() ),
+ $reopens );
+$_ = $after;
+
+method 'foo1' => [ Int, Int ] => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+};
+
+method 'foo2' => [ Int, Int ] => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+};
+
+#15...........
+ },
+
+ 'kba1.kba1' => {
+ source => "kba1",
+ params => "kba1",
+ expect => <<'#16...........',
+$this_env = join(
+ "", $before, $closures
+ , $contents
+ , ( $defenv ? '' : &balance_tags() )
+ , $reopens
+);
+$_ = $after;
+
+method 'foo1'
+ => [ Int, Int ]
+ => sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
+method 'foo2' =>
+ [ Int, Int ] =>
+ sub {
+ my ( $self, $x, $y ) = ( shift, @_ );
+ ...;
+ };
+
+#16...........
+ },
};
my $ntests = 0 + keys %{$rtests};