Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1046.mcz ==================== Summary ==================== Name: Morphic-mt.1046 Author: mt Time: 18 November 2015, 10:42:36.478 pm UUID: 204f289b-46cb-4d7d-bf51-964ce4fdedd8 Ancestors: Morphic-eem.1045 Text editing: Fixes a bug with an endless loop when find/replace under certain conditions. Refactors the find, find/replace, and do-again code. =============== Diff against Morphic-eem.1045 =============== Item was changed: ----- Method: TextEditor>>again (in category 'menu messages') ----- again "Do the same replace command again. Unlike #findReplaceAgain, this looks up the editor's own command history and uses the previous command." + (self history hasPrevious and: [self history previous hasReplacedSomething]) + ifFalse: [morph flash. ^ false]. - self history hasPrevious ifFalse: [morph flash. ^ self]. + self + setSearchFromSelectionOrHistory; + setReplacementFromHistory. + + "If we have no selection, give the user one to avoid annoying surprises." + ^ self hasSelection + ifTrue: [self findReplaceAgainNow] + ifFalse: [self findAgainNow. false "see #againUpToEnd"]! - self history previous hasReplacedSomething - ifFalse: [morph flash. ^ self] - ifTrue: [ | nextOperation | - nextOperation := (self selection=ChangeText) ifTrue: [#findAgain] ifFalse: [#findReplaceAgain]. - "Reset shared find/replace state." - FindText := self history previous contentsBefore. - ChangeText := self history previous contentsAfter. - - self selectAt: self stopIndex. - self perform: nextOperation. - nextOperation = #findReplaceAgain ifTrue: [ self findAgainSettingSearch: false ] ].! Item was changed: ----- Method: TextEditor>>againUpToEnd (in category 'menu messages') ----- againUpToEnd "Find and replace until the end." + | first | + self again ifFalse: [^ self]. - | interval pivot isFirst last | - self history hasPrevious ifFalse: [morph flash. ^ self]. - - pivot := self history previous. - pivot hasReplacedSomething ifFalse: [morph flash. ^ self]. + first := self history previous. - "Reset shared find/replace state." - FindText := pivot contentsBefore. - ChangeText := pivot contentsAfter. + [self hasSelection] whileTrue: [ + self history previous + isCompositeUndo: true; + isCompositeRedo: true. + self findReplaceAgainNow]. - isFirst := true. - last := pivot. - [self selectionInterval ~= interval] whileTrue: [ - last ~= pivot ifTrue: [ - last - isCompositeUndo: isFirst not; - isCompositeRedo: true. - isFirst := false]. - last := self history previous. - interval := self selectionInterval. - - self selectAt: self stopIndex. "No selection to make find work." - self findReplaceAgain]. + first isCompositeUndo: false. + + self history previous isCompositeUndo: first ~~ self history previous. + self history previous isCompositeRedo: false.! - last isCompositeRedo: false.! Item was changed: ----- Method: TextEditor>>doAgainUpToEnd: (in category 'typing/selecting keys') ----- doAgainUpToEnd: aKeyboardEvent + "Do the previous thing again once. 1/26/96 sw" + + self insertAndCloseTypeIn. + self againUpToEnd. - "Do the previous thing again repeatedly to the end of my contents. Under circumstances this can require two calls to againUpToEnd " - self - insertAndCloseTypeIn ; - againUpToEnd ; - againUpToEnd. ^ true! Item was changed: ----- Method: TextEditor>>find (in category 'menu messages') ----- find "Prompt the user for a string to search for, and search the receiver from the current selection onward for it. 1/26/96 sw" + self setSearchFromSelectionOrHistory. + + (UIManager default request: 'Find what to select? ' initialAnswer: FindText) - (UIManager default request: 'Find what to select? ' initialAnswer: (self selection ifEmpty: [FindText])) ifEmpty: [^ self] ifNotEmpty: [:reply | + FindText := reply. + self findAgainNow].! - self setSearch: reply. - self findAgain].! Item was changed: ----- Method: TextEditor>>find: (in category 'typing/selecting keys') ----- find: aKeyboardEvent + "Prompt the user for what to find, then find it, searching from the current selection onward." - "Prompt the user for what to find, then find it, searching from the current selection onward. 1/24/96 sw" + self + insertAndCloseTypeIn; + find. + - self insertAndCloseTypeIn. - self find. ^ true! Item was changed: ----- Method: TextEditor>>findAgain (in category 'menu messages') ----- findAgain + self setSearchFromSelectionOrHistory. - | where | - where := self text - findString: FindText - startingAt: self stopIndex - caseSensitive: Preferences caseSensitiveFinds. + ^ self findAgainNow! - where = 0 ifTrue: [^ false]. - - self selectFrom: where to: where + FindText size - 1. - - ^ true! Item was changed: ----- Method: TextEditor>>findAgain: (in category 'typing/selecting keys') ----- findAgain: aKeyboardEvent + "Find the desired text again." + - | previousHistory | - previousHistory := self history previous. self + insertAndCloseTypeIn; + findAgain. + - insertAndCloseTypeIn ; - findAgainSettingSearch: (previousHistory isNil or: [ previousHistory hasReplacedSomething not ]). ^ true! Item was added: + ----- Method: TextEditor>>findAgainNow (in category 'typing support') ----- + findAgainNow + + | where | + where := self text + findString: FindText + startingAt: self stopIndex + caseSensitive: Preferences caseSensitiveFinds. + + where = 0 + ifTrue: [self selectFrom: self stopIndex to: self stopIndex - 1] + ifFalse: [self selectFrom: where to: where + FindText size - 1]. + + ^ true! Item was removed: - ----- Method: TextEditor>>findAgainSettingSearch: (in category 'menu messages') ----- - findAgainSettingSearch: aBoolean - aBoolean ifTrue: - [ self hasSelection ifTrue: - [ self setSearch: self selection string ] ]. - self findAgain! Item was changed: ----- Method: TextEditor>>findReplace (in category 'menu messages') ----- findReplace + self + setSearchFromSelectionOrHistory; + setReplacementFromHistory. + + (UIManager default request: 'Find what to replace?' initialAnswer: FindText) - (UIManager default request: 'Find what to replace?' initialAnswer: (self selection ifEmpty: [FindText])) ifEmpty: [^ self] ifNotEmpty: [:find | (UIManager default request: ('Replace ''{1}'' with?' format: {find}) initialAnswer: (ChangeText ifEmpty: [find])) ifEmpty: [^ self] ifNotEmpty: [:replace | FindText := find. ChangeText := replace. + self findReplaceAgainNow]]! - self findReplaceAgain]]! Item was changed: ----- Method: TextEditor>>findReplace: (in category 'typing/selecting keys') ----- findReplace: aKeyboardEvent + self + insertAndCloseTypeIn; + findReplace. + - self insertAndCloseTypeIn. - self findReplace. ^ true! Item was changed: ----- Method: TextEditor>>findReplaceAgain (in category 'menu messages') ----- findReplaceAgain + self + setSearchFromSelectionOrHistory; + setReplacementFromHistory. + + ^ self findReplaceAgainNow! - | where | - self hasSelection ifTrue: [ - "Search from the beginning of the current selection. Supports a nice combination with regular find feature." - self selectInvisiblyFrom: self startIndex to: self startIndex - 1]. - - where := self text - findString: FindText - startingAt: self stopIndex-FindText size - caseSensitive: Preferences caseSensitiveFinds. - - where = 0 ifTrue: [^ false]. - - self selectInvisiblyFrom: where to: where + FindText size - 1. - self replaceSelectionWith: ChangeText. - - ^ true! Item was changed: ----- Method: TextEditor>>findReplaceAgain: (in category 'typing/selecting keys') ----- findReplaceAgain: aKeyboardEvent + self + insertAndCloseTypeIn; + findReplaceAgain. + - self insertAndCloseTypeIn. - self findReplaceAgain. ^ true! Item was added: + ----- Method: TextEditor>>findReplaceAgainNow (in category 'typing support') ----- + findReplaceAgainNow + + self hasSelection ifTrue: [ + "Search from the beginning of the current selection. Supports a nice combination with regular find feature." + self selectInvisiblyFrom: self startIndex to: self startIndex - 1]. + + self findAgainNow. + self hasSelection ifFalse: [^ false]. + + self replaceSelectionWith: ChangeText. + self findAgainNow. "Select possible next thing to replace." + + ^ true! Item was changed: ----- Method: TextEditor>>mouseMove: (in category 'events') ----- + mouseMove: evt - mouseMove: evt "Change the selection in response to mouse-down drag" + pointBlock := paragraph characterBlockAtPoint: evt position. + self storeSelectionInParagraph! - self - storeSelectionInParagraph ; - setSearch: self selection string! Item was changed: + ----- Method: TextEditor>>redoAndReselect (in category 'undo') ----- - ----- Method: TextEditor>>redoAndReselect (in category 'undoers') ----- redoAndReselect self replace: self history current intervalBefore with: self history current contentsAfter and: [self selectInterval: self history current intervalAfter].! Item was changed: + ----- Method: TextEditor>>replace:with: (in category 'undo') ----- - ----- Method: TextEditor>>replace:with: (in category 'accessing') ----- replace: interval with: newText self replace: interval with: newText and: ["Do nothing."].! Item was changed: + ----- Method: TextEditor>>replace:with:and: (in category 'undo') ----- - ----- Method: TextEditor>>replace:with:and: (in category 'accessing') ----- replace: xoldInterval with: newText and: selectingBlock "Replace the text in oldInterval with newText and execute selectingBlock to establish the new selection. Create an undoAndReselect:redoAndReselect: undoer to allow perfect undoing." | undoInterval | undoInterval := self selectionInterval. undoInterval = xoldInterval ifFalse: [self selectInterval: xoldInterval]. self zapSelectionWith: newText. selectingBlock value. otherInterval := self selectionInterval.! Item was changed: + ----- Method: TextEditor>>replaceSelectionWith: (in category 'undo') ----- - ----- Method: TextEditor>>replaceSelectionWith: (in category 'accessing') ----- replaceSelectionWith: aText "Remember the selection text in UndoSelection. Deselect, and replace the selection text by aText. Remember the resulting selectionInterval in UndoInterval and PriorInterval. Set up undo to use UndoReplace." self openTypeIn. self zapSelectionWith: aText. self closeTypeIn.! Item was changed: ----- Method: TextEditor>>selectFrom:to: (in category 'new selection') ----- selectFrom: start to: stop "Select the specified characters inclusive." self selectInvisiblyFrom: start to: stop. self closeTypeIn. self storeSelectionInParagraph. "Preserve current emphasis if selection is empty" stop > start ifTrue: [ + self setEmphasisHere ]! - self setEmphasisHere ]. - self hasSelection ifTrue: [ self setSearch: self selection string ]! Item was added: + ----- Method: TextEditor>>setReplacementFromHistory (in category 'accessing') ----- + setReplacementFromHistory + "Use history to get the previous replacement." + + (self history hasPrevious and: [self history previous hasReplacedSomething]) + ifTrue: [ChangeText := self history previous contentsAfter].! Item was changed: ----- Method: TextEditor>>setSearch: (in category 'accessing') ----- setSearch: aStringOrText + FindText := aStringOrText.! - FindText := aStringOrText. - ChangeText := self nullText.! Item was added: + ----- Method: TextEditor>>setSearchFromSelectionOrHistory (in category 'accessing') ----- + setSearchFromSelectionOrHistory + "Updates the current string to find with the current selection or the last change if it replaced something and thus had a prior selection." + + self hasSelection + ifTrue: [FindText := self selection] + ifFalse: [(self history hasPrevious and: [self history previous hasReplacedSomething]) + ifTrue: [FindText := self history previous contentsBefore]].! Item was changed: + ----- Method: TextEditor>>undoAndReselect (in category 'undo') ----- - ----- Method: TextEditor>>undoAndReselect (in category 'undoers') ----- undoAndReselect self replace: self history current intervalBetween with: self history current contentsBefore and: [self selectInterval: self history current intervalBefore].! |
Free forum by Nabble | Edit this page |