9 B<vidir> [--verbose] [directory|file|-] ...
13 vidir allows editing of the contents of a directory in a text editor. If no
14 directory is specified, the current directory is edited.
16 When editing a directory, each item in the directory will appear on its own
17 numbered line. These numbers are how vidir keeps track of what items are
18 changed. Delete lines to remove files from the directory, or
19 edit filenames to rename files. You can also switch pairs of numbers to
22 Note that if "-" is specified as the directory to edit, it reads a list of
23 filenames from stdin and displays those for editing. Alternatively, a list
24 of files can be specified on the command line.
32 Verbosely display the actions taken by the program.
48 Edit subdirectory contents too. To delete subdirectories,
49 delete all their contents and the subdirectory itself in the editor.
51 =item find -type f | vidir -
53 Edit all files under the current directory and subdirectories.
55 =head1 ENVIRONMENT VARIABLES
65 Also supported to determine what editor to use.
71 Copyright 2006 by Joey Hess <joey@kitenet.net>
73 Licensed under the GNU GPL.
84 if (! GetOptions
("verbose|v" => \
$verbose)) {
85 die "Usage: $0 [--verbose] [directory|file|-]\n";
92 foreach my $item (@ARGV) {
94 push @dir, map { chomp; $_ } <STDIN
>;
96 open(STDIN
, "/dev/tty") || die "reopen: $!\n";
100 opendir(DIR
, $item) || die "$0: cannot read $item: $!\n";
101 push @dir, map { "$item$_" } sort readdir(DIR
);
109 if (grep(/[[:cntrl:]]/, @dir)) {
110 die "$0: control characters in filenames are not supported\n";
113 my $tmp=File
::Temp
->new(TEMPLATE
=> "dirXXXXX", DIR
=> File
::Spec
->tmpdir);
114 open (OUT
, ">".$tmp->filename) || die "$0: cannot create ".$tmp->filename.": $!\n";
119 next if /^(.*\/)?\
.$/ || /^(.*\
/)?\.\.$/;
121 print OUT
"$c\t$_\n";
124 close OUT
|| die "$0: cannot write ".$tmp->filename.": $!\n";
127 if (-x
"/usr/bin/editor") {
128 @editor="/usr/bin/editor";
130 if (exists $ENV{EDITOR
}) {
131 @editor=split(' ', $ENV{EDITOR
});
133 if (exists $ENV{VISUAL
}) {
134 @editor=split(' ', $ENV{VISUAL
});
136 $ret=system(@editor, $tmp);
138 die "@editor exited nonzero, aborting\n";
141 open (IN
, $tmp->filename) || die "$0: cannot read ".$tmp->filename.": $!\n";
144 if (/^(\d+)\t{0,1}(.*)/) {
147 if (! exists $item{$num}) {
148 die "$0: unknown item number $num\n";
150 elsif ($name ne $item{$num}) {
151 next unless length $name;
154 if (! (-e
$src || -l
$src) ) {
155 print STDERR
"$0: $src does not exist\n";
161 if (-e
$name || -l
$name) {
164 while (-e
$tmp || -l
$tmp) {
168 if (! rename($name, $tmp)) {
169 print STDERR
"$0: failed to rename $name to $tmp: $!\n";
173 print "'$name' -> '$tmp'\n";
175 foreach my $item (keys %item) {
176 if ($item{$item} eq $name) {
182 if (! rename($src, $name)) {
183 print STDERR
"$0: failed to rename $src to $name: $!\n";
188 foreach (values %item) {
193 print "'$src' => '$name'\n";
203 die "$0: unable to parse line \"$_\", aborting\n";
206 close IN
|| die "$0: cannot read ".$tmp->filename.": $!\n";
207 unlink($tmp.'~') if -e
$tmp.'~';
212 if (-d
$file && ! -l
$file) {
220 foreach my $item (reverse sort values %item) {
222 print STDERR
"$0: failed to remove $item: $!\n";
226 print "removed '$item'\n";