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.
57 =head1 ENVIRONMENT VARIABLES
67 Also supported to determine what editor to use.
73 Copyright 2006 by Joey Hess <joey@kitenet.net>
75 Licensed under the GNU GPL.
86 if (! GetOptions
("verbose|v" => \
$verbose)) {
87 die "Usage: $0 [--verbose] [directory|file|-]\n";
94 foreach my $item (@ARGV) {
96 push @dir, map { chomp; $_ } <STDIN
>;
98 open(STDIN
, "/dev/tty") || die "reopen: $!\n";
102 opendir(DIR
, $item) || die "$0: cannot read $item: $!\n";
103 push @dir, map { "$item$_" } sort readdir(DIR
);
111 if (grep(/[[:cntrl:]]/, @dir)) {
112 die "$0: control characters in filenames are not supported\n";
115 my $tmp=File
::Temp
->new(TEMPLATE
=> "dirXXXXX", DIR
=> File
::Spec
->tmpdir);
116 open (OUT
, ">".$tmp->filename) || die "$0: cannot create ".$tmp->filename.": $!\n";
121 next if /^(.*\/)?\
.$/ || /^(.*\
/)?\.\.$/;
123 print OUT
"$c\t$_\n";
126 close OUT
|| die "$0: cannot write ".$tmp->filename.": $!\n";
129 if (-x
"/usr/bin/editor") {
130 @editor="/usr/bin/editor";
132 if (exists $ENV{EDITOR
}) {
133 @editor=split(' ', $ENV{EDITOR
});
135 if (exists $ENV{VISUAL
}) {
136 @editor=split(' ', $ENV{VISUAL
});
138 $ret=system(@editor, $tmp);
140 die "@editor exited nonzero, aborting\n";
143 open (IN
, $tmp->filename) || die "$0: cannot read ".$tmp->filename.": $!\n";
146 if (/^(\d+)\t{0,1}(.*)/) {
149 if (! exists $item{$num}) {
150 die "$0: unknown item number $num\n";
152 elsif ($name ne $item{$num}) {
153 next unless length $name;
156 if (! (-e
$src || -l
$src) ) {
157 print STDERR
"$0: $src does not exist\n";
163 if (-e
$name || -l
$name) {
166 while (-e
$tmp || -l
$tmp) {
170 if (! rename($name, $tmp)) {
171 print STDERR
"$0: failed to rename $name to $tmp: $!\n";
175 print "'$name' -> '$tmp'\n";
177 foreach my $item (keys %item) {
178 if ($item{$item} eq $name) {
184 if (! rename($src, $name)) {
185 print STDERR
"$0: failed to rename $src to $name: $!\n";
190 foreach (values %item) {
191 s
,^\Q
$src\E
($|/),$name$1,;
195 print "'$src' => '$name'\n";
205 die "$0: unable to parse line \"$_\", aborting\n";
208 close IN
|| die "$0: cannot read ".$tmp->filename.": $!\n";
209 unlink($tmp.'~') if -e
$tmp.'~';
214 if (-d
$file && ! -l
$file) {
222 foreach my $item (reverse sort values %item) {
224 print STDERR
"$0: failed to remove $item: $!\n";
228 print "removed '$item'\n";