TextView.st
changeset 478 180275291838
parent 458 14e994e20eb5
child 486 4c1cfc595c51
--- a/TextView.st	Wed Mar 06 12:41:29 1996 +0100
+++ b/TextView.st	Wed Mar 06 15:00:25 1996 +0100
@@ -13,9 +13,9 @@
 ListView subclass:#TextView
 	instanceVariableNames:'selectionStartLine selectionStartCol selectionEndLine
 		selectionEndCol clickStartLine clickStartCol clickLine clickCol
-		clickCount wordStartCol wordStartLine wordEndCol wordEndLine
-		selectionFgColor selectionBgColor fileBox searchBox lineNumberBox
-		selectStyle directoryForFileDialog contentsWasSaved'
+		clickCount expandingTop wordStartCol wordStartLine wordEndCol
+		wordEndLine selectionFgColor selectionBgColor selectStyle
+		directoryForFileDialog contentsWasSaved'
 	classVariableNames:'DefaultViewBackground DefaultSelectionForegroundColor
 		DefaultSelectionBackgroundColor MatchDelayTime'
 	poolDictionaries:''
@@ -52,20 +52,24 @@
       selectionStartCol       <Number>                the col of the selection start
       selectionEndLine        <Number>                the line of the selection end
       selectionEndCol         <Number>                the col of the selection end
-      clickStartLine          <Number>                temporary
+
+      clickStartLine          <Number>                temporary - remember where select operation started
       clickStartCol           <Number>                temporary
       clickLine               <Number>                temporary
       clickCol                <Number>                temporary
       clickCount              <Number>                temporary
+      expandingTop            <Boolean>               temporary - for expandSelection
+
       selectionFgColor        <Color>                 color used to draw selections
       selectionBgColor        <Color>                 color used to draw selections
-      fileBox                 <FileSelectionBox>      box for save
-      searchBox               <EnterBox2>             box to enter searchpattern
-      lineNumberBox           <EnterBox>              box to enter linenumber
+
       selectStyle             <Symbol>                how words are selected
+
       directoryForFileDialog  <nil|pathName>          directory where save dialog should start
+
       contentsWasSaved        <Boolean>               set to true, whenever saved in a file
 
+
     StyleSheet parameters:
 
       textViewBackground                 defaults to viewBackground
@@ -461,78 +465,83 @@
 buttonMultiPress:button x:x y:y
     "multi-mouse-click - select word under pointer"
 
