fvwm-convert-2.6: Handle "+ foo" lines correctly by not culling them.
[fvwm.git] / bin / fvwm-menu-directory.in
blob8e1ff42a4cd5ec5fae47a751268ffc8e4747b9c5
1 #!@PERL@
3 # Copyright (c) 1999-2009 Mikhael Goikhman
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 # Filter this script to pod2man to get a man page:
20 #   pod2man -c "Fvwm Utilities" fvwm-menu-directory | nroff -man | less -e
22 # To speed up the script, several optimizations were made: trying to minimize
23 # the number of additional file operations, function calls and includes.
25 #print STDERR "fvwm-menu-directory @ARGV\n";
27 use strict;
28 use Getopt::Long;
30 my $version = "@VERSION@";
32 my $name  = "MenuBrowser";  # used only with --reuse
33 my $title = "%*-40p";  # may contain specifiers %d, %p.
34 my $itemf = "%n";      # may contain specifiers %n, %t, %T, %d, %D, %s.
35 my $icont = "";
36 my $icond = "";
37 my $iconf = "";
38 my $icona = "";
39 my $home  = $ENV{'HOME'} || '/tmp';
40 my $dir   = $home;
41 my $xterm = "xterm -e";              # the X terminal program to invoke
42 my $exect = $ENV{'SHELL'} || '/bin/sh';
43 my $execf = $ENV{'EDITOR'} || "vi";  # the command to execute on plain files
44 my $execa = undef;
45 my $commt = undef;
46 my $commf = undef;
47 my $comma = undef;
48 my $all   = 0;  # whether show hidden files (like in 'ls -A')
49 my $links = 0;  # whether follow linked dirs or not
50 my $order = 5;  # -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6
51 my $reuse = 0;  # non-popup mode
52 my $wm_icons = 0;
53 my $check_subdirs = 0;  # whether check subdirs for +x permissions
54 my $special_dir_val = undef;  # which of (.. ~ /) dirs include or none
55 my $memory_for_speed = 0;
56 my $submenu_pos = " item +100 c";  # " menu +0 +0"
57 my $fvwm_user_dir = $ENV{'FVWM_USERDIR'} || "$home/.fvwm";
58 $fvwm_user_dir = $home unless -d $fvwm_user_dir;
59 my $dir_filename = "$fvwm_user_dir/.fvwm-menu-directory.dir";
60 my $change_menu_style = "";
61 my $func_name = "FuncFvwmMenuDirectory";
63 GetOptions(
64         "help|h|?"     => \&show_help,
65         "version|V"    => \&show_version,
66         "name=s"       => \$name,
67         "title=s"      => \$title,
68         "item=s"       => \$itemf,
69         "icon-title=s" => \$icont,
70         "icon-dir=s"   => \$icond,
71         "icon-file=s"  => \$iconf,
72         "icon-app=s"   => \$icona,
73         "dir=s"        => \$dir,
74         "order=i"      => \$order,
75         "all!"         => \$all,
76         "links!"       => \$links,
77         "xterm=s"      => \$xterm,
78         "exec-title=s" => \$exect,
79         "exec-file=s"  => \$execf,
80         "exec-app:s"   => \$execa,
81         "command-title=s" => \$commt,
82         "command-file=s"  => \$commf,
83         "command-app=s"   => \$comma,
84         "reuse!"       => \$reuse,
85         "wm-icons"     => \$wm_icons,
86         "check-subdirs!"    => \$check_subdirs,
87         "special-dirs:s"    => \$special_dir_val,
88         "memory-for-speed!" => \$memory_for_speed,
89         "menu-style=s" => \$change_menu_style,
90         "func-name=s"  => \$func_name,
91 ) || wrong_usage();
92 wrong_usage() if @ARGV;
94 $name = $dir unless $reuse;
95 $dir =~ s:^~(/|$):$home$1:;
96 chomp($dir = `cat "$dir_filename"`) if $reuse && -f $dir_filename;
98 unless (-d $dir) {
99         # the next line may be commented not to throw error
100         #die "$dir does not exist, exiting.\n";
101         $dir = $home;
104 $links || !-l $dir || exit(-1);  # exit if linked directories are disabled
105 chdir($dir) || exit(-1);  # exit if no execute permission on the directory
107 # expand title
108 &expand_width_specifier(\$title, 'd', (split('/', $dir))[-1] || '/')
109         if $title =~ /%(-?\d+)?(\*-?\d+)?d/;
110 &expand_width_specifier(\$title, 'p', $dir)
111         if $title =~ /%(-?\d+)?(\*-?\d+)?p/;
112 $title =~ s/\\t/\t/g;
113 $itemf =~ s/\\t/\t/g;
115 # item format optimization variables
116 my $itemf_eval = $itemf ne '%f';  # evaluation needed
117 my $itemf_name = undef;
118 my $itemf_stat = undef;  # stat() needed
119 my $itemf_date = undef;
120 my $itemf_size = undef;
121 my $itemf_type = undef;
123 if ($itemf_eval) {
124         $itemf_name = $itemf =~ /%(-?\d+)?(\*-?\d+)?[nN]/;
125         $itemf_date = $itemf =~ /%[dD]/;
126         $itemf_size = $itemf =~ /%(-?\d+)?(\*-?\d+)?s/;
127         $itemf_type = $itemf =~ /%[tT]/;
128         $itemf_stat = $itemf_size || $itemf_date || $itemf_size || $itemf_type;
131 my @type1 = ("Sock", "Link", "File", "Blck", "Dir ", "Char", "Pipe");
132 my @type2 = ("S", "L", "F", "B", "D", "C", "P");
134 if ($wm_icons) {
135         $icont ||= "menu/folder-open.xpm";
136         $icond ||= "menu/folder.xpm";
137         $iconf ||= "menu/file.xpm";
138         $icona ||= "menu/utility.xpm";
141 my $icont_str = $icont ? "%$icont%" : "";
142 my $icond_str = $icond ? "%$icond%" : "";
143 my $iconf_str = $iconf ? "%$iconf%" : "";
144 my $icona_str = $icona ? "%$icona%" : "";
146 $exect = undef if defined $exect && $exect eq '-';
147 $execf = undef if defined $execf && $execf eq '-';
148 $execa = undef if defined $execa && $execa eq '-';
150 $exect = $exect =~ /^\^(.*)$/ ? $1 : "$xterm $exect" if defined $exect;
151 $execf = $execf =~ /^\^(.*)$/ ? $1 : "$xterm $execf" if defined $execf;
152 $execa = $execa =~ /^\^(.*)$/ ? $1 : "$xterm $execa" if defined $execa;
154 $commt = undef if defined $commt && $commt eq '-';
155 $commf = undef if defined $commf && $commf eq '-';
156 $comma = undef if defined $comma && $comma eq '-';
158 $commt = defined $exect ? qq(Exec cd "%d"; $exect): "Nop" if !defined $commt;
159 $commf = defined $execf ? qq(Exec $execf "%f"):     "Nop" if !defined $commf;
160 $comma = defined $execa ? qq(Exec $execa "%f"):    $commf if !defined $comma;
162 # manage special directories if needed
163 my ($special_dir_lines, $special_dir_pos, @special_dirs) = ("");
164 $special_dir_val = "1,2" if defined $special_dir_val && $special_dir_val eq "";
165 if ($special_dir_val && $special_dir_val =~ /([\d,]+)(-?)/) {
166         @special_dirs = grep(/^[1-3]$/, split(/,+/, $1));
167         $special_dir_pos = $2 ? -1 : 1;
169 if (@special_dirs) {
170         my $parent_dir = $dir eq '/' || $dir !~ m!^(.*)/[^\/]+$! ? undef : $1;
171         $parent_dir = '/' if defined $parent_dir && $parent_dir eq '';
172         my @special_dir_def = (
173                 [ '..' => $parent_dir ],
174                 [ '~'  => $home ],
175                 [ '/'  => '/' ],
176         );
177         foreach (@special_dirs) {
178                 $special_dir_lines .= qq(+ "" Nop\n) if $special_dir_lines;
179                 $special_dir_lines .= &eval_folder_line(@{$special_dir_def[$_ - 1]});
180         }
181 } else {
182         $special_dir_pos = 0;
185 # create file listing
186 opendir(DIR, ".");
187 my @files = readdir(DIR);
188 closedir(DIR);
189 @files = grep /^[^.]/, @files unless $all;
191 my $abs_order = abs($order);
192 # To avoid warnings, '!!' must be added before '-d'. Will this slow things?
193 my $sort_sub =
194         $abs_order == 2 ? sub { -d $b <=> -d $a } :
195         $abs_order == 3 ? sub { -d $a <=> -d $b } :
196         $abs_order == 4 ? sub { $a cmp $b } :
197         $abs_order == 5 ? sub { -d $b <=> -d $a || $a cmp $b } :
198         $abs_order == 6 ? sub { -d $a <=> -d $b || $a cmp $b } :
199         sub { 0 };
200 @files = sort $sort_sub @files if $abs_order != 1;
201 @files = reverse @files if $order < 0;
203 # dump all menu items and start adding new items
204 my $menu_name  = &escape_fvwm_name($name);
205 my $menu_name2 = &escape_menu_name($name);
206 print qq(DestroyMenu recreate "$menu_name"\nAddToMenu "$menu_name2"\n);
208 # destroy the menu after it is popped down
209 print qq(+ DynamicPopDownAction DestroyMenu "$menu_name"\n)
210         unless $memory_for_speed || $reuse;
212 # set the 'missing submenu function'
213 print qq(+ MissingSubmenuFunction $func_name\n) unless $reuse;
215 # add a new title (item and separator, or real Title if no action)
216 my $title_act = $commt; $title_act =~ s/%d/$dir/g;
217 if ($title ne "") {
218         if ($title_act eq "") {
219                 print qq(+ "$icont_str$title" Title\n);
220         } else {
221                 print qq(+ "$icont_str$title" $title_act\n+ "" Nop\n);
222         }
225 # add special dirs at the top if needed
226 print qq($special_dir_lines+ "" Nop\n) if $special_dir_pos > 0;
228 # add directory contents
229 foreach (@files) {
230         next if $_ eq '.' or $_ eq '..';
231         my $file_path = "$dir/$_";
232         $file_path =~ s|/+|/|g;
233         if (-d) {
234                 # it's a directory
235                 print &eval_folder_line($_, $file_path);
236         } else {
237                 # something else, apply editor to it or run itself
238                 my $item_str = $itemf_eval ? &eval_item($_, $file_path) : $_;
239                 $item_str = &escape_item_name($item_str);
240                 my $is_app = -x && -f;
241                 my $icon_str = $is_app && $icona_str ? $icona_str : $iconf_str;
242                 my $file_act = $is_app ? $comma : $commf;
243                 $file_act =~ s/%f/&escape_file_name($file_path)/ge;
244                 print qq(+ "$icon_str$item_str" $file_act\n);
245         }
248 # add special dirs at the bottom if needed
249 print qq(+ "" Nop\n$special_dir_lines) if $special_dir_pos < 0;
251 # add style:
252 if ($change_menu_style ne "") {
253         print qq(ChangeMenuStyle "$change_menu_style" "$menu_name"\n);
255 exit(0);
257 # ---------------------------------------------------------------------------
259 sub escape_fvwm_name ($) {
260         my $name = shift;
261         $name =~ s/\\/\\\\/g;
262         $name =~ s/"/\\"/g;
263         $name =~ s/\$/\$\$/g;
264         $name;
267 sub escape_menu_name ($) {
268         my $name = escape_fvwm_name(shift());
269         # fvwm is really inconsistent here
270         $name =~ s/\^/^^/g;
271         $name =~ s/@/@@/g;
272         $name;
275 sub escape_item_name ($) {
276         my $name = escape_fvwm_name(shift());
277         $name =~ s/%/%%/g;
278         $name =~ s/&/&&/g;
279         $name =~ s/\*/**/g;
280         $name =~ s/\n/ /g;
281         $name;
284 sub escape_file_name ($) {
285         my $name = shift;
286         $name =~ s/\\/\\\\/g;
287         $name =~ s/"/\\"/g;
288         $name =~ s/\$/\\\$\$/g;
289         $name =~ s/\n/\\\n/g;
290         $name;
293 sub eval_folder_line ($$) {
294         my ($_name, $dir) = @_;
295         my $item_str = $dir && $itemf_eval ? &eval_item($_name, $dir) : $_name;
296         $item_str = escape_item_name($item_str);
297         my $act = !$dir || $check_subdirs && !-x $dir ? "Nop" : !$reuse ?
298                 qq(Popup ") . escape_file_name($dir) . qq("$submenu_pos) :
299                 qq(PipeRead 'echo ") . escape_file_name($dir) . qq(" >$dir_filename; )
300                 . qq(echo Menu ") . escape_fvwm_name($name) . qq(" WarpTitle');
301         return qq(+ "$icond_str$item_str" $act\n);
304 sub eval_item ($$) {
305         my ($name, $file) = @_;
306         return $name unless $itemf_eval;
308         my $item_str = "$itemf";
309         if ($itemf_name) {
310                 &expand_width_specifier(\$item_str, 'n', $name);
311                 &expand_width_specifier(\$item_str, 'N', $file);
312         }
313         return $item_str unless $itemf_stat;
315         # / $dev, $ino, $mode, $nlink, $uid, $gid, $rdev,
316         # \ $size, $atime, $mtime, $ctime, $blksize, $blocks
317         my ($misc1, $misc2, $mode, $misc3, $misc4, $misc5, $misc6, $size,
318                 $misc7, $time) = stat($file);
319         if ($itemf_date) {
320                 eval 'use POSIX qw(strftime);' unless defined $POSIX::VERSION;
321                 my @time = localtime($time);
322                 my $date1 = strftime("%Y-%m-%d %H:%M:%S", @time);
323                 my $date2 = strftime("%Y-%m-%d", @time);
324                 $item_str =~ s/%d/$date1/g;
325                 $item_str =~ s/%D/$date2/g;
326         }
327         if ($itemf_size) {
328                 &expand_width_specifier(\$item_str, 's', $size);
329         }
330         if ($itemf_type) {
331                 my $type;
332 #               $type = 2 if ($mode & 0100000);  # regular
333 #               $type = 4 if ($mode & 0040000);  # directory
334 #               $type = 0 if ($mode & 0140000);  # socket
335 #               $type = 1 if ($mode & 0120000);  # symlink
336 #               $type = 3 if ($mode & 0060000);  # block
337 #               $type = 5 if ($mode & 0020000);  # char-dev
338 #               $type = 6 if ($mode & 0010000);  # fifo
339                 $type = -p _ ? 6 : -c _ ? 5 : -b _ ? 3 : -l $file ? 1 :
340                         -S _ ? 0 : -d _ ? 4 : 2;
341                 $item_str =~ s/%t/$type1[$type]/g;
342                 $item_str =~ s/%T/$type2[$type]/g;
343         }
344         return $item_str;
347 # Substitutes all %N1*N2x in $name by properly stripped and justified $value.
348 sub expand_width_specifier (\$$$) {
349         my ($name, $char, $value) = @_;
350         $$name =~ s/%(-?\d+)?(\*(-?)(\d+))?$char/
351                 my $value = !$2 || $4 <= 3 || $4 > length($value) ? $value : $3
352                         ? "..." . substr($value, -$4 + 3, $4 - 3)
353                         : substr($value, 0, $4 - 3) . "...";
354                 $1 ? sprintf("%$1s", $value) : $value;
355         /ge;
358 sub show_help {
359         print "A perl script that builds directory listing for fvwm.\n\n";
360         print "Usage: $0 [OPTIONS]\n";
361         print "Options:\n";
362         print "\t--help             show this help and exit\n";
363         print "\t--version          show the version and exit\n";
364         print "\t--name=NAME        menu name,  default is '$name'\n";
365         print "\t--title=NAME       menu title, default is '$title'\n";
366         print "\t--item=NAME        menu item format, default is '$itemf'\n";
367         print "\t--icon-title=XPM   menu title icon, default is none\n";
368         print "\t--icon-dir=XPM     menu dir   icon, default is none\n";
369         print "\t--icon-file=XPM    menu file  icon, default is none\n";
370         print "\t--icon-app=XPM     menu +x    icon, default is none\n";
371         print "\t--wm-icons         define icon names to use with wm-icons\n";
372         print "\t--dir=NAME         starting dir, default is '$dir'\n";
373         print "\t--order=NUM        NUM (-6 .. 6), default is 5\n";
374         print "\t\t1 - do not sort,  2 - dirs first, 3 - files first\n";
375         print "\t\t4 - sort by name, 5 - dirs first, 6 - files first\n";
376         print "\t\tNegative number represents reverse order.\n";
377         print "\t--all              show hidden files, default is no\n";
378         print "\t--links            follow linked dirs, default is no\n";
379         print "\t--xterm=CMD        xterm call, default is '$xterm'\n";
380         print "\t--exec-title=CMD   title exec command, default is '$exect'\n";
381         print "\t--exec-file=CMD    file exec command, default is '$execf'\n";
382         print "\t--exec-app[=CMD]   +x files exec command, default is '-'\n";
383         print "\t--command-title=CMD title fvwm command, default is '-'\n";
384         print "\t--command-file=CMD file fvwm command, default is '-'\n";
385         print "\t--command-app=CMD  +x files fvwm command, default is '-'\n";
386         print "\t--reuse            no popups, reuse the same menu (no)\n";
387         print "\t--check-subdirs    check subdir for +x permission (no)\n";
388         print "\t--special-dirs[=X] include .. and ~ directories (no)\n";
389         print "\t--memory-for-speed use speed optimization (no)\n";
390         print "\t--menu-style=NAME  assign specified MenuStyle name to menus\n";
391         print "Short options are ok if not ambiguous: -a, -icon-f.\n";
392         exit 0;
395 sub show_version {
396         print "$version\n";
397         exit 0;
400 sub wrong_usage {
401         print STDERR "Try '$0 --help' for more information.\n";
402         exit -1;
405 __END__
407 # ---------------------------------------------------------------------------
409 =head1 NAME
411 fvwm-menu-directory - builds a directory browsing menu for fvwm
413 =head1 SYNOPSIS
415 B<fvwm-menu-directory>
416 [ B<--help>|B<-h>|B<-?> ]
417 [ B<--version>|B<-V> ]
418 [ B<--name>|B<-na> NAME ]
419 [ B<--title>|B<-t> NAME ]
420 [ B<--item>|B<-it> NAME ]
421 [ B<--icon-title>|B<-icon-t> XPM ]
422 [ B<--icon-dir>|B<-icon-d> XPM ]
423 [ B<--icon-file>|B<-icon-f> XPM ]
424 [ B<--icon-app>|B<-icon-a> XPM ]
425 [ B<--wm-icons> ]
426 [ B<--dir>|B<-d> NAME ]
427 [ B<--order>|B<-o> NUM ]
428 [ B<--[no]all>|B<-a> ]
429 [ B<--[no]links>|B<-l> ]
430 [ B<--xterm>|B<-x> CMD ]
431 [ B<--exec-title>|B<-exec-t> CMD ]
432 [ B<--exec-file>|B<-exec-f> CMD ]
433 [ B<--exec-app>|B<-exec-a> [CMD] ]
434 [ B<--command-title>|B<-command-t> CMD ]
435 [ B<--command-file>|B<-command-f> CMD ]
436 [ B<--command-app>|B<-command-a> CMD ]
437 [ B<--[no]reuse>|B<-r> ]
438 [ B<--[no]check-subdirs>|B<-ch> ]
439 [ B<--special-dirs>|B<-s> [VALUE] ]
440 [ B<--[no]memory-for-speed>|B<-mem> ]
441 [ B<--menu-style>|B<-men> NAME ]
442 [ B<--func-name>|B<-f> NAME ]
444 =head1 DESCRIPTION
446 A perl script which provides an output to read in with PipeRead to build an
447 fvwm menu containing a directory listing. Almost everything can be configured.
449 =head1 HINTS
451 The title item with its own attached action is usually added to the menu.
452 This may be used to define an action for the directory for which the menu is
453 built, such as starting a terminal in this directory (the default).
454 However, this may annoy some users. To disable the title action use
455 B<--command-title> "", to remove the title completely use B<--title> "".
457 =head1 OPTIONS
459 =over 4
461 =item B<--help>
463 show the usage and exit
465 =item B<--version>
467 show version and exit
469 =item B<--name> name
471 menu name, used only with --reuse, default is MenuBrowser
473 =item B<--title> title
475 menu title format, default is '%*-40p' - last 40 characters
476 of the current full path.
477 TAB can be specified as '\t', but in .fvwm2rc you should specify a double
478 backslash or a real TAB.
480 Format specifiers:
481   %d - the current directory name
482   %p - the current directory full path
484 These specifiers can receive an optional integer size, positive for right
485 adjusted string or negative for left adjusted, example: %8x; and optional
486 *num or *-num, which means to leave only the first or last (if minus) num of
487 chars, the num must be greater than 3, since the striped part is replaced
488 with "...", example: %*30x. Both can be combined: %-10*-20x, this instructs to
489 get only the 20 last characters, but if the length is less then 10 - to fill
490 with up to 10 spaces on the right.
492 =item B<--item> format
494 menu item format, default is '%n'. TAB and width modifiers
495 for %n, %N and %s can be specified as described in B<--title> above.
496 Note, specifying a non default format slows the script.
498 Format specifiers:
500   %n - file/dir name (without the path)
501   %N - file/dir name (full with the path)
502   %d - file/dir date (yyyy-mm-dd HH:MM:SS)
503   %D - file/dir date (yyyy-mm-dd)
504   %s - file/dir size (in bytes)
505   %t - file/dir type (File|Dir |Link|Sock|Blck|Char|Pipe)
506   %T - file/dir type (F|D|L|S|B|C|P)
508 Example: --title '%*-40p\tDate, Type\tSize' --item '%*40n\t%d %t\t%s'
510 =item B<--icon-title> icon
512 menu title icon, default is none
514 =item B<--icon-dir> icon
516 menu dir icon, default is none
518 =item B<--icon-file> icon
520 menu file icon, default is none
522 =item B<--icon-app> icon
524 menu application icon, default is none
526 =item B<--wm-icons>
528 define icon names suitable for use with wm-icons package.
529 Currently this is equivalent to: --icon-title menu/folder-open.xpm --icon-item
530 menu/file.xpm --icon-dir menu/folder.xpm --icon-app menu/utility.xpm.
532 =item B<--dir> dir
534 starting dir, default is ${HOME-.}
536 =item B<--order> number
538 in the range (-6 .. 6), default is 5:
540   1 - do not sort,  2 - dirs first, 3 - files first
541   4 - sort by name, 5 - dirs first, 6 - files first
542   Negative number represents reverse order.
544 =item B<--[no]all>
546 show hidden files, like in 'ls -A', default is --noall
548 =item B<--[no]links>
550 follow linked directories, default is --nolinks
552 =item B<--xterm> command
554 X terminal call, default is 'xterm -e'
556 =item B<--exec-title> command
558 an fvwm Exec command on directory title (usually the
559 shell), default is ${SHELL-/bin/sh}.
560 '-' means no Exec command, i.e. Nop.
561 If the command is not started with '^' X terminal call is prepended.
562 The command is started in the currently browsed directory.
564 =item B<--exec-file> command
566 an fvwm Exec command on regular files,
567 default is ${EDITOR-vi}.
568 '-' means no Exec command, i.e. Nop.
569 If the command is not started with '^' X terminal call is prepended.
570 The actual file name is appended to the command.
572 =item B<--exec-app> [command]
574 an fvwm Exec command on +x files, default is '-',
575 which means the same command as on regular files. If no command is given,
576 it is assumed to be empty - simply run the +x file.
577 If the command is not started with '^' X terminal call is prepended.
578 The actual file name is appended to the command.
580 =item B<--command-title> command
582 an fvwm command to execute on title.
583 If this option is not given (or command is '-'), the C<--exec-title>
584 is used instead.
585 In the command, %d is substituted with the full directory path.
587 In fact, I<--exec-title=tcsh> is equivalent
588 to I<--command-title='Exec cd "%d"; xterm -e tcsh'>
590 The empty value disables the title action.
592 =item B<--command-file> command
594 an fvwm command to execute on regular files.
595 If this option is not given (or command is '-'), the C<--exec-file>
596 is used instead.
597 In the command, %f is substituted with the full file path.
599 In fact, --exec-file=vi is equivalent
600 to --command-file='Exec xterm -e vi "%f"'
602 =item B<--command-app> command
604 an fvwm command to execute on +x files.
605 If this option is not given (or command is '-'), the C<--command-app>
606 is used instead.
607 In the command, %f is substituted with the full file path.
609 In fact, --exec-app=^exec is equivalent
610 to --command-app='Exec exec "%f"'
612 =item B<--[no]reuse>
614 no pop-up menus, reuse the same menu, default is --noreuse.
615 When you specify this option the Menu action is used, not Popup. Also,
616 the --name parameter is not ignored, and --dir parameter is ignored
617 if there is ~/.fvwm/.fvwm-menu-directory.dir file. This file is only created
618 or used with this option specified, it is the only solution for the current
619 fvwm menu state.
621 =item B<--[no]check-subdirs>
623 check all subdirs for having execute (+x) permission
624 and replace "Popup"/"Menu" command with "Nop" for these without permissions.
625 This has a visual effect of disabling popup triangle in the subdirectory item.
626 The default is --nocheck-subdirs, because: 1) enabling this slows a bit the
627 script, 2) with this option enabled, if no icons used and no dir/file separate
628 sorting used there is no way to know that the item is directory and not file.
630 =item B<--special-dirs> value
632 add .. or ~ or / special directories according to
633 given optional value. Without with option these directories are not added.
634 Default value if not specified is "1,2". The value is comma separated ordered
635 special directory indexes, where 1 is parent directory, 2 is home directory,
636 3 is root directory. If minus is prepended to the value, special directories
637 are added at the bottom of menu instead of top. Value "0" or any bad value
638 is equivalent to non-specifying this option at all.
640 =item B<--[no]memory-for-speed>
642 use speed optimization, i.e. use previously
643 created directory menus without destroying it when closed, default is
644 --nomemory-for-speed
646     Warning: speed optimization takes up a lot of memory
647     that is never free'd again while fvwm is running.
649 =item B<--menu-style> name
651 assign MenuStyle name to the menus
653 =item B<--func-name> name
655 overwrite the default MissingSubmenuFunction name that is
656 "FuncFvwmMenuDirectory"
658 =back
660 Option parameters can be specified either using '=' or in the next argument.
661 Short options are ok if not ambiguous: C<-a>, C<-x>, C<-icon-f>; but be
662 careful with short options, what is now unambiguous, can become ambiguous
663 in the next versions.
665 =head1 USAGE
667 Put this into your fvwm configuration file to invoke the script:
669   AddToFunc FuncFvwmMenuDirectory
670   + I PipeRead "fvwm-menu-directory -d '$0'"
672 More complex example:
674   # AddToFunc FuncFvwmMenuDirectory
675   # + I PipeRead "fvwm-menu-directory -d '$0' -x 'Eterm -g 80x40 -e' \\
676     -a -l -o 6 --exec-app --exec-title 'tcsh -l' --exec-file 'vim -R' \\
677     -t 'Go to: %d' --wm-icons"
679 And put this in the menu from which you want to pop-up the directory menus:
681   AddToMenu SomeMenu MissingSubmenuFunction FuncFvwmMenuDirectory
682   + "Home Directory"  Popup $[HOME]
683   + "Httpd Directory" Popup /home/httpd
685 Note: please use absolute path names.
687 It is a good idea to set the menu pop-up delay to something positive
688 and enable busy cursor
690   MenuStyle * PopupDelayed, PopupDelay 200
691   BusyCursor DynamicMenu True
693 in your configuration file when using this script for better results.
695 Another interesting usage (C<--reuse> or C<-r> is mandatary for this):
697   AddToMenu Browser
698   + DynamicPopupAction PipeRead \\
699     "fvwm-menu-directory -r -na Browser -d / -s"
700   AddToMenu SomeMenu "My Browser" Menu Browser
702 Here the C<--dir> parameter (starting directory) is ignored if there is
703 ~/.fvwm/.fvwm-menu-directory.dir file, which you can delete.
705 =head1 AUTHORS
707 Inspired  on 1999-06-07 by Dominik Vogt     <domivogt@fvwm.org>.
709 Rewritten on 1999-08-05 by Mikhael Goikhman <migo@homemail.com>.
711 =head1 COPYING
713 The script is distributed by the same terms as fvwm itself.
714 See GNU General Public License for details.
716 =head1 BUGS
718 Report bugs to fvwm-bug@fvwm.org.
720 =cut
722 # ***************************************************************************