--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Tools__CodeHighlightingService.st Fri Jul 01 15:20:16 2011 +0200
@@ -0,0 +1,311 @@
+"
+ COPYRIGHT (c) 2006 by eXept Software AG
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+"{ Package: 'stx:libtool' }"
+
+"{ NameSpace: Tools }"
+
+CodeViewService subclass:#CodeHighlightingService
+ instanceVariableNames:'worker workerRunning'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Interface-CodeView'
+!
+
+!CodeHighlightingService class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 2006 by eXept Software AG
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+! !
+
+!CodeHighlightingService class methodsFor:'accessing'!
+
+label
+
+ "Answers short label - for UI"
+
+ ^'Syntax Highlighting'
+
+ "Created: / 07-03-2010 / 14:00:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeHighlightingService methodsFor:'change & update'!
+
+update: aspect with: param from: sender
+
+ sender == codeView textView modifiedChannel ifTrue:[^self codeChanged: false].
+ sender == codeView textView model ifTrue:[^self codeChanged: true].
+ sender == codeView languageHolder ifTrue:[^self codeChanged: true].
+ sender == codeView classHolder ifTrue:[^self codeChanged: true].
+
+ super update: aspect with: param from: sender
+
+ "Created: / 06-03-2010 / 19:38:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeHighlightingService methodsFor:'private'!
+
+codeChanged: force
+
+ (force or:[codeView textView modified]) ifTrue:
+ [self startSyntaxHighlightProcess].
+
+ "Modified: / 06-03-2010 / 19:32:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+setHighlightedCode:newCode elements: elements
+ "the background synhighlighter has generated new colored text,
+ with highlighted syntax.
+ If there have been no modifications in the meantime, install it."
+
+ |firstShown lastShown cursorWasOn anyChange newLines l replaceAction textView list|
+
+ textView := codeView textView.
+ textView modified ifTrue:[
+ "/ new input arrived in the meantime
+
+ ^ self
+ ].
+ worker notNil ifTrue:[
+ "/ another coloring process has already been started.
+ "/ ignore this (leftover) code.
+
+ ^ self
+ ].
+ firstShown := textView firstLineShown.
+ lastShown := textView lastLineShown.
+ replaceAction := [:lNr :line |
+ |oldLine|
+
+ oldLine := list at:lNr ifAbsent:nil.
+ oldLine notNil ifTrue:[
+ line notNil ifTrue:[
+ "/ this check is needed - there is a race
+ "/ when the text is converted. This detects the
+ "/ resulting error.
+ "/ Certainly a kludge.
+
+ oldLine string = line string ifTrue:[
+ oldLine emphasis ~= line emphasis ifTrue:[
+ textView modifiedChannel removeDependent:self.
+ list at:lNr put:line.
+ textView modifiedChannel addDependent:self.
+ (lNr between:firstShown and:lastShown) ifTrue:[
+ anyChange ifFalse:[
+ anyChange := true.
+ cursorWasOn := textView hideCursor
+ ].
+ textView redrawLine:lNr
+ ]
+ ]
+ ]
+ ]
+ ]
+ ].
+ anyChange := false.
+ newLines := newCode asStringCollection.
+ list := textView list.
+ list isNil ifTrue:[
+ textView list:newLines.
+ ] ifFalse:[
+ "/ the cursor line first - thats where your eyes are ...
+ (l := textView cursorLine) notNil ifTrue:[
+ l <= newLines size ifTrue:[
+ replaceAction value:l value:(newLines at:l)
+ ]
+ ].
+ newLines keysAndValuesDo:replaceAction.
+ anyChange ifTrue:[
+ cursorWasOn ifTrue:[
+ textView showCursor
+ ]
+ ]
+ ].
+ codeView syntaxElements: elements
+
+ "Modified: / 09-10-2006 / 11:50:17 / cg"
+ "Created: / 14-02-2010 / 16:10:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 06-03-2010 / 19:58:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+showInfo: aString
+
+ codeView showInfo: aString
+
+ "Created: / 06-03-2010 / 19:34:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+startSyntaxHighlightProcess
+ "start a background process, which does the syntax coloring.
+ When it finishes, it pushes a user event to show the new text in the codeView.
+ (This is done as an event to synchronize the coloring with modifications
+ done to the text - the colored text will discarded, if there were
+ any new modifications in the meanwhile)"
+
+ |dontDoIt oldCodeList highlighterClass prio textView|
+
+ textView := codeView textView.
+
+ highlighterClass := self syntaxHighlighterClass.
+
+ dontDoIt := highlighterClass isNil.
+ "dontDoIt := dontDoIt
+ or:[self doSyntaxColoring value ~~ true
+ or:[(self doImmediateSyntaxColoring) value ~~ true]]."
+ dontDoIt ifTrue:[^self].
+
+
+
+
+ "/ this clobbers the codeViews modified state; therefore, we have to remember
+ "/ this info somewhere ...
+ textView modified ifTrue:[
+ codeView modifiedChannel value:true
+ ].
+ textView modifiedChannel setValue:false.
+
+ worker notNil ifTrue:[
+ workerRunning ~~ true ifTrue:[
+ "/ process already created, but did not get a change to start yet;
+ ^ self
+ ].
+ self stopSyntaxHighlightProcess
+ ].
+ prio := Processor userBackgroundPriority - 1.
+ textView shown ifFalse:[
+ prio := prio - 1 max:1
+ ].
+ worker := [
+ |oldCode newCode elements cls sensor |
+ [
+ workerRunning := true.
+ codeView syntaxElements: nil.
+ codeView syntaxElementSelection: nil.
+ cls := codeView classHolder value.
+ (cls notNil and:[cls isObsolete]) ifTrue:[
+ cls isMeta ifTrue:[
+ cls := (Smalltalk at:cls theNonMetaclass name) class
+ ] ifFalse:[
+ cls := Smalltalk at:cls name
+ ].
+ ].
+ textView modified ifFalse:[
+ oldCodeList := textView list copy.
+ textView modified ifFalse:[
+ oldCodeList isNil ifFalse:[
+ oldCode := oldCodeList asStringWithoutEmphasis.
+ textView modified ifFalse:[
+ Screen currentScreenQuerySignal answer:codeView device
+ do:[
+ Parser::ParseError handle:[:ex |
+ |errMsg|
+
+ errMsg := ex description asStringCollection first asString.
+
+ "/ Transcript topView raiseDeiconified.
+ "/ Transcript showCR:'ParseError: ', ex description.
+"/ self halt.
+ self showInfo:(errMsg colorizeAllWith:Color red).
+ newCode := nil.
+ ] do:[
+ elements := SortedCollection new.
+ codeView codeAspect == #method ifTrue:[
+ newCode := highlighterClass formatMethod:oldCode in:cls using: nil elementsInto: elements.
+ ] ifFalse:[
+ codeView codeAspect == #expression ifTrue:[
+ newCode := highlighterClass formatExpression:oldCode in:cls elementsInto: elements.
+ ] ifFalse:[
+ codeView codeAspect == #classDefinition ifTrue:[
+ newCode := highlighterClass formatClassDefinition:oldCode in:cls elementsInto: elements.
+ ]
+ ].
+ ].
+ ]
+ ].
+ newCode notNil ifTrue:[
+ textView modified ifFalse:[
+ newCode := newCode asStringCollection.
+ textView modified ifFalse:[
+ worker := nil.
+ (textView := codeView textView) notNil ifTrue:[
+ "/ must add this event - and not been interrupted
+ "/ by any arriving key-event.
+ self showInfo:nil.
+ codeView sensor
+ pushUserEvent:#setHighlightedCode:elements:
+ for:self
+ withArguments:(Array with:newCode with: elements).
+ "/self delayedUpdateBufferLabelWithCheckIfModified
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ] ensure:[
+ workerRunning := false.
+ worker := nil
+ ]
+ ] forkAt:prio
+
+ "Modified: / 22-08-2006 / 14:27:09 / cg"
+ "Modified: / 10-04-2011 / 18:21:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stopSyntaxHighlightProcess
+ "stop any syntax coloring background process."
+
+ |p|
+
+ (p := worker) ifNil:[^self].
+ worker := nil.
+ p terminate.
+ "/ raise its prio to make it terminate quickly
+ p priority:(Processor userSchedulingPriority + 1)
+
+ "Modified: / 03-09-2010 / 22:27:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+syntaxHighlighterClass
+
+ | lang cls |
+ cls := (lang := codeView languageHolder value)
+ ifNil:[nil]
+ ifNotNil:[lang syntaxHighlighterClass].
+ "Ugly hack because I don't want to branch libcomp :-)"
+ cls == SyntaxHighlighter ifTrue:[cls := SyntaxHighlighter2].
+ ^cls
+
+ "Created: / 14-02-2010 / 12:39:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 06-03-2010 / 19:39:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeHighlightingService class methodsFor:'documentation'!
+
+version_CVS
+ ^ '$Header: /cvs/stx/stx/libtool/Tools__CodeHighlightingService.st,v 1.1 2011-07-01 13:20:16 cg Exp $'
+!
+
+version_SVN
+ ^ '§Id: Tools__CodeHighlightingService.st 7715 2011-04-10 16:32:58Z vranyj1 §'
+! !