-    |sel|
+    |sel ch|
 
     ((button == 1) or:[button == #select]) ifTrue:[
-	clickCount notNil ifTrue:[
-	    clickCount := clickCount + 1.
-	    (clickCount == 2) ifTrue:[
-		self selectWordAtX:x y:y.
-		"
-		 special - if clicked on a parenthesis, select to matching
-		"
-		((sel := self selection) size == 1 
-		and:[(sel := sel at:1) size == 1]) ifTrue:[
-		    ('()[]{}<>' includes:(sel at:1)) ifTrue:[
-			self searchForMatchingParenthesisFromLine:selectionStartLine col:selectionStartCol
-			      ifFound:[:line :col | 
-					  |prevLine prevCol|
+        clickCount notNil ifTrue:[
+            clickCount := clickCount + 1.
+            (clickCount == 2) ifTrue:[
+                self selectWordAtX:x y:y.
+                "
+                 special - if clicked on a parenthesis, select to matching
+                "
+                ((sel := self selection) size == 1 
+                and:[(sel := sel at:1) size == 1]) ifTrue:[
+                    ch := sel at:1.
+                    ('()[]{}<>' includes:ch) ifTrue:[
+                        self searchForMatchingParenthesisFromLine:selectionStartLine col:selectionStartCol
+                              ifFound:[:line :col | 
+                                          |prevLine prevCol|
 
-					  prevLine := firstLineShown.
-					  prevCol := leftOffset.
-					  self selectFromLine:selectionStartLine col:selectionStartCol
-						       toLine:line col:col.
-					  "/ undo scroll operation ...
-					  (')]}>' includes:(sel at:1)) ifTrue:[
-					       (firstLineShown ~~ prevLine or:[prevCol ~~ leftOffset]) ifTrue:[
-						   Delay waitForSeconds:MatchDelayTime. 
-						   self scrollToLine:prevLine; scrollToCol:prevCol.
-					       ] 
-					  ] ifFalse:[
-					       selectionEndLine > (firstLineShown + nFullLinesShown) ifTrue:[
-						   self makeLineVisible:selectionEndLine.
-						   Delay waitForSeconds:MatchDelayTime. 
-						   self scrollToLine:prevLine; scrollToCol:prevCol.
-					       ]
-					  ]
-				      ]
-			   ifNotFound:[self showNotFound]
-			      onError:[device beep].
-			selectStyle := nil
-		    ]
-		].
+                                          prevLine := firstLineShown.
+                                          prevCol := leftOffset.
+                                          self selectFromLine:selectionStartLine col:selectionStartCol
+                                                       toLine:line col:col.
+                                          self sensor ctrlDown ifFalse:[
+                                              "/ undo scroll operation ...
+                                              self withCursor:Cursor eye do:[  
+                                                  (')]}>' includes:ch) ifTrue:[
+                                                       (firstLineShown ~~ prevLine or:[prevCol ~~ leftOffset]) ifTrue:[
+                                                           Delay waitForSeconds:MatchDelayTime. 
+                                                           self scrollToLine:prevLine; scrollToCol:prevCol.
+                                                       ] 
+                                                  ] ifFalse:[
+                                                       selectionEndLine > (firstLineShown + nFullLinesShown) ifTrue:[
+                                                           self makeLineVisible:selectionEndLine.
+                                                           Delay waitForSeconds:MatchDelayTime. 
+                                                           self scrollToLine:prevLine; scrollToCol:prevCol.
+                                                       ]
+                                                  ]
+                                              ]
+                                          ]
+                                      ]
+                           ifNotFound:[self showNotFound]
+                              onError:[device beep].
+                        selectStyle := nil
+                    ]
+                ].
 
-		"
-		 remember words position in case of a drag following
-		"
-		wordStartLine := selectionStartLine.
-		wordEndLine := selectionEndLine.
-		selectStyle == #wordLeft ifTrue:[
-		    wordStartCol := selectionStartCol + 1
-		] ifFalse:[
-		    wordStartCol := selectionStartCol.
-		].
-		selectStyle == #wordRight ifTrue:[
-		    wordEndCol := selectionEndCol - 1
-		] ifFalse:[
-		    wordEndCol := selectionEndCol
-		]
-	    ] ifFalse:[
-		(clickCount == 3) ifTrue:[
-		    self selectLineAtY:y.
-		    selectStyle := #line
-		] ifFalse:[
-		    (clickCount == 4) ifTrue:[
-			self selectAll
-		    ]
-		]
-	    ]
-	]
+                "
+                 remember words position in case of a drag following
+                "
+                wordStartLine := selectionStartLine.
+                wordEndLine := selectionEndLine.
+                selectStyle == #wordLeft ifTrue:[
+                    wordStartCol := selectionStartCol + 1
+                ] ifFalse:[
+                    wordStartCol := selectionStartCol.
+                ].
+                selectStyle == #wordRight ifTrue:[
+                    wordEndCol := selectionEndCol - 1
+                ] ifFalse:[
+                    wordEndCol := selectionEndCol
+                ]
+            ] ifFalse:[
+                (clickCount == 3) ifTrue:[
+                    self selectLineAtY:y.
+                    selectStyle := #line
+                ] ifFalse:[
+                    (clickCount == 4) ifTrue:[
+                        self selectAll
+                    ]
+                ]
+            ]
+        ]
     ] ifFalse:[
-	super buttonMultiPress:button x:x y:y
+        super buttonMultiPress:button x:x y:y
     ]
 
-    "Modified: 18.11.1995 / 18:30:33 / cg"
+    "Modified: 6.3.1996 / 14:55:11 / cg"
 !
 
 buttonPress:button x:x y:y
@@ -620,22 +629,6 @@
 
 !TextView methodsFor:'initialize & release'!
 
-destroy
-    fileBox notNil ifTrue:[
-	fileBox destroy.
-	fileBox := nil
-    ].
-    searchBox notNil ifTrue:[
-	searchBox destroy.
-	searchBox := nil
-    ].
-    lineNumberBox notNil ifTrue:[
-	lineNumberBox destroy.
-	lineNumberBox := nil
-    ].
-    super destroy
-!
-
 initStyle
     super initStyle.
 
@@ -780,25 +773,26 @@
 gotoLine
     "show a box to enter lineNumber for positioning"
 
-    |l|
+    |l lineNumberBox|
 
-    lineNumberBox isNil ifTrue:[
-	lineNumberBox :=
-	    EnterBox
-	       title:(resources string:'line number:')
-	       okText:(resources string:'goto')
-	       abortText:(resources string:'cancel')
-	       action:[:l | |num|
-			   num := Integer readFromString:l onError:nil.
-			   num notNil ifTrue:[self gotoLine:num]
-		      ]
-    ].
+    lineNumberBox :=
+        EnterBox
+           title:(resources string:'line number:')
+           okText:(resources string:'goto')
+           abortText:(resources string:'cancel')
+           action:[:l | |num|
+                       num := Integer readFromString:l onError:nil.
+                       num notNil ifTrue:[self gotoLine:num]
+                  ].
+
     l := self defaultForGotoLine.
     l notNil ifTrue:[
-	l := l printString
+        l := l printString
     ].
     lineNumberBox initialText:l .
     lineNumberBox showAtPointer
