--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__CompletionController.st Wed Oct 02 13:37:01 2013 +0100
@@ -0,0 +1,204 @@
+"{ Package: 'jv:smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+EditTextViewCompletionSupport subclass:#CompletionController
+ instanceVariableNames:'support'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'SmallSense-Core'
+!
+
+!CompletionController methodsFor:'accessing'!
+
+support
+ ^ support
+!
+
+support:anEditSupport
+ support := anEditSupport.
+! !
+
+!CompletionController methodsFor:'events'!
+
+handleKeyPress:key x:x y:y
+
+ key == #Control_L ifTrue:[
+ completionView notNil ifTrue:[
+ ^ false.
+ ].
+ ].
+
+ key == #CodeCompletion ifTrue: [
+ autoSelect := true.
+ self startCompletionProcess.
+ ^ true
+ ].
+
+ (key == #BackSpace or:[key == #BasicBackspace]) ifTrue:[
+ | c |
+
+ c := editView characterBeforeCursor.
+ (c notNil and:[c isAlphaNumeric]) ifTrue:[
+ ^ false
+ ].
+ ].
+
+
+ completionView notNil ifTrue:[
+ (key == #Return and:[completionView hasSelection]) ifTrue:[
+ self complete.
+ ^ true.
+ ].
+ key isCharacter ifTrue:[
+ self updateSelection.
+ ].
+ ].
+ ^ super handleKeyPress:key x:x y:y
+
+ "Created: / 27-09-2013 / 15:38:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 30-09-2013 / 15:00:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+postKeyPress:key
+ UserPreferences current immediateCodeCompletion ifFalse:[
+ "/ only update, if already open
+ completionView isNil ifTrue:[^ self].
+ ].
+
+ (key == #BackSpace or:[key == #BasicBackspace]) ifTrue:[
+ | c |
+
+ c := editView characterBeforeCursor.
+ (c notNil and:[c isLetterOrDigit]) ifTrue:[
+ autoSelect := false.
+ self updateCompletionList.
+ ] ifFalse:[
+ self closeCompletionView.
+ ].
+ ^ self
+ ].
+
+ key isCharacter ifTrue:[
+ key isLetterOrDigit not ifTrue:[
+ self closeCompletionView
+ ] ifFalse:[
+ autoSelect := false.
+ self updateCompletionList.
+ ].
+ ^ self
+ ].
+
+ "Created: / 28-09-2013 / 00:21:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 30-09-2013 / 14:55:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionController methodsFor:'private'!
+
+complete
+ support insertCompletion: completionView selection.
+ self closeCompletionView.
+
+ "Created: / 27-09-2013 / 15:38:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateCompletionList
+ "called for keypress events"
+
+ completionView isNil ifTrue:[
+ super updateCompletionList
+ ] ifFalse:[
+ self updateSelection.
+ ].
+
+ "Created: / 27-09-2013 / 15:58:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 28-09-2013 / 00:15:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateSelection
+
+ | matches word |
+
+ word := support wordBeforeCursor.
+ matches := completionView list select:[:po | po stringToComplete startsWith: word ].
+ matches notEmptyOrNil ifTrue:[
+ completionView selection: (matches inject: matches anElement into:[:shortest :each |
+ each stringToComplete size < shortest stringToComplete size
+ ifTrue:[each]
+ ifFalse:[shortest]
+ ]).
+ ] ifFalse:[
+ completionView selection: nil.
+ ]
+
+ "Created: / 27-09-2013 / 16:16:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionController methodsFor:'private-API'!
+
+computeCompletions
+ "Actually compute the completions and update the completion view."
+
+ | completions |
+
+ "/ Wait a while to give user chance finish typing.
+ "/ This also reduces CPU consumption by avoiding
+ "/ useless computation
+ Delay waitForMilliseconds: 200.
+ completions := support computeCompletion.
+ completions notEmptyOrNil ifTrue:[
+ editView sensor pushUserEvent: #updateCompletions: for: self withArgument: completions.
+ ].
+
+ "Created: / 27-09-2013 / 13:12:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 30-09-2013 / 11:53:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+openCompletionView
+ self openCompletionView: #()
+
+ "Created: / 27-09-2013 / 16:17:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+openCompletionView: list
+ "Makes sure the completion view is opened and with given `list`."
+
+ | movePos topView x y|
+ "/ move the window
+
+ list isEmpty ifTrue:[ ^ self ].
+
+ x := (editView xOfCol:editView cursorCol inVisibleLine:editView cursorLine)
+ - 16"icon" - (editView widthOfString: support wordBeforeCursor) - 5"magic constant".
+ y := editView yOfCursor + editView font maxHeight + 3.
+ movePos := (editView originRelativeTo: nil) + (x @ y).
+
+ completionView isNil ifTrue:[
+ completionView := CompletionView new.
+ completionView list:list.
+ completionView font: editView font.
+ topView := completionView.
+ topView origin:movePos.
+"/ topView resizeToFit.
+ self updateSelection.
+ topView open.
+ ] ifFalse:[
+ completionView list:list.
+ self updateSelection.
+"/ topView := completionView topView.
+"/ topView ~~ completionView ifTrue:[
+"/ topView origin:movePos.
+"/ topView resizeToFit.
+"/ ]
+ ].
+
+ "Created: / 27-09-2013 / 14:01:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 27-09-2013 / 23:54:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateCompletions: completionResult
+ self openCompletionView: completionResult
+
+ "Created: / 27-09-2013 / 13:52:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+