Openbox:Pipemenus:Dirsmenu

From Openbox

(Difference between revisions)
Jump to: navigation, search
(It now uses Perl's File::Find instead of GNU find and added some more configuration options)
Line 1: Line 1:
 
[[Image:Dirsmenuv2.jpg|thumb|right]]
 
[[Image:Dirsmenuv2.jpg|thumb|right]]
  
Another pipe menu for recursive directory listing. I tried to keep the code as simple and short as possible. It uses ''find'' to get the directories and the other 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'').
+
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 the other 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'').
  
 
== dirsmenu: ==
 
== dirsmenu: ==

Revision as of 11:46, 20 September 2014

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 the other 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).

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;

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

# set default starting directory
our $base_dir = '/';
# your file browser
our $browser = 'Thunar';
# 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
$base_dir =~ s/&/&/g;
$base_dir =~ s/"/"/g;
$base_dir =~ s/\$/$/g;
$base_dir =~ s/</</g;
$base_dir =~ s/=/=/g;
$base_dir =~ s/>/>/g;
$base_dir =~ s/\\/\/g;
# 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>$browser $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
	$_ =~ s/&/&/g;
	$_ =~ s/"/"/g;
	$_ =~ s/\$/$/g;
	$_ =~ s/</</g;
	$_ =~ s/=/=/g;
	$_ =~ s/>/>/g;
	$_ =~ s/\\/\/g;
	# 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
    $_ =~ s/&/&/g;
    $_ =~ s/"/"/g;
    $_ =~ s/\$/$/g;
    $_ =~ s/</</g;
    $_ =~ s/=/=/g;
    $_ =~ s/>/>/g;
    $_ =~ s/\\/\/g;
    # 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>";
}