+
+    "Modified: 6.3.1996 / 13:12:27 / cg"
 !
 
 print
@@ -818,18 +812,22 @@
     "save contents into a file 
      - ask user for filename using a fileSelectionBox."
 
-    fileBox isNil ifTrue:[
-	fileBox := FileSaveBox
-			title:(resources string:'save contents in:')
-			okText:(resources string:'save')
-			abortText:(resources string:'cancel')
-			action:[:fileName | self saveAs:fileName].
-	fileBox appendAction:[:fileName | self appendTo:fileName].
+    |fileBox|
+
+    fileBox := FileSaveBox
+                    title:(resources string:'save contents in:')
+                    okText:(resources string:'save')
+                    abortText:(resources string:'cancel')
+                    action:[:fileName | self saveAs:fileName].
+    fileBox appendAction:[:fileName | self appendTo:fileName].
+    directoryForFileDialog notNil ifTrue:[
+        fileBox directory:directoryForFileDialog
     ].
-    directoryForFileDialog notNil ifTrue:[
-	fileBox directory:directoryForFileDialog
-    ].
-    fileBox showAtPointer
+    fileBox showAtPointer.
+
+    directoryForFileDialog := fileBox directory  "/ remember for next time
+
+    "Modified: 6.3.1996 / 13:09:19 / cg"
 !
 
 saveAs:fileName
@@ -998,6 +996,20 @@
     ]
 !
 
+clearMarginOfVisibleLine:visLine with:color
+    "if there is a margin, clear it - a helper for selection drawing"
+
+    (leftMargin ~~ 0) ifTrue:[
+        self paint:color.
+        self fillRectangleX:margin
+                          y:(self yOfVisibleLine:visLine)
+                      width:leftMargin
+                     height:fontHeight
+    ]
+
+    "Created: 6.3.1996 / 14:22:55 / cg"
+!
+
 redrawFromVisibleLine:startVisLineNr to:endVisLineNr
     "redraw a visible line range"
 
@@ -1083,70 +1095,82 @@
     ]
 !
 
+redrawMarginOfVisibleLine:visLine
+    "draw margin - a helper for selection drawing"
+
+
+    (leftMargin ~~ 0) ifTrue:[
+    ]
+
+    "Created: 6.3.1996 / 14:21:48 / cg"
+!
+
 redrawVisibleLine:visLine
     "redraw visible line lineNr"
 
     |len line l|
 
     selectionStartLine notNil ifTrue:[
-	line := self visibleLineToAbsoluteLine:visLine.
-	(line between:selectionStartLine and:selectionEndLine) ifTrue:[
-	    (line == selectionStartLine) ifTrue:[
-		(line == selectionEndLine) ifTrue:[
-		    "its part-of-single-line selection"
-		    self clearMarginOfVisible:visLine with:bgColor.
-		    (selectionStartCol > 1) ifTrue:[
-			super redrawVisibleLine:visLine
-					   from:1
-					     to:(selectionStartCol - 1)
-		    ].
-		    self drawVisibleLine:visLine from:selectionStartCol
-						   to:selectionEndCol
-						 with:selectionFgColor
-						  and:selectionBgColor.
-		    super redrawVisibleLine:visLine
-				       from:(selectionEndCol + 1).
-		    ^ self
-		].
+        line := self visibleLineToAbsoluteLine:visLine.
+        (line between:selectionStartLine and:selectionEndLine) ifTrue:[
+            (line == selectionStartLine) ifTrue:[
+                (line == selectionEndLine) ifTrue:[
+                    "its part-of-single-line selection"
+                    self clearMarginOfVisibleLine:visLine with:bgColor.
+                    (selectionStartCol > 1) ifTrue:[
+                        super redrawVisibleLine:visLine
+                                           from:1
+                                             to:(selectionStartCol - 1)
+                    ].
+                    self drawVisibleLine:visLine from:selectionStartCol
+                                                   to:selectionEndCol
+                                                 with:selectionFgColor
+                                                  and:selectionBgColor.
+                    super redrawVisibleLine:visLine
+                                       from:(selectionEndCol + 1).
+                    ^ self
+                ].
 
-		"its the first line of a multi-line selection"
-		(selectionStartCol ~~ 1) ifTrue:[
-		    self clearMarginOfVisible:visLine with:bgColor.
-		    super redrawVisibleLine:visLine
-				       from:1
-					 to:(selectionStartCol - 1)
-		] ifFalse:[
-		    leftOffset == 0 ifTrue:[
-			self clearMarginOfVisible:visLine with:selectionBgColor.
-		    ]
-		].
-		self drawVisibleLine:visLine from:selectionStartCol
-				with:selectionFgColor and:selectionBgColor.
-		^ self
-	    ].
+                "its the first line of a multi-line selection"
+                (selectionStartCol ~~ 1) ifTrue:[
+                    self clearMarginOfVisibleLine:visLine with:bgColor.
+                    super redrawVisibleLine:visLine
+                                       from:1
+                                         to:(selectionStartCol - 1)
+                ] ifFalse:[
+                    leftOffset == 0 ifTrue:[
+                        self clearMarginOfVisibleLine:visLine with:selectionBgColor.
+                    ]
+                ].
+                self drawVisibleLine:visLine from:selectionStartCol
+                                with:selectionFgColor and:selectionBgColor.
+                ^ self
+            ].
 
-	    (line == selectionEndLine) ifTrue:[
-		"its the last line of a multi-line selection"
-		(selectionEndCol == 0) ifTrue:[
-		    ^ super redrawVisibleLine:visLine
-		].
-		l := self visibleAt:selectionEndLine.
-		len := l size.
+            (line == selectionEndLine) ifTrue:[
+                "its the last line of a multi-line selection"
+                (selectionEndCol == 0) ifTrue:[
+                    ^ super redrawVisibleLine:visLine
+                ].
+                l := self visibleAt:selectionEndLine.
+                len := l size.
 
-		self clearMarginOfVisible:visLine with:selectionBgColor.
-		self drawVisibleLine:visLine from:1 to:selectionEndCol
-				with:selectionFgColor and:selectionBgColor.
-		super redrawVisibleLine:visLine from:(selectionEndCol + 1).
-		^ self
-	    ].
+                self clearMarginOfVisibleLine:visLine with:selectionBgColor.
+                self drawVisibleLine:visLine from:1 to:selectionEndCol
+                                with:selectionFgColor and:selectionBgColor.
+                super redrawVisibleLine:visLine from:(selectionEndCol + 1).
+                ^ self
+            ].
 
-	    "its a full line in a multi-line selection"
-	    self clearMarginOfVisible:visLine with:selectionBgColor.
-	    self drawVisibleLine:visLine with:selectionFgColor and:selectionBgColor.
-	    ^ self
-	]
+            "its a full line in a multi-line selection"
+            self clearMarginOfVisibleLine:visLine with:selectionBgColor.
+            self drawVisibleLine:visLine with:selectionFgColor and:selectionBgColor.
+            ^ self
+        ]
     ].
     super redrawVisibleLine:visLine
