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 ('' , \&ShowFile ) ; $dir -> bind ('' , \&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 ('' , \&LocateStrings ) ; $fil -> bind ('' , \&LocateStrings ) ; $loc -> bind ('' , \&ChangeLocation ) ; $log -> bind ('' , \&ShowPath ) ; $sea -> bind ('' , \&QuitSearch ) ; $fil -> bind ('' , \&QuitSearch ) ; $loc -> bind ('' , \&QuitSearch ) ; $sea -> bind ('' , \&QuitSearch ) ; $fil -> bind ('' , \&QuitSearch ) ; $loc -> bind ('' , \&QuitSearch ) ; $log -> bind ('' , \&QuitSearch ) ; $sea -> bind ('' , \&LocateStrings ) ; $fil -> bind ('' , \&LocateStrings ) ; $loc -> bind ('' , \&ChangeLocation ) ; $log -> bind ('' , \&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 () { ++$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() ;