Skip to content

Commit

Permalink
One possible solution to RT#120895
Browse files Browse the repository at this point in the history
Deindents delete from the front.  Any spaces that are not
contributing to the length are deleted along with the tab
they are concealed by.

Spaces from tab explosions still get added to the end of
the remaining whitespace.  You can no longer expect
e.g. .indent(4).indent(-4) to roundtrip, but this will
consistently cause tabs to be moved leftward and deleted
when mixing spaces.

The example in the RT will work if $?TABSTOP is set to 4 first.
(We can't preserve visual consistency without requiring this.)
  • Loading branch information
skids committed Sep 24, 2015
1 parent 4653d98 commit 12db6c0
Showing 1 changed file with 19 additions and 5 deletions.
24 changes: 19 additions & 5 deletions src/core/Str.pm
Expand Up @@ -1346,15 +1346,29 @@ my class Str does Stringy { # declared in BOOTSTRAP
warn "Asked to remove $outdent spaces, but the shortest indent is $common-prefix spaces"
if $outdent > $common-prefix;

# Work backwards from the right end of the indent whitespace, removing
# Work forwards from the left end of the indent whitespace, removing
# array elements up to # (or over, in the case of tab-explosion)
# the specified outdent amount.
@lines.map({
@lines.map(-> $l {
my $pos = 0;
while $_<indent-chars> and $pos < $outdent {
$pos += $_<indent-chars>.pop.value;
while $l<indent-chars> and $pos < $outdent {
if $l<indent-chars>.shift.key eq "\t" {
$pos -= $pos % $?TABSTOP;
$pos += $?TABSTOP;
} else {
$pos++
}
}
if $l<indent-chars> and $pos % $?TABSTOP {
my $check = $?TABSTOP - $pos % $?TABSTOP;
$check = $l<indent-chars>[0..^$check].first-index({$_.key eq "\t"});
if $check.defined {
$l<indent-chars>.shift for 0..$check;
$pos -= $pos % $?TABSTOP;
$pos += $?TABSTOP;
}
}
$_<indent-chars.key.join ~ ' ' x ($pos - $outdent) ~ $_<rest>;
$l<indent-chars.key.join ~ ' ' x ($pos - $outdent) ~ $l<rest>;
}).join;
}

Expand Down

0 comments on commit 12db6c0

Please sign in to comment.