More fixes for #10: delete the rest of inserted text when typed text differ from inserted.
authorJan Vrany <jan.vrany@fit.cvut.cz>
Fri, 06 Mar 2015 07:09:06 +0000
changeset 446 59afe5adfbf7
parent 445 783f2a4af9c2
child 447 2d45c613a5bd
More fixes for #10: delete the rest of inserted text when typed text differ from inserted. This fix should handle following case: `th` is typed so completion would insert `thisContext` but the user continues typing `isValue`. The resulting text is now correct: `thisValue`.
SmallSense__EditSupport.st
SmallSense__SmalltalkEditSupport.st
SmallSense__SmalltalkEditSupportTests.st
--- a/SmallSense__EditSupport.st	Wed Mar 04 06:01:34 2015 +0000
+++ b/SmallSense__EditSupport.st	Fri Mar 06 07:09:06 2015 +0000
@@ -25,7 +25,8 @@
 Object subclass:#EditSupport
 	instanceVariableNames:'textView backspaceIsUndo completionController
 		completionEnvironment snippets ignoreKeystrokes
-		ignoreKeystrokesPosition electricInsertSuppressed'
+		ignoreKeystrokesPosition ignoreKeystrokesStartLine
+		ignoreKeystrokesStartCol electricInsertSuppressed'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'SmallSense-Core-Services'
@@ -192,9 +193,13 @@
      `ignoreKeystrokeSequence` a sequenceable collection of keys (in a form
             as passed to #keyPress:x:y: method."
     
-    | lineOffset  colOffset  newCursorCol  newCursorLine  advanceCursor |
+    | lineOffset colOffset oldCursorLine oldCursorCol newCursorLine newCursorCol advanceCursor |
 
     advanceCursor := false.
+    ignoreKeystrokeSequence notNil ifTrue:[ 
+        oldCursorLine := textView cursorLine.
+        oldCursorCol := textView cursorCol.
+    ].
     offsetOrNil notNil ifTrue:[
         lineOffset := offsetOrNil isPoint ifTrue:[
                 offsetOrNil x
@@ -228,11 +233,14 @@
     ignoreKeystrokeSequence notEmptyOrNil ifTrue:[
         ignoreKeystrokes := ignoreKeystrokeSequence.
         ignoreKeystrokesPosition := 1.
+        stringOrLines isString ifTrue:[ 
+            ignoreKeystrokesStartLine := oldCursorLine.
+            ignoreKeystrokesStartCol := oldCursorCol + (stringOrLines size - ignoreKeystrokeSequence size)
+        ].
     ].
 
     "Created: / 19-01-2014 / 20:29:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 20-01-2014 / 09:24:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified (format): / 22-01-2014 / 21:13:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-03-2015 / 06:29:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 electricInsert:text ignoreKeystrokes:ignore 
@@ -326,19 +334,51 @@
             ignoreKeystrokesPosition := ignoreKeystrokesPosition + 1.
             ignoreKeystrokesPosition > ignoreKeystrokes size ifTrue:[
                 "/ Nil out instvars if there's no more keys to ignore.
-                ignoreKeystrokes := ignoreKeystrokesPosition := nil.
+                ignoreKeystrokes := ignoreKeystrokesPosition := ignoreKeystrokesStartLine := ignoreKeystrokesStartCol := nil.
             ].
             ^ true.
         ] ifFalse:[
-            "/ Nil out instvars, user typed something else!!
-            ignoreKeystrokes := ignoreKeystrokesPosition := nil.
+            "/ User continued typing something else. If it *seems* to be
+            "/ thet user wanted something else, then delete the rest, i.e.,
+            "/ user typed:
+            "/ 
+            "/ th
+            "/ 
+            "/ then the machinery completed `isContext` so the text is
+            "/ 
+            "/ thisContext
+            "/ 
+            "/ and user continues typing `isValue`. In that case user wanted to
+            "/ `thisValue` instead of `thisContext` - in this case remove the rest
+            "/ of what has been completed.
+            "/ 
+            "/ However, imagine following case: user types `th` so it completes
+            "/ `thisContext` like in previous case. Now the user types . (dot).
+            "/ to end the statement. In this case, perhaps `thisContext` is what
+            "/ he needs.
+            "/ 
+            "/ How to tell between those two cases?
+            "/ 
+            "/ Currently, a simple heuristics is used - if the typed character can be
+            "/ part of an identifier, then it's the former case, otherwise assume
+            "/ the latter. We'll see.
+            "/
+            (key isCharacter and:[key isLetterOrDigit or:[key == $_]]) ifTrue:[ 
+                ignoreKeystrokesStartLine notNil ifTrue:[  
+                    textView deleteCharsAtLine: ignoreKeystrokesStartLine fromCol: ignoreKeystrokesStartCol + ignoreKeystrokesPosition - 1 toCol: ignoreKeystrokesStartCol + ignoreKeystrokes size - 1.
+                    textView setCursorLine: ignoreKeystrokesStartLine.
+                    textView setCursorCol: ignoreKeystrokesStartCol + ignoreKeystrokesPosition - (ignoreKeystrokesPosition > 1 ifTrue:[ 1 ] ifFalse:[ 0 ]).
+                ].
+            ].
+            ignoreKeystrokes := ignoreKeystrokesPosition := ignoreKeystrokesStartLine := ignoreKeystrokesStartCol := nil.
             ^ false.
         ].
     ].
     ^ false.
 
     "Created: / 20-01-2014 / 09:11:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified (comment): / 11-08-2014 / 14:54:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 05-03-2015 / 12:47:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 06-03-2015 / 07:08:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 keyPressSpace
--- a/SmallSense__SmalltalkEditSupport.st	Wed Mar 04 06:01:34 2015 +0000
+++ b/SmallSense__SmalltalkEditSupport.st	Fri Mar 06 07:09:06 2015 +0000
@@ -392,21 +392,21 @@
 
     RBFormatter spaceAfterBlockStart ifTrue:[
         RBFormatter spaceBeforeBlockEnd ifTrue:[
-            self electricInsert:'[  ]' advanceCursorBy: 2.
+            self electricInsert:'[  ]' advanceCursorBy: 2 ignoreKeystrokes: nil.
         ] ifFalse:[
-            self electricInsert:'[ ]' advanceCursorBy: 2.
+            self electricInsert:'[ ]' advanceCursorBy: 2 ignoreKeystrokes: nil.
         ].
     ] ifFalse:[
         RBFormatter spaceBeforeBlockEnd ifTrue:[
-            self electricInsert:'[ ]' advanceCursorBy: 1.
+            self electricInsert:'[ ]' advanceCursorBy: 1 ignoreKeystrokes: nil .
         ] ifFalse:[
-            self electricInsert:'[]' advanceCursorBy: 1.
+            self electricInsert:'[]' advanceCursorBy: 1 ignoreKeystrokes: nil.
         ].
     ].
     ^ true.
 
     "Created: / 22-01-2014 / 21:35:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 03-03-2015 / 17:07:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-03-2015 / 06:33:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 keyPressPaste
--- a/SmallSense__SmalltalkEditSupportTests.st	Wed Mar 04 06:01:34 2015 +0000
+++ b/SmallSense__SmalltalkEditSupportTests.st	Fri Mar 06 07:09:06 2015 +0000
@@ -148,7 +148,9 @@
     self assert: (codeView list at: 2) = '    the := thisContext'.
 
     "Created: / 03-03-2015 / 17:01:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
+! !
+
+!SmalltalkEditSupportTests methodsFor:'tests - electric snippets'!
 
 test_electric_snippet_do_01
 
@@ -168,6 +170,24 @@
     self assert: (codeView list at: 2) = '    snippets do:'.
 
     "Created: / 04-03-2015 / 05:54:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_electric_snippet_do_02
+
+    UserPreferences current smallSenseCompleteIfUnambiguous: true.  
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService
+    snippets do'.
+    codeView setCursorLine: 2; setCursorCol: 16.
+
+    codeViewInteractor type: ':'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    snippets do:[:snippet |  ]'.
+    codeViewInteractor type: 'aBlock'.
+    self assert: (codeView list at: 2) = '    snippets do: aBlock'.
+
+    "Created: / 04-03-2015 / 06:11:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+
 
 !
 
@@ -203,6 +223,7 @@
     "Created: / 04-03-2015 / 08:14:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
+
 !SmalltalkEditSupportTests methodsFor:'tests - indent-on-paste'!
 
 test_indent_on_paste_01a