home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-08-15 | 46.1 KB | 1,614 lines | [TEXT/ALFA] |
- #############################################################################
- # MacPerl.tcl
- # -----------
- #
- # This is a set of routines that allow Alpha to act as a front end for the
- # standalone MacPerl application and that allow Perl scripts to be used as
- # text filters in Alpha. These functions are accessed through a special
- # MacPerl menu.
- #
- # The features of this package are explained in the file "MacPerl Help",
- # accessible from the Help menu.
- #
- #############################################################################
- #
- # If you don't already have MacPerl, it's available by anonymous ftp from
- # the umich site
- #
- # mac.archive.umich.edu [141.211.165.34] mac/development/languages
- #
- # and its mirrors. Also, MacPerl's home site is
- #
- # ftp.switch.ch [130.59.1.40] software/mac/src/mpw_c
- #
- # MacPerl was written (ported to the Mac) by
- # Matthias Neeracher <neeri@iis.ee.ethz.ch> , and
- # Tim Endres <time@ice.com>.
- #
- #############################################################################
- # Author: W. Thomas Pollard <pollard@chem.columbia.edu>
- #
- # Version History:
- #
- # 2.51 1/96 - Fixed problem w/ "Tell MacPerl:Save As..."
- # 2.5 1/96 - Colorization and cmd-dbl-click modified to support Perl 5 docs
- # 2.41 7/95 - Minor tweaks
- # 2.4 7/95 - Fixed bugs affecting running unsaved scripts and error handling
- # 2.3 7/95 - Minor tweaks and code rearrangement.
- # 2.2 6/95 - Text filters act only on current line if "Apply to Buffer" is
- # false and no text has been selected.
- # Bug fix in error-marking for scripts sent as AppleEvent params.
- # Cmd-dbl-clicking a function call jumps to function, if
- # defined in the same file.
- # 2.1 6/95 - Cmd-dbl-clicking a 'require'd filename opens the file.
- # 2.0 6/95 - Minor bug fixes (incl. keyword decapitalization)
- # Alpha 6.0b17 compatibility updates.
- # Text Filters folder is settable from the App Paths menu now.
- # 1.9 5/95 - Cmd-dbl-clicking Perl keywords and special variables displays
- # the man page info.
- # 1.81 4/95 - one very minor Alpha compatibility update (winInfo->getWinInfo).
- # 1.8 4/95 - Menu reorganized somewhat.
- # Text Filters folder can now be anywhere.
- # "ApplyToBuffer" flag ignored if text has been selected.
- # Bug fixes.
- # 1.7 1/95 - Updated to take advantage of MacPerl 4.1.4 AppleEvent features:
- # 1) Text filters use 'batch' doScript (.: STDOUT file obsolete)
- # 2) Filter scripts sent as doScript params (.: SCRIPT file obsolete)
- # 3) "Save As Droplet" and "Save as Runtime" commands added.
- # Errors generated in 'require'd files are now displayed correctly
- # 1.6 10/94 - "UseDebugger" flag added (forces scripts to run under debugger).
- # Key bindings added for some menu commands.
- # "perlDoScript{,2,3}" procs consolidated into a single proc.
- # "saveAndRun" option added.
- # Command-line args now parsed into units more correctly, in
- # particular, quoted file names aren't broken up.
- # "Close Output Window" added to "Tell MacPerl" menu.
- # Updated for Alpha 5.98 to load when menu is inserted.
- # The error messages window is now recycled.
- # "perlRecycleOutput" recycles output window.
- # Minor bug fixes.
- # 1.5 9/94 - MacPerl menu rearranged somewhat.
- # Explicit "Get Output Window" command added to menu.
- # Reading "#!" line for args is incompatible w/ standard,
- # so it's been dropped.
- # Only scan the first 40 output lines for error messages (faster)
- # "wrapFilterScript" no longer opens STDIN
- # Text filters may now use command-line args
- # STDIN for text filters passed as explicit cmd-line arg
- # 1.4 9/94 - The "#!" line of every script is read for command-line args,
- # which are passed explicitly to MacPerl with the script.
- # "PromptForArgs" menu flag added.
- # "perlCmdlineArgs" modeVar holds default command-line args.
- # Scripts are sent using custom "perlDoScript2" proc, which
- # allows passing of explicit command-line args.
- # 1.3 9/94 - When any script generates a compilation error, the file
- # containing the script is brought up with the offending
- # line highlighted; all error output is also written to
- # a "Perl Error Messages" window.
- # 'repeatLastFilter' runs again the last text-filter script used.
- # 'perlLastFilter' modeVar holds pathname of last filter.
- # Menu flags now mirrored as modeVars, so they can be saved and
- # restored between sessions.
- # Minor bug fixes.
- # 1.2 8/94 - 'retrieveOutput' and 'autoSwitch' flags added.
- # 'openInMacperl' added.
- # MacPerl output window now closed before new scripts are sent.
- # Filters now abort if there are compilation errors, and
- # MacPerl diagnostic output retrieved and displayed in Alpha.
- # 1.1 8/94 - 'quitMacperl' added.
- # perl-mode file-marking updated for Alpha 5.90
- # Simplified installation via 'loadMacperl'(Pete Keleher).
- # 1.0 7/94 - perl-mode setup updated for Alpha 5.85:
- # keyword colorization supported
- # custom file-marking added
- # #! lines in filter scripts now handled correctly
- # Workarounds installed for AppleEvent bug in MacPerl 4.1.3
- # 0.9 3/94 - perl-mode stuff added, and
- # highlighted 'Perl commands' file (man page) prepared
- # minor bug fixes, too
- # 0.8 3/94 - flags are now check-marked
- # 0.7 3/94 - nested Text Filters folder now supported
- # menu format modified somewhat
- # 0.6 3/94 - 'applyToBuffer' flag added
- # scripts in Alpha buffers can now be used as filters
- # 0.5 2/94 - 'filters', 'open special' submenu added
- # 'overwrite' flag added
- # 0.2 1/94 - menu support added (Martijn Koster <m.koster@nexor.co.uk>)
- # 'execute selection', 'execute buffer' commands added
- # 0.1 9/93 - text filter functionality created
- #
- ##############################################################################
- #
- proc dummyPerl {} {
- }
-
- #############################################################################
- # Default settings for the Perl menu flags
- #
- set perlDefault(perlUseDebug) 0
- set perlDefault(perlGetOutput) 1
- set perlDefault(perlAutoSwitch) 1
- set perlDefault(perlOverwrite) 0
- set perlDefault(perlUsebuffer) 1
- set perlDefault(perlPromptArgs) 0
- set perlDefault(perlRecycleOutput) 0
- set perlDefault(perlPrevScript) {*startup*}
- set perlDefault(perlCmdlineArgs) {}
- set perlDefault(perlVersion) {4}
-
- if {![info exists perlFilterPath]} {
- set perlFilterPath "$HOME:Tcl:UserCode:Text Filters:"
- }
-
- ##NEW
- if {![info exists perlDocs]} {
- set perlDocs "$HOME:Help:Perl Commands"
- }
- ##
-
- foreach var [array names perlDefault] {
- if (![info exists PerlmodeVars($var)]) {
- set $var $perlDefault($var)
- } else {
- set $var $PerlmodeVars($var)
- }
- }
- unset perlDefault
-
- ##############################################################################
- # Make duplicate copies of these variables as modeVars, taking responsibility
- # for keeping the two sets consistent (argh!)
- #
- # (Maybe it's OK now to let them _just_ be modeVars, and not also ordinary
- # variables?)
- #
-
- newModeVar Perl perlUseDebug $perlUseDebug 1
- newModeVar Perl perlGetOutput $perlGetOutput 1
- newModeVar Perl perlAutoSwitch $perlAutoSwitch 1
- newModeVar Perl perlOverwrite $perlOverwrite 1
- newModeVar Perl perlUsebuffer $perlUsebuffer 1
- newModeVar Perl perlPromptArgs $perlPromptArgs 1
- newModeVar Perl perlRecycleOutput $perlRecycleOutput 1
-
- newModeVar Perl perlLastFilter $perlPrevScript 0
- newModeVar Perl perlCmdlineArgs $perlCmdlineArgs 0
-
- ##############################################################################
- # Other Perl-mode variable definitions
- #
- newModeVar Perl elecRBrace {0} 1
- newModeVar Perl elecLBrace {1} 1
- newModeVar Perl electricSemi {0} 1
- newModeVar Perl electricTab {1} 1
- newModeVar Perl electricReturn {1} 1
- newModeVar Perl wordBreak {(¥$)?¥w+} 0
- newModeVar Perl prefixString {# } 0
- newModeVar Perl wordWrap {0} 1
- newModeVar Perl funcExpr {^sub *([+-a-zA-Z0-9]+)} 0
- newModeVar Perl wordBreakPreface {[^a-zA-Z0-9_¥$]} 0
- newModeVar Perl autoMark 1 1
- newModeVar Perl stringColor green 0
-
- newModeVar Perl perlVersion $perlVersion 0
-
- ##############################################################################
- # Miscellaneous definitions
- #
- set perlErrorWindow {* Perl Error Messages *}
- set perlOutputWindow {* Perl Output *}
-
- set perlFilterMenu "textFilters"
-
- set modeCode ":Tcl:Modes:perl${perlVersion}.tcl"
- if {[catch {source $HOME$modeCode}]} {
- alertnote "Couldn't load the Perl-mode colorization file ¥"$modeCode¥". Contact the maintainer."
- }
-
- #############################################################################
- # Return paths to standard files, based on the path to MacPerl:
- #
- proc macperlFolder {} {
- set name [nameFromAppl McPL]
- regexp {(.*):([^:]*)} $name pathname dirname filename
- return ${dirname}:
- }
-
- proc stdinPath {} {
- return [macperlFolder]STDIN
- }
-
- proc scriptPath {} {
- return [macperlFolder]SCRIPT
- }
-
- #############################################################################
- # Define the dummy proc that will be called when the perl menu
- # is first inserted into the menubar
- #
- proc perlMenu {} {}
-
- #############################################################################
- # Build the perl menu
- #
- set perlMenu "・132"
- set perlOptsMenu "generalOptions"
- set filtOptsMenu "filterOptions"
-
- menu -n $perlMenu [ concat {
- "/'<Umacperl"
- {menu -m -n "tellMacperl..." -p perlTellProc {
- "/O<UOpen This File"
- "Save As Droplet"
- "Save As Runtime"
- "Save As CGI"
- "(-"
- "Get Output Window"
- "Close Output Window"
- "Quit"
- }
- }
- {menu -m -n help -p perlHelpProc {
- "MacPerl Mode"
- "Mac Specifics"
- "Perl4 Commands"
- "Perl5 Manual"
- }}
- perlPalette
- "(-"
- "runTheSelection"
- "/R<UrunTheBuffer"
- "/R<B<OsaveAndRun"
- "runAFile"
- "(-"
- } [list [list menu -n $perlFilterMenu {}]] {
- "selectBufferAsFilter"
- "selectFileAsFilter"
- "/F<UrepeatLastFilter"
- "(-"
- } [list [list menu -n $perlOptsMenu {}]] {
- } [list [list menu -n $filtOptsMenu {}]] {
- } ]
-
- enableMenuItem $perlMenu perlDebugWindow 0
- enableMenuItem "tellMacperl..." "Save As CGI" 0
-
- if {$perlPrevScript == {} || $perlPrevScript == {*startup*}} {
- enableMenuItem $perlMenu repeatLastFilter 0
- }
-
- # General Perl-menu options menu
- #
- menu -n $perlOptsMenu {
- "retrieveOutput"
- "autoSwitch"
- "promptForArgs"
- "useDebugger"
- }
- markMenuItem $perlOptsMenu useDebugger $perlUseDebug
- markMenuItem $perlOptsMenu retrieveOutput $perlGetOutput
- markMenuItem $perlOptsMenu autoSwitch $perlAutoSwitch
- markMenuItem $perlOptsMenu promptForArgs $perlPromptArgs
-
- # Text Filter options menu
- #
- menu -n $filtOptsMenu {
- "applyToBuffer"
- "overwriteSelection"
- "(-"
- "textFiltersFolder"
- "rebuildFilterMenu"
- }
- markMenuItem $filtOptsMenu overwriteSelection $perlOverwrite
- markMenuItem $filtOptsMenu applyToBuffer $perlUsebuffer
-
-
- #############################################################################
- # Build a submenu of "preattached" Perl filters using the names of the
- # scripts in the Text Filters directory. Called whenever Text Filters
- # folder is reassigned.
- #
- proc rebuildFilterMenu {{args}} {
- global perlFilters perlFilterMenu perlFilterPath
- global $perlFilterMenu
-
- eval [buildSubMenu [list $perlFilterPath] $perlFilterMenu textFiltersProc perlFilters]
- }
-
- rebuildFilterMenu
-
- #############################################################################
- # Use variable tracing to keep global vars and modeVars consistent.
- #
- trace variable PerlmodeVars(perlUseDebug) w shadowPerl
- trace variable PerlmodeVars(perlOverwrite) w shadowPerl
- trace variable PerlmodeVars(perlUsebuffer) w shadowPerl
- trace variable PerlmodeVars(perlGetOutput) w shadowPerl
- trace variable PerlmodeVars(perlAutoSwitch) w shadowPerl
- trace variable PerlmodeVars(perlPromptArgs) w shadowPerl
- trace variable PerlmodeVars(perlLastFilter) w shadowPerl
- trace variable PerlmodeVars(perlCmdlineArgs) w shadowPerl
- trace variable PerlmodeVars(perlRecycleOutput) w shadowPerl
- trace variable PerlmodeVars(perlVersion) w shadowPerl
-
- # perlFilterPath is now just a regular variable, set from the App Paths submenu
- trace variable perlFilterPath w rebuildFilterMenu
-
- # ShadowPerl sets the global vars when the mode vars are modified and
- # keeps the menu checkmarked correctly.
- #
- proc shadowPerl {name1 name2 op} {
- global HOME perlMenu perlOptsMenu filtOptsMenu
- global perlOverwrite perlUsebuffer perlGetOutput perlAutoSwitch
- global perlPromptArgs perlPrevScript perlCmdlineArgs perlUseDebug
- global PerlmodeVars
- if {$name1 == "PerlmodeVars" && $op == "w"} {
- switch $name2 {
- "perlUseDebug" {
- set perlUseDebug $PerlmodeVars(perlUseDebug)
- markMenuItem $perlOptsMenu useDebugger $perlUseDebug
- }
- "perlOverwrite" {
- set perlOverwrite $PerlmodeVars(perlOverwrite)
- markMenuItem $filtOptsMenu overwriteSelection $perlOverwrite
- }
- "perlUsebuffer" {
- set perlUsebuffer $PerlmodeVars(perlUsebuffer)
- markMenuItem $filtOptsMenu applyToBuffer $perlUsebuffer
- }
- "perlGetOutput" {
- set perlGetOutput $PerlmodeVars(perlGetOutput)
- markMenuItem $perlOptsMenu retrieveOutput $perlGetOutput
- }
- "perlAutoSwitch" {
- set perlAutoSwitch $PerlmodeVars(perlAutoSwitch)
- markMenuItem $perlOptsMenu autoSwitch $perlAutoSwitch
- }
- "perlPromptArgs" {
- set perlPromptArgs $PerlmodeVars(perlPromptArgs)
- markMenuItem $perlOptsMenu promptForArgs $perlPromptArgs
- }
- "perlCmdlineArgs" {
- set perlCmdlineArgs $PerlmodeVars(perlCmdlineArgs)
- }
- "perlRecycleOutput" {
- set perlRecycleOutput $PerlmodeVars(perlRecycleOutput)
- }
- "perlVersion" {
- set perlVersion $PerlmodeVars(perlVersion)
- set modeCode ":Tcl:Modes:perl${perlVersion}.tcl"
- if {[catch {source $HOME$modeCode}]} {
- alertnote "Couldn't load the Perl-mode colorization file ¥"$modeCode¥". Contact the maintainer."
- }
- }
- "perlLastFilter" {
- # Don't allow perlPrevScript to be changed from the flags menu
- if {$perlPrevScript == "*startup*"} {
- set perlPrevScript $PerlmodeVars(perlLastFilter)
- enableMenuItem $perlMenu repeatLastFilter 1
- } else {
- set PerlmodeVars(perlLastFilter) $perlPrevScript
- }
- }
- default {
- return
- }
- }
- }
- }
-
- #############################################################################
- # Menu commands
- #############################################################################
-
- ############################################################################
- # Toggle the perl menu flags
- #
- proc retrieveOutput {} {
- global perlMenu PerlmodeVars perlGetOutput modifiedModeVars
- lappend modifiedModeVars [list perlGetOutput PerlmodeVars]
- if {$perlGetOutput} then {
- set PerlmodeVars(perlGetOutput) 0
- } else {
- set PerlmodeVars(perlGetOutput) 1
- }
- }
-
- proc useDebugger {} {
- global perlMenu PerlmodeVars perlUseDebug modifiedModeVars
- lappend modifiedModeVars [list perlUseDebug PerlmodeVars]
- if {$perlUseDebug} then {
- set PerlmodeVars(perlUseDebug) 0
- } else {
- set PerlmodeVars(perlUseDebug) 1
- }
- }
-
- proc autoSwitch {} {
- global perlMenu PerlmodeVars perlAutoSwitch modifiedModeVars
- lappend modifiedModeVars [list perlAutoSwitch PerlmodeVars]
- if {$perlAutoSwitch} then {
- set PerlmodeVars(perlAutoSwitch) 0
- } else {
- set PerlmodeVars(perlAutoSwitch) 1
- }
- }
-
- proc overwriteSelection {} {
- global perlMenu perlOverwrite PerlmodeVars modifiedModeVars
- lappend modifiedModeVars [list perlOverwrite PerlmodeVars]
- if {$perlOverwrite} then {
- set PerlmodeVars(perlOverwrite) 0
- } else {
- set PerlmodeVars(perlOverwrite) 1
- }
- }
-
- proc applyToBuffer {} {
- global perlMenu perlUsebuffer PerlmodeVars modifiedModeVars
- lappend modifiedModeVars [list perlUsebuffer PerlmodeVars]
- if {$perlUsebuffer} then {
- set PerlmodeVars(perlUsebuffer) 0
- } else {
- set PerlmodeVars(perlUsebuffer) 1
- }
- }
-
- proc promptForArgs {} {
- global perlMenu perlPromptArgs PerlmodeVars modifiedModeVars
- lappend modifiedModeVars [list perlPromptArgs PerlmodeVars]
- if {$perlPromptArgs} then {
- set PerlmodeVars(perlPromptArgs) 0
- } else {
- set PerlmodeVars(perlPromptArgs) 1
- }
- }
-
- proc textFiltersFolder {} {
- global perlMenu perlFilterPath PerlmodeVars modifiedModeVars pathComments
-
- pathProc {} $pathComments(perlFilterPath)
- }
-
- #############################################################################
- # Switch to MacPerl:
- #
- proc macperl {} {
- launchForeAppl McPL
- }
-
- #############################################################################
- # Interact with MacPerl in some other way besides executing a script
- #
- proc perlTellProc {menu name} {
- switch -exact $name {
- "Open This File" { openInMacperl }
-
- "Save As Droplet" { saveThruMacperl "droplet" }
-
- "Save As Runtime" { saveThruMacperl "runtime" }
-
- "Save As CGI" { saveThruMacperl "cgi" }
-
- "Save As CGI-not" { saveThruMacperl "cgi-not" }
-
- "Get Output Window" { openPerlOutput }
-
- "Close Output Window" { sendCloseWinName MacPerl MacPerl ;
- sendCloseWinName MacPerl "Perl Debug" }
-
- "Quit" { quitMacperl }
- }
- }
-
- #############################################################################
- # Open the current file under MacPerl. This used to useful for saving files
- # as droplets or runtime scripts. Maybe it's still useful for something...?
- #
- proc openInMacperl {} {
- if {[winDirty]} {
- case [askyesno -c "Save '[lindex [winNames] 0]'?"] in {
- "yes" {save}
- "no" {}
- "cancel" {return}
- }
- }
- set name [launchForeAppl McPL]
- sendOpenEvent -n [file tail $name] [car [winNames -f]]
- }
-
- #############################################################################
- # Save the script in the current window as a MacPerl droplet or
- # runtime script.
- #
- proc saveThruMacperl {type} {
- global ALPHA
-
- set name [file tail [launchBackAppl McPL]]
- getWinInfo arr
- if {$arr(dirty) == 1} {
- case [askyesno -c "Save '[lindex [winNames] 0]' source file also?"] in {
- "yes" {save}
- "no" {}
- "cancel" {return}
- }
- }
-
- set destfile [AEFilename [putfile {Save droplet as} [lindex [winNames] 0]]]
-
- set script [curlyq [getText 0 [maxPos]]]
-
- if {$type == "droplet"} {
- set saveType "SCPT"
- } elseif {$type == "runtime"} {
- set saveType "MrP7"
- } elseif {$type == "cgi"} {
- set saveType "WWWス"
- } elseif {$type == "cgi-not"} {
- set saveType "WWWO"
- } elseif {$type == "text"} {
- set saveType "TEXT"
- }
-
- set err [catch {eval "AEBuild -t 36000 -r ¥"$name¥"" core save {----} [list $script] {dest:} [list $destfile] {fltp:} $saveType } reply ]
- if {$err} { message "AEBuild error code $err in saveThruMacperl" }
-
- # The following lines could be used to tell MacPerl to take the script file
- # from an existing disk file and then re-save it in the desired form.
- #
- # set srcfile "¥[ [AEFilename [car [winNames -f]]] ¥]"
- # set reply [eval "AEBuild -t 36000 -r ¥"$name¥"" core save {----} [list $srcfile] {dest:} [list $destfile] {fltp:} $saveType ]
- #
- }
-
- #############################################################################
- # Quit a running MacPerl app:
- #
- proc quitMacperl {} {
- foreach proc [processes] {
- set sig [lindex $proc 1]
- if {$sig == "McPL"} {
- sendQuitEvent [lindex $proc 0]
- # switchTo is necessary to keep MacPerl from blinking
- switchTo [lindex $proc 0]
- }
- }
- }
-
- #############################################################################
- # Run the selection as a MacPerl script:
- # (No special arrangements are made to provide input or capture the output)
- #
- proc runTheSelection {} {
- global scriptFile scriptStart
- set scriptFile [car [winNames -f]]
- set scriptStart [lindex [posToRowCol [getPos]] 0]
- perlExecuteScript [getSelect]
- }
-
- proc runTheBuffer {} {
- global scriptFile scriptStart
- set scriptFile [car [winNames -f]]
- set scriptStart 1
- perlExecuteScript [getText 0 [maxPos]]
- }
-
- proc runAFile {} {
- global scriptFile scriptStart
- if {! [catch {getfile "Select a Perl script"} path]} {
- set scriptFile $path
- set scriptStart 1
- perlExecuteFile $path
- }
- }
-
- proc saveAndRun {} {
- global scriptFile scriptStart
- save
- set path [car [winNames -f]]
- set scriptFile $path
- set scriptStart 1
- perlExecuteFile $path
- }
-
- #############################################################################
- # Run a preattached Perl text-filter script selected from the menu:
- #
- proc textFiltersProc {menu name} {
- global perlFilters scriptFile scriptStart
-
- perlFileAsFilter $perlFilters($menu:$name)
- }
-
- #############################################################################
- # Reuse the previous (buffer or file) filter:
- #
- proc repeatLastFilter {} {
- global scriptFile scriptStart perlPrevScript perlMenu PerlmodeVars
- if {$perlPrevScript != {}} {
- set stype [lindex $perlPrevScript 0]
- set name [lindex $perlPrevScript 1]
- if {$stype == "file"} {
- perlFileAsFilter $name
- } elseif {$stype == "buffer"} {
- perlBufferAsFilter $name
- } else {
- message "Bogus filter name : ¥"$perlPrevScript¥""
- set perlPrevScript {}
- set PerlmodeVars(perlLastFilter) $perlPrevScript
- enableMenuItem $perlMenu repeatLastFilter 0
- }
- }
- }
-
- #############################################################################
- # Ask for a file containing a Perl script to use as a filter:
- #
- proc selectFileAsFilter {} {
- global scriptFile scriptStart perlPrevScript
- if {! [catch {getfile "Select a MacPerl script"} path]} {
- perlFileAsFilter $path
- }
- }
-
- #############################################################################
- # Ask for an Alpha buffer containing a Perl script to use as a filter:
- #
- proc selectBufferAsFilter {} {
- global scriptFile scriptStart perlPrevScript
-
- set windows [winNames]
- set current [lindex $windows 0]
- if {[llength $windows] > 1} {
- set name [listpick [lsort $windows]]
- if {[string length $name]} {
- # get the full name of the chosen window
- set wname [lindex [winNames -f] [lsearch -exact $windows $name]]
- perlBufferAsFilter $wname
- }
- }
- }
-
- #############################################################################
- # Open a file from the MacPerl application folder - used by "Open Special"
- #
- proc perlOpenFile {menu name} {
- set filename [macperlFolder]$name
- if {[file exists $filename]} {
- edit $filename
- } else {
- alertnote "That file doesn't exist yet"
- }
- }
-
- #############################################################################
- # Support procs
- #############################################################################
-
- #############################################################################
- # Prompt the user to enter a string containing command-line args.
- #
- proc getCmdlineArgs {} {
- global PerlmodeVars
- set oldargs $PerlmodeVars(perlCmdlineArgs)
- if {![catch {prompt "Command-line arguments (if any):" $oldargs} args]} {
- set PerlmodeVars(perlCmdlineArgs) $args
- } else {
- error "getCmdlineArgs: User cancelled"
- }
- return $args
- }
-
- #############################################################################
- # Tell MacPerl to run a script file:
- #
- proc perlExecuteFile {path {args {}} {flags {}}} {
- global ALPHA
- global perlGetOutput perlAutoSwitch perlPromptArgs perlUseDebug
- global scriptFile scriptStart filterHeadLen
-
- if {[string length $path]} {
- set name [file tail [launchBackAppl McPL]]
- if {[string length $name]} {
-
- set ok [regexp {(.*):([^:]*)} $path pathname dirname filename]
- if {!$ok} { set name $wname }
-
- if {$path != [scriptPath]} {
- set filterHeadLen 0
- }
-
- if {$perlUseDebug} {
- append flags "debug"
- }
- if {$perlPromptArgs} {
- append args " [getCmdlineArgs]"
- }
-
- sendCloseWinName MacPerl MacPerl
- sendCloseWinName MacPerl "Perl Debug"
- if {$perlAutoSwitch || $perlUseDebug} then {
- switchTo $name
- } else {
- message "Running file ¥"$filename¥" as Perl script"
- watchCursor
- }
-
- perlDoScript "MacPerl" $path $args {} $flags
-
- # (not sure which choice is better...)
- # if {!$perlAutoSwitch} then {switchTo $ALPHA}
- switchTo $ALPHA
- #
- if {![getMacPerlError]} {
- if {$perlGetOutput} then {openPerlOutput}
- }
- } else {
- alertnote "Couldn't run MacPerl"
- }
- } else {
- alertnote "No file specified to execute"
- }
- }
-
- #############################################################################
- # Run a MacPerl script, passed explicitly as a string:
- #
- # If no "#!/bin/perl" line already exists, one is preprended to the script
- # by wrapSelectScript, which also sets $filterHeadLen for use by
- # getMacPerlError.
- #
- proc perlExecuteScript {script {args ""} {flags {}} } {
- global perlGetOutput perlAutoSwitch perlPromptArgs
- global scriptFile scriptStart filterHeadLen perlUseDebug ALPHA
-
- if {$script != ""} {
- set script [wrapSelectScript $script]
-
- if {![regexp {(.*):([^:]*)} $scriptFile pathname dirname filename]} {
- set filename $scriptFile
- }
-
- set name [file tail [launchBackAppl McPL]]
- if {[string length $name]} {
-
- if {$perlUseDebug} {
- append flags "debug"
- }
- if {$perlPromptArgs} {
- append args " [getCmdlineArgs]"
- }
-
- sendCloseWinName MacPerl MacPerl
- sendCloseWinName MacPerl "Perl Debug"
- if {$perlAutoSwitch || $perlUseDebug} then {
- switchTo $name
- } else {
- message "Running buffer ¥"$filename¥" as Perl script"
- watchCursor
- }
-
- perlDoScript "MacPerl" $script $args {} $flags
-
- switchTo $ALPHA
-
- if {![getMacPerlError]} {
- if {$perlGetOutput} then {openPerlOutput}
- }
- }
-
- } else {
- alertnote "Can't run an empty script"
- }
- }
-
- #############################################################################
- # Prepare the contents of a disk file for use as a text-filter script.
- # (calls perlTextFilter to actually run the script)
- #
- proc perlFileAsFilter {path} {
- global scriptFile scriptStart perlPrevScript perlMenu PerlmodeVars
-
- regexp {(.*):([^:]*)} $path pathname dirname name
-
- if {![catch {readFile $path} coreScript]} {
- set script [wrapFilterScript $coreScript]
- set scriptFile $path
- set scriptStart 1
- set perlPrevScript [list "file" $path]
- set PerlmodeVars(perlLastFilter) $perlPrevScript
- enableMenuItem $perlMenu repeatLastFilter 1
- message "Running file ¥"$name¥" as text filter ..."
-
- perlTextFilter $script
- } else {
- set perlPrevScript {}
- set PerlmodeVars(perlLastFilter) $perlPrevScript
- enableMenuItem $perlMenu repeatLastFilter 0
-
- alertnote "Couldn't read the script file : $path"
- return
- }
- }
-
- #############################################################################
- # Prepare the contents of a text window for use as a text-filter script.
- # (calls perlTextFilter to actually run the script)
- #
- proc perlBufferAsFilter {wname} {
- global scriptFile scriptStart perlPrevScript perlMenu PerlmodeVars
-
- set ok [regexp {(.*):([^:]*)} $wname pathname dirname name]
- if {!$ok} { set name $wname }
-
- if {[lsearch [winNames -f] $wname] >= 0} {
- set coreScript [getText -w $wname 0 [maxPos -w $wname]]
-
- # Does it have any text in it?
- if {[string length $coreScript]} {
- set scriptFile $wname
- set scriptStart 1
- set script [wrapFilterScript $coreScript]
- set perlPrevScript [list "buffer" $wname]
- set PerlmodeVars(perlLastFilter) $perlPrevScript
- enableMenuItem $perlMenu repeatLastFilter 1
- message "Running buffer ¥"$name¥" as text filter ..."
-
- perlTextFilter $script
- }
- } else {
- set perlPrevScript {}
- set PerlmodeVars(perlLastFilter) $perlPrevScript
- enableMenuItem $perlMenu repeatLastFilter 0
-
- alertnote "Couldn't find buffer : $name"
- }
- }
-
- #############################################################################
- # Run a Perl script as a command-line text filter, arranging for a text
- # buffer to be attached as standard input. The calling routine should already
- # have processed the script with wrapFilterScript. This routine actually
- # send the script and takes care of writing the input and reading the output
- # files.
- #
- proc perlTextFilter {script {args {}} {flags {}}} {
- global perlOverwrite perlUsebuffer perlPromptArgs
- global filterHeadLen scriptFile scriptStart perlUseDebug ALPHA
- global perlOutputWindow perlRecycleOutput
-
- set name [file tail [launchBackAppl McPL]]
- if {![string length $name]} {
- alertnote "Couldn't run MacPerl"
- error "Couldn't run MacPerl"
- }
- writeStdin
-
- if {$perlUseDebug} {
- append flags "debug"
- }
- if {$perlPromptArgs} {
- append args " [getCmdlineArgs]"
- }
-
- sendCloseWinName MacPerl MacPerl
- sendCloseWinName MacPerl "Perl Debug"
-
- if {$perlUseDebug} then {
- switchTo $name
- perlDoScript "MacPerl" [scriptPath] $args [list [stdinPath]] $flags
- set err [getMacPerlError]
-
- } else {
- watchCursor
- set reply [perlDoScriptBatch "MacPerl" [scriptPath] $args [list [stdinPath]]]
- set err [getBatchError $reply]
- }
-
- switchTo $ALPHA
-
- if {$err == 0} {
- if {$perlUseDebug} {
- set outp [sendGetText MacPerl MacPerl]
- } else {
- # set outp [parseReplyOutp $reply]
- set outp [parseReplyResult $reply]
- }
- pasteFilterResult $outp
- }
- }
-
-
- #############################################################################
- # Check the MacPerl output window for error messages.
- #
- proc getMacPerlError {} {
-
- set diag [getPerlDiag 40]
- set srcs [parseDiagSrcs $diag]
- set errf [parseDiagErrf $diag]
- set mesg [parseDiagMesg $diag]
-
- if {[string length $errf]} {
- showPerlDiag $diag [string length $diag] $mesg $errf $srcs
- gotoPerlError $errf $srcs $mesg
- return 1
-
- } else {
- return 0
- }
- }
-
- #############################################################################
- # Check the MacPerl batch reply for error messages.
- #
- proc getBatchError {reply} {
- global perlErrorWindow
-
- set fatalError 0
- set diag [parseReplyDiag $reply]
- set errf [parseDiagErrf $diag ]
- set srcs [parseReplySrcs $reply]
- set mesg [parseDiagMesg $diag ]
- set errn [parseReplyErrn $reply]
-
- if {$errn} {
- showPerlDiag $diag $errn $mesg $errf $srcs
- gotoPerlError $errf $srcs $mesg
- set fatalError 1
-
- } elseif {[string length $diag] > 0} {
- showPerlDiag $diag $errn $mesg $errf $srcs
- }
-
- return $fatalError
- }
-
- #############################################################################
- # Display the Perl diagnostic output in its own window.
- #
- proc showPerlDiag {diag {errn 1} {mesg {}} {errf {}} {srcs {}}} {
- global perlErrorWindow
-
- set currWin [lindex [winNames] 0]
- if {[lsearch [winNames] $perlErrorWindow] >= 0} {
- bringToFront $perlErrorWindow
- setWinInfo read-only 0
- deleteText 0 [maxPos]
- insertText $diag
- } else {
- new -n $perlErrorWindow
- insertText $diag
- }
-
- goto 0
- catch {shrinkWindow 2}
- setWinInfo dirty 0
- setWinInfo read-only 1
- bringToFront $currWin
- }
-
- #############################################################################
- # Bring up a window containing the bug-ridden Perl code and highlight the
- # line at which the error was found.
- #
- proc gotoPerlError {errf srcs {mesg {}}} {
- global scriptFile scriptStart filterHeadLen
-
- if {$errf == [scriptPath] || $errf == "<AppleEvent>"} {
- set errf $scriptFile
- # Convert it to the line number in the original file
- set srcs [expr $srcs + $scriptStart - $filterHeadLen - 1]
- }
- # ... and leave an informative error message
- #
- if {[string length $mesg]} {
- set mesg "$mesg at Line $srcs"
- } else {
- set mesg "MacPerl flagged an error at Line $srcs"
- }
-
- # Bring up the script file and highlight the flagged line
- #
- catch {gotoFileLine $errf $srcs $mesg} fname
- }
-
- #############################################################################
- # Read the first block of lines (up to a maximum number) from the MacPerl
- # output window.
- #
- proc getPerlDiag {maxlines} {
- set pat0 {^[ ¥t]*$}
-
- set lines {}
-
- # read first $maxlines of output to the MacPerl window
- # (faster, but assumes error message won't appear at
- # the end of a lot of output).
- #
- set nlines [sendCountLines MacPerl MacPerl]
- set nlines [expr ($nlines > $maxlines)?$maxlines:$nlines]
- if {$nlines > 0} {
- set output [sendGetText MacPerl MacPerl 1 $nlines]
-
- foreach line [split $output "¥r"] {
- if {[regexp $pat0 $line mtch]} {
- break
- } else {
- append lines "$line¥n"
- }
- }
- }
- return $lines
- }
-
- #############################################################################
- # Extract various items out of the MacPerl diagnostic output
- #
-
- # Name of the file in which the error was found
- #
- proc parseDiagErrf {diag} {
- if {![regexp {File '([^']+)'; Line} $diag allofit errf]} {
- set errf {}
- }
- return $errf
- }
-
- # The line number on which the error was found
- #
- proc parseDiagSrcs {diag} {
- if {![regexp {File '[^']+'; Line ([0-9]+)} $diag allofit srcs]} {
- set srcs 0
- }
- return $srcs
- }
-
- # The error message associated with error
- #
- proc parseDiagMesg {diag} {
- set pat1 {^#(.*)$}
- set pat2 {File '([^']+)'; Line ([0-9]+)}
-
- set errMessage {}
- set errFound 0
-
- foreach line [split $diag "¥n"] {
- if {[regexp $pat2 $line mtch num]} {
- set errFound 1
- } elseif {[regexp $pat1 $line mtch err]} {
- if {$errFound == 0} {
- set errMessage $err
- }
- }
- }
- return $errMessage
- }
-
- #############################################################################
- # Extract various return parameters out of a MacPerl DoScript reply
- #
-
- # Result from batch script
- #
- proc parseReplyResult {reply} {
- if {![regexp {'?¥-¥-¥-¥-'?:メ([^モ]*)モ} $reply allofit result]} {
- set result {}
- }
- return $result
- }
-
- # Standard output of batch script
- #
- proc parseReplyOutp {reply} {
- if {![regexp {OUTP:メ([^モ]*)モ} $reply allofit outp]} {
- set outp {}
- }
- return $outp
- }
-
- # Diagnostic output of the batch script
- #
- proc parseReplyDiag {reply} {
- if {[regexp {diag:メ([^モ]*)モ} $reply allofit diag]} {
- } else {
- set diag {}
- }
- return $diag
- }
-
- # File alias of the script file in which the error was found
- #
- proc parseReplyErob {reply} {
- if {![regexp {erob:alis¥(ヌ(.*)ネ¥)} $reply allofit erob]} {
- set erob {}
- }
- return $erob
- }
-
- # First line flagged in error
- #
- proc parseReplySrcs {reply} {
- if {![regexp {erng:{srcs:([0-9]+)[^¥}]*}} $reply allofit srcs]} {
- set srcs 0
- }
- return $srcs
- }
-
- # Last line flagged in error
- #
- proc parseReplySrce {reply} {
- if {![regexp {erng:{[^¥}]*srce:([0-9]+)}} $reply allofit srce]} {
- set srce 0
- }
- return $srce
- }
-
- # Error number
- #
- proc parseReplyErrn {reply} {
- if {![regexp {errn:([0-9]+)} $reply allofit errn]} {
- set errn 0
- }
- return $errn
- }
-
- #############################################################################
- # Take a Perl script and add commands to take the file STDIN as standard
- # input and STDOUT as standard output. This allows scripts written as
- # Unix command-line filters to be used in the (non-MPW) Mac environment as
- # text filters.
- #
- # If there's already a #! line in the script, then the new commands
- # are added after that line. If there was no #! line in the first place,
- # one is added, in case MacPerl is set up to require it (can't hurt...)
- #
- # $filterHeadLen counts the number of lines we add to the top of the
- # original script, so that we can allow for it in interpreting error
- # messages issued by MacPerl.
- #
- # *** As of MacPerl 4.1.4, this business is pretty much obsolete ***
- #
- proc wrapFilterScript {coreScript} {
- global filterHeadLen
-
- if {[regexp -indices {(#![ !-~]*)} $coreScript allofit cmdln]} {
- set endPos [lindex $cmdln 1]
- set filterHead [string range $coreScript 0 [expr $endPos+1]]
- set coreScript [string range $coreScript [expr $endPos+2] end]
- set filterHeadLen 0
- } else {
- set filterHead "#!/bin/perl¥n¥r"
- set filterHeadLen 2
- }
-
- set script $filterHead
- append script $coreScript
-
- # for debugging purposes, save the script on disk
- #
- writeScript $script
- return $script
- }
-
- #############################################################################
- # Add a #!/bin/perl line to the script if it doesn't contain one already.
- # (MacPerl puts up dialog if this line is missing when it expects it,
- # hanging the DoScript and leaving us stuck.)
- #
- proc wrapSelectScript {coreScript} {
- global filterHeadLen
-
- if {![regexp -indices {(#![ !-~]*)} $coreScript allofit cmdln]} {
- set script "#!/bin/perl¥r¥n"
- append script $coreScript
- set filterHeadLen 1
- } else {
- set script $coreScript
- set filterHeadLen 0
- }
-
- # for debugging purposes, save the script on disk
- #
- writeScript $script
- return $script
- }
-
- #############################################################################
- # Paste result of the filter operation in place of the input text, or in
- # a new window (depending on the flag $perlOverwrite
- #
- proc pasteFilterResult {text} {
- global perlOverwrite perlRecycleOutput perlOutputWindow
- global perlUsebuffer
-
- if {!$perlOverwrite} {
- if {$perlRecycleOutput &&
- [lsearch [winNames] $perlOutputWindow] >= 0} {
- bringToFront $perlOutputWindow
- } else {
- new -n $perlOutputWindow
- }
- }
-
- if {$perlUsebuffer || $perlRecycleOutput} {
- set from 0
- set to [maxPos]
- } else {
- set from [getPos]
- set to [selEnd]
- }
- replaceText $from $to $text
-
- if {!$perlOverwrite || $perlUseBuffer} {
- catch {shrinkWindow 2}
- goto 0
- } else {
- catch shrinkWindow
- goto $from
- }
- if {!$perlOverwrite} { setWinInfo dirty 0 }
- }
-
- #############################################################################
- # Extend the current selection to encompass complete lines. If the
- # 'applyToBuffer' flag is checked, then the entire buffer is selected.
- #
- proc completeSelection {} {
- global perlUsebuffer filterInput
- set filterInput "buffer ¥"[lindex [winNames] 0]¥""
- if {$perlUsebuffer} {
- set start 0
- set end [maxPos]
- } else {
- set start [lineStart [getPos]]
- set end [nextLineStart [expr [selEnd]-1]]
- if {$end == $start} { set end [nextLineStart [selEnd]] }
-
- set startLine [lindex [posToRowCol $start] 0]
- set endLine [expr [lindex [posToRowCol $end] 0] - 1]
- if {$endLine > $startLine+1} {
- set filterInput "lines $startLine to $endLine of $filterInput"
- } else {
- set filterInput "line $startLine of $filterInput"
- }
- }
- return [list $start $end]
- }
-
- #############################################################################
- # writeStdin: Extend the selection, as appropriate, and write it to the
- # STDIN file in the MacPerl directory.
- #
- # writeScript: Write the SCRIPT file in the MacPerl directory. MacPerl will
- # read the script from this file.
- #
- proc writeStdin {} {
- set res [completeSelection]
- set tmpfid [open [stdinPath] "w+"]
- puts $tmpfid [eval getText $res]
- close $tmpfid
- }
-
- # This is unnecessary now, but maybe it'll still useful to save the script
- # file for debugging.
- #
- proc writeScript {script} {
- set tmpfid [open [scriptPath] "w+"]
- puts $tmpfid $script
- close $tmpfid
- }
-
- #############################################################################
- # Read the MacPerl output window and load the contents, if any, into
- # a new Alpha window.
- #
- proc openPerlOutput {} {
- global perlRecycleOutput perlOutputWindow
-
- set output [sendGetText MacPerl MacPerl]
- if {[string length $output]} {
- if {$perlRecycleOutput &&
- [lsearch [winNames] $perlOutputWindow] >= 0} {
-
- bringToFront $perlOutputWindow
- replaceText 0 [maxPos] $output
- } else {
- new -n $perlOutputWindow
- insertText $output
- }
- catch {shrinkWindow 2}
- setWinInfo dirty 0
- goto 0
- }
- }
-
- #############################################################################
- # translate special DoScript flags into flags string $usrf
- #
- proc perlScriptFlags {{flags {}}} {
- set usrf {}
-
- if {[lsearch -exact $flags "extract"] >= 0} {
- append usrf { "EXTR" 'true'}
- } elseif {[lsearch -exact $flags "noextract"] >= 0} {
- append usrf { "EXTR" 'fals'}
- }
- if {[lsearch -exact $flags "debug"] >= 0} {
- append usrf { "DEBG" 'true'}
- } elseif {[lsearch -exact $flags "nodebug"] >= 0} {
- append usrf { "DEBG" 'fals'}
- }
-
- if {[lsearch -exact $flags "local"] >= 0} {
- append usrf { "MODE" 'LOCL'}
- } elseif {[lsearch -exact $flags "batch"] >= 0} {
- append usrf { "MODE" 'BATC'}
- } elseif {[lsearch -exact $flags "remote"] >= 0} {
- append usrf { "MODE" 'RCTL'}
- }
- return $usrf
- }
-
- proc perlScriptArgs {{args {}} {fileargs {}}} {
- set nargs 0
- set argv {}
-
- foreach item [parseWords $args] {
- set item [string trim $item]
- if {[string length $item]} {
- append argv ", [curlyq $item]"
- incr nargs
- }
- }
- foreach filename $fileargs {
- set item [string trim $filename]
- if {[string length $item]} {
- append argv ", [curlyq $item]"
- incr nargs
- }
- }
- return $argv
- }
-
- #############################################################################
- # General Apple Event routines
- # (most of these have been moved to Modes:appleEvents.tcl)
- #
- # DoScript for MacPerl 4.1.3
- # (runs in "Local" mode under v4.1.4+)
- #
- proc perlDoScript {appname script {args {}} {fileargs {}} {flags {}} } {
- # form list of quoted "command-line" args
- #
- if {$script != ""} {
- set argv "¥[[curlyq [string trim $script]]"
- # foreach item [split [join $args " "] " "] {
- #}
- append argv [perlScriptArgs $args $fileargs]
- append argv "]"
-
- set usrf [perlScriptFlags $flags]
- set reply [eval "AEBuild -t 36000 -r ¥"$appname¥" misc dosc $usrf ¥"----¥" [list $argv] "]
- # alertnote $reply
- }
- }
-
- # DoScript for MacPerl 4.1.4+
- #
- proc perlDoScriptBatch {appname script {args {}} {fileargs {}}} {
-
- # form list of quoted "command-line" args
- #
- if {$script != ""} {
- set argv "¥[[curlyq [string trim $script]]"
- append argv [perlScriptArgs $args $fileargs ]
- append argv "]"
-
- set reply [eval "AEBuild -t 36000 -r ¥"$appname¥" misc dosc MODE BATC ¥"----¥" [list $argv]"]
-
- # perlDisplayReply $reply
-
- } else {
- set reply {}
- }
- return $reply
- }
-
- # For debugging
- #
- proc perlDisplayReply {reply} {
- set currWin [lindex [winNames] 0]
- new -n {*** DoScript Reply **}
- insertText $reply
-
- goto 0
- catch {shrinkWindow 2}
- setWinInfo dirty 0
- setWinInfo read-only 1
- bringToFront $currWin
- }
-
- # DoScript to launch interactive debugger (for MacPerl 4.1.4+)
- #
- proc perlDoScriptDebug {appname script {args {}} {fileargs {}}} {
-
- # form list of quoted "command-line" args
- #
- if {$script != ""} {
- set argv "¥[[curlyq [string trim $script]]"
- append argv [perlScriptArgs "$args debug" $fileargs ]
- append argv "]"
-
- set reply [eval "AEBuild -t 36000 -r ¥"$appname¥" misc dosc MODE RCTL ¥"----¥" [list $argv]"]
-
- new -n {** DoScriptDebug Reply **}
- insertText $reply
-
- goto 0
- catch {shrinkWindow 2}
- setWinInfo dirty 0
- setWinInfo read-only 1
-
-
- } else {
- set reply {}
- }
- return $reply
- }
-
- ##############################################################################
- # Automatic indexing of Perl subs
- #
- proc PerlMarkFile {} {
- set end [maxPos]
- set pos 0
- set l {}
- while {![catch {search -f 1 -r 1 -m 0 -i 0 {^sub} $pos} res]} {
- set start [lindex $res 0]
- set end [nextLineStart $start]
- set text [lindex [getText $start $end] 1]
- set pos $end
- set inds($text) [lineStart [expr $start - 1]]
- }
-
- if {[info exists inds]} {
- foreach f [lsort [array names inds]] {
- set next [nextLineStart $inds($f)]
- setNamedMark $f $inds($f) $next $next
- }
- }
- }
-
-
- # Open a 'require'd Perl file.
- #
- proc perlFindRequire {from {to 0}} {
- set reqPat {^[ ]*require[ ]*(¥"[^¥"]+¥"|¥'[^¥']+¥'|[^ ]+)}
- if {$to == 0} { set to $from }
- set beg [lineStart $from]
- set end [nextLineStart $to]
- set words [parseWords [getText $beg $end]]
- if {[string tolower [lindex $words 0]] != "require"} {
- error "Not a require statement"
- }
- set root [string trim [lindex $words 1] {'"}]
- return $root
- }
-
- proc inlineRequires {} {
- global lastMatchingLines
-
- set reqPat {^[ ]*require[ ]*(¥"[^¥"]+¥"|¥'[^¥']+¥'|[^ ]+)}
- set pos 0
- while {![catch {search -s -f 1 -r 1 -m 0 -i 1 $reqPat $pos} mtch]} {
- [lindex [posToRowCol [lindex $mtch 0]] 0]]
- set name [string [eval getText $mtch]
- set pos [lindex $mtch 1]
- incr matches
- }
- }
-
- # Open a Perl source file.
- #
- proc openPerlFile {file {extensions {""}}} {
- global perlSearchPath
- # Determine absolute file specification
- # Ignore $extensions if $file already has an extension
- if {[string length [file extension $file]] == 0} {
- set extensions {""}
- }
- foreach ext $extensions {
- set filename [absolutePath $file$ext]
- if {![catch {openFileQuietly $filename}]} {
- message $filename
- return
- }
- }
- if {[llength $perlSearchPath] == 0} { buildPerlSearchPath }
- foreach folder $perlSearchPath {
- foreach ext $extensions {
- set filename "$folder$file$ext"
- if {![catch {openFileQuietly $filename}]} {
- message $filename
- return
- }
- }
- }
- beep
- message "can't find Perl source file ¥"$file¥""
- }
-
- # Return a list of folders in which to search for Perl library files,
- # including the lib folder in the Perl application directory and the
- # $perlLib folder (if it exists) .
- # The current folder is not included in the list.
- #
- # (The $perlLib folder is assigned from the AppPaths submenu.)
- #
- proc buildPerlSearchPath {} {
- global perlLib perlSearchPath
- message "building Perl search path..."
- set folders {}
-
- # The local lib folder:
- if {[info exists perlLib] && [string length $perlLib] > 0} {
- set folders [concat $folders [list $perlLib]]
- # Search subfolders one level deep:
- set folders [concat $folders [listSubfolders $perlLib 1]]
- }
-
- # Any "*lib*" folders in the MacPerl application folder:
- set macperlPath [nameFromAppl McPL]
- set appDir [file dirname $macperlPath]
- set folders [concat $folders [list $appDir]]
- # Bug: 'glob' is case sensitive!
- foreach folder [glob "$appDir:*¥[Ll¥]ib*"] {
- set folders [concat $folders [list $folder]]
- # Search subfolders one level deep:
- set folders [concat $folders [listSubfolders $folder 1]]
- }
-
- # Make sure each folder ends with a colon
- set perlSearchPath {}
- foreach folder $folders {
- set folder "[string trimright $folder {:}]:"
- set perlSearchPath [concat $perlSearchPath [list $folder]]
- }
- }
-
- ###########################################################################
-
-
-
-
- proc perlHelpProc {menu item} {
- global HOME
- switch $item {
- "MacPerl Mode" {edit -r "$HOME:Help:MacPerl Help"}
- "Mac Specifics" {edit -r "$HOME:Help:MacPerl.Specifics"}
- "Perl4 Commands" {edit -r "$HOME:Help:Perl Commands"}
- "Perl5 Manual" {
- if {[file exists "Development:Docs:PerlDocs:perl.html"]} {
- global browserSig
- set name [file tail [launchBackAppl $browserSig]]
- switchTo $name
- sendOpenEvent -n $name "Development:Docs:PerlDocs:perl.html"
- } else {
- alertnote "Only Pete can do that!"
- }
- }
- }
- }
-
- proc perlPalette {} {
- global perlMenu
- float -m $perlMenu -n Perl -M 2
- }
-
- bind '¥r' tclCarriageReturn Perl
- bind '¥}' <s> electricRight Perl
- bind '¥{' <s> electricLeft Perl
- bind '¥;' electricSemi Perl
- bind '¥t' <z> doATab Perl
-