EditTextView.st
branchtext-view-selection-refactoring
changeset 4854 6c3caad0bdfa
parent 4852 04fe7fca9320
parent 4818 22857701ea2f
child 4855 070208b64260
--- a/EditTextView.st	Mon Oct 14 08:05:59 2013 +0100
+++ b/EditTextView.st	Mon Nov 04 11:11:51 2013 -0300
@@ -88,7 +88,7 @@
 
 Object subclass:#LastReplacementInfo
 	instanceVariableNames:'lastReplacement lastStringToReplace lastReplaceWasMatch
-		lastReplaceIgnoredCase'
+		lastReplaceIgnoredCase stillCollectingInput previousReplacements'
 	classVariableNames:''
 	poolDictionaries:''
 	privateIn:EditTextView
@@ -1480,6 +1480,12 @@
 !
 
 lastStringToReplace: aString
+!
+
+previousReplacements
+    "accessor for the code completion"
+
+    ^ lastReplacementInfo previousReplacements
 ! !
 
 !EditTextView methodsFor:'change & update'!
@@ -2837,9 +2843,7 @@
     |soCol wasOn lineNrAboveCursor ln originalLine prevTab|
 
     wasOn := self hideCursor.
-    (autoIndent
-    and:[ (tabPositions includes:cursorCol)
-    ]) ifTrue:[
+    (autoIndent and:[ (tabPositions includes:cursorCol)]) ifTrue:[
         prevTab := (self prevTabBefore:cursorCol) max:1.
         ln := originalLine := (list at:cursorLine) ? ''.
         ln size < prevTab ifTrue:[
@@ -3198,17 +3202,18 @@
     autoIndent ifTrue:[
         indent := self leftIndentForLine:lineNr.
 
-        text := someText collect:[:ln||line|
-            ln notNil ifTrue:[
-                line := ln withoutLeadingSeparators.
-                (line isEmpty or:[indent == 0]) ifFalse:[
-                    line := (String new:indent), line
-                ].
-                line
-            ] ifFalse:[
-                nil
-            ]
-        ].
+        text := someText 
+            collect:[:ln||line|
+                ln notNil ifTrue:[
+                    line := ln withoutLeadingSeparators.
+                    (line isEmpty or:[indent == 0]) ifFalse:[
+                        line := (String new:indent), line
+                    ].
+                    line
+                ] ifFalse:[
+                    nil
+                ]
+            ].
     ] ifFalse:[
         text := someText
     ].
@@ -3710,7 +3715,7 @@
     l := cursorLine.
     c := cursorCol.
 
-    sel := self selection.
+    sel := self selectionAsString.
     sel isNil ifTrue:[
         selStartLine := l.
         selStartCol := c.
@@ -3722,20 +3727,17 @@
 
         self deleteSelection.
         replacing := true.
+        lastReplacementInfo rememberReplacement.
         lastReplacementInfo lastReplacement: ''.
+        lastReplacementInfo stillCollectingInput:true.
         undoSupport actionInfo:'replace'.
     ].
 
     something isCharacter ifTrue:[
         lastReplacementInfo lastReplacement notNil ifTrue:[
-"/ "XXX - replacing text with spaces ..."
-"/            (lastReplacement endsWith:Character space) ifTrue:[
-"/                lastReplacement := lastReplacementInfo lastReplacement copyWithoutLast:1 "copyTo:(lastReplacement size - 1)".
-"/                lastReplacement := lastReplacementInfo lastReplacement copyWith:something.
-"/                lastReplacement := lastReplacementInfo lastReplacement copyWith:Character space
-"/            ] ifFalse:[
+            lastReplacementInfo stillCollectingInput ifTrue:[
                 lastReplacementInfo lastReplacement: (lastReplacementInfo lastReplacement copyWith:something).
-"/            ]
+            ].
         ].
         self isInInsertMode ifTrue:[
             self insertCharAtCursor:something
@@ -4848,13 +4850,15 @@
                           #'F*' #'f*')>
 
     |fKeyMacros shiftPressed ctrlPressed i event macroName
-     immediateCompletion|
+     immediateCompletion currentUserPrefs|
+
+    currentUserPrefs := UserPreferences current.
 
     "/ experimental
-    immediateCompletion := UserPreferences current immediateCodeCompletion.
+    immediateCompletion := currentUserPrefs immediateCodeCompletion.
     (immediateCompletion 
-    or:[UserPreferences current codeCompletionOnControlKey
-    or:[UserPreferences current codeCompletionOnTabKey]]) ifTrue:[
+    or:[currentUserPrefs codeCompletionOnControlKey
+    or:[currentUserPrefs codeCompletionOnTabKey]]) ifTrue:[
         completionSupport isNil ifTrue:[
             self initializeCompletionSupport.
         ].
@@ -4867,11 +4871,18 @@
         (completionSupport handleKeyPress:key x:x y:y) ifTrue:["eaten" ^ self].
     ].
 
+    key isSymbol ifTrue:[
+        (device modifierKeys includes:key) ifFalse:[
+            lastReplacementInfo stillCollectingInput:false.
+        ]
+    ].
     (key == #LearnKeyboardMacro) ifTrue:[
+        lastReplacementInfo stillCollectingInput:false.
         self toggleLearnMode.
         ^ self
     ].
     (key == #ExecuteKeyboardMacro) ifTrue:[
+        lastReplacementInfo stillCollectingInput:false.
         self executeLearnedKeyboardMacro.
         ^ self.
     ].
@@ -4908,7 +4919,7 @@
     (key == #BackSpace or:[key == #BasicBackspace]) ifTrue:[
         selectionStartLine notNil ifTrue:[
             ((key == #BasicBackspace)
-            or:[ UserPreferences current deleteSetsClipboardText not ])
+            or:[ currentUserPrefs deleteSetsClipboardText not ])
             ifTrue:[
                 self deleteSelection.
             ] ifFalse: [
@@ -4957,7 +4968,7 @@
         (('[fF][0-9]' match:key)
         or:['[fF][0-9][0-9]' match:key]) ifTrue:[
             shiftPressed ifFalse:[
-                fKeyMacros := UserPreferences current functionKeySequences.
+                fKeyMacros := currentUserPrefs functionKeySequences.
                 fKeyMacros notNil ifTrue:[
                     (fKeyMacros includesKey:key) ifTrue:[
                         self pasteOrReplace:(fKeyMacros at:key) asStringCollection.
@@ -5091,9 +5102,13 @@
                 self cursorReturn.
                 autoIndent == true ifTrue:[
                     i := self leftIndentForLine:(cursorLine + 1).
-                    self cursorCol:(i+1 max:1)
+                    true "(self listAt:cursorLine) isEmptyOrNil" ifTrue:[
+                        self cursorCol:(i+1 max:1)
+                    ]
                 ]
             ] ifTrue:[
+                |left right|
+
                 "/ old version just unselected ...
                 "/ self unselect; makeCursorVisible.
 
@@ -5103,11 +5118,27 @@
                 ] ifFalse:[
                     self copyAndDeleteSelection.
                 ].
+                left := (self listAt:cursorLine to:cursorCol-1) ? ''.
+                right := (self listAt:cursorLine from:cursorCol) ? ''.
                 self insertCharAtCursor:(Character cr).
                 autoIndent == true ifTrue:[
-                    i := self leftIndentForLine:cursorLine.
-                    self indentFromLine:cursorLine toLine:cursorLine.
-                    self cursorCol:(i+1 max:1)
+                    (right isEmpty and:[cursorCol ~~ 1]) ifTrue:[
+                        "/ nothing to do.
+                    ] ifFalse:[
+                        ((self listAt:cursorLine) isEmptyOrNil 
+                        or:[ cursorCol == 1 ]) ifTrue:[
+                            i := (self leftIndentForLine:cursorLine).
+                            (left withoutSeparators endsWith:'[') ifTrue:[
+                                i := i + 4.
+                            ] ifFalse:[
+                                (right withoutSeparators startsWith:']') ifTrue:[
+                                    i := i - 4.
+                                ].
+                            ].
+                            self indentFromLine:cursorLine toLine:cursorLine by:i.
+                            self cursorCol:(i+1 max:1)
+                        ].
+                    ]
                 ].
             ].
         ].
@@ -5167,7 +5198,7 @@
 "/            self setLastStringToReplace: self selection asStringWithoutFinalCR.
 "/            lastReplacementInfo lastReplacement: nil.
             ((key == #BasicDelete)
-            or:[UserPreferences current deleteSetsClipboardText not]) ifTrue:[
+            or:[currentUserPrefs deleteSetsClipboardText not]) ifTrue:[
                 self deleteSelection.
             ] ifFalse:[
                 self copyAndDeleteSelection.
@@ -5476,6 +5507,14 @@
 
 !EditTextView methodsFor:'focus handling'!
 
+focusOut
+    super focusOut.
+
+    completionSupport notNil ifTrue:[
+        completionSupport release.
+    ].
+!
+
 hasKeyboardFocus:aBoolean
     "sent by the windowGroup, a delegate or myself to make me show a block cursor
      (otherwise, I would not know about this)"
@@ -5490,7 +5529,7 @@
 
     hasKeyboardFocus ifFalse:[
         completionSupport notNil ifTrue:[
-            completionSupport editViewLostFocus.
+            completionSupport release editViewLostFocus.
         ].
     ].
 
@@ -5508,6 +5547,14 @@
     "Modified: 11.12.1996 / 16:56:54 / cg"
 !
 
+unmapped
+    super unmapped.
+
+    completionSupport notNil ifTrue:[
+        completionSupport release.
+    ].
+!
+
 wantsFocusWithPointerEnter
     "return true, if I want the focus when
      the mouse pointer enters"
@@ -5582,13 +5629,24 @@
      last non-empty line before start, and change the indent
      of the selected line-range based on that line's indent."
 
-    |leftStart delta d line spaces anyChange|
+    |leftStart delta|
 
     leftStart := self leftIndentForLine:start.
     (leftStart == 0) ifTrue:[^ self].
 
     delta := leftStart - (self leftIndentOfLine:start).
     (delta == 0) ifTrue:[^ self].
+    self indentFromLine:start toLine:end by:delta
+!
+
+indentFromLine:start toLine:end by:delta
+    "indent a line-range - this is done by searching for the
+     last non-empty line before start, and change the indent
+     of the selected line-range based on that line's indent."
+
+    |d line spaces anyChange|
+
+    (delta == 0) ifTrue:[^ self].
     (delta > 0) ifTrue:[
         spaces := String new:delta
     ].
@@ -5641,15 +5699,18 @@
     lnr := lineNr.
 
     [lnr ~~ 1] whileTrue:[
-	lnr  := lnr - 1.
-	line := self listAt:lnr.
-
-	line notNil ifTrue:[
-	    indent := line indexOfNonSeparatorStartingAt:1.
-	    indent ~~ 0 ifTrue:[
-		^ indent - 1
-	    ]
-	]
+        lnr  := lnr - 1.
+        line := self listAt:lnr.
+
+        line notNil ifTrue:[
+            indent := line indexOfNonSeparatorStartingAt:1.
+            indent ~~ 0 ifTrue:[
+                (line endsWith:$[) ifTrue:[
+                    ^ indent + 4 - 1
+                ].
+                ^ indent - 1
+            ]
+        ]
     ].
     ^ 0
 
@@ -8285,6 +8346,40 @@
 
 lastStringToReplace:something
     lastStringToReplace := something.
+!
+
+previousReplacements
+    ^ previousReplacements ? #()
+!
+
+stillCollectingInput
+    ^ stillCollectingInput
+!
+
+stillCollectingInput:aBoolean
+    stillCollectingInput := aBoolean.
+! !
+
+!EditTextView::LastReplacementInfo methodsFor:'history'!
+
+rememberReplacement
+    "remember the previous replacement (called when a new one appears).
+     Mostly for the benefit of the code completion..."
+
+    |oldString newString|
+
+    oldString := lastStringToReplace.
+    newString := lastReplacement.
+    (oldString notEmptyOrNil and:[newString notEmptyOrNil]) ifTrue:[
+        previousReplacements isNil ifTrue:[
+            previousReplacements := OrderedCollection new.
+        ].
+        previousReplacements := previousReplacements reject:[:entry | entry key = oldString].
+        previousReplacements addFirst:(oldString -> newString).
+        previousReplacements size > 20 ifTrue:[
+            previousReplacements removeLast.
+        ]
+    ].
 ! !
 
 !EditTextView::PasteString methodsFor:'accessing'!
@@ -8543,11 +8638,11 @@
 !EditTextView class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg/EditTextView.st,v 1.588 2013-09-27 09:26:51 vrany Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg/EditTextView.st,v 1.593 2013-10-28 11:38:14 cg Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libwidg/EditTextView.st,v 1.588 2013-09-27 09:26:51 vrany Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg/EditTextView.st,v 1.593 2013-10-28 11:38:14 cg Exp $'
 !
 
 version_HG