home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-12-19 | 18.0 KB | 664 lines | [TEXT/ALFA] |
- # (nowrap)
-
- namespace eval mode {}
- namespace eval win {}
- namespace eval file {}
-
- # ◊◊◊◊ Declare Alpha packages ◊◊◊◊ #
- proc alpha::extension {name version {script ""} args} {
- global alpha::rebuilding
- if {!${alpha::rebuilding}} {return}
- global index::extension rebuild_cmd_count
- set index::extension($name) [list $version $script]
-
- if {[llength $args]} {
- eval alpha::package [lindex $args 0] $name $version [lrange $args 1 end]
- return
- }
- if {[info exists rebuild_cmd_count] && [incr rebuild_cmd_count -1] == 0} {
- return -code 11
- }
- }
-
- proc alpha::mode {name version dummyProc {ext ""} {menus ""} {script ""} args} {
- global alpha::rebuilding
- if {!${alpha::rebuilding}} {return}
- namespace eval ::$name {}
- global index::mode rebuild_cmd_count
- set index::mode($name) [list $version $dummyProc $ext $menus $script]
- if [llength $args] {
- eval alpha::package [lindex $args 0] $name $version [lrange $args 1 end]
- return
- }
- if {[info exists rebuild_cmd_count] && [incr rebuild_cmd_count -1] == 0} {
- return -code 11
- }
- }
-
- proc alpha::menu {name version value {menu 0} {script ""} args} {
- global alpha::rebuilding
- if {!${alpha::rebuilding}} {return}
- global index::menu rebuild_cmd_count
- if {$menu == "in_menu"} { set in_menu 1 } else {set in_menu 0}
- set index::menu($name) [list $version $value $in_menu $script]
- if [llength $args] {
- eval alpha::package [lindex $args 0] $name $version [lrange $args 1 end]
- return
- }
- if {[info exists rebuild_cmd_count] && [incr rebuild_cmd_count -1] == 0} {
- return -code 11
- }
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "addMode" -- you probably won't call this proc yourself
- #
- # -------------------------------------------------------------------------
- ##
- proc addMode {m dummy suffs menus} {
- global modeMenus filepats dummyProc
- namespace eval ::$m {}
- if {[string length $dummy]} {set dummyProc($m) $dummy}
- ensureset modeMenus($m) $menus
- ensureset filepats($m) $suffs
- }
-
- proc addMenu {name {val ""}} {
- global menus
- lunion menus $name
- if {$val != ""} {
- global $name
- if {![info exists $name]} { set $name $val }
- }
- }
-
-
- # ◊◊◊◊ Procs Alpha calls directly ◊◊◊◊ #
- proc getModeValuesAlpha {} {
- global showInvisibles
-
- getWinInfo blah
- lappend m "Mac" [expr {$blah(platform) == "mac"}]
- lappend m "UNIX" [expr {$blah(platform) == "unix"}]
- lappend m "IBM" [expr {$blah(platform) == "ibm"}] {(-} 0
- lappend m "MPW" [expr {$blah(state) == "mpw"}]
- lappend m "Think" [expr {$blah(state) == "think"}]
- lappend m "None" [expr {$blah(state) == "none"}] {(-} 0
- lappend m "Read Only" $blah(read-only)
- lappend m "Show Invisibles" $showInvisibles {(-} 0
- lappend m "Tab Size" 0
- return $m
- }
-
-
- proc setModeVarAlpha {var} {
- global mode allFlags modeVars
- global ${mode}modeVars
-
- set var [string tolower $var]
- switch -- $var {
- "unix" -
- "mac" -
- "ibm" { setWinInfo platform $var ; setWinInfo dirty 1 }
- "mpw" -
- "think" -
- "none" { setWinInfo state $var }
- "tab size" {
- getWinInfo arr
- if {![catch {prompt "New tab size?" $arr(tabsize)} res]} {
- setWinInfo tabsize $res
- }
- }
- "read only" {
- getWinInfo b
- setWinInfo read-only [expr -1 * ($b(read-only) - 1)]}
- "show invisibles" {
- global showInvisibles
- set showInvisibles [expr 1 - $showInvisibles]
- }
- }
- return
- }
-
- # Called from alpha in response to the mode popup.
- proc newMode mode {
- if [package::helpOrDescribe $mode] { return }
- global win::Modes modeProcs
- changeMode $mode
- if {[catch {car [winNames -f]} name]} return
- set win::Modes($name) $mode
- refresh
- }
-
- # ◊◊◊◊ Mode specific items ◊◊◊◊ #
-
- proc mode::menuProc {menu item} {
- if {![llength [winNames]]} {
- alertnote "No window!"
- return
- }
- switch -- $item {
- "preferences" dialog::modifyModeFlags
- "menus" mode::setMenus
- "editPrefsFile" mode::editPrefsFile
- "loadPrefsFile" mode::sourcePrefsFile
- "describeMode" mode::describe
- "change" mode::changeDialog
- default {
- mode::$item
- }
- }
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "win::setMode" --
- #
- # Copes with endings like '.orig'
- # or the backup ending '~' or ' copy', and checks a smart-mode line
- # like emacs, and handles a few Alpha-specific windows (trace dumps).
- #
- # -------------------------------------------------------------------------
- ##
- proc win::setMode name {
- global win::Modes
- set win::Modes($name) [file::whichModeForWin $name]
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "file::getModeForFile" --
- #
- # This is an adaptation of Tom Pollard's emacs mode setting facility.
- # I call it from activateHook, which means it takes effect before
- # the window yet exists, so you don't get a double redraw.
- # Here are Tom's comments from the original:
- #
- # # Emacs-style mode selection using first nonblank line of file
- # #
- # # Checks for interpreter line "#!/dir/subdir/command ...", or
- # # explicit major mode election "-*-Mode: vars ...-*-".
- # #
- # # "command" or "Mode" is compared (case-insensitively) to Alpha mode
- # # names and first matching mode is used for the file.
- # #
- # # Author: Tom Pollard <pollard@chem.columbia.edu>
- # # Modified: 9/11/95
- #
- # Note: this proc actually opens the file for reading. It _must_ close
- # the file before exiting. If you modify this proc, make sure that
- # happens!
- #
- # To Do: I currently use 'file exists' to catch activation of non-file
- # windows such as '*tcl shell*'. There may be a better way.
- #
- # --Version--Author------------------Changes-------------------------------
- # 1.0 <darley@fas.harvard.edu> first modification from Tom Pollard's
- # 1.1 <darley@fas.harvard.edu> copes with a common Tcl/Tk exec trick.
- # 1.2 <darley@fas.harvard.edu> can map creators if desired.
- # -------------------------------------------------------------------------
- ##
- proc file::getModeForFile {name} {
- # if it doesn't exist as a file it's probably a funny window, so return
- if ![file exists "$name"] {
- if {[string first "* Trace" $name] == "0" } {
- zoom
- toggleScrollbar
- return Tcl
- }
- return
- }
- global modeCreator
- if {[info exists modeCreator([set sig [getFileSig $name]])]} {
- return $modeCreator($sig)
- }
- if [catch { set fid [open "$name" r] } ] { return }
- # find first non-empty line. Return if we fail
- for { set line "" } { [string trim $line] == "" } {} {
- if { [gets $fid line] == -1} { close $fid ; return }
- }
- if {[regexp -nocase {^[^\n\r]+install} $line]} {
- global HOME
- if ![string match "${HOME}:Tcl:*" $name] {
- close $fid
- return "Inst"
- }
- }
- if {[regexp {^#![ ]*([^ \n\r]+)} $line dmy mtch] } {
- if [regexp {([^/]+)$} $mtch majorMode] {
- # remove trailing version number
- set majorMode [string trimright $majorMode "01234567890."]
- if {$majorMode == "sh"} {
- # need to check if we're using a common unix trick
- if {[gets $fid ll] != -1} {
- while {[string index [string trimleft $ll] 0] == "#"} {
- if {[gets $fid ll] == -1} { close $fid ; return }
- }
- } else {
- if [regexp {[\n\r][ \t]*[^#][^\r\n]*[\r\n]} $line ll] {
- set ll [string trimleft $ll]
- } else {
- set ll ""
- }
- }
- if [regexp {^exec +([^ ]+) } $ll dummy ll] {
- regexp {([^/]+)$} [string trimright $ll "01234567890."] majorMode
- }
- }
- } else {
- close $fid
- return
- }
- } elseif {[regexp {\-\*\- *([^ :;]+).*\-\*\-} $line mtch majorMode]} {
- # do nothing
- } else {
- close $fid
- return
- }
- close $fid
-
- global unixMode
- set majorMode [string tolower $majorMode]
- if [info exists unixMode($majorMode)] {
- return $unixMode($majorMode)
- } else {
- global modeMenus
- set m [array names modeMenus]
- if {[set i [lsearch [string tolower $m] $majorMode]] != -1} {
- return [lindex $m $i]
- }
- }
- return
- }
-
- # These are mappings required by the above proc. If you need to extend this
- # list to include a mode you are writting, place a statement like the following
- # in your alpha::mode body
- set unixMode(matlab) {MATL}
-
- ##
- # -------------------------------------------------------------------------
- #
- # "file::whichModeForWin" --
- #
- # Copes with trailing '<2>', .orig, copy, '~',...
- # -------------------------------------------------------------------------
- ##
- proc file::whichModeForWin {name} {
- regexp {(.*) <[0-9]+>$} $name dmy name
- if {[set m [file::getModeForFile $name]] != ""} { return $m }
- global ModeSuffixes
- set nm [file tail $name]
-
- regexp {(.*) copy$} $nm dmy nm
- regexp {(.*)~[0-9]*$} $nm dmy nm
- if {[file extension $nm] == ".orig"} {
- set nm [file root $nm]
- }
- case $nm in $ModeSuffixes
- return $winMode
- }
-
-
- ##
- # -------------------------------------------------------------------------
- #
- # "win::addToMenu" --
- #
- # Adds a window name to the window menu. This new version adds a
- # binding, to work-around a bug in Alpha, so that using cmd-0-9
- # works if the window name contains square brackets. The problem
- # is that the 'addMenuItem' line creates a binding of the form
- # 'menu::winProc •263 namewith[square]brackets' which when evaluated
- # causes an error. We force a separate binding to
- # 'menu::winProc •263 {namewith[square]brackets}' which does work.
- # -------------------------------------------------------------------------
- ##
- proc win::addToMenu {name} {
- global winNameToNum winMenu winNumToName
-
- for {set i 0} {$i<100} {incr i} {
- if ![info exists winNumToName($i)] {
- regsub { <\w+>$} $name {} nm
- if [file exists $nm] {
- regexp {[^:]*$} $name nm
- } else {
- set nm $name
- }
- if {$i < 10} {
- addMenuItem -m -l "/$i" $winMenu "$nm"
- namespace eval ::alpha [list bind '$i' <c> [list menu::winProc $winMenu $nm]]
- } else {
- addMenuItem -m -l "" $winMenu "$nm"
- }
- set winNumToName($i) $name
- set winNameToNum($name) $i
- return
- }
- }
- }
-
- proc win::removeFromMenu {name} {
- global winNameToNum winNumToName winMenu
- regsub -all {\\([][])} $name {\1} name
- set num $winNameToNum($name)
- unset winNumToName($num)
- unset winNameToNum($name)
- regsub { <\d+>$} $name {} nm
- if [file exists $nm] {
- regexp {[^:]*$} $name nm
- } else {
- # in case it was a file but the file was actually moved!
- if [regexp {[^:]*$} $name nm] {
- if {![catch {deleteMenuItem -m $winMenu $nm}]} { return } }
- set nm $name
- }
- # to handle alpha problem with rebuilding the menu
- if [catch {deleteMenuItem -m $winMenu $nm}] { deleteMenuItem $winMenu $nm }
- }
-
- proc mode::changeDialog {} {
- global mode modeMenus
-
- set nmode [listpick -p "Mode:" -L $mode \
- [lsort -ignore [array names modeMenus]]]
- newMode $nmode
- }
-
- proc mode::describe {} {
- global mode ModeSuffixes modeMenus
- global ${mode}modeVars
-
- set text "\r\tMODE $mode\r\r"
- if ![catch {package::describe $mode 1} res] {
- append text $res "\r\r"
- }
- append text [package::helpFile $mode 1] "\r"
- set suffs ""
- set first 1
- foreach suf $ModeSuffixes {
- if {([llength $suf] == 3) && ([lindex $suf 1] == "winMode") \
- && ([lindex $suf 2] == $mode)} {
- if {$first} {
- lappend suffs $last
- set first 0
- } else {
- append suffs ", $last"
- }
- }
- set last $suf
- }
- append text "Mode filepats: " $suffs "\r\r"
-
- set first 1
- append text "Mode menus: "
- if {[info exists modeMenus($mode)]} {
- foreach m $modeMenus($mode) {
- if $first {
- set first 0
- lappend text $m
- } else {
- append text ", " $m
- }
- }
- }
- append text "\r\r"
-
- append text "Mode-specific variables:\r"
- if {[info exists ${mode}modeVars]} {
- foreach v [lsort [array names ${mode}modeVars]] {
- set val [set ${mode}modeVars($v)]
- global flag::type
- if {[info exists flag::type($v)] \
- && [regexp {binding$} [set flag::type($v)]]} {
- set val [dialog::specialView_binding $val]
- }
- append text [format "\t%-20s: \"%s\"\r" $v $val]
- }
- }
-
-
- set etext "\rMode-independent bindings:\r"
- append text "\rMode-specific bindings:\r"
- foreach b [split [bindingList] "\r"] {
- set lst [lindex $b end]
- if {$lst == $mode} {
- append text "\t$b\r"
- }
- }
- append text "\rTo list mode-independent bindings, select\
- 'List Global Bindings'\rfrom the Global menu.\r"
- new -n "* <$mode> MODE *" -m Tcl
- insertText $text
- winReadOnly
- }
-
- # Now calls the new proc dialog::pickMenus
- proc mode::setMenus {} {
- global mode modeMenus menus modifiedModeMenus globalMenus_curr
-
- set ms [dialog::pickMenus $mode]
- set modeMenus($mode) $ms
-
- lappend modifiedModeMenus $mode
-
- foreach m $menus {
- if {[lsearch $globalMenus_curr $m] < 0} {
- global $m
- catch {removeMenu [set $m]}
- }
- }
-
- foreach m $ms {
- global $m
- catch {$m}
- catch {insertMenu [set $m]}
- }
- }
- if {[info tclversion] < 8.0} {
- proc mode::proc {name args} {
- global mode
- if {[info commands ${mode}::$name] != ""} {
- eval ${mode}::$name $args
- } elseif {[info commands ${mode}$name] != ""} {
- eval ${mode}$name $args
- } else {
- error ""
- }
- }
- proc mode::getProc {name} {
- global mode
- if {[info commands ${mode}::$name] != ""} {
- return ${mode}::$name
- } elseif {[info commands ${mode}$name] != ""} {
- return ${mode}$name
- } else {
- return ""
- }
- }
- } else {
- proc mode::proc {name args} {
- global mode
- namespace eval ::$mode "$name $args"
- }
- proc mode::getProc {name} {
- global mode
- namespace eval ::$mode "namespace which $name"
- }
- }
-
- # Suffixes used to determine mode for new windows.
- proc mode::updateSuffixes {} {
- global ModeSuffixes modeMenus filepats
-
- set ModeSuffixes { default { set winMode Text } }
- foreach m [lsort -ignore [array names modeMenus]] {
- if {[info exists filepats($m)]} {
- lappend ModeSuffixes $filepats($m) "set winMode $m"
- }
- }
- }
-
-
- proc synchroniseModeVar {var args} {
- global mode $var
- if {[llength $args] > 0} {
- set $var [lindex $args 0]
- }
- global ${mode}ModeVars modifiedArrayElements
- lappend modifiedArrayElements [list $var ${mode}modeVars]
- set ${mode}modeVars($var) [set $var]
- }
-
- # ◊◊◊◊ Miscellaneous ◊◊◊◊ #
-
- ##
- # -------------------------------------------------------------------------
- #
- # "saveACopyAs" --
- #
- # Finally a proc to add to your collection of Alpha bugs.
- # copyFile has an interesting bug. If the destination file exists it
- # puts the file in [pwd] instead. This proc makes sure it is removed first.
- #
- # -------------------------------------------------------------------------
- ##
- proc saveACopyAs {} {
- if {[file exists [set nm [stripNameCount [win::Current]]]]} {
- set nm2 [putfile "Save a copy as:" [file tail $nm]]
- if {[file exists $nm2]} {removeFile $nm2}
- copyFile $nm $nm2
- }
- }
-
- proc menu::winProc {menu name} {
- global winNameToNum
-
- set nms [array names winNameToNum]
-
- if {[lsearch $nms "*[quote::Find $name]"] < 0} {
- $name
- return
- }
-
- foreach nm $nms {
- if {[string match *[quote::Find $name] $nm] == "1"} {
- bringToFront $name
- if [icon -q] { icon -f $name -o }
- return
- }
- }
- return "normal"
- }
-
- proc alpha::try {msg args} {
- message "${msg}…"
- set i -1
- set ok 1
- while 1 {
- set do [lindex $args [incr i]]
- set say [lindex $args [incr i]]
- if {$say == ""} {
- set say "loading $do"
- }
- if {$do == ""} {
- if $ok {
- message "${msg}…Complete."
- } else {
- alertnote "${msg}…Failed."
- }
- return $ok
- }
- message "$say…"
- if [catch $do] {
- alertnote "$say failed!"
- }
-
- }
- }
-
- # ◊◊◊◊ Read in all the packages ◊◊◊◊ #
-
- proc alpha::getBasicModes {} {
- global PSwords
- addMode PS {} {*.ps} {}
- newPref v prefixString {% } PS
- set PSKeyWords {
- def begin end dict load exec if ifelse for repeat loop exit
- stop stopped countexecstack execstack quit start gsave
- grestore grestoreall initgraphics newpath erasepage fill
- eofill stroke image imagemask showpage copypage
- }
- if {[info exists PSwords]} {set PSKeyWords [concat $PSKeyWords $PSwords]}
- regModeKeywords -e {%} -m {/} -c red -k blue PS $PSKeyWords -i "\}" -i "\{" -i {[} -i {]} -I green
-
- addMode Inst "" [list "*Install" "*INSTALL"] {installMenu}
- addMenu installMenu
- hook::register openHook install::openHook Inst
-
- addMode Text {} {default} {}
- newPref v leftFillColumn {0} Text
- newPref v suffixString { <--} Text
- newPref v prefixString {> } Text
- newPref v fillColumn {75} Text
- newPref f wordWrap {1} Text
- newPref v wordBreak {\w+} Text
- newPref v wordBreakPreface {(\W)} Text
- newPref v wrapBreak {[\w_]+} Text
- newPref v wrapBreakPreface {([^\w_])} Text
- newPref f autoMark 0 Text
- newPref flag quietlyClearMarks 0 Text
- }
-
- proc alpha::findAllPlugins {} {
- alpha::findAllModes
- global skipPrefs
- if {!$skipPrefs} {
- alpha::findAllExtensions
- }
- alpha::findAllMenus
- }
-
- proc alpha::findAllModes {} {
- alpha::getBasicModes
- rename alpha::getBasicModes {}
- cache::read index::mode
- foreach f [array names index::mode] {
- eval addMode $f [lrange [set index::mode($f)] 1 3]
- if {[set script [lindex [set index::mode($f)] 4]] != ""} {
- if [catch {uplevel #0 $script}] {
- lappend problems "$f"
- }
- }
- }
- if {[info exists problems]} {
- alertnote "Problems loading modes: $problems"
- }
- mode::updateSuffixes
- }
-
- proc alpha::findAllMenus {} {
- cache::read index::menu
- global alpha::package_menus
- ensureset alpha::package_menus ""
- foreach f [array names index::menu] {
- addMenu $f [lindex [set index::menu($f)] 1]
- if [lindex [set index::menu($f)] 2] {
- lappend alpha::package_menus $f
- }
- if {[set script [lindex [set index::menu($f)] 3]] != ""} {
- if [catch {uplevel #0 $script}] {
- lappend problems "$f"
- }
- }
- }
- if {[info exists problems]} {
- alertnote "Problems loading menus: $problems"
- }
- }
-
-