diff --git a/nowrap b/nowrap index cfd5243..8856688 100755 --- a/nowrap +++ b/nowrap @@ -75,7 +75,7 @@ use Text::CharWidth::PurePerl qw(mbwidth); use open ':locale'; my $TABSTOP = 8; -my $ESCAPE_SEQUENCE_PATTERN = qr/(\e\[\d*(;\d+)*m)/; +my $ESCAPE_SEQUENCE_PATTERN = qr/(\e(\[\d*(;\d+)*m|\e*[ \t]*[^\e]))/; my $columns = `tput cols`; chomp($columns); @@ -138,15 +138,20 @@ while (my $line = <>) { $cursor += $TABSTOP - ($cursor % $TABSTOP); ++$nchars; } - elsif ($c eq "\e") { + elsif ($c eq "\e" && substr($line, $i, length($line) - $i) =~ m/$ESCAPE_SEQUENCE_PATTERN/) { # handle escape sequences - substr($line, $i, length($line) - $i) =~ m/$ESCAPE_SEQUENCE_PATTERN/; die "\$` should be empty, stopped" if $`; my $esc_seq = $1; # skip over the sequence $i += length($esc_seq) - 1; # -1 b/c of ++$i at loop top $nchars += length($esc_seq); - # $cursor is unchanged + + my $tabCount = () = $esc_seq =~ /\t/g; + if ($tabCount > 0) { + # In contrast to spaces, tabs within the escape sequence are not + # swallowed. + $cursor += ($tabCount * $TABSTOP) - ($cursor % $TABSTOP); + } $append = $esc_seq; } diff --git a/script/nowrap.pl b/script/nowrap.pl index 02aae5a..9e63050 100755 --- a/script/nowrap.pl +++ b/script/nowrap.pl @@ -29,7 +29,7 @@ use open ':locale'; my $TABSTOP = 8; -my $ESCAPE_SEQUENCE_PATTERN = qr/(\e\[\d*(;\d+)*m)/; +my $ESCAPE_SEQUENCE_PATTERN = qr/(\e(\[\d*(;\d+)*m|\e*[ \t]*[^\e]))/; my $columns = `tput cols`; chomp($columns); @@ -92,15 +92,20 @@ $cursor += $TABSTOP - ($cursor % $TABSTOP); ++$nchars; } - elsif ($c eq "\e") { + elsif ($c eq "\e" && substr($line, $i, length($line) - $i) =~ m/$ESCAPE_SEQUENCE_PATTERN/) { # handle escape sequences - substr($line, $i, length($line) - $i) =~ m/$ESCAPE_SEQUENCE_PATTERN/; die "\$` should be empty, stopped" if $`; my $esc_seq = $1; # skip over the sequence $i += length($esc_seq) - 1; # -1 b/c of ++$i at loop top $nchars += length($esc_seq); - # $cursor is unchanged + + my $tabCount = () = $esc_seq =~ /\t/g; + if ($tabCount > 0) { + # In contrast to spaces, tabs within the escape sequence are not + # swallowed. + $cursor += ($tabCount * $TABSTOP) - ($cursor % $TABSTOP); + } $append = $esc_seq; } diff --git a/tests/tcescape.expected b/tests/tcescape.expected new file mode 100644 index 0000000..e1f5df4 --- /dev/null +++ b/tests/tcescape.expected @@ -0,0 +1,12 @@ +ordinary t +thisboldte +singleescap +twoescapeocc +adjacentesc +adjacentesc +after single +after manysp +after tab +after +endescape +endescap diff --git a/tests/tcescape.in b/tests/tcescape.in new file mode 100644 index 0000000..8e71e96 --- /dev/null +++ b/tests/tcescape.in @@ -0,0 +1,12 @@ +ordinary text +thisboldtext +singleescape +twoescapeoccurrences +adjacentescapes +adjacentescapes +after singlespace +after manyspaces +after tabulator +after tabulators +endescape +endescap diff --git a/tests/test.sh b/tests/test.sh index c5e8ecb..42840df 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -85,6 +85,9 @@ do_test tc6 --columns=72 # ==== case 7: UTF-8-demo.txt @ 40 columns do_test tc7 --columns=40 +# ==== escape characters and colored text +do_test tcescape --columns=10 + # ==== wrap do_test tcwrap --wrap --columns=10 do_test tcindent-plain --wrap --indent-string '> ' --columns=10