SmallSense__SmalltalkEditSupport.st
changeset 242 7a056a0ab77c
parent 234 97857872ee47
child 247 5b0a13159028
child 350 762fdff80221
--- a/SmallSense__SmalltalkEditSupport.st	Wed Jun 18 10:26:41 2014 +0100
+++ b/SmallSense__SmalltalkEditSupport.st	Tue Jun 24 11:00:49 2014 +0100
@@ -10,6 +10,65 @@
 !
 
 
+!SmalltalkEditSupport class methodsFor:'utilities'!
+
+indent: text by: level
+    ^ String streamContents:[ :out |
+        | in |
+
+        in := text readStream.
+        [ in atEnd ] whileFalse:[
+            in peek == Character cr ifTrue:[
+                out nextPut: in next.
+                out next: level put: Character space.
+            ] ifFalse:[
+                out nextPut: in next.
+            ].
+        ].
+    ]
+
+    "Created: / 04-05-2014 / 23:29:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+undent: text
+    | lines indent tabwidth  |
+
+    lines := text asStringCollection.
+    tabwidth := (ListView userDefaultTabPositions = ListView tab4Positions) ifTrue:[ 4 ] ifFalse: [ 8 ].
+    1 to: lines size do:[:lineNo |
+        | line i |
+
+        line := lines at: lineNo.
+        i := line indexOfNonSeparator.
+        indent isNil ifTrue:[
+            (i ~~ 0) ifTrue:[
+                indent := ((i - 1) // tabwidth) * tabwidth.
+                indent == 0 ifTrue:[
+                    lineNo == 1 ifTrue:[
+                        indent := nil.
+                    ] ifFalse:[
+                        ^ text.
+                    ].
+                ].
+            ].
+        ].
+        indent notNil ifTrue:[
+            i > indent ifTrue:[
+                lines at: lineNo put: (line copyFrom: indent + 1).
+            ] ifFalse:[
+                ^ text.
+            ].
+        ].
+    ].
+    ^ (text last == Character cr) ifTrue:[
+        lines asString.
+    ] ifFalse:[
+        lines asStringWithoutFinalCR
+    ].
+
+    "Created: / 04-05-2014 / 23:09:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !SmalltalkEditSupport methodsFor:'accessing'!
 
 language
@@ -39,13 +98,13 @@
 
 !SmalltalkEditSupport methodsFor:'editing'!
 
-electricInsert:stringOrLines advanceCursorBy:offsetOrNil 
+electricInsert:stringOrLines advanceCursorBy:offsetOrNil
     | ignore |
 
     (stringOrLines isString and:[ stringOrLines first == lastTypedKey0 ]) ifTrue:[
         ignore := stringOrLines copyFrom:2.
     ].
-    ^ self 
+    ^ self
             electricInsert:stringOrLines
             advanceCursorBy:offsetOrNil
             ignoreKeystrokes:ignore
@@ -79,13 +138,13 @@
     (tokens last > service textView cursorCol) ifTrue:[
         ^ false
     ].
-    ((lastToken0 == #Identifier) 
-        and:[ (service textView cursorCol - 1) == tokens last ]) 
+    ((lastToken0 == #Identifier)
+        and:[ (service textView cursorCol - 1) == tokens last ])
             ifTrue:[
                 lastValue0 := tokens at:tokens size - 2.
                 tokens size > 4 ifTrue:[
-                    (#( #do #select #reject #detect #contains #allSatisfy #anySatisfy ) 
-                        includes:lastValue0) 
+                    (#( #do #select #reject #detect #contains #allSatisfy #anySatisfy )
+                        includes:lastValue0)
                             ifTrue:[
                                 | collectionName  eachName  space  part1  part2 |
 
@@ -136,8 +195,8 @@
     lastToken0 == #Keyword ifTrue:[
         lastValue0 := tokens at:tokens size - 2.
         tokens size > 4 ifTrue:[
-            (#( #do: #select: #reject: #detect: #contains: #allSatisfy: #anySatisfy: ) 
-                includes:lastValue0) 
+            (#( #do: #select: #reject: #detect: #contains: #allSatisfy: #anySatisfy: )
+                includes:lastValue0)
                     ifTrue:[
                         | collectionName  eachName  part1  part2 |
 
@@ -176,21 +235,21 @@
 
     (self keyPressIgnored: key) ifTrue:[
         ^ true.
-    ]. 
+    ].
 
     lastTypedKey3 := lastTypedKey2.
     lastTypedKey2 := lastTypedKey1.
     lastTypedKey1 := lastTypedKey0.
     lastTypedKey0 := key.
 
-    key == #CodeCompletion ifTrue:[ 
+    key == #CodeCompletion ifTrue:[
         | controller |
 
         (controller := self textView completionSupport) notNil ifTrue:[
-            ^ controller handleKeyPress:key x:x y:y 
+            ^ controller handleKeyPress:key x:x y:y
         ].
         ^ false
-    ]. 
+    ].
 
     key == #BackSpace ifTrue:[
         backspaceIsUndo ifTrue:[
@@ -201,6 +260,10 @@
     ].
     backspaceIsUndo := false.
 
+    key == #Paste ifTrue:[
+        ^ self keyPressPaste.
+    ].
+
 
     key == $^ ifTrue:[
         ^ self keyPressReturnToken
@@ -246,7 +309,7 @@
     line size > textView cursorCol ifTrue: [ ^ false ].
     line size < (textView cursorCol - 1) ifTrue: [ ^ false ].
     (line at: textView cursorCol - 1) == $: ifTrue: [
-        self electricInsert:'= '.  
+        self electricInsert:'= '.
         ^ true
     ].
     ^ false
@@ -261,8 +324,8 @@
     | line |
 
     line := textView listAt: textView cursorLine.
-    line notNil ifTrue:[ 
-        line := line string.  
+    line notNil ifTrue:[
+        line := line string.
         line size > textView cursorCol ifTrue: [
             line size downTo: textView cursorCol - 1 do:[:i |
                 (line at:i) == Character space ifFalse:[ ^ false ].
@@ -289,6 +352,35 @@
     "Modified: / 29-01-2014 / 10:30:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+keyPressPaste
+    | textSelected textPasted currentLineNo currentLine currentLineIsEmpty |
+
+    textView checkModificationsAllowed ifTrue:[
+        textSelected := textPasted := textView getTextSelectionOrTextSelectionFromHistory.
+        currentLineNo := textView currentLine.
+        currentLineIsEmpty := true.
+        ((currentLineNo > textView list size)
+            or:[ (currentLine := textView list at: currentLineNo) isNil
+                or:[ (currentLineIsEmpty := currentLine indexOfNonSeparator == 0) ]]) ifTrue:[
+                    | indent |
+
+                    currentLineIsEmpty ifTrue:[
+                        indent := textView leftIndentForLine: currentLineNo.
+                        textView setCursorCol: indent + 1.
+                    ].
+                    textPasted := self class undent: textPasted.
+                    textPasted := self class indent: textPasted by: textView cursorCol - 1.
+
+                ].
+
+        textView undoablePasteOrReplace: textPasted info: nil.
+    ].
+    ^ true
+
+    "Created: / 03-05-2014 / 01:08:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-06-2014 / 20:37:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 keyPressReturn
     | line tokens c i t currentLineIndent closingBracketIndex |
 
@@ -322,7 +414,7 @@
         "/ two actions so backspace deletes only the inserted '"/ ' text
         self electricInsert:#( '' '' ) advanceCursorBy:(1 @ i).
         self electricInsert:'"/ '.
-        ^ true   
+        ^ true
     ].
 
     "/ Now insert/reindent closing bracket ( ']' ) for block, byt only
@@ -368,7 +460,7 @@
         [ i > 1 and:[ (tokens at: i) == #Identifier and:[ (tokens at: i - 1) == $: ]] ] whileTrue:[ i := i - 2 ].
 
         (i ~~ 0 and: [(tokens at: i) == $[]) ifTrue:[
-            self electricDo:[  
+            self electricDo:[
                 closingBracketIndex ~~ 0 ifTrue:[
                     self electricDeleteCharacterAtCol: closingBracketIndex
                 ].
@@ -380,7 +472,7 @@
         [ i > 0 and:[ (tokens at: i) == #Identifier ] ] whileTrue:[ i := i - 1 ].
         (i ~~ 0 and: [(tokens at: i) == $|]) ifTrue:[
             RBFormatter emptyLineAfterTemporaries ifTrue:[
-                self electricDo:[  
+                self electricDo:[
                     closingBracketIndex ~~ 0 ifTrue:[
                         self electricDeleteCharacterAtCol: closingBracketIndex
                     ].
@@ -398,8 +490,8 @@
 
 keyPressReturnToken
     RBFormatter spaceAfterReturnToken ifTrue:[
-        self electricDo:[ 
-            textView insertStringAtCursor:'^ ' 
+        self electricDo:[
+            textView insertStringAtCursor:'^ '
         ].
         ^ true
     ].
@@ -411,7 +503,7 @@
 
 !SmalltalkEditSupport methodsFor:'initialization'!
 
-initializeForService: anEditService    
+initializeForService: anEditService
     super initializeForService: anEditService.
     service textView autoIndent:true.
 
@@ -425,7 +517,7 @@
     | line scanner token |
 
     line := (service textView listAt: service textView cursorLine) string.
-    line := line copyTo: textView cursorCol - 1.  
+    line := line copyTo: textView cursorCol - 1.
     line isEmpty ifTrue:[ ^ #() ].
     scanner := Scanner for: line.
     ^ OrderedCollection streamContents:[:tokens |