Skip to content

Instantly share code, notes, and snippets.

@tobyink
Created November 4, 2012 10:05
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 tobyink/4011150 to your computer and use it in GitHub Desktop.
Save tobyink/4011150 to your computer and use it in GitHub Desktop.
Pretty directory trees
#!/usr/bin/env perl
# This version adds pretty colours, plus command-line option processing
use 5.008;
use strict;
use warnings;
use utf8::all;
use constant {
HORIZ => "──",
SPUR_DOWN => "┬─",
VERT => "│ ",
SPUR => "├─",
SPUR_FINAL => "└─",
VERT_EMPTY => " ",
};
use Path::Class ();
use Term::ANSIColor;
use Getopt::Long qw(:config permute bundling no_ignore_case no_auto_abbrev);
my $help = <<'HELP';
Usage: dirtree [options] [directory]
If directory is ommitted, current directory is shown.
Options:
--hidden, -H show hidden files
--follow, -F follow symbolic links
--help, -h show this help
HELP
my ($hidden, $symlinks);
GetOptions(
'hidden|H' => \$hidden,
'follow|F' => \$symlinks,
'help|h' => sub { print $help and exit(1) },
);
{
my @stack;
sub draw {
my ($dir, $no_hidden, $follow_symlinks) = @_;
my @kids = sort $dir->children(no_hidden => $no_hidden);
foreach my $kid (@kids)
{
my $is_last = $kid eq $kids[-1];
my $has_kids = $kid->is_dir && $kid->children(no_hidden => $no_hidden) && ($follow_symlinks || !-l $kid);
my $shortname = $kid->is_dir ? ($kid->dir_list)[-1] : $kid->basename;
my $colour = 'bright_white';
$colour = 'bright_green' if -x $kid;
$colour = 'bright_blue' if $kid->is_dir;
$colour = 'bright_cyan' if -l $kid;
print VERT_EMPTY;
print map { $_->{is_last} ? VERT_EMPTY : VERT } @stack;
print $is_last ? SPUR_FINAL : SPUR;
print $has_kids ? SPUR_DOWN : HORIZ;
print colored(" $shortname\n", $colour);
if ($has_kids)
{
push @stack, { dir => $kid, is_last => $is_last };
draw($kid, $no_hidden, $follow_symlinks);
pop @stack;
}
}
}
}
my $dir = Path::Class::Dir->new( @ARGV?shift:() );
draw($dir, !$hidden, $symlinks);
#!/usr/bin/env perl
use 5.008;
use strict;
use warnings;
use utf8::all;
use constant {
HORIZ => "──",
SPUR_DOWN => "┬─",
VERT => "│ ",
SPUR => "├─",
SPUR_FINAL => "└─",
VERT_EMPTY => " ",
};
use Path::Class ();
{
my @stack;
sub draw
{
my ($dir, $no_hidden) = @_;
my @kids = sort $dir->children(no_hidden => $no_hidden);
foreach my $kid (@kids)
{
my $is_last = $kid eq $kids[-1];
my $has_kids = $kid->is_dir && $kid->children(no_hidden => $no_hidden);
my $shortname = $kid->is_dir ? ($kid->dir_list)[-1] : $kid->basename;
print VERT_EMPTY;
print map { $_->{is_last} ? VERT_EMPTY : VERT } @stack;
print $is_last ? SPUR_FINAL : SPUR;
print $has_kids ? SPUR_DOWN : HORIZ;
print " $shortname\n";
if ($has_kids)
{
push @stack, { dir => $kid, is_last => $is_last };
draw($kid, $no_hidden);
pop @stack;
}
}
}
}
my $dir = Path::Class::Dir->new( @ARGV?shift:() );
draw($dir, 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment