File: //usr/share/texmf/scripts/context/perl/texfind.pl
eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
if 0;
#D \module
#D [ file=texfind.pl,
#D version=1998.05.10,
#D title=\TEXFIND,
#D subtitle=searching files,
#D author=Hans Hagen,
#D date=\currentdate,
#D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
#C
#C This module is part of the \CONTEXT\ macro||package and is
#C therefore copyrighted by \PRAGMA. See licen-en.pdf for
#C details.
# test with "doif(un|)defined"
use strict ;
use Getopt::Long ;
use File::Find ;
use Cwd ;
use Tk ;
use Tk::widgets ;
use Tk::ROText ;
use FindBin ;
use lib $FindBin::Bin ;
use path_tre ;
my $FileSuffix = 'tex' ;
my $SearchString = '' ;
my $Recurse = 0 ;
my $NumberOfHits = 0 ;
my $QuitSearch = 0 ;
my $Location = '' ;
my $currentpath = '.' ;
my @FileList ;
my ($dw, $mw, $log, $sea, $fil, $num, $but, $dir, $loc) ;
$mw = MainWindow -> new () ;
$dw = MainWindow -> new () ;
$mw -> protocol( 'WM_DELETE_WINDOW' => sub { exit } ) ;
$dw -> protocol( 'WM_DELETE_WINDOW' => sub { exit } ) ;
$log = $mw -> Scrolled ( 'ROText' ,
-scrollbars => 'se' ,
-font => 'courier' ,
-wrap => 'none' ,
-width => 65 ,
-height => 22 )
-> pack ( -side => 'bottom' ,
-padx => 2 ,
-pady => 2 ,
-expand => 1 ,
-fill => 'both' ) ;
$sea = $mw -> Entry ( -textvariable => \$SearchString ,
-font => 'courier' ,
-width => 20 )
-> pack ( -side => 'left' ,
-padx => 2 ,
-pady => 2 ) ;
$fil = $mw -> Entry ( -textvariable => \$FileSuffix ,
-font => 'courier' ,
-width => 5 )
-> pack ( -side => 'left' ,
-padx => 2 ,
-pady => 2 ) ;
$but = $mw -> Checkbutton ( -variable => \$Recurse ,
-text => 'recurse' )
-> pack ( -side => 'left' ) ;
$num = $mw -> Entry ( -textvariable => \$NumberOfHits ,
-font => 'courier' ,
-justify => 'right' ,
-width => 5 )
-> pack ( -side => 'right' ,
-padx => 2 ,
-pady => 2 ) ;
$loc = $mw -> Entry ( -textvariable => \$Location ,
-font => 'courier' ,
-width => 8 )
-> pack ( -side => 'right' ,
-padx => 2 ,
-pady => 2 ) ;
sub BuildDir
{ if (Exists($dir)) { $dir -> destroy } ;
$dir = $dw -> Scrolled ( 'PathTree' ,
-scrollbars => 'se' )
-> pack ( -expand => 1 ,
-fill => 'both' ,
-padx => 2 ,
-pady => 2 ) ;
$dir -> configure ( -font => 'courier' ,
-height => 24 ,
-width => 65 ,
-selectbackground => 'blue3' ,
-browsecmd => \&ChangePath ) ;
$dir -> bind ('<Return>' , \&ShowFile ) ;
$dir -> bind ('<Double-1>' , \&ShowFile ) }
BuildDir ;
sub ShowFile { $mw -> raise ; $sea -> focusForce }
sub ShowPath { $dw -> raise ; $dir -> focusForce }
$log -> tagConfigure ( 'found', -foreground => 'green3' ) ;
$log -> tagConfigure ( 'title', -foreground => 'blue3' ) ;
$sea -> bind ('<Return>' , \&LocateStrings ) ;
$fil -> bind ('<Return>' , \&LocateStrings ) ;
$loc -> bind ('<Return>' , \&ChangeLocation ) ;
$log -> bind ('<Return>' , \&ShowPath ) ;
$sea -> bind ('<KeyPress>' , \&QuitSearch ) ;
$fil -> bind ('<KeyPress>' , \&QuitSearch ) ;
$loc -> bind ('<KeyPress>' , \&QuitSearch ) ;
$sea -> bind ('<Escape>' , \&QuitSearch ) ;
$fil -> bind ('<Escape>' , \&QuitSearch ) ;
$loc -> bind ('<Escape>' , \&QuitSearch ) ;
$log -> bind ('<Escape>' , \&QuitSearch ) ;
$sea -> bind ('<Double-1>' , \&LocateStrings ) ;
$fil -> bind ('<Double-1>' , \&LocateStrings ) ;
$loc -> bind ('<Double-1>' , \&ChangeLocation ) ;
$log -> bind ('<Double-1>' , \&ShowPath ) ;
sub ChangePath
{ my $currentpath = shift ;
chdir($currentpath) ;
$QuitSearch = 1 ;
$log -> delete ('1.0', 'end') ;
$log -> insert ('end', "$currentpath\n\n", 'title') }
sub ChangeLocation
{ $QuitSearch = 1 ;
$log -> delete ('1.0', 'end') ;
$Location =~ s/^\s*//o ;
$Location =~ s/\s*$//o ;
$Location =~ s/(\\|\/\/)/\//go ;
unless (-d $Location)
{ unless ($Location =~ /\//) { $Location .= '/' } }
if (-d $Location)
{ $log -> insert ('end', "changed to location '$Location'\n\n", 'title') ;
$currentpath = $Location ;
chdir ($currentpath) ;
$dir -> destroy ;
BuildDir ;
$dw -> raise ;
$dw -> focusForce }
else
{ $log -> insert ('end', "unknown location '$Location'\n\n", 'title') ;
$Location = '' } }
sub QuitSearch
{ $QuitSearch = 1 }
sub SearchFile
{ my ($FileName, $SearchString) = @_ ;
my $Ok = 0 ; my $len ;
open (TEX, $FileName) ;
my $LineNumber = 0 ;
while (<TEX>)
{ ++$LineNumber ;
if ($QuitSearch)
{ if ($Ok) { $log -> see ('end') }
last }
if (/$SearchString/i)
{ ++$NumberOfHits ; $num -> update ;
unless ($Ok)
{ $Ok = 1 ;
$log -> insert ('end', "$FileName\n\n",'title') }
$log -> insert ('end', sprintf("%5i : ",$LineNumber), 'title') ;
s/^\s*//o ;
#
$len = 0 ;
while (/(.*?)($SearchString)/gi)
{ $len += length($1) + length($2) ;
$log -> insert ('end', "$1") ;
$log -> insert ('end', "$2", 'found' ) }
$_ = substr($_,$len) ;
$log -> insert ('end', "$_") ;
#
$log -> update ;
$log -> see ('end') } }
if ($Ok) { $log -> insert ('end', "\n") }
close (TEX) }
sub DoLocateFiles
{ @FileList = () ;
$NumberOfHits = 0 ;
if ($FileSuffix ne "")
{ $log -> delete ('1.0', 'end') ;
if ($Recurse)
{ $log -> insert ('end', "recursively identifying files\n", 'title') ;
$log -> see ('end') ;
find (\&wanted, $currentpath) ;
sub wanted
{ if ($QuitSearch) { last ; return }
if (/.*\.$FileSuffix/i)
{ ++$NumberOfHits ; $num -> update ;
push @FileList, $File::Find::name } } }
else
{ $log -> insert ('end', "identifying files\n", 'title') ;
$log -> see ('end') ;
opendir(DIR, $currentpath) ; my @TEMPLIST = readdir(DIR) ; closedir(DIR) ;
foreach my $FileName (@TEMPLIST)
{ if ($FileName =~ /.*\.$FileSuffix/i)
{ ++$NumberOfHits ; $num -> update ;
if ($QuitSearch)
{ last }
push @FileList, $FileName } } }
@FileList = sort @FileList } }
sub DoLocateStrings
{ $log -> delete ('1.0', 'end') ;
$log -> update ;
$log -> see ('end') ;
$NumberOfHits = 0 ;
if ($SearchString ne "")
{ foreach my $FileName (@FileList)
{ if ($QuitSearch)
{ $log -> insert ('end', "search aborted\n", 'title') ;
$log -> see ('end') ;
last }
SearchFile($FileName,$SearchString) } }
unless ($QuitSearch)
{ $log -> insert ('end', "done\n", 'title') ;
$log -> see ('end') } }
sub LocateStrings
{ $QuitSearch = 0 ;
DoLocateFiles() ;
DoLocateStrings() }
$log -> insert ('end',
"data fields\n\n" , '' ,
"string :", 'title', " regular expression to search for\n" , '' ,
"suffix :", 'title', " type of file to search in\n" , '' ,
"recurse :", 'title', " enable searching subpaths\n" , '' ,
"location :", 'title', " drive of root path\n" , '' ,
"counter :", 'title', " file/hit counter\n\n" , '' ,
"key bindings\n\n" , '' ,
"double 1 :", 'title', " directory window <-> search window\n" , '' ,
"enter :", 'title', " start searching\n" , '' ,
"escape :", 'title', " quit searching\n\n" , '' ,
"current path\n\n" , '' ,
cwd(), 'title', "\n\n" , 'title' ) ;
$log -> update ;
ShowPath ;
MainLoop() ;