Openbox:Pipemenus:Dirsmenu

From Openbox

Revision as of 16:20, 20 September 2014 by AaylaSecura (Talk | contribs)

Jump to: navigation, search
Dirsmenuv2.jpg

Another pipe menu for recursive directory listing. I tried to keep the code as simple and short as possible. It uses Perl's File::Find to get the directories and files in the current directory and lists them in alphabetic order while making each directory a submenu. It escapes special characters and prints the underscore correctly (unlike obbrowser).

You can adjust options such as starting directory, show hidden files or show '..'

dirsmenu:

#!/usr/bin/perl
# Openbox menu to recursively list directories and files.
use File::Basename;
use File::Find;
use Cwd 'abs_path';

sub say { print @_, "\n"; }
sub print_files;
sub print_dirs;
sub fix_html (\$);

##################################################################################################
########################################## CONFIGURATION #########################################
##################################################################################################

# set default starting directory
our $base_dir = '/';
# true to show hidden files and directories
our $hidden = 1;
# true to show ..
our $show_up = 0;

##################################################################################################

# path to this script needed because it calls itself to list subdirectories
our $path = abs_path $0;
# when listing subdirectories, set the starting dir accordingly
$base_dir = shift if $ARGV[0];
# replace some special characters by their html codes
fix_html $base_dir;
# escape special characters in bash
$base_dir =~ s/(\ |'|`|!|\^|&amp|\*|\(|\)|\[|\]|\{|\}|&#..)/\\$1/g;

say "<openbox_pipe_menu>";
say "<item label=\"Open in browser\">";
say " <action name=\"Execute\"><execute>xdg-open $base_dir </execute></action>";
say "</item>";
say "<separator />";

find ( { preprocess => \&print_dirs, wanted => \&print_files }, $base_dir);

say "</openbox_pipe_menu>";

##################################################################################################
########################################### SUBROUTINES ##########################################
##################################################################################################

sub print_dirs {
    my @dirs = sort grep { -d && ( !$hidden ? $_ !~ /^\./ : 1 ) && ( !$show_up ? $_ !~ /^\.\.$/ : 1 ) } @_;
    my @files = sort grep { ( not -d ) && ( !$hidden ? $_ !~ /^\./ : 1 ) } @_;
    for ( @dirs ) {
	next if $_ eq '.';
	$_ = $File::Find::dir . "/" . $_;
	# replace some special characters by their html codes
	fix_html $_;
	# replace the underscore with a double underscore in the label to prevent openbox from interpreting it as a keyboard accelerator
	( my $label = basename $_ ) =~ s/_/__/g;
	# escape special characters in bash
	$_ =~ s/(\ |'|`|!|\^|&amp|\*|\(|\)|\[|\]|\{|\}|&#..)/\\$1/g;
	say "<menu id=\"$_\" label=\"$label\" execute=\"$path $_\" />";
    }
    return @files;
}

sub print_files {
    return if $_ eq '.';
    $_ = $File::Find::dir . "/" . $_;
    # replace some special characters by their html codes
    fix_html $_;
    # replace the underscore with a double underscore in the label to prevent openbox from interpreting it as a keyboard accelerator
    ( my $label = basename $_ ) =~ s/_/__/g;
    # escape special characters in bash
    $_ =~ s/(\ |'|`|!|\^|&amp|\*|\(|\)|\[|\]|\{|\}|&#..)/\\$1/g;
    say "<item label=\"$label\">";
    say " <action name=\"Execute\"><execute>xdg-open $_ </execute></action>";
    say "</item>";
}

sub fix_html (\$) {
    my $ref = shift;
    $$ref =~ s/&/&/g;
    $$ref =~ s/"/"/g;
    $$ref =~ s/\$/$/g;
    $$ref =~ s/</</g;
    $$ref =~ s/=/=/g;
    $$ref =~ s/>/>/g;
    $$ref =~ s/\\/\/g;
}
Personal tools