115 "insert a single character at lineNr/colNr" |
115 "insert a single character at lineNr/colNr" |
116 |
116 |
117 |line lineSize newLine drawCharacterOnly| |
117 |line lineSize newLine drawCharacterOnly| |
118 |
118 |
119 readOnly ifTrue: [ |
119 readOnly ifTrue: [ |
120 exceptionBlock value:errorMessage. |
120 exceptionBlock value:errorMessage. |
121 ^ self |
121 ^ self |
122 ]. |
122 ]. |
123 aCharacter == (Character cr) ifTrue:[ |
123 aCharacter == (Character cr) ifTrue:[ |
124 self splitLine:lineNr before:colNr. |
124 self splitLine:lineNr before:colNr. |
125 ^ self |
125 ^ self |
126 ]. |
126 ]. |
127 drawCharacterOnly := false. |
127 drawCharacterOnly := false. |
128 self checkForExistingLine:lineNr. |
128 self checkForExistingLine:lineNr. |
129 line := list at:lineNr. |
129 line := list at:lineNr. |
130 lineSize := line size. |
130 lineSize := line size. |
131 (aCharacter == Character space) ifTrue:[ |
131 (aCharacter == Character space) ifTrue:[ |
132 (colNr > lineSize) ifTrue:[ |
132 (colNr > lineSize) ifTrue:[ |
133 ^ self |
133 ^ self |
134 ] |
134 ] |
135 ]. |
135 ]. |
136 (lineSize == 0) ifTrue: [ |
136 (lineSize == 0) ifTrue: [ |
137 newLine := String new:colNr. |
137 newLine := String new:colNr. |
138 drawCharacterOnly := true |
138 drawCharacterOnly := true |
139 ] ifFalse: [ |
139 ] ifFalse: [ |
140 (colNr > lineSize) ifTrue: [ |
140 (colNr > lineSize) ifTrue: [ |
141 newLine := String new:colNr. |
141 newLine := String new:colNr. |
142 newLine replaceFrom:1 to:lineSize |
142 newLine replaceFrom:1 to:lineSize |
143 with:line startingAt:1. |
143 with:line startingAt:1. |
144 drawCharacterOnly := true |
144 drawCharacterOnly := true |
145 ] ifFalse: [ |
145 ] ifFalse: [ |
146 newLine := String new:(lineSize + 1). |
146 newLine := String new:(lineSize + 1). |
147 newLine replaceFrom:1 to:(colNr - 1) |
147 newLine replaceFrom:1 to:(colNr - 1) |
148 with:line startingAt:1. |
148 with:line startingAt:1. |
149 newLine replaceFrom:(colNr + 1) to:(lineSize + 1) |
149 newLine replaceFrom:(colNr + 1) to:(lineSize + 1) |
150 with:line startingAt:colNr |
150 with:line startingAt:colNr |
151 ] |
151 ] |
152 ]. |
152 ]. |
153 newLine at:colNr put:aCharacter. |
153 newLine at:colNr put:aCharacter. |
154 aCharacter == (Character tab) ifTrue:[ |
154 aCharacter == (Character tab) ifTrue:[ |
155 newLine := self withTabsExpanded:newLine. |
155 newLine := self withTabsExpanded:newLine. |
156 drawCharacterOnly := false |
156 drawCharacterOnly := false |
157 ]. |
157 ]. |
158 list at:lineNr put:newLine. |
158 list at:lineNr put:newLine. |
|
159 widthOfWidestLine notNil ifTrue:[ |
|
160 widthOfWidestLine := widthOfWidestLine max:(self widthOfLineString:line). |
|
161 ]. |
159 self textChanged. |
162 self textChanged. |
160 shown ifTrue:[ |
163 shown ifTrue:[ |
161 drawCharacterOnly ifTrue:[ |
164 drawCharacterOnly ifTrue:[ |
162 self redrawLine:lineNr col:colNr |
165 self redrawLine:lineNr col:colNr |
163 ] ifFalse:[ |
166 ] ifFalse:[ |
164 self redrawLine:lineNr from:colNr |
167 self redrawLine:lineNr from:colNr |
165 ] |
168 ] |
166 ] |
169 ] |
167 ! |
170 ! |
168 |
171 |
169 withoutRedrawInsertStringWithoutCRs:aString atLine:lineNr col:colNr |
172 withoutRedrawInsertStringWithoutCRs:aString atLine:lineNr col:colNr |
170 "insert aString (which has no crs) at lineNr/colNr" |
173 "insert aString (which has no crs) at lineNr/colNr" |
171 |
174 |
172 |strLen line lineSize newLine| |
175 |strLen line lineSize newLine| |
173 |
176 |
174 aString isNil ifTrue:[^ self]. |
177 aString isNil ifTrue:[^ self]. |
175 readOnly ifTrue: [ |
178 readOnly ifTrue: [ |
176 exceptionBlock value:errorMessage. |
179 exceptionBlock value:errorMessage. |
177 ^ self |
180 ^ self |
178 ]. |
181 ]. |
179 strLen := aString size. |
182 strLen := aString size. |
180 self checkForExistingLine:lineNr. |
183 self checkForExistingLine:lineNr. |
181 line := list at:lineNr. |
184 line := list at:lineNr. |
182 line notNil ifTrue:[ |
185 line notNil ifTrue:[ |
183 lineSize := line size |
186 lineSize := line size |
184 ] ifFalse:[ |
187 ] ifFalse:[ |
185 lineSize := 0 |
188 lineSize := 0 |
186 ]. |
189 ]. |
187 ((colNr == 1) and:[lineSize == 0]) ifTrue: [ |
190 ((colNr == 1) and:[lineSize == 0]) ifTrue: [ |
188 newLine := aString |
191 newLine := aString |
189 ] ifFalse:[ |
192 ] ifFalse:[ |
190 (lineSize == 0) ifTrue: [ |
193 (lineSize == 0) ifTrue: [ |
191 newLine := String new:(colNr + strLen - 1) |
194 newLine := String new:(colNr + strLen - 1) |
192 ] ifFalse: [ |
195 ] ifFalse: [ |
193 (colNr > lineSize) ifTrue: [ |
196 (colNr > lineSize) ifTrue: [ |
194 newLine := String new:(colNr + strLen - 1). |
197 newLine := String new:(colNr + strLen - 1). |
195 newLine replaceFrom:1 to:lineSize |
198 newLine replaceFrom:1 to:lineSize |
196 with:line startingAt:1 |
199 with:line startingAt:1 |
197 ] ifFalse: [ |
200 ] ifFalse: [ |
198 newLine := String new:(lineSize + strLen). |
201 newLine := String new:(lineSize + strLen). |
199 newLine replaceFrom:1 to:(colNr - 1) |
202 newLine replaceFrom:1 to:(colNr - 1) |
200 with:line startingAt:1. |
203 with:line startingAt:1. |
201 newLine replaceFrom:(colNr + strLen) to:(lineSize + strLen) |
204 newLine replaceFrom:(colNr + strLen) to:(lineSize + strLen) |
202 with:line startingAt:colNr |
205 with:line startingAt:colNr |
203 ] |
206 ] |
204 ]. |
207 ]. |
205 newLine replaceFrom:colNr to:(colNr + strLen - 1) |
208 newLine replaceFrom:colNr to:(colNr + strLen - 1) |
206 with:aString startingAt:1 |
209 with:aString startingAt:1 |
207 ]. |
210 ]. |
208 |
211 |
209 (aString occurrencesOf:(Character tab)) == 0 ifFalse:[ |
212 (aString occurrencesOf:(Character tab)) == 0 ifFalse:[ |
210 newLine := self withTabsExpanded:newLine |
213 newLine := self withTabsExpanded:newLine |
211 ]. |
214 ]. |
212 |
215 |
213 list at:lineNr put:newLine. |
216 list at:lineNr put:newLine. |
|
217 widthOfWidestLine notNil ifTrue:[ |
|
218 widthOfWidestLine := widthOfWidestLine max:(self widthOfLineString:newLine). |
|
219 ]. |
214 self textChanged. |
220 self textChanged. |
215 |
|
216 ! |
221 ! |
217 |
222 |
218 splitLine:lineNr before:colNr |
223 splitLine:lineNr before:colNr |
219 "split the line linNr before colNr; the right part (from colNr) |
224 "split the line linNr before colNr; the right part (from colNr) |
220 is cut off and inserted after lineNr; the view is redrawn" |
225 is cut off and inserted after lineNr; the view is redrawn" |
221 |
226 |
222 |line lineSize leftRest rightRest visLine w |
227 |line lineSize leftRest rightRest visLine w |
223 srcY "{ Class: SmallInteger }" | |
228 srcY "{ Class: SmallInteger }" | |
224 |
229 |
225 list isNil ifFalse:[ |
230 list isNil ifFalse:[ |
226 lineNr > (list size) ifFalse:[ |
231 lineNr > (list size) ifFalse:[ |
227 (colNr == 1) ifTrue:[ |
232 (colNr == 1) ifTrue:[ |
228 self insertLine:nil before:lineNr. |
233 self insertLine:nil before:lineNr. |
229 ^ self |
234 ^ self |
230 ]. |
235 ]. |
231 line := list at:lineNr. |
236 line := list at:lineNr. |
232 line isNil ifFalse:[ |
237 line isNil ifFalse:[ |
233 lineSize := line size. |
238 lineSize := line size. |
234 (colNr <= lineSize) ifTrue:[ |
239 (colNr <= lineSize) ifTrue:[ |
235 rightRest := line copyFrom:colNr to:lineSize. |
240 rightRest := line copyFrom:colNr to:lineSize. |
236 (colNr > 1) ifTrue:[ |
241 (colNr > 1) ifTrue:[ |
237 leftRest := line copyTo:(colNr - 1) |
242 leftRest := line copyTo:(colNr - 1) |
238 ] |
243 ] |
239 ] ifFalse:[ |
244 ] ifFalse:[ |
240 leftRest := line |
245 leftRest := line |
241 ] |
246 ] |
242 ]. |
247 ]. |
243 leftRest notNil ifTrue:[ |
248 leftRest notNil ifTrue:[ |
244 leftRest isBlank ifTrue:[leftRest := nil] |
249 leftRest isBlank ifTrue:[leftRest := nil] |
245 ]. |
250 ]. |
246 list at:lineNr put:leftRest. |
251 list at:lineNr put:leftRest. |
247 self withoutRedrawInsertLine:rightRest before:(lineNr + 1). |
252 self withoutRedrawInsertLine:rightRest before:(lineNr + 1). |
248 |
253 |
249 visLine := self listLineToVisibleLine:(lineNr). |
254 visLine := self listLineToVisibleLine:(lineNr). |
250 visLine notNil ifTrue:[ |
255 visLine notNil ifTrue:[ |
251 w := self widthForScrollBetween:lineNr |
256 w := self widthForScrollBetween:lineNr |
252 and:(firstLineShown + nLinesShown). |
257 and:(firstLineShown + nLinesShown). |
253 srcY := topMargin + (visLine * fontHeight). |
258 srcY := topMargin + (visLine * fontHeight). |
254 self catchExpose. |
259 self catchExpose. |
255 self copyFrom:self x:textStartLeft y:srcY |
260 self copyFrom:self x:textStartLeft y:srcY |
256 toX:textStartLeft y:(srcY + fontHeight) |
261 toX:textStartLeft y:(srcY + fontHeight) |
257 width:w |
262 width:w |
258 height:((nLinesShown - visLine - 1) * fontHeight). |
263 height:((nLinesShown - visLine - 1) * fontHeight). |
259 self redrawLine:lineNr. |
264 self redrawLine:lineNr. |
260 self redrawLine:(lineNr + 1). |
265 self redrawLine:(lineNr + 1). |
261 self waitForExpose |
266 self waitForExpose |
262 ]. |
267 ]. |
263 self textChanged. |
268 widthOfWidestLine := nil. "/ unknown |
264 ] |
269 self textChanged. |
|
270 ] |
265 ] |
271 ] |
266 ! |
272 ! |
267 |
273 |
268 withoutRedrawInsertLine:aString before:lineNr |
274 withoutRedrawInsertLine:aString before:lineNr |
269 "insert the argument, aString before line lineNr; the string |
275 "insert the argument, aString before line lineNr; the string |
312 |visLine w nLines "{ Class: SmallInteger }" |
318 |visLine w nLines "{ Class: SmallInteger }" |
313 srcY "{ Class: SmallInteger }" |
319 srcY "{ Class: SmallInteger }" |
314 dstY "{ Class: SmallInteger }" | |
320 dstY "{ Class: SmallInteger }" | |
315 |
321 |
316 readOnly ifTrue:[ |
322 readOnly ifTrue:[ |
317 ^ self |
323 ^ self |
318 ]. |
324 ]. |
319 visLine := self listLineToVisibleLine:lineNr. |
325 visLine := self listLineToVisibleLine:lineNr. |
320 (shown not or:[visLine isNil]) ifTrue:[ |
326 (shown not or:[visLine isNil]) ifTrue:[ |
321 self withoutRedrawInsertLines:someText |
327 self withoutRedrawInsertLines:someText |
322 from:start to:end |
328 from:start to:end |
323 before:lineNr. |
329 before:lineNr. |
324 self textChanged. |
|
325 ^ self |
|
326 ]. |
|
327 |
|
328 nLines := end - start + 1. |
|
329 ((visLine + nLines) >= nLinesShown) ifTrue:[ |
|
330 self withoutRedrawInsertLines:someText |
|
331 from:start to:end |
|
332 before:lineNr. |
|
333 self redrawFromVisibleLine:visLine to:nLinesShown |
|
334 ] ifFalse:[ |
330 ] ifFalse:[ |
335 w := self widthForScrollBetween:(lineNr + nLines) |
331 nLines := end - start + 1. |
336 and:(firstLineShown + nLines + nLinesShown). |
332 ((visLine + nLines) >= nLinesShown) ifTrue:[ |
337 srcY := topMargin + ((visLine - 1) * fontHeight). |
333 self withoutRedrawInsertLines:someText |
338 dstY := srcY + (nLines * fontHeight). |
334 from:start to:end |
339 " |
335 before:lineNr. |
340 stupid: must catchExpose before inserting new |
336 self redrawFromVisibleLine:visLine to:nLinesShown |
341 stuff - since catchExpose may perform redraws |
337 ] ifFalse:[ |
342 " |
338 w := self widthForScrollBetween:(lineNr + nLines) |
343 self catchExpose. |
339 and:(firstLineShown + nLines + nLinesShown). |
344 self withoutRedrawInsertLines:someText |
340 srcY := topMargin + ((visLine - 1) * fontHeight). |
345 from:start to:end |
341 dstY := srcY + (nLines * fontHeight). |
346 before:lineNr. |
342 " |
347 self copyFrom:self x:textStartLeft y:srcY |
343 stupid: must catchExpose before inserting new |
348 toX:textStartLeft y:dstY |
344 stuff - since catchExpose may perform redraws |
349 width:w |
345 " |
350 height:(height - dstY). |
346 self catchExpose. |
351 self redrawFromVisibleLine:visLine to:(visLine + nLines - 1). |
347 self withoutRedrawInsertLines:someText |
352 self waitForExpose |
348 from:start to:end |
|
349 before:lineNr. |
|
350 self copyFrom:self x:textStartLeft y:srcY |
|
351 toX:textStartLeft y:dstY |
|
352 width:w |
|
353 height:(height - dstY). |
|
354 self redrawFromVisibleLine:visLine to:(visLine + nLines - 1). |
|
355 self waitForExpose |
|
356 ]. |
|
357 ]. |
|
358 widthOfWidestLine notNil ifTrue:[ |
|
359 someText do:[:line | |
|
360 widthOfWidestLine := widthOfWidestLine max:(self widthOfLineString:line). |
|
361 ] |
353 ]. |
362 ]. |
354 self textChanged. |
363 self textChanged. |
355 ! |
364 ! |
356 |
365 |
357 deleteFromLine:startLine col:startCol toLine:endLine col:endCol |
366 deleteFromLine:startLine col:startCol toLine:endLine col:endCol |
359 joining lines if nescessary" |
368 joining lines if nescessary" |
360 |
369 |
361 |line lineSize| |
370 |line lineSize| |
362 |
371 |
363 readOnly ifTrue: [ |
372 readOnly ifTrue: [ |
364 exceptionBlock value:errorMessage. |
373 exceptionBlock value:errorMessage. |
365 ^ self |
374 ^ self |
366 ]. |
375 ]. |
367 list isNil ifTrue:[^ self]. |
376 list isNil ifTrue:[^ self]. |
368 |
377 |
369 (startLine == endLine) ifTrue:[ |
378 (startLine == endLine) ifTrue:[ |
370 "delete chars within a line" |
379 "delete chars within a line" |
371 self deleteCharsAtLine:startLine fromCol:startCol toCol:endCol. |
380 self deleteCharsAtLine:startLine fromCol:startCol toCol:endCol. |
372 ^ self |
381 ^ self |
373 ]. |
382 ]. |
374 |
383 |
375 ((startCol == 1) and:[endCol == 0]) ifTrue:[ |
384 ((startCol == 1) and:[endCol == 0]) ifTrue:[ |
376 "delete full lines only" |
385 "delete full lines only" |
377 endLine > startLine ifTrue:[ |
386 endLine > startLine ifTrue:[ |
378 self deleteFromLine:startLine toLine:(endLine - 1) |
387 self deleteFromLine:startLine toLine:(endLine - 1) |
379 ]. |
388 ]. |
380 ^ self |
389 ^ self |
381 ]. |
390 ]. |
382 |
391 |
383 "delete right rest of 1st line" |
392 "delete right rest of 1st line" |
384 self deleteCharsAtLine:startLine fromCol:startCol. |
393 self deleteCharsAtLine:startLine fromCol:startCol. |
385 |
394 |
386 "delete the inner lines ..." |
395 "delete the inner lines ..." |
387 endLine > (startLine + 1) ifTrue:[ |
396 endLine > (startLine + 1) ifTrue:[ |
388 self deleteFromLine:(startLine + 1) toLine:(endLine - 1) |
397 self deleteFromLine:(startLine + 1) toLine:(endLine - 1) |
389 ]. |
398 ]. |
390 |
399 |
391 (endCol ~~ 0) ifTrue:[ |
400 (endCol ~~ 0) ifTrue:[ |
392 "delete the left rest of the last line" |
401 "delete the left rest of the last line" |
393 self deleteCharsAtLine:(startLine + 1) toCol:endCol. |
402 self deleteCharsAtLine:(startLine + 1) toCol:endCol. |
394 |
403 |
395 "must add blanks, if startCal lies behond end of startLine" |
404 "must add blanks, if startCal lies behond end of startLine" |
396 line := list at:startLine. |
405 line := list at:startLine. |
397 lineSize := line size. |
406 lineSize := line size. |
398 (startCol > lineSize) ifTrue:[ |
407 (startCol > lineSize) ifTrue:[ |
399 line isNil ifTrue:[ |
408 line isNil ifTrue:[ |
400 line := String new:(startCol - 1) |
409 line := String new:(startCol - 1) |
401 ] ifFalse:[ |
410 ] ifFalse:[ |
402 line := line , (String new:(startCol - 1 - lineSize)) |
411 line := line , (String new:(startCol - 1 - lineSize)) |
403 ]. |
412 ]. |
404 list at:startLine put:line. |
413 list at:startLine put:line. |
405 self textChanged. |
414 widthOfWidestLine := nil. "/ i.e. unknown |
406 ] |
415 self textChanged. |
|
416 ] |
407 ]. |
417 ]. |
408 |
418 |
409 "merge the left rest of 1st line with right rest of last line into one" |
419 "merge the left rest of 1st line with right rest of last line into one" |
410 self mergeLine:startLine |
420 self mergeLine:startLine |
411 ! |
421 ! |
562 " |
572 " |
563 list replaceFrom:(lineNr + nLines) to:(list size) with:list startingAt:lineNr. |
573 list replaceFrom:(lineNr + nLines) to:(list size) with:list startingAt:lineNr. |
564 list replaceFrom:lineNr to:(lineNr + nLines - 1) with:newLines startingAt:start. |
574 list replaceFrom:lineNr to:(lineNr + nLines - 1) with:newLines startingAt:start. |
565 ! |
575 ! |
566 |
576 |
567 deleteCharsAtLine:lineNr fromCol:startCol toCol:endCol |
|
568 "delete characters from startCol to endCol in line lineNr" |
|
569 |
|
570 |line lineSize newLine| |
|
571 |
|
572 readOnly ifTrue: [ |
|
573 exceptionBlock value:errorMessage. |
|
574 ^ self |
|
575 ]. |
|
576 list isNil ifTrue: [^self]. |
|
577 (list size < lineNr) ifTrue: [^ self]. |
|
578 |
|
579 line := list at:lineNr. |
|
580 line isNil ifTrue: [^self]. |
|
581 lineSize := line size. |
|
582 (startCol > lineSize) ifTrue: [^ self]. |
|
583 (endCol == 0) ifTrue:[^ self]. |
|
584 (endCol < startCol) ifTrue:[^ self]. |
|
585 (startCol == endCol) ifTrue:[ |
|
586 self deleteCharAtLine:lineNr col:startCol. |
|
587 ^ self |
|
588 ]. |
|
589 (endCol >= lineSize) ifTrue:[ |
|
590 self deleteCharsAtLine:lineNr fromCol:startCol. |
|
591 ^ self |
|
592 ]. |
|
593 (startCol <= 1) ifTrue:[ |
|
594 self deleteCharsAtLine:lineNr toCol:endCol. |
|
595 ^ self |
|
596 ]. |
|
597 newLine := (line copyTo:(startCol - 1)) |
|
598 , (line copyFrom:(endCol + 1) to:lineSize). |
|
599 |
|
600 newLine isBlank ifTrue:[ |
|
601 newLine := nil |
|
602 ]. |
|
603 list at:lineNr put:newLine. |
|
604 self textChanged. |
|
605 self redrawLine:lineNr |
|
606 ! |
|
607 |
|
608 insertStringWithoutCRs:aString atLine:lineNr col:colNr |
577 insertStringWithoutCRs:aString atLine:lineNr col:colNr |
609 "insert aString (which has no crs) at lineNr/colNr" |
578 "insert aString (which has no crs) at lineNr/colNr" |
610 |
579 |
611 self withoutRedrawInsertStringWithoutCRs:aString atLine:lineNr col:colNr. |
580 self withoutRedrawInsertStringWithoutCRs:aString atLine:lineNr col:colNr. |
612 shown ifTrue:[self redrawLine:lineNr from:colNr] |
581 shown ifTrue:[self redrawLine:lineNr from:colNr] |
660 ]. |
629 ]. |
661 self makeCursorVisible |
630 self makeCursorVisible |
662 ] |
631 ] |
663 ! |
632 ! |
664 |
633 |
665 deleteFromLine:startLineNr toLine:endLineNr |
|
666 "delete some lines" |
|
667 |
|
668 readOnly ifTrue: [ |
|
669 exceptionBlock value:errorMessage. |
|
670 ^ self |
|
671 ]. |
|
672 list isNil ifTrue:[^ self]. |
|
673 list removeFromIndex:startLineNr toIndex:endLineNr. |
|
674 self textChanged. |
|
675 self redrawFromLine:startLineNr. |
|
676 (firstLineShown >= list size) ifTrue:[ |
|
677 self makeLineVisible:(list size) |
|
678 ] |
|
679 ! |
|
680 |
|
681 insertLine:aString before:lineNr |
634 insertLine:aString before:lineNr |
682 "insert the line aString before line lineNr" |
635 "insert the line aString before line lineNr" |
683 |
636 |
684 |visLine w |
637 |visLine w |
685 dstY "{ Class: SmallInteger }" | |
638 dstY "{ Class: SmallInteger }" | |
686 |
639 |
687 visLine := self listLineToVisibleLine:lineNr. |
640 visLine := self listLineToVisibleLine:lineNr. |
688 (shown not or:[visLine isNil]) ifTrue:[ |
641 (shown not or:[visLine isNil]) ifTrue:[ |
689 self withoutRedrawInsertLine:aString before:lineNr. |
642 self withoutRedrawInsertLine:aString before:lineNr. |
690 ] ifFalse:[ |
643 ] ifFalse:[ |
691 w := self widthForScrollBetween:lineNr |
644 w := self widthForScrollBetween:lineNr |
692 and:(firstLineShown + nLinesShown). |
645 and:(firstLineShown + nLinesShown). |
693 dstY := topMargin + ((visLine ) * fontHeight). |
646 dstY := topMargin + ((visLine ) * fontHeight). |
694 self catchExpose. |
647 self catchExpose. |
695 self withoutRedrawInsertLine:aString before:lineNr. |
648 self withoutRedrawInsertLine:aString before:lineNr. |
696 self copyFrom:self x:textStartLeft y:(dstY - fontHeight) |
649 self copyFrom:self x:textStartLeft y:(dstY - fontHeight) |
697 toX:textStartLeft y:dstY |
650 toX:textStartLeft y:dstY |
698 width:w |
651 width:w |
699 height:((nLinesShown - visLine "- 1") * fontHeight). |
652 height:((nLinesShown - visLine "- 1") * fontHeight). |
700 self redrawVisibleLine:visLine. |
653 self redrawVisibleLine:visLine. |
701 self waitForExpose. |
654 self waitForExpose. |
|
655 ]. |
|
656 widthOfWidestLine notNil ifTrue:[ |
|
657 widthOfWidestLine := widthOfWidestLine max:(self widthOfLineString:aString). |
702 ]. |
658 ]. |
703 self textChanged. |
659 self textChanged. |
704 ! |
660 ! |
705 |
661 |
706 mergeLine:lineNr |
662 mergeLine:lineNr |
740 self insertStringAtCursor:aString. |
696 self insertStringAtCursor:aString. |
741 self selectFromLine:startLine col:startCol |
697 self selectFromLine:startLine col:startCol |
742 toLine:cursorLine col:(cursorCol - 1) |
698 toLine:cursorLine col:(cursorCol - 1) |
743 ! |
699 ! |
744 |
700 |
|
701 deleteCharsAtLine:lineNr fromCol:startCol toCol:endCol |
|
702 "delete characters from startCol to endCol in line lineNr" |
|
703 |
|
704 |line lineSize newLine| |
|
705 |
|
706 readOnly ifTrue: [ |
|
707 exceptionBlock value:errorMessage. |
|
708 ^ self |
|
709 ]. |
|
710 list isNil ifTrue: [^self]. |
|
711 (list size < lineNr) ifTrue: [^ self]. |
|
712 |
|
713 line := list at:lineNr. |
|
714 line isNil ifTrue: [^self]. |
|
715 lineSize := line size. |
|
716 (startCol > lineSize) ifTrue: [^ self]. |
|
717 (endCol == 0) ifTrue:[^ self]. |
|
718 (endCol < startCol) ifTrue:[^ self]. |
|
719 (startCol == endCol) ifTrue:[ |
|
720 self deleteCharAtLine:lineNr col:startCol. |
|
721 ^ self |
|
722 ]. |
|
723 (endCol >= lineSize) ifTrue:[ |
|
724 self deleteCharsAtLine:lineNr fromCol:startCol. |
|
725 ^ self |
|
726 ]. |
|
727 (startCol <= 1) ifTrue:[ |
|
728 self deleteCharsAtLine:lineNr toCol:endCol. |
|
729 ^ self |
|
730 ]. |
|
731 newLine := (line copyTo:(startCol - 1)) |
|
732 , (line copyFrom:(endCol + 1) to:lineSize). |
|
733 |
|
734 newLine isBlank ifTrue:[ |
|
735 newLine := nil |
|
736 ]. |
|
737 list at:lineNr put:newLine. |
|
738 widthOfWidestLine := nil. "/ i.e. unknown |
|
739 self textChanged. |
|
740 self redrawLine:lineNr |
|
741 ! |
|
742 |
745 deleteCharAtLine:lineNr col:colNr |
743 deleteCharAtLine:lineNr col:colNr |
746 "delete single character at colNr in line lineNr" |
744 "delete single character at colNr in line lineNr" |
747 |
745 |
748 |line lineSize newLine drawCharacterOnly| |
746 |line lineSize newLine drawCharacterOnly wasLargest| |
749 |
747 |
750 readOnly ifTrue: [ |
748 readOnly ifTrue: [ |
751 exceptionBlock value:errorMessage. |
749 exceptionBlock value:errorMessage. |
752 ^ self |
750 ^ self |
753 ]. |
751 ]. |
754 list isNil ifTrue: [^self]. |
752 list isNil ifTrue: [^self]. |
755 (list size < lineNr) ifTrue: [^ self]. |
753 (list size < lineNr) ifTrue: [^ self]. |
756 |
754 |
757 line := list at:lineNr. |
755 line := list at:lineNr. |
758 line isNil ifTrue: [^self]. |
756 line isNil ifTrue: [^self]. |
759 lineSize := line size. |
757 lineSize := line size. |
760 (colNr > lineSize) ifTrue: [^ self]. |
758 (colNr > lineSize) ifTrue: [^ self]. |
761 |
759 |
|
760 wasLargest := (self widthOfLineString:line) == widthOfWidestLine. |
|
761 |
762 drawCharacterOnly := false. |
762 drawCharacterOnly := false. |
763 (colNr == lineSize) ifTrue:[ |
763 (colNr == lineSize) ifTrue:[ |
764 newLine := line copyTo:(lineSize - 1). |
764 newLine := line copyTo:(lineSize - 1). |
765 fontIsFixedWidth ifTrue:[ |
765 fontIsFixedWidth ifTrue:[ |
766 drawCharacterOnly := true |
766 drawCharacterOnly := true |
767 ] |
767 ] |
768 ] ifFalse:[ |
768 ] ifFalse:[ |
769 newLine := String new:(lineSize - 1). |
769 newLine := String new:(lineSize - 1). |
770 newLine replaceFrom:1 to:(colNr - 1) |
770 newLine replaceFrom:1 to:(colNr - 1) |
771 with:line startingAt:1. |
771 with:line startingAt:1. |
772 newLine replaceFrom:colNr to:(lineSize - 1) |
772 newLine replaceFrom:colNr to:(lineSize - 1) |
773 with:line startingAt:(colNr + 1) |
773 with:line startingAt:(colNr + 1) |
774 ]. |
774 ]. |
775 |
775 |
776 newLine isBlank ifTrue:[ |
776 newLine isBlank ifTrue:[ |
777 newLine := nil |
777 newLine := nil |
778 ]. |
778 ]. |
779 list at:lineNr put:newLine. |
779 list at:lineNr put:newLine. |
|
780 wasLargest ifTrue:[ |
|
781 widthOfWidestLine := nil. "/ i.e. unknown |
|
782 ]. |
780 self textChanged. |
783 self textChanged. |
781 drawCharacterOnly ifTrue:[ |
784 drawCharacterOnly ifTrue:[ |
782 self redrawLine:lineNr col:colNr |
785 self redrawLine:lineNr col:colNr |
783 ] ifFalse:[ |
786 ] ifFalse:[ |
784 self redrawLine:lineNr from:colNr |
787 self redrawLine:lineNr from:colNr |
785 ] |
788 ] |
786 ! |
789 ! |
787 |
790 |
788 removeTrailingBlankLines |
791 removeTrailingBlankLines |
789 "remove all blank lines at end of text" |
792 "remove all blank lines at end of text" |
792 line finished| |
795 line finished| |
793 |
796 |
794 lastLine := list size. |
797 lastLine := list size. |
795 finished := false. |
798 finished := false. |
796 [finished] whileFalse:[ |
799 [finished] whileFalse:[ |
797 (lastLine <= 1) ifTrue:[ |
800 (lastLine <= 1) ifTrue:[ |
798 finished := true |
801 finished := true |
799 ] ifFalse:[ |
802 ] ifFalse:[ |
800 line := list at:lastLine. |
803 line := list at:lastLine. |
801 line notNil ifTrue:[ |
804 line notNil ifTrue:[ |
802 line isBlank ifTrue:[ |
805 line isBlank ifTrue:[ |
803 list at:lastLine put:nil. |
806 list at:lastLine put:nil. |
804 line := nil |
807 line := nil |
805 ] |
808 ] |
806 ]. |
809 ]. |
807 line notNil ifTrue:[ |
810 line notNil ifTrue:[ |
808 finished := true |
811 finished := true |
809 ] ifFalse:[ |
812 ] ifFalse:[ |
810 lastLine := lastLine - 1 |
813 lastLine := lastLine - 1 |
811 ] |
814 ] |
812 ] |
815 ] |
813 ]. |
816 ]. |
814 (lastLine ~~ list size) ifTrue:[ |
817 (lastLine ~~ list size) ifTrue:[ |
815 list grow:lastLine. |
818 list grow:lastLine. |
816 "/ self textChanged |
819 "/ self textChanged |
817 ] |
820 ] |
818 ! |
821 ! |
819 |
822 |
820 deleteCharsAtLine:lineNr toCol:colNr |
823 deleteCharsAtLine:lineNr toCol:colNr |
821 "delete characters from start up to colNr in line lineNr" |
824 "delete characters from start up to colNr in line lineNr" |
822 |
825 |
823 |line lineSize newLine| |
826 |line lineSize newLine| |
824 |
827 |
825 readOnly ifTrue: [ |
828 readOnly ifTrue: [ |
826 exceptionBlock value:errorMessage. |
829 exceptionBlock value:errorMessage. |
827 ^ self |
830 ^ self |
828 ]. |
831 ]. |
829 list isNil ifTrue: [^self]. |
832 list isNil ifTrue: [^self]. |
830 (list size < lineNr) ifTrue: [^ self]. |
833 (list size < lineNr) ifTrue: [^ self]. |
831 line := list at:lineNr. |
834 line := list at:lineNr. |
832 line isNil ifTrue: [^self]. |
835 line isNil ifTrue: [^self]. |
833 lineSize := line size. |
836 lineSize := line size. |
834 (colNr >= lineSize) ifTrue:[ |
837 (colNr >= lineSize) ifTrue:[ |
835 newLine := nil |
838 newLine := nil |
836 ] ifFalse:[ |
839 ] ifFalse:[ |
837 newLine := line copyFrom:(colNr + 1) to:lineSize. |
840 newLine := line copyFrom:(colNr + 1) to:lineSize. |
838 newLine isBlank ifTrue:[ |
841 newLine isBlank ifTrue:[ |
839 newLine := nil |
842 newLine := nil |
840 ] |
843 ] |
841 ]. |
844 ]. |
842 list at:lineNr put:newLine. |
845 list at:lineNr put:newLine. |
|
846 widthOfWidestLine := nil. "/ i.e. unknown |
843 self textChanged. |
847 self textChanged. |
844 self redrawLine:lineNr |
848 self redrawLine:lineNr |
845 ! |
849 ! |
846 |
850 |
847 insertTabAtCursor |
851 insertTabAtCursor |
2196 |
2220 |
2197 "find a line to base indent on..." |
2221 "find a line to base indent on..." |
2198 leftStart := 0. |
2222 leftStart := 0. |
2199 lnr := start. |
2223 lnr := start. |
2200 [(leftStart == 0) and:[lnr ~~ 1]] whileTrue:[ |
2224 [(leftStart == 0) and:[lnr ~~ 1]] whileTrue:[ |
2201 lnr := lnr - 1. |
2225 lnr := lnr - 1. |
2202 leftStart := self leftIndentOfLine:lnr |
2226 leftStart := self leftIndentOfLine:lnr |
2203 ]. |
2227 ]. |
2204 |
2228 |
2205 (leftStart == 0) ifTrue:[^ self]. |
2229 (leftStart == 0) ifTrue:[^ self]. |
2206 |
2230 |
2207 delta := leftStart - (self leftIndentOfLine:start). |
2231 delta := leftStart - (self leftIndentOfLine:start). |
2208 (delta == 0) ifTrue:[^ self]. |
2232 (delta == 0) ifTrue:[^ self]. |
2209 (delta > 0) ifTrue:[ |
2233 (delta > 0) ifTrue:[ |
2210 spaces := String new:delta |
2234 spaces := String new:delta |
2211 ]. |
2235 ]. |
2212 start to:end do:[:lineNr | |
2236 start to:end do:[:lineNr | |
2213 line := self listAt:lineNr. |
2237 line := self listAt:lineNr. |
2214 line notNil ifTrue:[ |
2238 line notNil ifTrue:[ |
2215 line isBlank ifTrue:[ |
2239 line isBlank ifTrue:[ |
2216 list at:lineNr put:nil |
2240 list at:lineNr put:nil |
2217 ] ifFalse:[ |
2241 ] ifFalse:[ |
2218 (delta > 0) ifTrue:[ |
2242 (delta > 0) ifTrue:[ |
2219 line := spaces , line |
2243 line := spaces , line. |
2220 ] ifFalse:[ |
2244 widthOfWidestLine notNil ifTrue:[ |
2221 "check if deletion is ok" |
2245 widthOfWidestLine := widthOfWidestLine max:(self widthOfLineString:line). |
2222 d := delta negated + 1. |
2246 ] |
2223 |
2247 ] ifFalse:[ |
2224 line size > d ifTrue:[ |
2248 "check if deletion is ok" |
2225 (line copyTo:(d - 1)) withoutSeparators isEmpty ifTrue:[ |
2249 d := delta negated + 1. |
2226 line := line copyFrom:d |
2250 |
2227 ] |
2251 line size > d ifTrue:[ |
2228 ] |
2252 (line copyTo:(d - 1)) withoutSeparators isEmpty ifTrue:[ |
2229 ]. |
2253 line := line copyFrom:d |
2230 list at:lineNr put:line. |
2254 ] |
2231 self textChanged. |
2255 ]. |
2232 ] |
2256 widthOfWidestLine := nil |
2233 ] |
2257 ]. |
|
2258 list at:lineNr put:line. |
|
2259 self textChanged. |
|
2260 ] |
|
2261 ] |
2234 ]. |
2262 ]. |
2235 self redrawFromLine:start to:end |
2263 self redrawFromLine:start to:end |
2236 ! ! |
2264 ! ! |
2237 |
2265 |
2238 !EditTextView methodsFor:'undo & again'! |
2266 !EditTextView methodsFor:'undo & again'! |