use List::Util qw(min);
use DX::Class;
+our $WS;
+our $Extra = 0;
+
has ambient_indent_level => (
is => 'rwp', lazy => 1, clearer => 1, default => 0
);
sub indent_by { ' ' }
+sub max_width { 78 }
+
sub format {
my ($self, $thing) = @_;
local our $Indent_Level = $self->ambient_indent_level;
sub _format {
my ($self, $thing) = @_;
my ($as, $data) = @{blessed($thing) ? $thing->for_deparse : $thing};
- $self->${\"_format_as_${as}"}($data);
+ local $WS = ' ';
+ my $spaced = $self->${\"_format_as_${as}"}($data);#
+ if ($spaced =~ /\n/
+ or (length($spaced)
+ > ($self->max_width -
+ ((length($self->indent_by) * our $Indent_Level) + $Extra)))
+ ) {
+ local $WS = "\n";
+ local $Extra = 0;
+ return $self->${\"_format_as_${as}"}($data);
+ }
+ return $spaced;
+}
+
+sub _format_as_word_and_body {
+ my ($self, $wb) = @_;
+ my ($word, $body) = @$wb;
+ my $word_f = $self->_format_as_maybe_bareword($word).' ';
+ local $Extra = length($word_f);
+ return $word_f.$self->_format($body);
}
sub _format_indented {
my ($self, $cb) = @_;
+ return $cb->() if $WS eq ' ';
our $Indent_Level;
local $Indent_Level = $Indent_Level + 1;
my $unindented = $cb->();
sub _format_as_array {
my ($self, $members) = @_;
- join ' ', '{[', (map $self->_format($_), @$members), ']}';
+ join $WS,
+ '{[',
+ (map $self->_format_indented($self->curry::_format($_)), @$members)
+ , ']}';
}
sub _format_as_dict {
my ($self, $members) = @_;
- join ' ', '{{', (
- map +(
- $self->_format_as_maybe_bareword($_),
- $self->_format($members->{$_}),
- ), sort keys %$members
+ join $WS, '{{', (
+ map $self->_format_indented($self->curry::_format(
+ [ word_and_body => [ $_, $members->{$_} ] ],
+ )), sort keys %$members
), '}}';
}
sub _format_as_list {
my ($self, $members) = @_;
- join "\n", '{', (
+ join $WS, '{', (
map $self->_format_indented($self->curry::_format($_)), @$members
), '}';
}
sub _format_as_pairs {
my ($self, $members) = @_;
- join "\n", '{', (
- map $self->_format_indented(sub {
- $self->_format_as_maybe_bareword($_->[0])
- .' '.$self->_format($_->[1])
- }), @$members
+ join $WS, '{', (
+ map $self->_format_indented($self->curry::_format(
+ [ word_and_body => $_ ]
+ )), @$members
), '}';
}
sub _format_as_block {
my ($self, $members) = @_;
- join "\n", '{', (
- map $self->_format_indented($self->curry::_format($_)), @$members
+ join $WS, '{', (
+ join +($WS eq ' ' ? '; ' : $WS),
+ map $self->_format_indented($self->curry::_format($_)), @$members
), '}';
}