+
+    "Modified: 6.3.1996 / 14:22:19 / cg"
 !
 
 redrawVisibleLine:visLine col:col
@@ -1156,43 +1180,58 @@
 
     line := self visibleLineToAbsoluteLine:visLine.
     selectionStartLine notNil ifTrue:[
-	(line between:selectionStartLine and:selectionEndLine) ifTrue:[
-	    ((line == selectionStartLine)
-	    and: [col < selectionStartCol]) ifFalse:[
-		((line == selectionEndLine)
-		and: [col > selectionEndCol]) ifFalse:[
-		    "its in the selection"
-		    self drawVisibleLine:visLine col:col with:selectionFgColor
-							  and:selectionBgColor.
-		    ^ self
-		]
-	    ]
-	]
+        (line between:selectionStartLine and:selectionEndLine) ifTrue:[
+            ((line == selectionStartLine)
+            and: [col < selectionStartCol]) ifFalse:[
+                ((line == selectionEndLine)
+                and: [col > selectionEndCol]) ifFalse:[
+                    "its in the selection"
+                    self 
+                        drawVisibleLine:visLine 
+                        col:col 
+                        with:selectionFgColor
+                        and:selectionBgColor.
+                    ^ self
+                ]
+            ]
+        ]
     ].
     super redrawVisibleLine:visLine col:col
+
+    "Modified: 6.3.1996 / 14:20:14 / cg"
 !
 
 redrawVisibleLine:visLine from:startCol
     "redraw visible line lineNr from startCol to end of line"
 
-    |line|
+    |col line|
+
+    col := startCol.
+    col == 0 ifTrue:[
+        col := 1.
+    ].
 
     line := self visibleLineToAbsoluteLine:visLine.
     selectionStartLine notNil ifTrue:[
-	(line between:selectionStartLine and:selectionEndLine) ifTrue:[
-	    ((line == selectionStartLine) 
-	     or:[line == selectionEndLine]) ifTrue:[
-		"since I'm lazy, redraw full line"
-		self redrawVisibleLine:visLine.
-		^ self
-	    ].
-	    "the line is fully within the selection"
-	    self drawVisibleLine:visLine from:startCol with:selectionFgColor
-							and:selectionBgColor.
-	    ^ self
-	]
+        (line between:selectionStartLine and:selectionEndLine) ifTrue:[
+            ((line == selectionStartLine) 
+             or:[line == selectionEndLine]) ifTrue:[
+                "since I'm lazy, redraw full line"
+                self redrawVisibleLine:visLine.
+                ^ self
+            ].
+            "the line is fully within the selection"
+            self 
+                drawVisibleLine:visLine 
+                from:col 
+                with:selectionFgColor
+                and:selectionBgColor.
+            ^ self
+        ]
     ].
