File Coverage

blib/lib/Term/Table/Util.pm
Criterion Covered Total %
statement 38 41 92.6
branch 9 18 50.0
condition 2 9 22.2
subroutine 11 11 100.0
pod 0 1 0.0
total 60 80 75.0


line stmt bran cond sub pod time code
1             package Term::Table::Util;
2 8     8   139697 use strict;
  8         20  
  8         324  
3 8     8   43 use warnings;
  8         16  
  8         397  
4              
5 8     8   50 use List::Util qw/max/;
  8         18  
  8         852  
6 8     8   40 use Config qw/%Config/;
  8         15  
  8         603  
7              
8             our $VERSION = '0.028';
9              
10 8     8   50 use base 'Exporter';
  8         27  
  8         2125  
11             our @EXPORT_OK = qw/term_size USE_GCS USE_TERM_READKEY USE_TERM_SIZE_ANY uni_length/;
12              
13             sub DEFAULT_SIZE() { 80 }
14              
15             my @IO;
16             my @TIO;
17             BEGIN {
18 8     8   77 for my $fh (\*STDOUT, \*STDERR, \*STDIN) {
19 24 50       508 open(my $io, '>&', $fh) or next;
20 24         42 push @IO => $io;
21 24 50       9268 push @TIO => $io if -t $io;
22             }
23             }
24              
25             sub try(&) {
26 24     24 0 49 my $code = shift;
27 24         215 local ($@, $?, $!);
28 24         48 my $ok = eval { $code->(); 1 };
  24         63  
  15         353087  
29 24         513 my $err = $@;
30 24         167 return ($ok, $err);
31             }
32              
33             my ($tsa) = try { require Term::Size::Any; Term::Size::Any->import('chars') };
34             my ($trk) = try { require Term::ReadKey };
35             $trk &&= Term::ReadKey->can('GetTerminalSize');
36              
37             if ($tsa) {
38             *USE_TERM_READKEY = sub() { 0 };
39             *USE_TERM_SIZE_ANY = sub() { 1 };
40             *_term_size = sub {
41 2 50   2   5 my $size = max map { chars($_) || DEFAULT_SIZE } @IO;
  6         55  
42              
43 2 50 33     29 if (!$size || $size < DEFAULT_SIZE) {
44 0 0 0     0 return $ENV{COLUMNS} if $ENV{COLUMNS} && $ENV{COLUMNS} > DEFAULT_SIZE;
45 0         0 return DEFAULT_SIZE;
46             }
47              
48 2         5 return $size;
49             };
50             }
51             elsif ($trk && @TIO) {
52             *USE_TERM_READKEY = sub() { 1 };
53             *USE_TERM_SIZE_ANY = sub() { 0 };
54             *_term_size = sub {
55             my @totals;
56             try {
57             my @warnings;
58             {
59             local $SIG{__WARN__} = sub { push @warnings => @_ };
60             for my $io (@TIO) {
61             my ($total) = Term::ReadKey::GetTerminalSize($io);
62             push @totals => $total;
63             }
64             }
65             @warnings = grep { $_ !~ m/Unable to get Terminal Size/ } @warnings;
66             warn @warnings if @warnings;
67             };
68             my $total = @totals ? max(@totals) : 0;
69              
70             if (!$total || $total < DEFAULT_SIZE) {
71             return $ENV{COLUMNS} if $ENV{COLUMNS} && $ENV{COLUMNS} > DEFAULT_SIZE;
72             return DEFAULT_SIZE;
73             }
74              
75             return $total;
76             };
77             }
78             else {
79             *USE_TERM_READKEY = sub() { 0 };
80             *USE_TERM_SIZE_ANY = sub() { 0 };
81             *term_size = sub {
82 2 100   2   162764 return $ENV{TABLE_TERM_SIZE} if $ENV{TABLE_TERM_SIZE};
83 1 50 33     15 return $ENV{COLUMNS} if $ENV{COLUMNS} && $ENV{COLUMNS} > DEFAULT_SIZE;
84 0           return DEFAULT_SIZE;
85             };
86             }
87              
88             if (USE_TERM_READKEY() || USE_TERM_SIZE_ANY()) {
89             if (index($Config{sig_name}, 'WINCH') >= 0) {
90             my $changed = 0;
91             my $polled = -1;
92             $SIG{WINCH} = sub { $changed++ };
93              
94             my $size;
95             *term_size = sub {
96 2 50   2   201413 return $ENV{TABLE_TERM_SIZE} if $ENV{TABLE_TERM_SIZE};
97              
98 2 50       6 unless ($changed == $polled) {
99 2         3 $polled = $changed;
100 2         7 $size = _term_size();
101             }
102              
103 2         5 return $size;
104             }
105             }
106             else {
107             *term_size = sub {
108             return $ENV{TABLE_TERM_SIZE} if $ENV{TABLE_TERM_SIZE};
109             _term_size();
110             };
111             }
112             }
113              
114             my ($gcs, $err) = try { require Unicode::GCString };
115              
116             if ($gcs) {
117             *USE_GCS = sub() { 1 };
118 3406     3406   6047 *uni_length = sub { Unicode::GCString->new($_[0])->columns };
119             }
120             else {
121             *USE_GCS = sub() { 0 };
122             *uni_length = sub { length($_[0]) };
123             }
124              
125             1;
126              
127             __END__