home *** CD-ROM | disk | FTP | other *** search
/ MacWorld UK 2000 March / MW_UK_2000_03.iso / Shareware World / Utilities / Text Processing / Alpha / Tcl / Modes / javaMode.tcl < prev    next >
Encoding:
Text File  |  2000-01-17  |  11.6 KB  |  358 lines  |  [TEXT/ALFA]

  1. # (install)
  2.  
  3. alpha::mode Java 1.12 javaMenu {*.java *.j} {
  4.     javaMenu electricBraces electricSemicolon electricReturn
  5. } {
  6.     addMenu javaMenu "•140" Java
  7.     alpha::package require AlphaTcl 7.2.1b5
  8. }
  9.  
  10. array set javacompilerAppSignatures {
  11.     Suncompiler Javc
  12. }
  13. array set javacompilerAppScripts {
  14.     Suncompiler {
  15.     {sendOpenEvent -n $quotedSig $filename}
  16.     }
  17. }
  18.  
  19. # required for use of C++::correctIndentation
  20. newPref f useFasterButWorseIndentation 0 Java
  21. newPref v indentComments "code 0" Java "" indentationTypes varitem
  22. newPref v indentC++Comments "code 0" Java "" indentationTypes varitem
  23.  
  24. newPref    f elecColon {1} Java
  25. newPref    v leftFillColumn {3} Java
  26. newPref    v prefixString {//} Java 
  27. newPref    f wordWrap {0} Java
  28. newPref    v funcExpr {^[^ \t\(#\r/@].*\(.*\)$} Java
  29. newPref    v parseExpr {\b([_:\w]+)\s*\(} Java
  30. newPref v wordBreak {[\w_]+} Java
  31. newPref v wordBreakPreface {[^_\w]} Java
  32. newPref    f autoMark    0 Java
  33. # To synchronise Alpha's value for your java class path with the current
  34. # value in your system environment each time Alpha starts up, click this 
  35. # box||To let Alpha maintain its own value for your classpath independent
  36. # of the systemwide value, click this box.
  37. newPref    f classPathSynchroniseWithEnv    1 Java
  38. # Your Java class path.
  39. newPref v classSearchPath "" Java
  40. newPref    v stringColor    green Java
  41. newPref    v commentColor    red     Java
  42. newPref    v keywordColor    blue Java
  43. newPref v funcColor yellow Java
  44. newPref f includeMenu 1 Java
  45. newPref variable showJavacompilerLog 1 Java "" \
  46.   [list "Never" "Only after error" "Always"] index
  47.  
  48. ensureset Java_projectStore(placeClassesHere) ""
  49. ensureset Java_projectStore(compileFromThisFolder) ""
  50. ensureset JavaProjects(Usual) [array get Java_projectStore]
  51. ensureset JavaProject Usual
  52.  
  53. regModeKeywords     -e {//} -b {/*} {*/}    -c $JavamodeVars(commentColor) \
  54.          -f $JavamodeVars(funcColor) -k $JavamodeVars(keywordColor) \
  55.          -s $JavamodeVars(stringColor) Java {
  56.     abstract boolean break byte byvalue case catch char class const 
  57.     continue default do double else extends false final finally float for 
  58.     goto if implements import instanceof int interface long native new 
  59.     null package private protected public return short static super switch 
  60.     synchronized this throw throws transient true try void while future 
  61.     generic inner outer operator rest var volatile
  62. }
  63. regModeKeywords -a -k color_9 Java { Object String }
  64.  
  65. proc javaMenu {} {}
  66.  
  67. if {$JavamodeVars(classPathSynchroniseWithEnv)} {
  68.     if {[info exists env(CLASSPATH)]} {
  69.     set JavamodeVars(classSearchPath) [split $env(CLASSPATH) ";"]
  70.     }
  71. }
  72.  
  73. ## 
  74.  # -------------------------------------------------------------------------
  75.  # 
  76.  # "menu::buildjavaMenu" --
  77.  # 
  78.  #  Use a build proc so we can add things on the fly.
  79.  # -------------------------------------------------------------------------
  80.  ##
  81. proc Java::buildMenu {} {
  82.     global javaMenu
  83.     set ma {
  84.     "/S<U<OswitchToCompiler"
  85.     "(-"
  86.     "/K<U<OcompileFile"
  87.     "(-"
  88.     "/V<U<OviewApplet"
  89.     "//<BnewJavadocComment"
  90.     "editProjects"
  91.     }
  92.     return [list build $ma Java::MenuProc "" $javaMenu]
  93. }
  94. menu::buildProc javaMenu Java::buildMenu
  95.  
  96. set Java::commentCharacters(Paragraph) [list "/**" " */" " * "]
  97.  
  98. # If this package exists, add the headers menu
  99. if {[alpha::package exists searchPaths]} {
  100.     menu::buildProc javaSearchPath {mode::rebuildSearchPathMenu javaSearchPath}
  101.     menu::insert javaMenu submenu end javaSearchPath
  102. }
  103.  
  104. menu::buildSome javaMenu
  105.  
  106. proc Java::MenuProc {menu item} {
  107.     eval Java::$item
  108. }
  109.  
  110. proc Java::electricLeft {args} {
  111.     uplevel 1 C++::electricLeft $args
  112. }
  113.  
  114. proc Java::correctIndentation {args} {
  115.     uplevel 1 C++::correctIndentation $args
  116. }
  117. proc Java::indentLine {args} {
  118.     uplevel 1 C++::indentLine $args
  119. }
  120.  
  121. proc Java::newJavadocComment {} {
  122.     elec::Insertion "/**\r * •comment body•\r */\r••"
  123. }
  124.  
  125. proc Java::editProjects {} {
  126.     dialog::editOneOfMany "Edit or create a new Java project" \
  127.       JavaProject JavaProjects Java_projectStore project
  128. }
  129.  
  130. # Launches Java Compiler
  131. proc Java::switchToCompiler {} {
  132.     global javacompilerSig
  133.     app::launchAnyOfThese Javc javacompilerSig "Please locate the Java compiler:"
  134.     switchTo '$javacompilerSig'
  135. }
  136.  
  137. # Sends the window to the compiler.
  138. proc Java::compileFile {} {
  139.     global showJavacompilerLog classSearchPath JavaProjects
  140.     set path [stripNameCount [win::Current]]
  141.  
  142.     if {[winDirty]} {
  143.     case [askyesno -c "Save '[file tail $path]'?"] in {
  144.         "yes" {
  145.         save
  146.         # Get path again, in case it was Untitled before.
  147.         set path [stripNameCount [win::Current]]
  148.         }
  149.         "no" {
  150.         if {![file exists $path]} {
  151.             alertnote "Can't send window to compiler."
  152.             return
  153.         }
  154.         }
  155.         "cancel" {return}
  156.     }
  157.     }
  158.     # Experimental code which will allow you to compile into a hierarchy
  159.     # using javac's ability to find related class files in multiple packages
  160.     # automatically.  This is needed for any project which contains files
  161.     # in more than one directory.
  162.  
  163.     # Of course we only want to do this if the current file is in the 
  164.     # compilation path given.  Else we'll assume it's a standalone file.
  165.     set compileFrom ""
  166.     set placeClasses ""
  167.  
  168.     # We check automatically whether a given file is in a project
  169.     # by examining whether the path matches.
  170.     foreach proj [array names JavaProjects] {
  171.     array set tmp $JavaProjects($proj)
  172.     if {$tmp(compileFromThisFolder) != "" \
  173.       && [file::pathStartsWith $path $tmp(compileFromThisFolder)]} {
  174.         set compileFrom $tmp(compileFromThisFolder)
  175.         set placeClasses $tmp(placeClassesHere)
  176.         break
  177.     }
  178.     }
  179.     
  180.     if {$placeClasses != ""} {
  181.     app::runScript javacompiler "Java compiler" \
  182.       $path 0 $showJavacompilerLog \
  183.       "-d $placeClasses -classpath [join $classSearchPath {;}]" \
  184.       $compileFrom
  185.     } else {
  186.     app::runScript javacompiler "Java compiler" \
  187.       $path 0 $showJavacompilerLog "-classpath [join $classSearchPath {;}]" \
  188.       $compileFrom
  189.     }
  190. }
  191.  
  192. # Opens a HTML file corresponding to a java file in the Applet Viewer.
  193. # If there is a file some_applet.html in the same folder as some_applet.java
  194. # it is sent. Otherwise the user is asked to select a HTML file.
  195. # This file is remembered throughout this session with Alpha.
  196. proc Java::viewApplet {} {
  197.     global javaAppletFile javaviewerSig
  198.     set name [stripNameCount [win::Current]]
  199.     set dir [file dirname $name]
  200.     set root [file rootname [file tail $name]]
  201.     set path [file join $dir $root.html]
  202.     if {[info exists javaAppletFile($name)] && [file exists $javaAppletFile($name)]} {
  203.     set path $javaAppletFile($name)
  204.     } elseif {![file exists $path]} {
  205.     set path [getfile "Please locate HTML file for applet."]
  206.     set javaAppletFile($name) $path
  207.     }
  208.     app::launchAnyOfThese [list AppV WARZ] javaviewerSig "Please locate the Applet viewer:"
  209.     sendOpenEvent noReply '$javaviewerSig' $path
  210.     switchTo '$javaviewerSig'
  211. }
  212.  
  213. proc Java::MarkFile {} {
  214.     Java::MarkFile2 1
  215. }
  216.  
  217. proc Java::parseFuncs {} {
  218.     Java::MarkFile2 0
  219. }
  220.  
  221.  
  222. # My version of    Java::MarkFile. First revision, April 1996.
  223. # Jim Menard, jimm@io.com
  224. # Improved by Vince: both start and end position of embedded classes are
  225. # stored, so if we order methods/sub-classes randomly, we still mark 
  226. # things properly.
  227. proc Java::MarkFile2 {marking} {
  228.     # Sorry, but globals are a lot easier than using "upvar" in subroutines
  229.     global markArray
  230.     global classInfo
  231.     
  232.     catch {unset markArray}
  233.     set classInfo ""
  234.     
  235.     # Look for class definitions first
  236.     set markExpr "^\[ \t\]*(\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\]+)*class\[ \t\]+\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\r\](\[A-Za-z_\]\[A-Za-z0-9_.\]*\[ \t\]+)*\{"
  237.     set wordExpr "class\[ \t\]+(\[A-Za-z_\]\[A-Za-z0-9_\]*)"
  238.     set commands {
  239.     set markArray([concat $word "class"]) $markPos
  240.     # Remember mark    position and name separately so    we can call
  241.     # Java::getClassFromPos() later.
  242.     lappend    classInfo [list $word $markPos $endPos]
  243.     }
  244.     Java::searchAndDestroy $markExpr $wordExpr $commands 0
  245.     
  246.     # The following regular expression is overly restrictive. After the open
  247.     # paren, I disallow semicolons. That avoids finding lines like
  248.     # throw new FooException(arg);
  249.     # which is good, but unfortunately also avoids finding lines like
  250.     # public int foo(arg) // comment with semi;
  251.     #
  252.     # It doesn't find constructors without a "public", "private", or other phrase
  253.     # before the method name since it requires at least one word before the
  254.     # method name. They are special-cased below. I did that so function calls,
  255.     # "if" statements, and the like wouldn't be found.
  256.     set markExpr "^\[ \t\]*(\[A-Za-z_\]\[A-Za-z0-9_\]*(\\\[\\])*\[ \t\]+)+\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\r\]*\\(\[^;\]+$"
  257.     set wordExpr "(\[A-Za-z_\]\[A-Za-z0-9_\]*)\[ \t\]*\\("
  258.     set commands {
  259.     if {$className == $word} {
  260.         set markArray([concat $className "constructor"]) $markPos
  261.     } else {
  262.         set markArray(${className}::$word) $markPos
  263.     }
  264.     }
  265.     Java::searchAndDestroy $markExpr $wordExpr $commands 1
  266.     
  267.     # One more time; let's go back for constructors    with no    modifiers.
  268.     set markExpr "^\[ \t\]*\[A-Za-z\]\[A-Za-z0-9_\]*\[ \t\r\]*\\(\[^;\]+$"
  269.     set wordExpr "(\[A-Za-z\]\[A-Za-z0-9_\]*)\[ \t\]*\\("
  270.     set commands {
  271.     if {$className == $word} {
  272.         set markArray([concat $className "constructor"]) [lineStart [expr $start - 1]]
  273.     }
  274.     }
  275.     Java::searchAndDestroy $markExpr $wordExpr $commands 1
  276.     
  277.     if {[info exists markArray]} {
  278.     foreach    f [lsort -ignore [array    names markArray]] {
  279.         set next [nextLineStart $markArray($f)]
  280.         
  281.         if {[regexp {.*(::if)$} $f] == 0} {
  282.         if {[string length $f] > 35} { 
  283.             set ff "[string range $f 0 31]..." 
  284.         } else {
  285.             set ff $f
  286.         }
  287.         if {$marking} {
  288.             setNamedMark "$ff" "$markArray($f)" $next $next
  289.         } else {
  290.             lappend parse $ff $next
  291.         }
  292.         }
  293.     }
  294.     }
  295.     if {!$marking} {return $parse}
  296. }
  297.  
  298. # Start    at top of file and find    text that matches markExpr. Clean it up    and
  299. # use wordExpr to find the word    we want. Execute commands.
  300. proc Java::searchAndDestroy {markExpr wordExpr commands needClassName} {
  301.     global markArray
  302.     global classInfo
  303.     if {!$needClassName} {
  304.     set getEnd 0
  305.     }
  306.     
  307.     set pos [minPos]
  308.     while {![catch {search -s -f 1 -r 1 -m 0 -i 0 -- "$markExpr" $pos} res]} {
  309.     set start [lindex $res 0]
  310.     set end    [pos::math [lindex $res 1] + 1]
  311.     if {[pos::compare $end > [maxPos]]} {
  312.         set end [maxPos]
  313.     }
  314.     set thistext [getText $start $end]
  315.     if {$needClassName} {
  316.         set className [Java::getClassFromPos $start $classInfo]
  317.     }
  318.     # regexp doesn't like carriage returns or tabs
  319.     regsub -all "\[\n\r\t\]" $thistext " " thistext
  320.     # If the open paren was    the last character on the line,
  321.     # the selected text included the last carriage return as well.
  322.     # Trim this off    now that it is changed into a space.
  323.     set thistext [string trimright $thistext]
  324.     if {[regexp -- $wordExpr $thistext dummy word]} {
  325.         set markPos [lineStart [pos::math $start - 1]]
  326.         if {[info exists getEnd]} {
  327.         if {$getEnd} {
  328.             set endPos [lindex [search -s -f 1 -m 0 -i 0 -- "\{" $markPos] 1]
  329.             set endPos [matchIt "\{" $endPos]
  330.         } else {
  331.             # little efficiency thing: the first class we find, we know
  332.             # extends to the end of the file, so we don't bother doing
  333.             # its 'matchIt' because it is very time-consuming.
  334.             set endPos [maxPos]
  335.             set getEnd 1
  336.         }
  337.         }
  338.         eval $commands
  339.     }
  340.     set pos    $end
  341.     }
  342. }
  343.  
  344. # Given    a file position, find the class    definition in which it resides.
  345. # There's got to be an easier way than passing two separate lists. 
  346. # I tried fooling
  347. # around with markArray(), but don't know Tcl well enough to use it instead.
  348. proc Java::getClassFromPos {pos classInfo} {
  349.     set nClasses [llength $classInfo]
  350.     for {set i [expr {$nClasses - 1}]} {$i >= 0} {incr i -1} {
  351.     set range [lindex $classInfo $i]
  352.     if {[pos::compare [lindex $range 1] <= $pos] && [pos::compare [lindex $range 2] >= $pos]} {
  353.         return [lindex $range 0]
  354.     }
  355.     }
  356.     return ""
  357. }
  358.