-    super redrawVisibleLine:visLine from:startCol
+    super redrawVisibleLine:visLine from:col
+
+    "Modified: 6.3.1996 / 14:19:38 / cg"
 !
 
 redrawVisibleLine:visLine from:startCol to:endCol
@@ -1205,77 +1244,77 @@
     allIn := false.
     allOut := false.
     selectionStartLine isNil ifTrue:[
-	allOut := true
+        allOut := true
     ] ifFalse:[
-	(line between:selectionStartLine and:selectionEndLine) ifFalse:[
-	    allOut := true
-	] ifTrue:[
-	    (selectionStartLine == selectionEndLine) ifTrue:[
-		((endCol < selectionStartCol) 
-		or:[startCol > selectionEndCol]) ifTrue:[
-		    allOut := true
-		] ifFalse:[
-		    ((startCol >= selectionStartCol) 
-		    and:[endCol <= selectionEndCol]) ifTrue:[
-			allIn := true
-		    ]
-		]
-	    ] ifFalse:[
-		(line == selectionStartLine) ifTrue:[
-		    (endCol < selectionStartCol) ifTrue:[
-			allOut := true
-		    ] ifFalse:[
-			(startCol >= selectionStartCol) ifTrue:[
-			    allIn := true
-			]
-		    ]
-		] ifFalse:[
-		    (line == selectionEndLine) ifTrue:[
-			(startCol > selectionEndCol) ifTrue:[
-			    allOut := true
-			] ifFalse:[
-			    (endCol <= selectionEndCol) ifTrue:[
-				allIn := true
-			    ]
-			]
-		    ] ifFalse:[
-			allIn := true
-		    ]
-		]
-	    ]
-	]
+        (line between:selectionStartLine and:selectionEndLine) ifFalse:[
+            allOut := true
+        ] ifTrue:[
+            (selectionStartLine == selectionEndLine) ifTrue:[
+                ((endCol < selectionStartCol) 
+                or:[startCol > selectionEndCol]) ifTrue:[
+                    allOut := true
+                ] ifFalse:[
+                    ((startCol >= selectionStartCol) 
+                    and:[endCol <= selectionEndCol]) ifTrue:[
+                        allIn := true
+                    ]
+                ]
+            ] ifFalse:[
+                (line == selectionStartLine) ifTrue:[
+                    (endCol < selectionStartCol) ifTrue:[
+                        allOut := true
+                    ] ifFalse:[
+                        (startCol >= selectionStartCol) ifTrue:[
+                            allIn := true
+                        ]
+                    ]
+                ] ifFalse:[
+                    (line == selectionEndLine) ifTrue:[
+                        (startCol > selectionEndCol) ifTrue:[
+                            allOut := true
+                        ] ifFalse:[
+                            (endCol <= selectionEndCol) ifTrue:[
+                                allIn := true
+                            ]
+                        ]
+                    ] ifFalse:[
+                        allIn := true
+                    ]
+                ]
+            ]
+        ]
     ].
     allOut ifTrue:[
-	super redrawVisibleLine:visLine from:startCol to:endCol.
-	^ self
+        super redrawVisibleLine:visLine from:startCol to:endCol.
+        ^ self
     ].
 
     allIn ifTrue:[
-	self drawVisibleLine:visLine from:startCol to:endCol
-			with:selectionFgColor and:selectionBgColor
+        self drawVisibleLine:visLine from:startCol to:endCol
+                        with:selectionFgColor and:selectionBgColor
     ] ifFalse:[
-	"redraw part before selection"
-	((line == selectionStartLine)
-	 and:[startCol <= selectionStartCol]) ifTrue:[
-	    super redrawVisibleLine:visLine from:startCol
-					      to:(selectionStartCol - 1).
-	    leftCol := selectionStartCol
-	] ifFalse:[
-	    leftCol := startCol
-	].
-	"redraw selected part"
-	(selectionEndLine > line) ifTrue:[
-	    rightCol := endCol
-	] ifFalse:[
-	    rightCol := selectionEndCol min:endCol
-	].
-	self drawVisibleLine:visLine from:leftCol to:rightCol
-			with:selectionFgColor and:selectionBgColor.
+        "redraw part before selection"
+        ((line == selectionStartLine)
+         and:[startCol <= selectionStartCol]) ifTrue:[
+            super redrawVisibleLine:visLine from:startCol
+                                              to:(selectionStartCol - 1).
+            leftCol := selectionStartCol
+        ] ifFalse:[
+            leftCol := startCol
+        ].
+        "redraw selected part"
+        (selectionEndLine > line) ifTrue:[
+            rightCol := endCol
+        ] ifFalse:[
+            rightCol := selectionEndCol min:endCol
+        ].
+        self drawVisibleLine:visLine from:leftCol to:rightCol
+                        with:selectionFgColor and:selectionBgColor.
 
-	"redraw part after selection"
-	(rightCol < endCol) ifTrue:[
-	    super redrawVisibleLine:visLine from:(rightCol + 1) to:endCol
-	]
+        "redraw part after selection"
+        (rightCol < endCol) ifTrue:[
+            super redrawVisibleLine:visLine from:(rightCol + 1) to:endCol
+        ]
     ].
 
     "special care for first and last line of selection:
