Skip to content

Instantly share code, notes, and snippets.

@nkh
Created September 6, 2018 21:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nkh/f12e5116a9ecbba29c63317299975a08 to your computer and use it in GitHub Desktop.
Save nkh/f12e5116a9ecbba29c63317299975a08 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use strict ;
use warnings ;
use File::Spec ;
use Term::ANSIColor ;
use File::LsColor qw(ls_color_custom) ;
use Getopt::Long ;
my $values = 0 ;
die 'Error parsing options!'unless
GetOptions
(
'v|values' => \$values,
'h|help' => \&display_help,
) ;
sub display_help
{
print <<'EOH' ;
Options:
'v|values' Expect values after path
examples:
EOH
exit ;
}
my $ansi = qr/\e\[(?:[0-9;]*)[mK]/ ;
while (<>)
{
chomp ;
#separate path from rest of line
my ($path, $rest, @rest) = split( /(?<!:) : (?!:)/x ) ;
if($values && defined $rest)
{
$rest = ':' . $rest ;
$rest .= ':' . join(':', @rest) if @rest ;
}
else
{
$rest = '' ;
}
$path =~ s/$ansi//g ;
my (undef, $directories, $file_name) = File::Spec->splitpath($path) ;
my $colored_path = ls_color_custom($ENV{LS_COLORS}, $directories) ;
if (-d $path)
{
$path .= '/' unless /\/$/ ;
print ls_color_custom($ENV{LS_COLORS}, $path) . color('reset') . "$rest\n" ;
}
else
{
my $f = ls_color_custom($ENV{LS_COLORS}, $path) ;
(my $color) = $f =~ /($ansi)/ ;
$color //= '' ;
print "$colored_path$color$file_name" . color('reset') . "$rest\n" ;
}
}
#!/usr/bin/env perl
use strict ;
use warnings ;
use File::Spec ;
use Data::TreeDumper ;
use Term::ANSIColor ;
use Getopt::Long ;
my $values = 0 ;
die 'Error parsing options!'unless
GetOptions
(
't|title=s' => \my $title,
'a|ansi_lines' => \my $lines,
'v|values' => \$values,
'no_color' => \my $no_color,
'h|help' => \&display_help,
) ;
sub display_help
{
print <<'EOH' ;
Options:
't|title=s' Set the tree title
'v|values' keep nd display values, the input is in the form
path/path/path: value
multiple values can be associated with the same path
'no_color' remove color from input
examples:
grep -n -r --color=always regex path | ... | ./tw -v -t matches
find path | grep -v '.git' | ./tw -t tree
EOH
exit ;
}
my (%tree, $tree_position, %tree_directories) ;
my $ansi = qr/\e\[(?:[0-9;]*)m/ ;
while (<>)
{
chomp ;
s/$ansi//g if $no_color ;
my ($color_path, $path, $rest) ;
#separate path from rest of line
($path, $rest, my @rest) = split( /(?<!:) : (?!:)/x ) ; ;
$rest .= ':' . join(':', @rest) if @rest ;
($color_path) = $path =~ /^($ansi)*/ ;
$color_path //= '' ;
$rest //= '' ;
my (undef, $directories, $file_name) = File::Spec->splitpath($path) ;
if(defined $tree_directories{$directories} && 'HASH' eq ref $tree_directories{$directories})
{
$tree_position = $tree_directories{$directories} ;
}
else
{
$tree_position = \%tree ;
my @dirs = File::Spec->splitdir($directories) ;
delete $dirs[-1] ;
for (@dirs)
{
next if $_ eq '' ;
$_ = $color_path.$_.color('reset') ;
$tree_position->{$_} = {} unless exists $tree_position->{$_} ;
$tree_position->{$_} = {} if('HASH' ne ref $tree_position->{$_}) ;
$tree_position = $tree_position->{$_} ;
}
}
$tree_directories{$directories} = $tree_position ;
$file_name =~ s/$ansi$// ;
if ($file_name ne '')
{
my $element_name = $color_path.$file_name.color('reset') ;
if (exists $tree_position->{$element_name} && $values)
{
# keep list of values
if ( '' eq ref($tree_position->{$element_name}) )
{
$tree_position->{$element_name}
= [ $tree_position->{$element_name} ] ;
}
push @{ $tree_position->{$element_name} }, $rest.color('reset') ;
}
else
{
$tree_position->{$element_name} = $rest.color('reset')
}
}
}
#todo: sort directories first
print DumpTree \%tree, $title || 'tw: use -t to set title',
DISPLAY_ADDRESS => 0,
DISPLAY_NO_VALUE => !$values,
USE_ASCII => !$lines,
NO_NO_ELEMENTS => 1 ;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment