#!/usr/bin/perl
#
# This creates, dynamically, menus for fvwm95. It lists files, mostly.
# $Id: fvwm95.find,v 1.3 1997/07/12 04:32:32 ryo2 Exp ryo2 $
# Lines per menu
$MenuLines = 28;
# Include directory tree in the first menu.
# Define following line &YES if the directory tree crash fvwm95
$IncludeTree = &YES;
# Default file viewer. %s will be replaced by filename.
$viewer = 'xterm -sb -ls -T %s -e less %s';
# Start directory
$curr = $ENV{'HOME'};
# Files to ignore
@ignore = ('*.o', '#*', '*~');
# File name of .mime.types (similar format to xclass-exploror)
$mimetypes = ".smime.types";
# The rule to sort by --- Lexico, DirFirst, BySuffix
$rule = 'DirFirst';
# Default editor
unless ($editor = $ENV{'EDITOR'}) {
$editor = 'xterm -sb -ls -T %s -e vi';
}
$editor .= " %s";
$usemime = &YES;
$debug = &NO;
$FileScript = $0;
# If this script is placed in the executable path,
# use following line instead.
#($FileScript) = ($0 =~ /([^\/]+)$/);
OPT:
while (@ARGV > 0) {
$_ = shift;
/^-d/ && ($debug = &YES, next);
/^-l[\s\t]*(\S)/ && do {$1 =~ /([a-zA-OQ-Z])/ && ($fopt ="-$1"); next};
/^-v[\s\t]*(\S*)/ && do {$1 =~ /edit/ && ($usemime =&NO); next};
/^-n(\S*)/ && do {$1 && push(@primaries, "-name '$1'"); next};
/^-c\s*(\S*)/ && do {$1 && push(@primaries, "-ctime '$1'"); next};
/^-m\s*(\S*)/ && do {$1 && push(@primaries, "-mtime '$1'"); next};
/^-a\s*(\S*)/ && do {$1 && push(@primaries, "-atime '$1'"); next};
/^-u\s*(\S*)/ && do {$1 && push(@primaries, "-user $1"); next};
/^-g\s*(\S*)/ && do {$1 && push(@primaries, "-group $1"); next};
/^-p\s*(\S*)/ && do {$1 && push(@primaries, "-perm '$1'"); next};
/^-s\s*(\S*)/ && do {$1 && push(@primaries, "-size '$1'"); next};
/^-e\s*(\S*)/ && do {$1 && push(@primaries, "-newer '$1'"); next};
/^-t[\s\t]*(\S*)/ && do {$1 !~ /a/ && push(@primaries,"-type '$1'"); next};
/^-U[\s\t]*(\S*)/ && do {$1 && push(@primaries, "-nouser"); next};
/^-G[\s\t]*(\S*)/ && do {$1 && push(@primaries, "-nogroup"); next};
$curr = $_; $curr =~ s,/$,,; last;
}
# Default search directory is HOME not to search all the file system.
$curr || ($curr = $ENV{'HOME'});
$findopt_exist = join("", @primaries);
$allopt = "$fopt $curr ". join(" ", @primaries);
$debug && $findopt_exist && do {
$debstr = "( find $allopt )"; $debstr =~ s/\s+(\S)/ $1/g;
};
# Read mime.types if it exists.
open(INI, "$ENV{'HOME'}/$mimetypes") && &readMimeTypes;
if ($findopt_exist) {
$_ = `find $allopt -print`;
@fullpaths = split(/\n/);
} else {
# Get a file list.
while (<$curr/*>) { push(@fullpaths, $_); }
# Comment following line to exclude dot files.
while (<$curr/.*>) { /^$curr\/\.+$/ || push(@fullpaths, $_); }
}
foreach (@ignore) { s/\./\\\./; s/\*/\.\*/; };
LOOP: foreach (@fullpaths) {
s/^$curr\///;
-b "$curr/$_" && next;
foreach $i (@ignore) {
/^.$i$/ && next LOOP;
}
($head) = ($_ =~ /^(.)/);
# Index whether it's a directory or not.
$ftype{$_} = ((-d _) ? "1" : "2") . $head;
# Index of Suffixes
if ($head eq '.'){
# Move dot files last in case of sorting BySuffixes
$head = 'zz'; $ext = 'z' x 5; $trunk = $_;
} else {
unless (($trunk, $ext) = (/(.*)\.([^\.]+)$/)) { $trunk = $_; }
}
$fsuf{$_} = "$ext$head$ftype{$_}$trunk";
}
$MoreCount = $count = 0;
# Re-start a "Files" menu.
$buf = "\nDestroyMenu \"Files\"\n";
$buf .= "AddToMenu Files \\\n";
# Title shows the current directory that works as "cd ../".
$topdir = ($curr)? $curr : '/';
$buf .= " \"$topdir$debstr%mini-lower.xpm%\" PipeRead \"$FileScript ".
&dirname($curr) . "\"\n+ \"\" Nop\n";
# Create directory tree from current path
# Define
$dircount = $#compdir +1;
$buf_tree = ($IncludeTree)? ""
: "\nDestroyMenu \"DirTree\"\nAddToMenu DirTree \\\n".
" \"Higher Directory\" Nop\n" . "+ \"\" Nop\n";
while (@compdir > 0) {
$full = join('/', @compdir);
$i = pop(@compdir);
$full || last;
$buf_tree .= "+ \"$i %mini-ofolder.xpm%\" ".
"PipeRead \"$FileScript '$full'\"\n";
}
$buf_tree .= "+ \"/ %mini-ofolder.xpm%\" PipeRead \"$FileScript '/'\"\n";
if ($IncludeTree) {
$buf .= "$buf_tree\n\+ \"\" Nop\n"; $count += $dircount;
$buf_tree = "";
} else {
$buf .= "+ \"Jump To...%mini-ofolder.xpm%\" Popup DirTree\n";
$count++;
}
# Show the list.
foreach $file (sort $rule keys %ftype) {
# Make a new menu every $MenuLines entries or so...
$count++;
if ($count == $MenuLines) {
# If too many entries, make a new menu.
$MoreCount++;
$buf .= "+ More... Popup More$MoreCount\n\n";
$buf .= "DestroyMenu \"More$MoreCount\"\n";
$buf .= "AddToMenu More$MoreCount \"More($MoreCount)...\" Nop\n";
$buf .= "+ \"\" Nop\n";
$count = 1;
}
if (-d "$curr/$file") {
$buf .= "+ \"$file%mini-folder.xpm%\" PipeRead \"$FileScript \'$curr/$file\'\"\n";
} else {
if (-x "$curr/$file") {
# Executable files have "exec" as their menu command.
$tmp = "+ \"$file%" . (($usemime)?
("mini-run.xpm%\" Exec $curr/$file\n")
: ("mini-edit.xpm%\" Exec ". &edits("$curr/$file") ." &\n"));
} else {
# Everything else should be viewed by the default viewer.
$viewer_tmp = $viewer; $viewer_tmp =~ s,%s,$curr/$file,g;
$tmp = "+ \"$file%". (($usemime)?
("mini-doc.xpm%\" Exec $viewer_tmp&\n")
: ("mini-edit.xpm%\" Exec ". &edits("$curr/$file") ." &\n"));
}
$usemime && do {
# Execute viewer written in mime.types
foreach $i (keys %ACT) {
if ($file =~ /^$i$/) {
$act = $ACT{$i}; $act =~ s,%s,$curr/$file,g;
$tmp = "+ \"$file%$ICON{$i}%\" Exec $act &\n";
last;
}
}
};
$buf .= $tmp;
}
}
$| = 1;
print $buf_tree . $buf;
exit 0;
sub readMimeTypes {
local(@each);
while (<INI>) {
/^\s*$/ && do {undef $s_pat; undef $s_icon; undef $s_act;};
/^\s*pattern[\s\t]*=[\s\t]*(\S.*)$/i && ($s_pat = $1);
/^\s*icon[\s\t]*=[\s\t]*(\S.*)$/i && ($s_icon = $1);
/^\s*action[\s\t]*=[\s\t]*(\S.*)$/i && ($s_act = $1);
$s_pat && $s_icon && $s_act && do {
@each = split(/[\s\t]+/, $s_pat);
foreach $i (@each) {
$i =~ s/\./\\\./; $i =~ s/\*/\.\*/;
$ICON{$i} = $s_icon; $ACT{$i} = $s_act;
}
};
}
}
sub DirFirst {
$ftype{$a} cmp $ftype{$b};
}
sub BySuffix {
$fsuf{$a} cmp $fsuf{$b};
}
sub Lexico {
$a cmp $b;
}
sub dirname {
local($_) = @_;
@compdir = split(/\//);
pop(@compdir);
if ($#compdir < 1) {
@compdir = ("");
return '/';
}
join('/', @compdir);
}
sub edits {
local($path) = @_;
local($tmp);
$tmp = $editor; $tmp =~ s,%s,$path,g;
$tmp;
}
sub YES {1;}
sub NO {undef;}
syntax highlighted by Code2HTML, v. 0.9.1