@@ -1285,15 +1324,17 @@
     and:[(startCol == 1)
     and:[selectionStartLine < selectionEndLine]])
     ifTrue:[
-	self clearMarginOfVisible:visLine with:selectionBgColor.
+        self clearMarginOfVisibleLine:visLine with:selectionBgColor.
     ].
 
     ((line == selectionStartLine)
     and:[(startCol == 1)
     and:[selectionStartLine < selectionEndLine]])
     ifTrue:[
-	self clearMarginOfVisible:visLine with:bgColor.
+        self clearMarginOfVisibleLine:visLine with:bgColor.
     ]
+
+    "Modified: 6.3.1996 / 14:23:26 / cg"
 ! !
 
 !TextView methodsFor:'searching'!
@@ -1305,8 +1346,10 @@
     "
      cache the searchBox
      Q: should we use one global searchBox for all textViews ?
-	(we could then preserve the last searchstring between views)
+        (we could then preserve the last searchstring between views)
     "
+    |searchBox|
+
 
 "/ "soon to come: search & replace box ...
 "/    |box|
@@ -1325,25 +1368,26 @@
 "/        addOkButtonLabelled:(resources at:'next').
 "/    box open.
 
-    searchBox isNil ifTrue:[
-	searchBox :=
-	    EnterBox2
-	       title:(resources at:'searchPattern:')
-	     okText1:(resources at:'prev')
-	     okText2:(resources at:'next')
-	   abortText:(resources at:'cancel')
-	     action1:[:pattern | pattern notEmpty ifTrue:[self searchBwd:(pattern withoutSeparators)]]
-	     action2:[:pattern | pattern notEmpty ifTrue:[self searchFwd:(pattern withoutSeparators)]]
-    ].
+    searchBox :=
+        EnterBox2
+           title:(resources at:'searchPattern:')
+         okText1:(resources at:'prev')
+         okText2:(resources at:'next')
+       abortText:(resources at:'cancel')
+         action1:[:pattern | pattern notEmpty ifTrue:[self searchBwd:(pattern withoutSeparators)]]
+         action2:[:pattern | pattern notEmpty ifTrue:[self searchFwd:(pattern withoutSeparators)]].
+
     searchPattern notNil ifTrue:[
-	searchBox initialText:searchPattern
+        searchBox initialText:searchPattern
     ].
     self hasSelection ifTrue:[
-	selectionStartLine == selectionEndLine ifTrue:[
-	    searchBox initialText:self selection
-	]
+        selectionStartLine == selectionEndLine ifTrue:[
+            searchBox initialText:self selection
+        ]
     ].
     searchBox showAtPointer
+
+    "Modified: 6.3.1996 / 13:11:46 / cg"
 !
 
 searchBwd
@@ -1403,10 +1447,10 @@
 !
 
 searchForMatchingParenthesisFromLine:startLine col:startCol
-		     ifFound:foundBlock 
-		  ifNotFound:notFoundBlock
-		     onError:failBlock
-		    ignoring:ignoreSet
+                     ifFound:foundBlock 
+                  ifNotFound:notFoundBlock
+                     onError:failBlock
+                    ignoring:ignoreSet
     "search for a matching parenthesis, parChar is one of '$( $[ ${ $) $] $}'. 
      Search for the corresponding character is done forward if its an opening,
      backwards if its a closing parenthesis.
@@ -1416,26 +1460,26 @@
     |i direction lineString line col parChar charSet  closingChar 
      ignoring delta endCol cc incSet decSet nesting maxLine|
 
-    charSet := #( $( $) $[ $] ${ $} ).
+    charSet := #( $( $) $[ $] ${ $} " $< $> " ).
 
     parChar := self characterAtLine:startLine col:startCol.
     i := charSet indexOf:parChar.
     i == 0 ifTrue:[
-	^ failBlock value   "not a parenthesis"
+        ^ failBlock value   "not a parenthesis"
     ].
-    direction := #( fwd bwd fwd bwd fwd bwd) at:i.
-    closingChar := #( $) $( $] $[ $} ${ ) at:i.
+    direction := #( fwd bwd fwd bwd fwd bwd fwd bwd) at:i.
+    closingChar := #( $) $( $] $[ $} ${ "$> $<") at:i.
 
     col := startCol.
     line := startLine.
     direction == #fwd ifTrue:[
-	delta := 1.
-	incSet := #( $( $[ ${ ).
-	decSet := #( $) $] $} ).
+        delta := 1.
+        incSet := #( $( $[ ${ "$<" ).
+        decSet := #( $) $] $} "$>" ).
     ] ifFalse:[
-	delta := -1.
-	incSet := #( $) $] $} ).
-	decSet := #( $( $[ ${ ).
+        delta := -1.
+        incSet := #( $) $] $} "$>" ).
+        decSet := #( $( $[ ${ "$<" ).
     ].
 
     nesting := 1.
@@ -1445,52 +1489,52 @@
 
     col := col + delta.
     [nesting ~~ 0] whileTrue:[
-	lineString notNil ifTrue:[
-	    direction == #fwd ifTrue:[
-		endCol := lineString size.
-	    ] ifFalse:[
-		endCol := 1
-	    ].
-	    col to:endCol by:delta do:[:runCol |
-		cc := lineString at:runCol.
+        lineString notNil ifTrue:[
+            direction == #fwd ifTrue:[
+                endCol := lineString size.
+            ] ifFalse:[
+                endCol := 1
+            ].
+            col to:endCol by:delta do:[:runCol |
+                cc := lineString at:runCol.
 
-		(ignoreSet includes:cc) ifTrue:[
-		    ignoring := ignoring not
-		].
-		ignoring ifFalse:[
-		    (incSet includes:cc) ifTrue:[
-			nesting := nesting + 1
-		    ] ifFalse:[
-			(decSet includes:cc) ifTrue:[
-			    nesting := nesting - 1
-			]
-		    ]
-		].
-		nesting == 0 ifTrue:[
-		    "check if legal"
+                (ignoreSet includes:cc) ifTrue:[
+                    ignoring := ignoring not
+                ].
+                ignoring ifFalse:[
+                    (incSet includes:cc) ifTrue:[
+                        nesting := nesting + 1
+                    ] ifFalse:[
+                        (decSet includes:cc) ifTrue:[
+                            nesting := nesting - 1
+                        ]
+                    ]
+                ].
+                nesting == 0 ifTrue:[
+                    "check if legal"
 
-		    cc == closingChar ifFalse:[
-			^ failBlock value
-		    ].
-		    ^ foundBlock value:line value:runCol.
-		]
-	    ].
-	].
-	line := line + delta.
-	(line < 1 or:[line > maxLine]) ifTrue:[
-	    ^ failBlock value
-	].
-	lineString := list at:line.
-	direction == #fwd ifTrue:[
-	    col := 1
-	] ifFalse:[
-	    col := lineString size
-	]
+                    cc == closingChar ifFalse:[
+                        ^ failBlock value
+                    ].
+                    ^ foundBlock value:line value:runCol.
+                ]
+            ].
+        ].
+        line := line + delta.
+        (line < 1 or:[line > maxLine]) ifTrue:[
+            ^ failBlock value
+        ].
+        lineString := list at:line.
+        direction == #fwd ifTrue:[
+            col := 1
+        ] ifFalse:[
+            col := lineString size
+        ]
     ].
 
     ^ notFoundBlock value
 
-    "Modified: 18.11.1995 / 16:30:56 / cg"
+    "Modified: 6.3.1996 / 14:58:29 / cg"
 !
 
 searchFwd
@@ -1608,54 +1652,128 @@
 !TextView methodsFor:'selections'!
 
 expandSelectionDown
