Openbox:Pipemenus:Dirsmenu
From Openbox
(Difference between revisions)
AaylaSecura (Talk | contribs) m (Fixed a minor bug (escape a literal ^ rather than beginning of string)) |
AaylaSecura (Talk | contribs) (It now uses Perl's File::Find instead of GNU find and added some more configuration options) |
||
Line 7: | Line 7: | ||
# Openbox menu to recursively list directories and files. | # Openbox menu to recursively list directories and files. | ||
use File::Basename; | 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 | # replace some special characters by their html codes | ||
− | $base_dir =~ s/&/& | + | $base_dir =~ s/&/&/g; |
− | $base_dir =~ s/"/& | + | $base_dir =~ s/"/"/g; |
− | $base_dir =~ s/\$/& | + | $base_dir =~ s/\$/$/g; |
− | $base_dir =~ s/</& | + | $base_dir =~ s/</</g; |
− | $base_dir =~ s/=/& | + | $base_dir =~ s/=/=/g; |
− | $base_dir =~ s/>/& | + | $base_dir =~ s/>/>/g; |
− | $base_dir =~ s/\\/& | + | $base_dir =~ s/\\/\/g; |
# escape special characters in bash | # escape special characters in bash | ||
$base_dir =~ s/(\ |'|`|!|\^|&|\*|\(|\)|\[|\]|\{|\}|&#..)/\\$1/g; | $base_dir =~ s/(\ |'|`|!|\^|&|\*|\(|\)|\[|\]|\{|\}|&#..)/\\$1/g; | ||
+ | |||
say "<openbox_pipe_menu>"; | say "<openbox_pipe_menu>"; | ||
Line 48: | Line 51: | ||
say "<separator />"; | 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/(\ |'|`|!|\^|&|\*|\(|\)|\[|\]|\{|\}|&#..)/\\$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; | |
− | my $ | + | $_ =~ 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 |
− | say "<item label=\"$ | + | $_ =~ s/(\ |'|`|!|\^|&|\*|\(|\)|\[|\]|\{|\}|&#..)/\\$1/g; |
− | say " <action name=\"Execute\"><execute>xdg-open $ | + | say "<item label=\"$label\">"; |
+ | say " <action name=\"Execute\"><execute>xdg-open $_ </execute></action>"; | ||
say "</item>"; | say "</item>"; | ||
} | } | ||
− | |||
− |
Revision as of 11:45, 20 September 2014
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).
#!/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/(\ |'|`|!|\^|&|\*|\(|\)|\[|\]|\{|\}|&#..)/\\$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/(\ |'|`|!|\^|&|\*|\(|\)|\[|\]|\{|\}|&#..)/\\$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/(\ |'|`|!|\^|&|\*|\(|\)|\[|\]|\{|\}|&#..)/\\$1/g; say "<item label=\"$label\">"; say " <action name=\"Execute\"><execute>xdg-open $_ </execute></action>"; say "</item>"; }