#UI_ENHANCEMENT by cg
authorClaus Gittinger <cg@exept.de>
Thu, 12 May 2016 21:30:38 +0200
changeset 5103 fc854b0d6ee8
parent 5102 3b10327d3648
child 5104 b295c198a0d0
#UI_ENHANCEMENT by cg class: DoWhatIMeanSupport changed: #codeCompletionForMessage:into: #tryCodeCompletionWithSource:nodeInterval:at:mustBeExpression:into:
DoWhatIMeanSupport.st
--- a/DoWhatIMeanSupport.st	Thu May 12 18:07:46 2016 +0200
+++ b/DoWhatIMeanSupport.st	Thu May 12 21:30:38 2016 +0200
@@ -1873,7 +1873,7 @@
      offerParenthisationAroundNode parenthesisAroundIndex parentNodeToParenthesize
      offerValueInsertion valueToInsert valueToInsertIndex valueInfo
      classesFromAssignmentsToReceiver otherMessagesToReceiver
-     canParenthesize|
+     canParenthesize classesOfReceiver|
  
     "/ Transcript show:'node '; show:node; show:' ; '.
     "/ Transcript show:'msg in '; show:methodOrNil; show:' / '; showCR:classOrNil.
@@ -1887,8 +1887,10 @@
         [:node :selector |
             |srchClasses bestSelectors bestPrefixes
              allMessagesSentToVariable classesImplementingAllMessages|
- 
-            srchClasses := self classesOfNode:node.
+
+            srchClasses := node==nodeReceiver 
+                            ifTrue:[classesOfReceiver]
+                            ifFalse:[self classesOfNode:node].
  
             srchClasses isEmptyOrNil ifTrue:[
                 node isVariable ifTrue:[
@@ -1932,6 +1934,7 @@
                     bestSelectors addAll:bestForThisClass.
                 ].
             ].
+            (bestSelectors includes:'h1')ifTrue:[self halt].
             "/ remove the already typed-in selector itself, in case.
             bestSelectors remove:selector ifAbsent:[].
             bestSelectors := bestSelectors asOrderedCollection.
@@ -1942,6 +1945,10 @@
     lcSelector := selector asLowercase.
     parentNode := node parent.
     nodeReceiver := node receiver.
+    nodeReceiver notNil ifTrue:[
+        classesOfReceiver := self classesOfNode:nodeReceiver.
+    ].
+( node isVariable and:[node name = 'self']) ifTrue:[self halt].
 
     "/ if there is already space before the cursor, and the parent node is not a message,
     "/ do not attempt to complete the current message.
@@ -2100,11 +2107,15 @@
         ] ifFalse:[
             |kwSels|
  
-            "/ if its a unary message AND the parent is a unary or binary node, try again, sending the partial message
+            "/ if its a unary message AND the parent is a unary or binary node, 
+            "/ try again, sending the partial message
             "/ as a keyword to the parent node.
-            "/ this is the case when after "foo binOp bar if", which should include ifTrue: in the result.
-            "/ transform from (the incorrectly parsed)
+            "/ this is the case when after "foo binOp bar if", or "foo unOp bar if"
+            "/ which should include ifTrue: in the suggestion result.
+            
+            "/ suggestion will transform from (the incorrectly parsed)
             "/    foo == (shift if)
+            "/
             "/        nonKWsel-msg(parent)
             "/     /         \
             "/    /           \
@@ -2124,34 +2135,42 @@
             "/             /
             "/           arg
  
-            kwSels := findBest value:parentNode value:selector.
-            kwSels := kwSels select:[:sel | sel isKeyword].
+            "/ but only do this, if typing to the end of the parent message
+            "/ (i.e. after (foo == shift) <-
+            "/    or after foo bar baz <-
+            "/ not if typing into an existing message
+            "/ (i.e. into foo == shift <- more
+            "/    or into foo bar <- baz
+            codeView characterPositionOfCursor >= parentNode stop ifTrue:[
+                kwSels := findBest value:parentNode value:selector.
+                kwSels := kwSels select:[:sel | sel isKeyword].
+     
+                kwSels := kwSels asOrderedCollection sort:[:a :b | a size < b size].
  
-            kwSels := kwSels asOrderedCollection sort:[:a :b | a size < b size].
- 
-            bestSelectors := bestSelectors reject:[:sel | kwSels includes:sel].
+                bestSelectors := bestSelectors reject:[:sel | kwSels includes:sel].
  
-            "/ these need to go to bestSelectors (see editAction)
-            parentNodeClassIfKnown := self classOfNode:parentNode.
-            (parentNodeClassIfKnown notNil and:[ parentNodeClassIfKnown includesBehavior: Boolean ]) ifTrue:[
-                "/ this is so common, that it deserves a special case:
-                "/ if we complete an if after some boolean message e.g '(a == b) if'
-                "/ throw out the very unlikely ifNil, ifEmpty etc. messages (which are inherited by Object, but absolutely unrealistic)
-                bestSelectors := self
-                                    withoutSelectorsUnlikelyFor:parentNodeClassIfKnown
-                                    from:bestSelectors
-                                    forPartial:selector.
-                kwSels := self
-                            withoutSelectorsUnlikelyFor:parentNodeClassIfKnown
-                            from:kwSels
-                            forPartial:selector.
- 
-                "/ put keyword selectors in front, because they are very likely
-                bestSelectors := kwSels , bestSelectors.
-            ] ifFalse:[
-                "/ put them at the end
-                bestSelectors := bestSelectors , kwSels.
-            ].
+                "/ these need to go to bestSelectors (see editAction)
+                parentNodeClassIfKnown := self classOfNode:parentNode.
+                (parentNodeClassIfKnown notNil and:[ parentNodeClassIfKnown includesBehavior: Boolean ]) ifTrue:[
+                    "/ this is so common, that it deserves a special case:
+                    "/ if we complete an if after some boolean message e.g '(a == b) if'
+                    "/ throw out the very unlikely ifNil, ifEmpty etc. messages (which are inherited by Object, but absolutely unrealistic)
+                    bestSelectors := self
+                                        withoutSelectorsUnlikelyFor:parentNodeClassIfKnown
+                                        from:bestSelectors
+                                        forPartial:selector.
+                    kwSels := self
+                                withoutSelectorsUnlikelyFor:parentNodeClassIfKnown
+                                from:kwSels
+                                forPartial:selector.
+     
+                    "/ put keyword selectors in front, because they are very likely
+                    bestSelectors := kwSels , bestSelectors.
+                ] ifFalse:[
+                    "/ put them at the end
+                    bestSelectors := bestSelectors , kwSels.
+                ].
+            ]
         ]
     ].
  
@@ -4308,6 +4327,7 @@
             ^ self.
         ].
     ].
+    (source startsWith:'sel') ifTrue:[self halt].
     nodeParent := node parent.
 
     (node isVariable