-    selectionStartLine notNil ifTrue:[
-        selectionEndLine := selectionEndLine + 1.
+    |l t|
 
-        self redrawLine:selectionEndLine-1. 
-        self redrawLine:selectionEndLine. 
+    selectionStartLine notNil ifTrue:[
+        expandingTop ifTrue:[
+            l := selectionStartLine.
+            selectionStartLine := selectionStartLine + 1.
+            (selectionStartLine > clickLine
+            or:[selectionStartLine == clickLine and:[selectionStartCol > clickCol]])
+            ifTrue:[
+                t := selectionStartLine.
+                selectionStartLine := selectionEndLine.
+                selectionEndLine := t.
+                t := selectionStartCol.
+                selectionStartCol := selectionEndCol.
+                selectionEndCol := t.
+                expandingTop := false
+            ].
+        ] ifFalse:[
+            l := selectionEndLine.
+            selectionEndLine := selectionEndLine + 1.
+            selectionEndLine <= clickLine ifTrue:[
+                expandingTop := true
+            ]
+        ].
+        self redrawLine:l. 
+        self redrawLine:l+1.
+        self makeSelectionVisible.
     ].
 
     "Created: 1.3.1996 / 23:35:08 / cg"
+    "Modified: 6.3.1996 / 14:18:12 / cg"
 !
 
 expandSelectionLeft
+    |c l t|
+
     selectionStartLine notNil ifTrue:[
-        selectionEndCol := (selectionEndCol - 1) max:0.
-        selectionEndLine == selectionStartLine ifTrue:[
-            selectionEndCol := selectionEndCol max:selectionStartCol
+        expandingTop ifTrue:[
+            selectionStartCol == 0 ifTrue:[^ self].
+            l := selectionStartLine.
+            selectionStartCol := (selectionStartCol - 1) max:0.
+            c := selectionStartCol.
+        ] ifFalse:[
+            l := selectionEndLine.
+            selectionEndCol := (selectionEndCol - 1) max:0.
+            c := selectionEndCol.
+            selectionEndLine == selectionStartLine ifTrue:[
+                selectionEndCol <= selectionStartCol ifTrue:[
+                    t := selectionStartCol. selectionStartCol := selectionEndCol.
+                    selectionEndCol := t.
+                    expandingTop := true.
+                    c := selectionStartCol.
+                ]
+            ].
         ].
-        self redrawLine:selectionEndLine. 
+        self redrawLine:l from:c to:c+1. 
+        self makeSelectionVisible.
     ].
 
-    "Modified: 2.3.1996 / 00:00:00 / cg"
+    "Modified: 6.3.1996 / 14:18:27 / cg"
 !
 
 expandSelectionRight
-    selectionStartLine notNil ifTrue:[
-        selectionEndCol := selectionEndCol + 1.
+    |l c t|
 
-        self redrawLine:selectionEndLine 
-                   from:selectionEndCol-1
-                     to:selectionEndCol
+    selectionStartLine notNil ifTrue:[
+        expandingTop ifTrue:[
+            l := selectionStartLine.
+            c := selectionStartCol.
+            selectionStartCol := selectionStartCol + 1.
+            l == selectionEndLine ifTrue:[
+                c >= selectionEndCol ifTrue:[
+                    expandingTop := false.
+                    t := selectionStartCol. selectionStartCol := selectionEndCol.
+                    selectionEndCol := t.
+                    c := selectionStartCol.
+                ]
+            ]
+        ] ifFalse:[
+            l := selectionEndLine.
+            c := selectionEndCol.
+            selectionEndCol := selectionEndCol + 1.
+        ].
+
+        self redrawLine:l from:c to:c+1.
+        self makeSelectionVisible.
     ].
 
     "Created: 1.3.1996 / 23:33:17 / cg"
+    "Modified: 6.3.1996 / 13:54:10 / cg"
 !
 
 expandSelectionUp
-    |t|
+    |l t|
 
     selectionStartLine notNil ifTrue:[
-        selectionEndLine := (selectionEndLine - 1) max:0.
-        selectionEndLine := selectionEndLine max:selectionStartLine.
-        selectionEndLine == selectionStartLine ifTrue:[
-            selectionEndCol := selectionEndCol max:selectionStartCol
+        expandingTop ifTrue:[
+            selectionStartLine := (selectionStartLine - 1) max:1.
+            l := selectionStartLine. 
+        ] ifFalse:[
+            selectionEndLine := (selectionEndLine - 1) max:0.
+
+            l := selectionEndLine.
+            (selectionEndLine < clickLine
+            or:[(selectionEndLine == clickLine and:[selectionEndCol < clickCol])])
+            ifTrue:[
+                t := selectionStartLine.
+                selectionStartLine := selectionEndLine.
+                selectionEndLine := t.
+                t := selectionStartCol.
+                selectionStartCol := selectionEndCol.
+                selectionEndCol := t.
+                l := selectionStartLine.
+                expandingTop := true
+            ].
         ].
-        self redrawLine:selectionEndLine+1. 
-        self redrawLine:selectionEndLine. 
+        self redrawLine:l. 
+        self redrawLine:l+1. 
+        self makeSelectionVisible.
     ].
 
-    "Modified: 2.3.1996 / 00:01:17 / cg"
+    "Modified: 6.3.1996 / 14:12:06 / cg"
 !
 
 hasSelection
@@ -1667,9 +1785,21 @@
 makeSelectionVisible
     "scroll to make the selection visible"
 
+    |line col|
+
     selectionStartLine notNil ifTrue:[
-	self makeLineVisible:selectionStartLine
+        expandingTop ~~ false ifTrue:[
+            line := selectionStartLine.
+            col := selectionStartCol.
+        ] ifFalse:[
+            line := selectionEndLine.
+            col := selectionEndCol.
+        ].
+        self makeLineVisible:line.
+        self makeColVisible:col inLine:line.        
     ]
+
+    "Modified: 6.3.1996 / 13:53:45 / cg"
 !
 
 selectAll
@@ -1931,5 +2061,5 @@
 !TextView class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg/TextView.st,v 1.40 1996-03-01 23:05:45 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg/TextView.st,v 1.41 1996-03-06 14:00:25 cg Exp $'
 ! !