|
@ -1,317 +0,0 @@ |
|
|
#!/usr/bin/perl |
|
|
|
|
|
use strict; |
|
|
|
|
|
use warnings; |
|
|
|
|
|
|
|
|
|
|
|
use constant |
|
|
|
|
|
{ |
|
|
|
|
|
PROG_EDIT => 'vim', |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
sub open_smart; |
|
|
|
|
|
sub edit; |
|
|
|
|
|
sub stdin_to_editor; |
|
|
|
|
|
sub reveal; |
|
|
|
|
|
sub header_edit; |
|
|
|
|
|
sub wait_or_not; |
|
|
|
|
|
|
|
|
|
|
|
sub usage |
|
|
|
|
|
{ |
|
|
|
|
|
print STDERR <<"!"; |
|
|
|
|
|
Usage: $0 -[efWwRh] |
|
|
|
|
|
-e: edit |
|
|
|
|
|
-f: stdin-edit |
|
|
|
|
|
-W: wait for exit (true by default for editing) |
|
|
|
|
|
-w: don't wait for exit |
|
|
|
|
|
-R: reveal |
|
|
|
|
|
-h: header search |
|
|
|
|
|
! |
|
|
|
|
|
exit 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
my $cmd = \&open_smart; |
|
|
|
|
|
my(@files, @args); |
|
|
|
|
|
|
|
|
|
|
|
my %opts = ( |
|
|
|
|
|
'e' => 0, |
|
|
|
|
|
'f' => 0, |
|
|
|
|
|
'W' => 0, |
|
|
|
|
|
'R' => 0, |
|
|
|
|
|
'h' => 0, |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
my $wait_set = 0; |
|
|
|
|
|
|
|
|
|
|
|
usage() unless @ARGV; |
|
|
|
|
|
|
|
|
|
|
|
for(my $i = 0; $i < @ARGV; ++$i){ |
|
|
|
|
|
$_ = $ARGV[$i]; |
|
|
|
|
|
|
|
|
|
|
|
if($_ eq '--'){ |
|
|
|
|
|
push @files, @ARGV[$i + 1 .. $#ARGV]; |
|
|
|
|
|
last; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(/^-([a-z])$/i){ |
|
|
|
|
|
my $k = $1; |
|
|
|
|
|
|
|
|
|
|
|
if(exists $opts{$k}){ |
|
|
|
|
|
$opts{$k} = 1; |
|
|
|
|
|
$wait_set = 1 if $k eq 'W'; |
|
|
|
|
|
}elsif($k eq 'w'){ |
|
|
|
|
|
$opts{W} = 0; |
|
|
|
|
|
$wait_set = 1; |
|
|
|
|
|
}else{ |
|
|
|
|
|
usage(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}elsif($_ eq '--args'){ |
|
|
|
|
|
push @args, @ARGV[$i + 1 .. $#ARGV]; |
|
|
|
|
|
last; |
|
|
|
|
|
|
|
|
|
|
|
}elsif(/^-/){ |
|
|
|
|
|
usage(); |
|
|
|
|
|
|
|
|
|
|
|
}else{ |
|
|
|
|
|
push @files, $_; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if($opts{e} + $opts{f} + $opts{R} + $opts{h} > 1){ |
|
|
|
|
|
print STDERR "Can't combine -e, -f, -R and -h\n"; |
|
|
|
|
|
usage(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
my $should_wait = 1; |
|
|
|
|
|
if($opts{e}){ |
|
|
|
|
|
$cmd = \&edit; |
|
|
|
|
|
|
|
|
|
|
|
}elsif($opts{f}){ |
|
|
|
|
|
# <STDIN> | $EDITOR - |
|
|
|
|
|
$cmd = \&stdin_to_editor; |
|
|
|
|
|
|
|
|
|
|
|
}elsif($opts{R}){ |
|
|
|
|
|
# open with rox |
|
|
|
|
|
$cmd = \&reveal; |
|
|
|
|
|
$should_wait = 0; |
|
|
|
|
|
|
|
|
|
|
|
}elsif($opts{h}){ |
|
|
|
|
|
# search /usr/include/$_ for @files |
|
|
|
|
|
$cmd = \&header_edit; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$opts{W} = 1 if $should_wait and not $wait_set; |
|
|
|
|
|
|
|
|
|
|
|
exit(&{$cmd}(( |
|
|
|
|
|
wait => !!$opts{W}, |
|
|
|
|
|
args => [@args], |
|
|
|
|
|
files => [@files]))); |
|
|
|
|
|
|
|
|
|
|
|
# end --- |
|
|
|
|
|
|
|
|
|
|
|
sub read_maps |
|
|
|
|
|
{ |
|
|
|
|
|
my $rc = "$ENV{HOME}/.openrc"; |
|
|
|
|
|
open F, '<', $rc or die "open $rc: $!\n"; |
|
|
|
|
|
|
|
|
|
|
|
my %maps; |
|
|
|
|
|
my $prog_reveal = ''; |
|
|
|
|
|
|
|
|
|
|
|
my $mode = 0; |
|
|
|
|
|
while(<F>){ |
|
|
|
|
|
chomp; |
|
|
|
|
|
s/#.*//; |
|
|
|
|
|
|
|
|
|
|
|
if(/^\[(.*)\]$/){ |
|
|
|
|
|
if($1 eq 'full'){ |
|
|
|
|
|
$mode = $1; |
|
|
|
|
|
}elsif($1 eq 'suffix'){ |
|
|
|
|
|
$mode = $1; |
|
|
|
|
|
}elsif($1 eq 'directories'){ |
|
|
|
|
|
$mode = $1; |
|
|
|
|
|
}else{ |
|
|
|
|
|
die "invalid section \"$1\" in $rc\n"; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}elsif(!($mode eq 'directories') and my($prog, $matches) = /^([^:]+): *(.*)/){ |
|
|
|
|
|
sub getenv |
|
|
|
|
|
{ |
|
|
|
|
|
my $k = shift; |
|
|
|
|
|
return $ENV{$k} if $ENV{$k}; |
|
|
|
|
|
my %backup = ( |
|
|
|
|
|
"TERM" => "urxvt", |
|
|
|
|
|
"VISUAL" => "vim", |
|
|
|
|
|
); |
|
|
|
|
|
return $backup{$k} if $backup{$k}; |
|
|
|
|
|
return "\$$k"; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
my @matches = split / *, */, $matches; |
|
|
|
|
|
|
|
|
|
|
|
$prog =~ s/\$([A-Z_]+)/getenv($1)/e; |
|
|
|
|
|
|
|
|
|
|
|
my $key = $prog; |
|
|
|
|
|
if($mode eq 'suffix'){ |
|
|
|
|
|
# compare file extensions case insensitively |
|
|
|
|
|
$key = lc $key; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
push @{$maps{$key}}, [ $_, $mode ] for @matches; |
|
|
|
|
|
|
|
|
|
|
|
}elsif($mode eq 'directories' && length){ |
|
|
|
|
|
if(length($prog_reveal)){ |
|
|
|
|
|
die "already have dir program, in $rc\n"; |
|
|
|
|
|
} |
|
|
|
|
|
$prog_reveal = $_; |
|
|
|
|
|
|
|
|
|
|
|
}elsif(length){ |
|
|
|
|
|
die "invalid confiuration line: \"$1\" in $rc\n"; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(!length($prog_reveal)){ |
|
|
|
|
|
die "no directory program specified, in $rc\n"; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
close F; |
|
|
|
|
|
|
|
|
|
|
|
return $prog_reveal, \%maps; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sub open_smart |
|
|
|
|
|
{ |
|
|
|
|
|
my $ec = 0; |
|
|
|
|
|
my %h = @_; |
|
|
|
|
|
|
|
|
|
|
|
my @to_open; |
|
|
|
|
|
|
|
|
|
|
|
my ($prog_reveal, $maps) = read_maps(); |
|
|
|
|
|
|
|
|
|
|
|
file: |
|
|
|
|
|
for my $fnam (@{$h{files}}){ |
|
|
|
|
|
#print "maps:\n"; |
|
|
|
|
|
|
|
|
|
|
|
if(-d $fnam){ |
|
|
|
|
|
push @to_open, [($h{wait}, $prog_reveal, @{$h{args}}, $fnam)]; |
|
|
|
|
|
next file; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
(my $fnam_for_test = $fnam) =~ s/\.[a-zA-Z]+$/lc($&)/e; |
|
|
|
|
|
|
|
|
|
|
|
for my $prog (keys %$maps){ |
|
|
|
|
|
#print " $_:\n"; |
|
|
|
|
|
for(@{$maps->{$prog}}){ |
|
|
|
|
|
my($reg, $mode) = ($_->[0], $_->[1]); |
|
|
|
|
|
if($mode eq 'suffix'){ |
|
|
|
|
|
$reg = "\\.$reg\$"; |
|
|
|
|
|
} |
|
|
|
|
|
#print " $reg\n" |
|
|
|
|
|
|
|
|
|
|
|
if($fnam_for_test =~ /$reg/){ |
|
|
|
|
|
push @to_open, [($h{wait}, $prog, @{$h{args}}, $fnam)]; |
|
|
|
|
|
next file; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
die "no program found for $fnam\n"; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
wait_or_not(@{$_}) for @to_open; |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sub wait_or_not |
|
|
|
|
|
{ |
|
|
|
|
|
my($wait, @rest) = @_; |
|
|
|
|
|
my $pid = fork(); |
|
|
|
|
|
|
|
|
|
|
|
die "fork(): $!\n" unless defined $pid; |
|
|
|
|
|
|
|
|
|
|
|
if($pid == 0){ |
|
|
|
|
|
if($rest[0] =~ / /){ |
|
|
|
|
|
my $a = shift @rest; |
|
|
|
|
|
unshift @rest, split / +/, $a; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
exec @rest; |
|
|
|
|
|
die; |
|
|
|
|
|
}else{ |
|
|
|
|
|
# parent |
|
|
|
|
|
if($wait){ |
|
|
|
|
|
my $reaped = wait(); |
|
|
|
|
|
my $ret = $?; |
|
|
|
|
|
|
|
|
|
|
|
die "wait(): $!\n" if $reaped == -1; |
|
|
|
|
|
warn "unexpected dead child $reaped (expected $pid)\n" if $reaped != $pid; |
|
|
|
|
|
|
|
|
|
|
|
return $ret; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sub edit |
|
|
|
|
|
{ |
|
|
|
|
|
my %h = @_; |
|
|
|
|
|
my $e = $ENV{VISUAL} || $ENV{EDITOR} || PROG_EDIT; |
|
|
|
|
|
return wait_or_not($h{wait}, $e, @{$h{args}}, @{$h{files}}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sub stdin_to_editor |
|
|
|
|
|
{ |
|
|
|
|
|
my $tmp = "/tmp/stdin_$$"; |
|
|
|
|
|
|
|
|
|
|
|
open F, '>', $tmp or die "open $tmp: $!\n"; |
|
|
|
|
|
print F $_ while <STDIN>; |
|
|
|
|
|
close F; |
|
|
|
|
|
|
|
|
|
|
|
my %h = @_; |
|
|
|
|
|
push @{$h{files}}, $tmp; |
|
|
|
|
|
my $r = edit(%h); |
|
|
|
|
|
unlink $tmp; |
|
|
|
|
|
return $r; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sub reveal |
|
|
|
|
|
{ |
|
|
|
|
|
my %h = @_; |
|
|
|
|
|
my ($prog_reveal) = read_maps(); |
|
|
|
|
|
return wait_or_not($h{wait}, $prog_reveal, @{$h{args}}, @{$h{files}}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sub header_edit |
|
|
|
|
|
{ |
|
|
|
|
|
my %h = @_; |
|
|
|
|
|
my @files = @{$h{files}}; |
|
|
|
|
|
@{$h{files}} = (); |
|
|
|
|
|
|
|
|
|
|
|
for my $name (@files){ |
|
|
|
|
|
sub find_header |
|
|
|
|
|
{ |
|
|
|
|
|
my @inc = ("", "arpa", "net", "sys"); |
|
|
|
|
|
my $r = shift; |
|
|
|
|
|
my @matches; |
|
|
|
|
|
|
|
|
|
|
|
for(my @tmp = @inc){ |
|
|
|
|
|
push @inc, "x86_64-linux-gnu/$_"; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for my $inc (@inc){ |
|
|
|
|
|
$inc = "/usr/include/$inc"; |
|
|
|
|
|
|
|
|
|
|
|
opendir D, $inc or next; |
|
|
|
|
|
push @matches, map { "$inc/$_" } grep /$r/, readdir D; |
|
|
|
|
|
closedir D; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return @matches; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
my @paths = find_header($name); |
|
|
|
|
|
push @{$h{files}}, @paths if @paths; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return edit(%h); |
|
|
|
|
|
} |
|
|
|