The default is not to do this, indicated by B<-nicb>.
+
+=item B<-nib>, B<--non-indenting-braces>
+
+If this flag is set, perltidy will look for opening block braces which are
+followed by a special side comment, which is B<#<<<> by default. If found, the
+code between this opening brace and its corresponding closing brace will not be
+given the normal extra indentation level. As a simple example,
+
+ perltidy -nib:
+
+ { #<<<
+ print "hello world\n";
+ }
+
+This might be useful, for example, to keep large sections of code from
+moving to the right when placed in a closure.
+
+Only the opening brace needs to be marked, and nested braces can be marked.
+The special side comment can be changed with the next parameter.
+
+
+=item B<-nibp=s>, B<--non-indenting-brace-prefix=s>
+
+The B<-nibp=string> parameter may be used to change the marker for
+non-indenting braces. The default is equivalent to -nibp='#<<<'. The string
+that you enter must begin with a # and should be in quotes as necessary to get
+past the command shell of your system. This string is the leading text of a
+regex pattern that is constructed by appending pre-pending a '^', so you must
+also include backslashes for characters to be taken literally rather than as
+patterns.
+
+For example, to match the side comment '#++', the parameter would be
+
+ -nibp='#\+\+'
+
+Note that the default string is the same as the string for starting a
+B<format-skipping> section, but it is for a side-comment rather than a block
+comment.
+
=item B<-olq>, B<--outdent-long-quotes>
When B<-olq> is set, lines which is a quoted string longer than the
$format_skipping_pattern_begin
$format_skipping_pattern_end
+ $non_indenting_brace_pattern
+
$bli_pattern
$block_brace_vertical_tightness_pattern
};
-###################################################################
-# Section 2: Global variables which relate to an individual script.
-# These are work arrays for the current batch of tokens.
-###################################################################
+#########################################################
+# Section 2: Work arrays for the current batch of tokens.
+#########################################################
use vars qw{
$max_index_to_go
return $weld_len;
}
+sub adjust_indentation_levels {
+
+ my ($self) = @_;
+
+ # Set adjusted levels for any non-indenting braces
+ $self->non_indenting_braces();
+
+ # Set adjusted levels for the whitespace cycle option
+ $self->whitespace_cycle_adjustment();
+
+}
+
+sub non_indenting_braces {
+
+ # remove indentation within marked braces if requested
+ my ($self) = @_;
+ return unless ( $rOpts->{'non-indenting-braces'} );
+
+ my $rLL = $self->[_rLL_];
+ return unless ( defined($rLL) && @{$rLL} );
+
+ my $radjusted_levels;
+ my $Kmax = @{$rLL} - 1;
+ my @seqno_stack;
+
+ my $is_non_indenting_brace = sub {
+ my ($KK) = @_;
+ my $token = $rLL->[$KK]->[_TOKEN_];
+ my $block_type = $rLL->[$KK]->[_BLOCK_TYPE_];
+ return unless ( $token eq '{' && $block_type );
+ my $line_index = $rLL->[$KK]->[_LINE_INDEX_];
+ my $K_sc = $self->K_next_nonblank($KK);
+ return unless defined($K_sc);
+ my $line_index_sc = $rLL->[$K_sc]->[_LINE_INDEX_];
+ return unless ( $line_index_sc == $line_index );
+ my $type_sc = $rLL->[$K_sc]->[_TYPE_];
+ return unless ( $type_sc eq '#' );
+ my $token_sc = $rLL->[$K_sc]->[_TOKEN_];
+ return ( $token_sc =~ /$non_indenting_brace_pattern/ );
+ };
+
+ foreach my $KK ( 0 .. $Kmax ) {
+ my $seqno = $rLL->[$KK]->[_TYPE_SEQUENCE_];
+ my $level_abs = $rLL->[$KK]->[_LEVEL_];
+ my $level = $level_abs;
+ my $num = @seqno_stack;
+ if ($seqno) {
+ my $token = $rLL->[$KK]->[_TOKEN_];
+ if ( $token eq '{' && $is_non_indenting_brace->($KK) ) {
+ push @seqno_stack, $seqno;
+ }
+ if ( $token eq '}' && @seqno_stack && $seqno_stack[-1] == $seqno ) {
+ pop @seqno_stack;
+ $num -= 1;
+ }
+ }
+ if ($num) { $level -= $num }
+ $radjusted_levels->[$KK] = $level;
+ }
+ $self->[_radjusted_levels_] = $radjusted_levels;
+ return;
+}
+
sub whitespace_cycle_adjustment {
my $self = shift;
my $rLL = $self->[_rLL_];
return unless ( defined($rLL) && @{$rLL} );
- my $radjusted_levels;
+ my $radjusted_levels = $self->[_radjusted_levels_];
+
my $rOpts_whitespace_cycle = $rOpts->{'whitespace-cycle'};
if ( $rOpts_whitespace_cycle && $rOpts_whitespace_cycle > 0 ) {
+
+ my $Kmax = @{$rLL} - 1;
+
+ # We have to start with any existing adjustments
+ my $adjusted_levels_defined =
+ defined($radjusted_levels) && @{$radjusted_levels} == @{$rLL};
+ if ( !$adjusted_levels_defined ) {
+ foreach my $KK ( 0 .. $Kmax ) {
+ $radjusted_levels->[$KK] = $rLL->[$KK]->[_LEVEL_];
+ }
+ }
+
my $whitespace_last_level = -1;
my @whitespace_level_stack = ();
my $last_nonblank_type = 'b';
my $last_nonblank_token = '';
- my $Kmax = @{$rLL} - 1;
foreach my $KK ( 0 .. $Kmax ) {
- my $level_abs = $rLL->[$KK]->[_LEVEL_];
+ my $level_abs = $radjusted_levels->[$KK]; ##$rLL->[$KK]->[_LEVEL_];
my $level = $level_abs;
if ( $level_abs < $whitespace_last_level ) {
pop(@whitespace_level_stack);
# Locate small nested blocks which should not be broken
$self->mark_short_nested_blocks();
- # Set adjusted levels for the whitespace cycle option
- $self->whitespace_cycle_adjustment();
+ $self->adjust_indentation_levels();
# Adjust continuation indentation if -bli is set
$self->bli_adjustment();
# Adjust levels if necessary to recycle whitespace:
my $level = $level_abs;
my $radjusted_levels = $self->[_radjusted_levels_];
+ my $nK = @{$rLL};
+ my $nws = @{$radjusted_levels};
if ( defined($radjusted_levels) && @{$radjusted_levels} == @{$rLL} ) {
$level = $radjusted_levels->[$Kj];
+
+ # negative levels can occure in bad files
+ if ( $level < 0 ) { $level = 0 }
}
# The continued_quote flag means that this is the first token of a
make_format_skipping_pattern( 'format-skipping-begin', '#<<<' );
$format_skipping_pattern_end =
make_format_skipping_pattern( 'format-skipping-end', '#>>>' );
+ make_non_indenting_brace_pattern();
# If closing side comments ARE selected, then we can safely
# delete old closing side comments unless closing side comment
return $pattern;
}
+sub make_non_indenting_brace_pattern {
+
+ # create the pattern used to identify static side comments
+ $non_indenting_brace_pattern = '^#<<<';
+
+ # allow the user to change it
+ if ( $rOpts->{'non-indenting-brace-prefix'} ) {
+ my $prefix = $rOpts->{'non-indenting-brace-prefix'};
+ $prefix =~ s/^\s*//;
+ if ( $prefix !~ /^#/ ) {
+ Die("ERROR: the -nibp parameter '$prefix' must begin with '#'\n");
+ }
+ my $pattern = '^' . $prefix;
+ if ( bad_pattern($pattern) ) {
+ Die(
+"ERROR: the -nibp prefix '$prefix' causes the invalid regex '$pattern'\n"
+ );
+ }
+ $non_indenting_brace_pattern = $pattern;
+ }
+ return;
+}
+
sub make_closing_side_comment_list_pattern {
# turn any input list into a regex for recognizing selected block types
my $radjusted_levels = $self->[_radjusted_levels_];
if ( defined($radjusted_levels) && @{$radjusted_levels} == @{$rLL} ) {
$level_wc = $radjusted_levels->[$Ktoken_vars];
+
+ # negative levels can occure in bad files
+ if ( $level_wc < 0 ) { $level_wc = 0 }
}
my $space_count =
$ci_level * $rOpts_continuation_indentation +
}
}
+ my $level_adj = $lev;
+ my $radjusted_levels = $self->[_radjusted_levels_];
+ if ( defined($radjusted_levels) && @{$radjusted_levels} == @{$rLL} ) {
+ $level_adj = $radjusted_levels->[$Kbeg];
+ if ( $level_adj < 0 ) { $level_adj = 0 }
+ }
+
# add any new closing side comment to the last line
if ( $closing_side_comment && $n == $n_last_line && @{$rfields} ) {
$rfields->[-1] .= " $closing_side_comment";
my $rvalign_hash = {};
$rvalign_hash->{level} = $lev;
$rvalign_hash->{level_end} = $level_end;
+ $rvalign_hash->{level_adj} = $level_adj;
$rvalign_hash->{indentation} = $indentation;
$rvalign_hash->{is_forced_break} = $forced_breakpoint || $in_comma_list;
$rvalign_hash->{outdent_long_lines} = $outdent_long_lines;