The Trunk: Morphic-dtl.297.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Morphic-dtl.297.mcz

commits-2
David T. Lewis uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-dtl.297.mcz

==================== Summary ====================

Name: Morphic-dtl.297
Author: dtl
Time: 3 January 2010, 11:54:26 am
UUID: b656a757-aedc-47a4-9014-21327212c021
Ancestors: Morphic-ar.296

Add TextEditor>>explainDelimitor: copied from ParagraphEditor, required for explain function in code panes.

Run FixUnderscores on package Morphic to update methods adopted from Cuis.
Note: Did not fix underscores in MorphicModel class>>compileAccessorsFor:


=============== Diff against Morphic-ar.296 ===============

Item was changed:
  ----- Method: TextEditor>>reverseSelection (in category 'current selection') -----
  reverseSelection
  "Reverse the valence of the current selection highlighting."
+ selectionShowing := selectionShowing not.
- selectionShowing _ selectionShowing not.
  paragraph reverseFrom: self pointBlock to: self markBlock!

Item was changed:
  ----- Method: TextEditor>>completeSymbol:lastOffering: (in category 'private') -----
  completeSymbol: hintText lastOffering: selectorOrNil
  "Invoked by Ctrl-q when there is only a caret.
  Do selector-completion, i.e., try to replace the preceding identifier by a
  selector that begins with those characters & has as many keywords as possible.
  Leave two spaces after each colon (only one after the last) as space for
  arguments.  Put the caret after the space after the first keyword.  If the
  user types Ctrl-q again immediately, choose a different selector.
  Undoer: #undoQuery:lastOffering:; Redoer: itself.
  If redoing, just redisplay the last offering, selector[OrNil]."
 
  | firstTime input prior caret newStart sym kwds outStream |
+ firstTime := self isRedoing
+ ifTrue: [prior := sym := selectorOrNil. true]
- firstTime _ self isRedoing
- ifTrue: [prior _ sym _ selectorOrNil. true]
  ifFalse: [hintText isNil].
  firstTime
  ifTrue: "Initial Ctrl-q (or redo)"
+ [caret := self startIndex.
- [caret _ self startIndex.
  self selectPrecedingIdentifier.
+ input := self selection]
- input _ self selection]
  ifFalse: "Repeated Ctrl-q"
+ [caret := UndoInterval first + hintText size.
- [caret _ UndoInterval first + hintText size.
  self selectInvisiblyFrom: UndoInterval first to: UndoInterval last.
+ input := hintText.
+ prior := selectorOrNil].
- input _ hintText.
- prior _ selectorOrNil].
  (input size ~= 0 and: [sym ~~ nil or:
+ [(sym := Symbol thatStarts: input string skipping: prior) ~~ nil]])
- [(sym _ Symbol thatStarts: input string skipping: prior) ~~ nil]])
  ifTrue: "found something to offer"
+ [newStart := self startIndex.
+ outStream := WriteStream on: (String new: 2 * sym size).
+ 1 to: (kwds := sym keywords) size do:
- [newStart _ self startIndex.
- outStream _ WriteStream on: (String new: 2 * sym size).
- 1 to: (kwds _ sym keywords) size do:
  [:i |
  outStream nextPutAll: (kwds at: i).
+ i = 1 ifTrue: [caret := newStart + outStream contents size + 1].
- i = 1 ifTrue: [caret _ newStart + outStream contents size + 1].
  outStream nextPutAll:
  (i < kwds size ifTrue: ['  '] ifFalse: [' '])].
+ UndoSelection := input.
- UndoSelection _ input.
  self deselect; zapSelectionWith: outStream contents asText.
  self undoer: #undoQuery:lastOffering: with: input with: sym]
  ifFalse: "no more matches"
  [firstTime ifFalse: "restore original text & set up for a redo"
+ [UndoSelection := self selection.
- [UndoSelection _ self selection.
  self deselect; zapSelectionWith: input.
  self undoer: #completeSymbol:lastOffering: with: input with: prior.
+ Undone := true].
- Undone _ true].
  morph flash].
  self selectAt: caret!

Item was changed:
  ----- Method: SmalltalkEditor class>>initializeShiftCmdKeyShortcuts (in category 'keyboard shortcut tables') -----
  initializeShiftCmdKeyShortcuts
  "Initialize the shift-command-key (or control-key) shortcut table."
  "NOTE: if you don't know what your keyboard generates, use Sensor kbdTest"
  "wod 11/3/1998: Fix setting of cmdMap for shifted keys to actually use the
  capitalized versions of the letters.
  TPR 2/18/99: add the plain ascii values back in for those VMs that don't return the shifted values."
 
  "SmalltalkEditor initialize"
 
  | cmds |
  super initializeShiftCmdKeyShortcuts.
 
+ cmds := #(
- cmds _ #(
  $a argAdvance:
  $b browseItHere:
  $e methodStringsContainingIt:
  $f displayIfFalse:
  $g fileItIn:
  $i exploreIt:
  $n referencesToIt:
  $t displayIfTrue:
  $v pasteInitials:
  $w methodNamesContainingIt:
  ).
  1 to: cmds size by: 2 do: [ :i |
  shiftCmdActions at: ((cmds at: i) asciiValue + 1) put: (cmds at: i + 1). "plain keys"
  shiftCmdActions at: ((cmds at: i) asciiValue - 32 + 1) put: (cmds at: i + 1). "shifted keys"
  shiftCmdActions at: ((cmds at: i) asciiValue - 96 + 1) put: (cmds at: i + 1). "ctrl keys"
  ].!

Item was changed:
  ----- Method: TextEditor>>crWithIndent: (in category 'typing/selecting keys') -----
  crWithIndent: characterStream
  "Replace the current text selection with CR followed by as many tabs
  as on the current line (+/- bracket count) -- initiated by Shift-Return."
  | char s i tabCount |
  sensor keyboard. "flush character"
+ s := paragraph string.
+ i := self stopIndex.
+ tabCount := 0.
+ [(i := i-1) > 0 and: [(char := s at: i) ~= Character cr]]
- s _ paragraph string.
- i _ self stopIndex.
- tabCount _ 0.
- [(i _ i-1) > 0 and: [(char _ s at: i) ~= Character cr]]
  whileTrue:  "Count tabs and brackets (but not a leading bracket)"
+ [(char = Character tab and: [i < s size and: [(s at: i+1) ~= $[ ]]) ifTrue: [tabCount := tabCount + 1].
+ char = $[ ifTrue: [tabCount := tabCount + 1].
+ char = $] ifTrue: [tabCount := tabCount - 1]].
- [(char = Character tab and: [i < s size and: [(s at: i+1) ~= $[ ]]) ifTrue: [tabCount _ tabCount + 1].
- char = $[ ifTrue: [tabCount _ tabCount + 1].
- char = $] ifTrue: [tabCount _ tabCount - 1]].
  characterStream crtab: tabCount.  "Now inject CR with tabCount tabs"
  ^ false!

Item was changed:
  ----- Method: Editor>>selectWord (in category 'new selection') -----
  selectWord
  "Select delimited text or word--the result of double-clicking."
 
  | openDelimiter closeDelimiter direction match level leftDelimiters rightDelimiters
  string here hereChar start stop |
+ string := self string.
+ here := self pointIndex.
- string _ self string.
- here _ self pointIndex.
  (here between: 2 and: string size)
  ifFalse: ["if at beginning or end, select entire string"
  ^self selectFrom: 1 to: string size].
+ leftDelimiters := '([{<''"
- leftDelimiters _ '([{<''"
  '.
+ rightDelimiters := ')]}>''"
- rightDelimiters _ ')]}>''"
  '.
+ openDelimiter := string at: here - 1.
+ match := leftDelimiters indexOf: openDelimiter.
- openDelimiter _ string at: here - 1.
- match _ leftDelimiters indexOf: openDelimiter.
  match > 0
  ifTrue:
  ["delimiter is on left -- match to the right"
+ start := here.
+ direction := 1.
+ here := here - 1.
+ closeDelimiter := rightDelimiters at: match]
- start _ here.
- direction _ 1.
- here _ here - 1.
- closeDelimiter _ rightDelimiters at: match]
  ifFalse:
+ [openDelimiter := string at: here.
+ match := rightDelimiters indexOf: openDelimiter.
- [openDelimiter _ string at: here.
- match _ rightDelimiters indexOf: openDelimiter.
  match > 0
  ifTrue:
  ["delimiter is on right -- match to the left"
+ stop := here - 1.
+ direction := -1.
+ closeDelimiter := leftDelimiters at: match]
- stop _ here - 1.
- direction _ -1.
- closeDelimiter _ leftDelimiters at: match]
  ifFalse: ["no delimiters -- select a token"
+ direction := -1]].
+ level := 1.
- direction _ -1]].
- level _ 1.
  [level > 0 and: [direction > 0
  ifTrue: [here < string size]
  ifFalse: [here > 1]]]
  whileTrue:
+ [hereChar := string at: (here := here + direction).
- [hereChar _ string at: (here _ here + direction).
  match = 0
  ifTrue: ["token scan goes left, then right"
  hereChar tokenish
  ifTrue: [here = 1
  ifTrue:
+ [start := 1.
- [start _ 1.
  "go right if hit string start"
+ direction := 1]]
- direction _ 1]]
  ifFalse: [direction < 0
  ifTrue:
+ [start := here + 1.
- [start _ here + 1.
  "go right if hit non-token"
+ direction := 1]
+ ifFalse: [level := 0]]]
- direction _ 1]
- ifFalse: [level _ 0]]]
  ifFalse: ["bracket match just counts nesting level"
  hereChar = closeDelimiter
+ ifTrue: [level := level - 1"leaving nest"]
- ifTrue: [level _ level - 1"leaving nest"]
  ifFalse: [hereChar = openDelimiter
+ ifTrue: [level := level + 1"entering deeper nest"]]]].
- ifTrue: [level _ level + 1"entering deeper nest"]]]].
 
+ level > 0 ifTrue: ["in case ran off string end" here := here + direction].
- level > 0 ifTrue: ["in case ran off string end" here _ here + direction].
  direction > 0
  ifTrue: [self selectFrom: start to: here - 1]
  ifFalse: [self selectFrom: here + 1 to: stop]!

Item was changed:
  ----- Method: TextEditor>>exchangeWith: (in category 'private') -----
  exchangeWith: prior
  "If the prior selection is non-overlapping and legal, exchange the text of
  it with the current selection and leave the currently selected text selected
  in the location of the prior selection (or leave a caret after a non-caret if it was
  exchanged with a caret).  If both selections are carets, flash & do nothing.
  Don't affect the paste buffer.  Undoer: itself; Redoer: Undoer."
 
  | start stop before selection priorSelection delta altInterval |
+ start := self startIndex.
+ stop := self stopIndex - 1.
- start _ self startIndex.
- stop _ self stopIndex - 1.
  ((prior first <= prior last) | (start <= stop) "Something to exchange" and:
  [self isDisjointFrom: prior])
  ifTrue:
+ [before := prior last < start.
+ selection := self selection.
+ priorSelection := paragraph text copyFrom: prior first to: prior last.
- [before _ prior last < start.
- selection _ self selection.
- priorSelection _ paragraph text copyFrom: prior first to: prior last.
 
+ delta := before ifTrue: [0] ifFalse: [priorSelection size - selection size].
- delta _ before ifTrue: [0] ifFalse: [priorSelection size - selection size].
  self zapSelectionWith: priorSelection.
  self selectFrom: prior first + delta to: prior last + delta.
 
+ delta := before ifTrue: [stop - prior last] ifFalse: [start - prior first].
- delta _ before ifTrue: [stop - prior last] ifFalse: [start - prior first].
  self zapSelectionWith: selection.
+ altInterval := prior first + delta to: prior last + delta.
- altInterval _ prior first + delta to: prior last + delta.
  self undoer: #exchangeWith: with: altInterval.
  "If one was a caret, make it otherInterval & leave the caret after the other"
  prior first > prior last ifTrue: [self selectAt: UndoInterval last + 1].
+ otherInterval := start > stop
- otherInterval _ start > stop
  ifTrue: [self selectAt: altInterval last + 1. UndoInterval]
  ifFalse: [altInterval]]
  ifFalse:
  [morph flash]!

Item was changed:
  ----- Method: TextEditor>>shiftEnclose: (in category 'editing keys') -----
  shiftEnclose: characterStream
  "Insert or remove bracket characters around the current selection.
  Flushes typeahead."
 
  | char left right startIndex stopIndex oldSelection which text |
+ char := sensor keyboard.
+ char = $9 ifTrue: [ char := $( ].
+ char = $, ifTrue: [ char := $< ].
+ char = $[ ifTrue: [ char := ${ ].
+ char = $' ifTrue: [ char := $" ].
+ char asciiValue = 27 ifTrue: [ char := ${ ]. "ctrl-["
- char _ sensor keyboard.
- char = $9 ifTrue: [ char _ $( ].
- char = $, ifTrue: [ char _ $< ].
- char = $[ ifTrue: [ char _ ${ ].
- char = $' ifTrue: [ char _ $" ].
- char asciiValue = 27 ifTrue: [ char _ ${ ]. "ctrl-["
 
  self closeTypeIn.
+ startIndex := self startIndex.
+ stopIndex := self stopIndex.
+ oldSelection := self selection.
+ which := '([<{"''' indexOf: char ifAbsent: [1].
+ left := '([<{"''' at: which.
+ right := ')]>}"''' at: which.
+ text := paragraph text.
- startIndex _ self startIndex.
- stopIndex _ self stopIndex.
- oldSelection _ self selection.
- which _ '([<{"''' indexOf: char ifAbsent: [1].
- left _ '([<{"''' at: which.
- right _ ')]>}"''' at: which.
- text _ paragraph text.
  ((startIndex > 1 and: [stopIndex <= text size])
  and: [ (text at: startIndex-1) = left and: [(text at: stopIndex) = right]])
  ifTrue: [
  "already enclosed; strip off brackets"
  self selectFrom: startIndex-1 to: stopIndex.
  self replaceSelectionWith: oldSelection]
  ifFalse: [
  "not enclosed; enclose by matching brackets"
  self replaceSelectionWith:
  (Text string: (String with: left), oldSelection string, (String with: right) attributes: emphasisHere).
  self selectFrom: startIndex+1 to: stopIndex].
  ^true!

Item was changed:
  ----- Method: Editor>>backWord: (in category 'typing/selecting keys') -----
  backWord: characterStream
  "If the selection is not a caret, delete it and leave it in the backspace buffer.
  Else if there is typeahead, delete it.
  Else, delete the word before the caret."
 
  | startIndex |
  sensor keyboard.
  characterStream isEmpty
  ifTrue:
  [self hasCaret
  ifTrue: "a caret, delete at least one character"
+ [startIndex := 1 max: self markIndex - 1.
- [startIndex _ 1 max: self markIndex - 1.
  [startIndex > 1 and:
  [(self string at: startIndex - 1) tokenish]]
  whileTrue:
+ [startIndex := startIndex - 1]]
- [startIndex _ startIndex - 1]]
  ifFalse: "a non-caret, just delete it"
+ [startIndex := self markIndex].
- [startIndex _ self markIndex].
  self backTo: startIndex]
  ifFalse:
  [characterStream reset].
  ^false!

Item was changed:
  ----- Method: TextEditor>>indent:fromStream:toStream: (in category 'private') -----
  indent: delta fromStream: inStream toStream: outStream
  "Append the contents of inStream to outStream, adding or deleting delta or -delta
  tabs at the beginning, and after every CR except a final CR.  Do not add tabs
  to totally empty lines, and be sure nothing but tabs are removed from lines."
 
  | ch skip cr tab prev atEnd |
+ cr := Character cr.
+ tab := Character tab.
- cr _ Character cr.
- tab _ Character tab.
  delta > 0
  ifTrue: "shift right"
+ [prev := cr.
+ [ch := (atEnd := inStream atEnd) ifTrue: [cr] ifFalse: [inStream next].
- [prev _ cr.
- [ch _ (atEnd _ inStream atEnd) ifTrue: [cr] ifFalse: [inStream next].
   (prev == cr and: [ch ~~ cr]) ifTrue:
  [delta timesRepeat: [outStream nextPut: tab]].
   atEnd]
  whileFalse:
  [outStream nextPut: ch.
+ prev := ch]]
- prev _ ch]]
  ifFalse: "shift left"
+ [skip := delta. "a negative number"
- [skip _ delta. "a negative number"
  [inStream atEnd] whileFalse:
+ [((ch := inStream next) == tab and: [skip < 0]) ifFalse:
- [((ch _ inStream next) == tab and: [skip < 0]) ifFalse:
  [outStream nextPut: ch].
+ skip := ch == cr ifTrue: [delta] ifFalse: [skip + 1]]]!
- skip _ ch == cr ifTrue: [delta] ifFalse: [skip + 1]]]!

Item was changed:
  ----- Method: TextEditor>>prettyPrint: (in category 'menu messages') -----
  prettyPrint: decorated
  "Reformat the contents of the receiver's view (a Browser)."
 
  | selectedClass newText |
  model selectedMessageName ifNil: [^ morph flash].
+ selectedClass := model selectedClassOrMetaClass.
+ newText := selectedClass compilerClass new
- selectedClass _ model selectedClassOrMetaClass.
- newText _ selectedClass compilerClass new
  format: self text
  in: selectedClass
  notifying: self
  decorated: decorated.
  newText ifNotNil:
  [self deselect; selectInvisiblyFrom: 1 to: paragraph text size.
  self replaceSelectionWith: (newText asText makeSelectorBoldIn: selectedClass).
  self selectAt: 1]!

Item was changed:
  ----- Method: TextLine>>justifiedPadFor:font: (in category 'scanning') -----
  justifiedPadFor: spaceIndex font: aFont
  "Compute the width of pad for a given space in a line of justified text."
 
  | pad |
  internalSpaces = 0 ifTrue: [^0].
  ^(aFont notNil and:[aFont isSubPixelPositioned])
  ifTrue:[paddingWidth * 1.0 / internalSpaces]
  ifFalse:[
+ pad := paddingWidth // internalSpaces.
- pad _ paddingWidth // internalSpaces.
  spaceIndex <= (paddingWidth \\ internalSpaces)
  ifTrue: [pad + 1]
  ifFalse: [pad]]
  !

Item was changed:
  ----- Method: TextEditor>>selectedSymbol (in category 'menu messages') -----
  selectedSymbol
  "Return the currently selected symbol, or nil if none.  Spaces, tabs and returns are ignored"
 
  | aString |
  self hasCaret ifTrue: [^ nil].
+ aString := self selection string copyWithoutAll:
- aString _ self selection string copyWithoutAll:
  {Character space.  Character cr.  Character tab}.
  aString size = 0 ifTrue: [^ nil].
  Symbol hasInterned: aString  ifTrue: [:sym | ^ sym].
 
  ^ nil!

Item was changed:
  ----- Method: TextEditor>>explainTemp: (in category 'explain') -----
  explainTemp: string
  "Is string the name of a temporary variable (or block argument variable)?"
 
  | selectedClass tempNames i reply methodNode method msg |
  (model respondsTo: #selectedMessageName) ifFalse: [^ nil].
+ (msg := model selectedMessageName) ifNil: [^nil]. "not in a message"
+ selectedClass := model selectedClassOrMetaClass.
+ tempNames := selectedClass parserClass new
- (msg _ model selectedMessageName) ifNil: [^nil]. "not in a message"
- selectedClass _ model selectedClassOrMetaClass.
- tempNames _ selectedClass parserClass new
  parseArgsAndTemps: model selectedMessage notifying: nil.
+ method := selectedClass compiledMethodAt: msg.
+ (i := tempNames findFirst: [:each | each = string]) = 0 ifTrue: [
- method _ selectedClass compiledMethodAt: msg.
- (i _ tempNames findFirst: [:each | each = string]) = 0 ifTrue: [
  (method numTemps > tempNames size)
  ifTrue:
  ["It must be an undeclared block argument temporary"
+ methodNode := selectedClass compilerClass new
- methodNode _ selectedClass compilerClass new
  parse: model selectedMessage
  in: selectedClass
  notifying: nil.
+ tempNames := methodNode tempNames]
- tempNames _ methodNode tempNames]
  ifFalse: [^nil]].
+ (i := tempNames findFirst: [:each | each = string]) > 0 ifTrue: [i > method numArgs
+ ifTrue: [reply := '"is a temporary variable in this method"']
+ ifFalse: [reply := '"is an argument to this method"']].
- (i _ tempNames findFirst: [:each | each = string]) > 0 ifTrue: [i > method numArgs
- ifTrue: [reply _ '"is a temporary variable in this method"']
- ifFalse: [reply _ '"is an argument to this method"']].
  ^reply!

Item was changed:
  ----- Method: TextEditor>>undoCutCopy: (in category 'undoers') -----
  undoCutCopy: oldPasteBuffer
  "Undo of a cut, copy, or any edit that changed CurrentSelection.  Be sure
  undo-copy does not lock the model.  Redoer: itself, so never isRedoing."
 
  | recentCut |
+ recentCut := self clipboardText.
- recentCut _ self clipboardText.
  UndoSelection size = UndoInterval size
  ifFalse: [self replaceSelectionWith: UndoSelection].
  self clipboardTextPut: oldPasteBuffer.
  self undoer: #undoCutCopy: with: recentCut!

Item was changed:
  ----- Method: TextEditor>>explainInst: (in category 'explain') -----
  explainInst: string
  "Is string an instance variable of this class?"
  | classes cls |
 
  (model respondsTo: #selectedClassOrMetaClass) ifTrue: [
+ cls := model selectedClassOrMetaClass].
- cls _ model selectedClassOrMetaClass].
  cls ifNil: [^ nil].  "no class known"
+ classes := (Array with: cls)
- classes _ (Array with: cls)
  , cls allSuperclasses.
+ classes := classes detect: [:each | (each instVarNames
- classes _ classes detect: [:each | (each instVarNames
  detect: [:name | name = string] ifNone: [])
  ~~ nil] ifNone: [^nil].
+ classes := classes printString.
- classes _ classes printString.
  ^ '"is an instance variable of the receiver; defined in class ' , classes ,
  '"\' withCRs , classes , ' systemNavigation browseAllAccessesTo: ''' , string , ''' from: ', classes, '.'!

Item was changed:
  ----- Method: TextEditor>>makeCapitalized: (in category 'editing keys') -----
  makeCapitalized: characterStream
  "Force the current selection to uppercase.  Triggered by Cmd-X."
  | prev |
  sensor keyboard. "flush the triggering cmd-key character"
+ prev := $-.  "not a letter"
- prev _ $-.  "not a letter"
  self replaceSelectionWith: (Text fromString:
  (self selection string collect:
+ [:c | prev := prev isLetter ifTrue: [c asLowercase] ifFalse: [c asUppercase]])).
- [:c | prev _ prev isLetter ifTrue: [c asLowercase] ifFalse: [c asUppercase]])).
  ^ true!

Item was changed:
  ----- Method: TextEditor>>blinkPrevParen (in category 'parenblinking') -----
  blinkPrevParen
  | openDelimiter closeDelimiter level string here hereChar |
+ string := paragraph text string.
+ here := pointBlock stringIndex.
+ openDelimiter := sensor keyboardPeek.
+ closeDelimiter := '([{' at: (')]}' indexOf: openDelimiter).
+ level := 1.
- string _ paragraph text string.
- here _ pointBlock stringIndex.
- openDelimiter _ sensor keyboardPeek.
- closeDelimiter _ '([{' at: (')]}' indexOf: openDelimiter).
- level _ 1.
  [level > 0 and: [here > 2]]
  whileTrue:
+ [hereChar := string at: (here := here - 1).
- [hereChar _ string at: (here _ here - 1).
  hereChar = closeDelimiter
  ifTrue:
+ [level := level - 1.
- [level _ level - 1.
  level = 0
  ifTrue: [^ self blinkParenAt: here]]
  ifFalse:
  [hereChar = openDelimiter
+ ifTrue: [level := level + 1]]]!
- ifTrue: [level _ level + 1]]]!

Item was changed:
  ----- Method: TextEditor>>doneTyping (in category 'typing support') -----
  doneTyping
+ beginTypeInBlock := nil!
- beginTypeInBlock _ nil!

Item was changed:
  ----- Method: TextEditor>>explainChar: (in category 'explain') -----
  explainChar: string
  "Does string start with a special character?"
 
  | char |
+ char := string at: 1.
- char _ string at: 1.
  char = $. ifTrue: [^'"Period marks the end of a Smalltalk statement.  A period in the middle of a number means a decimal point.  (The number is an instance of class Float)."'].
  char = $' ifTrue: [^'"The characters between two single quotes are made into an instance of class String"'].
  char = $" ifTrue: [^'"Double quotes enclose a comment.  Smalltalk ignores everything between double quotes."'].
  char = $# ifTrue: [^'"The characters following a hash mark are made into an instance of class Symbol.  If parenthesis follow a hash mark, an instance of class Array is made.  It contains literal constants."'].
  (char = $( or: [char = $)]) ifTrue: [^'"Expressions enclosed in parenthesis are evaluated first"'].
  (char = $[ or: [char = $]]) ifTrue: [^'"The code inside square brackets is an unevaluated block of code.  It becomes an instance of BlockContext and is usually passed as an argument."'].
  (char = ${ or: [char = $}]) ifTrue: [^ '"A sequence of expressions separated by periods, when enclosed in curly braces, are evaluated to yield the elements of a new Array"'].
  (char = $< or: [char = $>]) ifTrue: [^'"<primitive: xx> means that this method is usually preformed directly by the virtual machine.  If this method is primitive, its Smalltalk code is executed only when the primitive fails."'].
  char = $^ ifTrue: [^'"Uparrow means return from this method.  The value returned is the expression following the ^"'].
  char = $| ifTrue: [^'"Vertical bars enclose the names of the temporary variables used in this method.  In a block, the vertical bar separates the argument names from the rest of the code."'].
  char = $_ ifTrue: [^'"Left arrow means assignment.  The value of the expression after the left arrow is stored into the variable before it."'].
  char = $; ifTrue: [^'"Semicolon means cascading.  The message after the semicolon is sent to the same object which received the message before the semicolon."'].
  char = $: ifTrue: [^'"A colon at the end of a keyword means that an argument is expected to follow.  Methods which take more than one argument have selectors with more than one keyword.  (One keyword, ending with a colon, appears before each argument).', '\\' withCRs, 'A colon before a variable name just inside a block means that the block takes an agrument.  (When the block is evaluated, the argument will be assigned to the variable whose name appears after the colon)."'].
  char = $$ ifTrue: [^'"The single character following a dollar sign is made into an instance of class Character"'].
  char = $- ifTrue: [^'"A minus sign in front of a number means a negative number."'].
  char = $e ifTrue: [^'"An e in the middle of a number means that the exponent follows."'].
  char = $r ifTrue: [^'"An r in the middle of a bunch of digits is an instance of Integer expressed in a certain radix.  The digits before the r denote the base and the digits after it express a number in that base."'].
  char = Character space ifTrue: [^'"the space Character"'].
  char = Character tab ifTrue: [^'"the tab Character"'].
  char = Character cr ifTrue: [^'"the carriage return Character"'].
  ^nil!

Item was changed:
  ----- Method: TextEditor>>hiddenInfo (in category 'editing keys') -----
  hiddenInfo
  "In TextLinks, TextDoits, TextColor, and TextURLs, there is hidden info.  Return the entire string that was used by Cmd-6 to create this text attribute.  Usually enclosed in < >."
 
  | attrList |
+ attrList := paragraph text attributesAt: (self pointIndex + self markIndex)//2.
- attrList _ paragraph text attributesAt: (self pointIndex + self markIndex)//2.
  attrList do: [:attr |
  (attr isKindOf: TextAction) ifTrue:
  [^ self selection asString, '<', attr info, '>']].
  "If none of the above"
  attrList do: [:attr |
  attr class == TextColor ifTrue:
  [^ self selection asString, '<', attr color printString, '>']].
  ^ self selection asString, '[No hidden info]'!

Item was changed:
  ----- Method: TextEditor>>selectPrecedingIdentifier (in category 'new selection') -----
  selectPrecedingIdentifier
  "Invisibly select the identifier that ends at the end of the selection, if any."
 
  | string sep stop tok |
+ tok := false.
+ string := paragraph text string.
+ stop := self stopIndex - 1.
+ [stop > 0 and: [(string at: stop) isSeparator]] whileTrue: [stop := stop - 1].
+ sep := stop.
+ [sep > 0 and: [(string at: sep) tokenish]] whileTrue: [tok := true. sep := sep - 1].
- tok _ false.
- string _ paragraph text string.
- stop _ self stopIndex - 1.
- [stop > 0 and: [(string at: stop) isSeparator]] whileTrue: [stop _ stop - 1].
- sep _ stop.
- [sep > 0 and: [(string at: sep) tokenish]] whileTrue: [tok _ true. sep _ sep - 1].
  tok ifTrue: [self selectInvisiblyFrom: sep + 1 to: stop]!

Item was changed:
  ----- Method: TextEditor>>fileItIn (in category 'menu messages') -----
  fileItIn
  "Make a Stream on the text selection and fileIn it.
  1/24/96 sw: moved here from FileController; this function can be useful from any text window that shows stuff in chunk format"
 
  | selection |
+ selection := self selection.
- selection _ self selection.
  (ReadWriteStream on: selection string from: 1 to: selection size) fileIn
  !

Item was changed:
  ----- Method: TextEditor>>changeLfToCr: (in category 'editing keys') -----
  changeLfToCr: characterStream
  "Replace all LFs by CRs.
  Triggered by Cmd-U -- useful when getting code from FTP sites
  jmv- Modified to als change crlf by cr"
 
  | fixed |
  sensor keyboard. "flush the triggering cmd-key character"
 
+ fixed := self selection string.
+ fixed := fixed copyReplaceAll: String crlf with: String cr.
+ fixed := fixed copyReplaceAll: String lf with: String cr.
- fixed _ self selection string.
- fixed _ fixed copyReplaceAll: String crlf with: String cr.
- fixed _ fixed copyReplaceAll: String lf with: String cr.
  self replaceSelectionWith: (Text fromString: fixed).
  ^ true!

Item was changed:
  ----- Method: TextEditor>>correctFrom:to:with: (in category 'new selection') -----
  correctFrom: start to: stop with: aString
  "Make a correction in the model that the user has authorised from somewhere else in the system (such as from the compilier).  The user's selection is not changed, only corrected."
  | wasShowing userSelection delta loc |
  aString = '#insert period' ifTrue:
+ [loc := start.
+ [(loc := loc-1)>0 and: [(paragraph text string at: loc) isSeparator]]
+ whileTrue: [loc := loc-1].
- [loc _ start.
- [(loc _ loc-1)>0 and: [(paragraph text string at: loc) isSeparator]]
- whileTrue: [loc _ loc-1].
  ^ self correctFrom: loc+1 to: loc with: '.'].
+ (wasShowing := selectionShowing) ifTrue: [ self reverseSelection ].
+ userSelection := self selectionInterval.
- (wasShowing _ selectionShowing) ifTrue: [ self reverseSelection ].
- userSelection _ self selectionInterval.
 
  self selectInvisiblyFrom: start to: stop.
  self replaceSelectionWith: aString asText.
 
+ delta := aString size - (stop - start + 1).
- delta _ aString size - (stop - start + 1).
  self selectInvisiblyFrom:
  userSelection first + (userSelection first > start ifFalse: [ 0 ] ifTrue: [ delta ])
  to: userSelection last + (userSelection last > start ifFalse: [ 0 ] ifTrue: [ delta ]).
  wasShowing ifTrue: [ self reverseSelection ].
  !

Item was changed:
  ----- Method: Morph>>openModal: (in category 'polymorph') -----
  openModal: aSystemWindow
  "Open the given window locking the receiver until it is dismissed.
  Answer the system window.
  Restore the original keyboard focus when closed."
 
  |area mySysWin keyboardFocus|
+ keyboardFocus := self activeHand keyboardFocus.
- keyboardFocus _ self activeHand keyboardFocus.
  mySysWin := self isSystemWindow ifTrue: [self] ifFalse: [self ownerThatIsA: SystemWindow].
  mySysWin ifNil: [mySysWin := self].
  mySysWin modalLockTo: aSystemWindow.
  ( RealEstateAgent respondsTo: #reduceByFlaps: )
  ifTrue:[
  area := RealEstateAgent reduceByFlaps: RealEstateAgent maximumUsableArea]
  ifFalse:[
  area := RealEstateAgent maximumUsableArea].
  aSystemWindow extent: aSystemWindow initialExtent.
  aSystemWindow position = (0@0)
  ifTrue: [aSystemWindow
  position: self activeHand position - (aSystemWindow extent // 2)].
  aSystemWindow
  bounds: (aSystemWindow bounds translatedToBeWithin: area).
  [ToolBuilder default runModal: aSystemWindow openAsIs]
  ensure: [mySysWin modalUnlockFrom: aSystemWindow.
  self activeHand newKeyboardFocus: keyboardFocus].
  ^aSystemWindow!

Item was changed:
  ----- Method: TextEditor>>againOnce: (in category 'private') -----
  againOnce: indices
  "Find the next occurrence of FindText.  If none, answer false.
  Append the start index of the occurrence to the stream indices, and, if
  ChangeText is not the same object as FindText, replace the occurrence by it.
  Note that the search is case-sensitive for replacements, otherwise not."
 
  | where |
+ where := paragraph text findString: FindText startingAt: self stopIndex
- where _ paragraph text findString: FindText startingAt: self stopIndex
  caseSensitive: ((ChangeText ~~ FindText) or: [Preferences caseSensitiveFinds]).
  where = 0 ifTrue: [^ false].
  self deselect; selectInvisiblyFrom: where to: where + FindText size - 1.
  ChangeText ~~ FindText ifTrue: [self zapSelectionWith: ChangeText].
  indices nextPut: where.
  ^ true!

Item was changed:
  ----- Method: TextEditor>>pageHeight (in category 'private') -----
  pageHeight
  | howManyLines visibleHeight totalHeight ratio |
+ howManyLines := paragraph numberOfLines.
+ visibleHeight := self visibleHeight.
+ totalHeight := self totalTextHeight.
+ ratio := visibleHeight / totalHeight.
- howManyLines _ paragraph numberOfLines.
- visibleHeight _ self visibleHeight.
- totalHeight _ self totalTextHeight.
- ratio _ visibleHeight / totalHeight.
  ^(ratio * howManyLines) rounded - 2!

Item was changed:
  ----- Method: TextEditor>>againOrSame:many: (in category 'private') -----
  againOrSame: useOldKeys many: many
  "Subroutine of search: and again.  If useOldKeys, use same FindText and ChangeText as before.  If many is true, do it repeatedly.  Created 1/26/96 sw by adding the many argument to #againOrSame."
 
  |  home indices wasTypedKey |
 
+ home := self selectionInterval.  "what was selected when 'again' was invoked"
- home _ self selectionInterval.  "what was selected when 'again' was invoked"
 
  "If new keys are to be picked..."
  useOldKeys ifFalse: "Choose as FindText..."
+ [FindText := UndoSelection.  "... the last thing replaced."
- [FindText _ UndoSelection.  "... the last thing replaced."
  "If the last command was in another paragraph, ChangeText is set..."
  paragraph == UndoParagraph ifTrue: "... else set it now as follows."
  [UndoInterval ~= home ifTrue: [self selectInterval: UndoInterval]. "blink"
+ ChangeText := ((UndoMessage sends: #undoCutCopy:) and: [self hasSelection])
- ChangeText _ ((UndoMessage sends: #undoCutCopy:) and: [self hasSelection])
  ifTrue: [FindText] "== objects signal no model-locking by 'undo copy'"
  ifFalse: [self selection]]]. "otherwise, change text is last-replaced text"
 
+ (wasTypedKey := FindText size = 0)
- (wasTypedKey _ FindText size = 0)
  ifTrue: "just inserted at a caret"
+ [home := self selectionInterval.
- [home _ self selectionInterval.
  self replaceSelectionWith: self nullText.  "delete search key..."
+ FindText := ChangeText] "... and search for it, without replacing"
- FindText _ ChangeText] "... and search for it, without replacing"
  ifFalse: "Show where the search will start"
  [home last = self selectionInterval last ifFalse:
  [self selectInterval: home]].
 
  "Find and Change, recording start indices in the array"
+ indices := WriteStream on: (Array new: 20). "an array to store change locs"
- indices _ WriteStream on: (Array new: 20). "an array to store change locs"
  [(self againOnce: indices) & many] whileTrue. "<-- this does the work"
  indices isEmpty ifTrue:  "none found"
  [self flash.
  wasTypedKey ifFalse: [^self]].
 
  (many | wasTypedKey) ifFalse: "after undo, select this replacement"
+ [home := self startIndex to:
- [home _ self startIndex to:
  self startIndex + UndoSelection size - 1].
 
  self undoer: #undoAgain:andReselect:typedKey: with: indices contents with: home with: wasTypedKey!

Item was changed:
  ----- Method: Editor>>previousWord: (in category 'private') -----
  previousWord: position
  | string index |
+ string := self string.
+ index := position.
- string _ self string.
- index _ position.
  [(index between: 1 and: string size) and: [(string at: index) isAlphaNumeric not]]
+ whileTrue: [index := index - 1].
- whileTrue: [index _ index - 1].
  [(index between: 1 and: string size) and: [(string at: index) isAlphaNumeric]]
+ whileTrue: [index := index - 1].
- whileTrue: [index _ index - 1].
  ^ index + 1!

Item was changed:
  ----- 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."
 
  beginTypeInBlock ~~ nil ifTrue: [^self zapSelectionWith: aText]. "called from old code"
+ UndoSelection := self selection.
- UndoSelection _ self selection.
  self zapSelectionWith: aText.
  self undoer: #undoReplace!

Item was changed:
  ----- Method: TextEditor>>changeEmphasis: (in category 'editing keys') -----
  changeEmphasis: characterStream
  "Change the emphasis of the current selection or prepare to accept characters with the change in emphasis. Emphasis change amounts to a font change.  Keeps typeahead."
 
  "control 0..9 -> 0..9"
 
  | keyCode attribute oldAttributes index thisSel colors extras |
  keyCode := ('0123456789-=' indexOf: sensor keyboard ifAbsent: [1]) - 1.
  oldAttributes := paragraph text attributesAt: self pointIndex.
  thisSel := self selection.
 
  "Decipher keyCodes for Command 0-9..."
  (keyCode between: 1 and: 5)
  ifTrue: [attribute := TextFontChange fontNumber: keyCode].
 
  keyCode = 6
  ifTrue: [
  colors := #(#black #magenta #red #yellow #green #blue #cyan #white).
  extras := self emphasisExtras.
  index := UIManager default chooseFrom:colors , #('choose color...' ), extras
  lines: (Array with: colors size + 1).
  index = 0 ifTrue: [^true].
  index <= colors size
  ifTrue: [attribute := TextColor color: (Color perform: (colors at: index))]
  ifFalse: [
  index := index - colors size - 1. "Re-number!!!!!!"
  index = 0
  ifTrue: [attribute := self chooseColor]
  ifFalse:[^self handleEmphasisExtra: index with: characterStream] "handle an extra"]].
  (keyCode between: 7 and: 11)
  ifTrue: [
  sensor leftShiftDown
  ifTrue: [
  keyCode = 10 ifTrue: [attribute := TextKern kern: -1].
  keyCode = 11 ifTrue: [attribute := TextKern kern: 1]]
  ifFalse: [
  attribute := TextEmphasis
  perform: (#(#bold #italic #narrow #underlined #struckOut) at: keyCode - 6).
  oldAttributes
  do: [:att | (att dominates: attribute) ifTrue: [attribute turnOff]]]].
  keyCode = 0 ifTrue: [attribute := TextEmphasis normal].
  attribute ifNotNil: [
  thisSel size = 0
  ifTrue: [
  "only change emphasisHere while typing"
  self insertTypeAhead: characterStream.
+ emphasisHere := Text addAttribute: attribute toArray: oldAttributes ]
- emphasisHere _ Text addAttribute: attribute toArray: oldAttributes ]
  ifFalse: [
  self replaceSelectionWith: (thisSel asText addAttribute: attribute) ]].
  ^true!

Item was changed:
  ----- Method: TextEditor>>cursorEnd: (in category 'nonediting/nontyping keys') -----
  cursorEnd: characterStream
 
  "Private - Move cursor end of current line."
  | string |
  self closeTypeIn: characterStream.
+ string := paragraph text string.
- string _ paragraph text string.
  self
  moveCursor:
  [:position | Preferences wordStyleCursorMovement
  ifTrue:[| targetLine |
+ targetLine := paragraph lines at:(paragraph lineIndexOfCharacterIndex: position).
- targetLine _ paragraph lines at:(paragraph lineIndexOfCharacterIndex: position).
  targetLine = paragraph lastLine
  ifTrue:[targetLine last + 1]
  ifFalse:[targetLine last]]
  ifFalse:[
  string
  indexOf: Character cr
  startingAt: position
  ifAbsent:[string size + 1]]]
  forward: true
  specialBlock:[:dummy | string size + 1].
  ^true!

Item was changed:
  ----- Method: TextEditor>>undo (in category 'menu messages') -----
  undo
  "Reset the state of the paragraph prior to the previous edit.
  If another ParagraphEditor instance did that edit, UndoInterval is invalid;
  just recover the contents of the undo-buffer at the start of the paragraph."
 
  sensor flushKeyboard. "a way to flush stuck keys"
  self closeTypeIn.
 
  UndoParagraph == paragraph ifFalse: "Can't undo another paragraph's edit"
+ [UndoMessage := Message selector: #undoReplace.
+ UndoInterval := 1 to: 0.
+ Undone := true].
- [UndoMessage _ Message selector: #undoReplace.
- UndoInterval _ 1 to: 0.
- Undone _ true].
  UndoInterval ~= self selectionInterval ifTrue: "blink the actual target"
  [self selectInterval: UndoInterval; deselect].
 
  "Leave a signal of which phase is in progress"
+ UndoParagraph := Undone ifTrue: [#redoing] ifFalse: [#undoing].
- UndoParagraph _ Undone ifTrue: [#redoing] ifFalse: [#undoing].
  UndoMessage sentTo: self.
+ UndoParagraph := paragraph!
- UndoParagraph _ paragraph!

Item was changed:
  ----- Method: TextEditor>>undoMessage:forRedo: (in category 'undo support') -----
  undoMessage: aMessage forRedo: aBoolean
  "Call this from an undoer/redoer to set up UndoMessage as the
  corresponding redoer/undoer.  Also set up UndoParagraph, as well
  as the state variable Undone.  It is assumed that UndoInterval has been
  established (generally by zapSelectionWith:) and that UndoSelection has been
  saved (generally by replaceSelectionWith: or replace:With:and:)."
 
+ self isDoing ifTrue: [UndoParagraph := paragraph].
+ UndoMessage := aMessage.
+ Undone := aBoolean!
- self isDoing ifTrue: [UndoParagraph _ paragraph].
- UndoMessage _ aMessage.
- Undone _ aBoolean!

Item was changed:
  ----- Method: TextEditor>>inspectIt (in category 'do-its') -----
  inspectIt
  "1/13/96 sw: minor fixup"
  | result |
+ result := self evaluateSelection.
- result _ self evaluateSelection.
  ((result isKindOf: FakeClassPool) or: [result == #failedDoit])
  ifTrue: [morph flash]
  ifFalse: [result inspect]!

Item was changed:
  ----- Method: Editor>>initialize (in category 'initialize-release') -----
  initialize
  "Initialize the state of the receiver. Subclasses should include 'super
  initialize' when redefining this message to insure proper initialization."
 
+ sensor := InputSensor default!
- sensor _ InputSensor default!

Item was changed:
  ----- 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 _ self selectionInterval.
  undoInterval = xoldInterval ifFalse: [self selectInterval: xoldInterval].
+ UndoSelection := self selection.
- UndoSelection _ self selection.
  self zapSelectionWith: newText.
  selectingBlock value.
+ otherInterval := self selectionInterval.
- otherInterval _ self selectionInterval.
  self undoer: #undoAndReselect:redoAndReselect: with: undoInterval with: otherInterval!

Item was changed:
  ----- Method: TextEditor>>stateArrayPut: (in category 'initialize-release') -----
  stateArrayPut: stateArray
  | sel |
+ ChangeText := stateArray at: 1.
+ FindText := stateArray at: 2.
+ UndoInterval := stateArray at: 3.
+ UndoMessage := stateArray at: 4.
+ UndoParagraph := stateArray at: 5.
+ UndoSelection := stateArray at: 6.
+ Undone := stateArray at: 7.
+ sel := stateArray at: 8.
- ChangeText _ stateArray at: 1.
- FindText _ stateArray at: 2.
- UndoInterval _ stateArray at: 3.
- UndoMessage _ stateArray at: 4.
- UndoParagraph _ stateArray at: 5.
- UndoSelection _ stateArray at: 6.
- Undone _ stateArray at: 7.
- sel _ stateArray at: 8.
  self selectFrom: sel first to: sel last.
+ beginTypeInBlock := stateArray at: 9.
+ emphasisHere := stateArray at: 10!
- beginTypeInBlock _ stateArray at: 9.
- emphasisHere _ stateArray at: 10!

Item was changed:
  ----- Method: TextEditor>>copySelection (in category 'menu messages') -----
  copySelection
  "Copy the current selection and store it in the paste buffer, unless a caret.  Undoer & Redoer: undoCutCopy"
 
  self lineSelectAndEmptyCheck: [^ self].
 
  "Simulate 'substitute: self selection' without locking the controller"
+ UndoSelection := self selection.
- UndoSelection _ self selection.
  self undoer: #undoCutCopy: with: self clipboardText.
+ UndoInterval := self selectionInterval.
- UndoInterval _ self selectionInterval.
  self clipboardTextPut: UndoSelection!

Item was added:
+ ----- Method: TextEditor>>explainDelimitor: (in category 'explain') -----
+ explainDelimitor: string
+ "Is string enclosed in delimitors?"
+
+ | str |
+ (string at: 1) isLetter ifTrue: [^nil].  "only special chars"
+ (string first = string last) ifTrue:
+ [^ self explainChar: (String with: string first)]
+ ifFalse:
+ [(string first = $( and: [string last = $)]) ifTrue:
+ [^ self explainChar: (String with: string first)].
+ (string first = $[ and: [string last = $]]) ifTrue:
+ [^ self explainChar: (String with: string first)].
+ (string first = ${ and: [string last = $}]) ifTrue:
+ [^ self explainChar: (String with: string first)].
+ (string first = $< and: [string last = $>]) ifTrue:
+ [^ self explainChar: (String with: string first)].
+ (string first = $# and: [string last = $)]) ifTrue:
+ [^'"An instance of class Array.  The Numbers, Characters, or Symbols between the parenthesis are the elements of the Array."'].
+ string first = $# ifTrue:
+ [^'"An instance of class Symbol."'].
+ (string first = $$ and: [string size = 2]) ifTrue:
+ [^'"An instance of class Character.  This one is the character ', (String with: string last), '."'].
+ (string first = $:) ifTrue:
+ [str := string allButFirst.
+ (self explainTemp: str) ~~ nil ifTrue:
+ [^'"An argument to this block will be bound to the temporary variable ',
+ str, '."']]].
+ ^ nil!

Item was changed:
  ----- Method: TextEditor>>mouseUp: (in category 'events') -----
  mouseUp: evt
  "An attempt to break up the old processRedButton code into threee phases"
  oldInterval ifNil: [^ self].  "Patched during clickAt: repair"
  (self hasCaret
  and: [oldInterval = self selectionInterval])
  ifTrue: [self selectWord].
  self setEmphasisHere.
  (self isDisjointFrom: oldInterval) ifTrue:
+ [otherInterval := oldInterval].
- [otherInterval _ oldInterval].
  self storeSelectionInParagraph!

Item was changed:
  ----- Method: TextEditor>>enclose: (in category 'editing keys') -----
  enclose: characterStream
  "Insert or remove bracket characters around the current selection.
  Flushes typeahead."
 
  | char left right startIndex stopIndex oldSelection which text |
+ char := sensor keyboard.
- char _ sensor keyboard.
  self closeTypeIn.
+ startIndex := self startIndex.
+ stopIndex := self stopIndex.
+ oldSelection := self selection.
+ which := '([<{"''' indexOf: char ifAbsent: [ ^true ].
+ left := '([<{"''' at: which.
+ right := ')]>}"''' at: which.
+ text := paragraph text.
- startIndex _ self startIndex.
- stopIndex _ self stopIndex.
- oldSelection _ self selection.
- which _ '([<{"''' indexOf: char ifAbsent: [ ^true ].
- left _ '([<{"''' at: which.
- right _ ')]>}"''' at: which.
- text _ paragraph text.
  ((startIndex > 1 and: [stopIndex <= text size])
  and: [ (text at: startIndex-1) = left and: [(text at: stopIndex) = right]])
  ifTrue: [
  "already enclosed; strip off brackets"
  self selectFrom: startIndex-1 to: stopIndex.
  self replaceSelectionWith: oldSelection]
  ifFalse: [
  "not enclosed; enclose by matching brackets"
  self replaceSelectionWith:
  (Text string: (String with: left), oldSelection string, (String with: right) attributes: emphasisHere).
  self selectFrom: startIndex+1 to: stopIndex].
  ^true!

Item was changed:
  ----- Method: TextEditor>>debugIt (in category 'do-its') -----
  debugIt
 
  | method receiver context |
  (model respondsTo: #doItReceiver)
  ifTrue:
  [FakeClassPool adopt: model selectedClass.
+ receiver := model doItReceiver.
+ context := model doItContext]
- receiver _ model doItReceiver.
- context _ model doItContext]
  ifFalse:
+ [receiver := context := nil].
- [receiver _ context _ nil].
  self lineSelectAndEmptyCheck: [^self].
+ method := self compileSelectionFor: receiver in: context.
- method _ self compileSelectionFor: receiver in: context.
  method notNil ifTrue:
  [self debug: method receiver: receiver in: context].
  FakeClassPool adopt: nil!

Item was changed:
  ----- Method: TextEditor>>setAlignment: (in category 'menu messages') -----
  setAlignment: aSymbol
  | attr interval |
+ attr := TextAlignment perform: aSymbol.
+ interval := self encompassLine: self selectionInterval.
- attr _ TextAlignment perform: aSymbol.
- interval _ self encompassLine: self selectionInterval.
  paragraph
  replaceFrom: interval first
  to: interval last
  with: ((paragraph text copyFrom: interval first to: interval last) addAttribute: attr)!

Item was changed:
  ----- Method: TextEditor>>setSearchString: (in category 'nonediting/nontyping keys') -----
  setSearchString: characterStream
  "Establish the current selection as the current search string."
 
  | aString |
  self closeTypeIn: characterStream.
  sensor keyboard.
  self lineSelectAndEmptyCheck: [^ true].
+ aString :=  self selection string.
- aString _  self selection string.
  aString size = 0
  ifTrue:
  [self flash]
  ifFalse:
  [self setSearch: aString].
  ^ true!

Item was changed:
  ----- Method: TextEditor>>resetState (in category 'initialize-release') -----
  resetState
  "Establish the initial conditions for editing the paragraph: place caret
  before first character, set the emphasis to that of the first character,
  and save the paragraph for purposes of canceling."
 
+ markBlock := paragraph defaultCharacterBlock.
- markBlock _ paragraph defaultCharacterBlock.
  self pointBlock: markBlock copy.
+ beginTypeInBlock := nil.
+ UndoInterval := otherInterval := 1 to: 0.
- beginTypeInBlock _ nil.
- UndoInterval _ otherInterval _ 1 to: 0.
  self setEmphasisHere.
+ selectionShowing := false!
- selectionShowing _ false!

Item was changed:
  ----- Method: TextEditor>>backTo: (in category 'typing support') -----
  backTo: startIndex
  "During typing, backspace to startIndex.  Deleted characters fall into three
  clusters, from left to right in the text: (1) preexisting characters that were
  backed over; (2) newly typed characters that were backed over (excluding
  typeahead, which never even appears); (3) preexisting characters that
  were highlighted before typing began.  If typing has not yet been opened,
  open it and watch for the first and third cluster.  If typing has been opened,
  watch for the first and second cluster.  Save characters from the first and third
  cluster in UndoSelection.  Tally characters from the first cluster in UndoMessage's parameter.
  Delete all the clusters.  Do not alter Undoer or UndoInterval (except via
  openTypeIn).  The code is shorter than the comment."
 
  | saveLimit newBackovers |
+ saveLimit := beginTypeInBlock
+ ifNil: [self openTypeIn. UndoSelection := self nullText. self stopIndex]
- saveLimit _ beginTypeInBlock
- ifNil: [self openTypeIn. UndoSelection _ self nullText. self stopIndex]
  ifNotNil: [self startOfTyping].
  self markIndex: startIndex.
  startIndex < saveLimit ifTrue: [
+ newBackovers := self startOfTyping - startIndex.
+ beginTypeInBlock := self startIndex.
- newBackovers _ self startOfTyping - startIndex.
- beginTypeInBlock _ self startIndex.
  UndoSelection replaceFrom: 1 to: 0 with:
  (paragraph text copyFrom: startIndex to: saveLimit - 1).
  UndoMessage argument: (UndoMessage argument ifNil: [1]) + newBackovers].
  self zapSelectionWith: self nullText.
  self unselect!

Item was changed:
  ----- Method: Editor>>sensor: (in category 'private') -----
  sensor: aSensor
  "Set the receiver's sensor to aSensor."
 
+ sensor := aSensor!
- sensor _ aSensor!

Item was changed:
  ----- Method: PasteUpMorph>>modalLockTo: (in category 'polymorph') -----
  modalLockTo: aSystemWindow
  "Don't lock the world!! Lock the submorphs.
  The modal window gets opened afterwards so is OK."
 
  |lockStates|
+ lockStates := IdentityDictionary new.
- lockStates _ IdentityDictionary new.
  self submorphsDo: [:m |
  lockStates at: m put: m isLocked.
  m lock].
  self
  setProperty: #submorphLockStates
  toValue: lockStates!

Item was changed:
  ----- Method: TextEditor>>noUndoer (in category 'undo support') -----
  noUndoer
  "The Undoer to use when the command can not be undone.  Checked for
  specially by readKeyboard."
 
+ UndoMessage := Message selector: #noUndoer!
- UndoMessage _ Message selector: #noUndoer!

Item was changed:
  ----- Method: TextEditor>>explainNumber: (in category 'explain') -----
  explainNumber: string
  "Is string a Number?"
 
  | strm c |
+ (c := string at: 1) isDigit ifFalse: [(c = $- and: [string size > 1 and: [(string at: 2) isDigit]])
- (c _ string at: 1) isDigit ifFalse: [(c = $- and: [string size > 1 and: [(string at: 2) isDigit]])
  ifFalse: [^nil]].
+ strm := ReadStream on: string.
+ c := Number readFrom: strm.
- strm _ ReadStream on: string.
- c _ Number readFrom: strm.
  strm atEnd ifFalse: [^nil].
  c printString = string
  ifTrue: [^'"' , string , ' is a ' , c class name , '"']
  ifFalse: [^'"' , string , ' (= ' , c printString , ') is a ' , c class name , '"']!

Item was changed:
  ----- Method: TextEditor>>sameColumn:newLine:forward: (in category 'private') -----
  sameColumn: start newLine: lineBlock forward: isForward
  "Private - Compute the index in my text
  with the line number derived from lineBlock,"
  " a one argument block accepting the old line number.
  The position inside the line will be preserved as good as possible"
  "The boolean isForward is used in the border case to determine if
  we should move to the beginning or the end of the line."
  | wordStyle column currentLine offsetAtTargetLine targetEOL lines numberOfLines currentLineNumber targetLineNumber |
+ wordStyle := Preferences wordStyleCursorMovement.
- wordStyle _ Preferences wordStyleCursorMovement.
  wordStyle
  ifTrue: [
+ lines := paragraph lines.
- lines _ paragraph lines.
  numberOfLines := paragraph numberOfLines.
+ currentLineNumber  := paragraph lineIndexOfCharacterIndex: start.
+ currentLine := lines at: currentLineNumber]
- currentLineNumber  _ paragraph lineIndexOfCharacterIndex: start.
- currentLine _ lines at: currentLineNumber]
  ifFalse: [
+ lines := self lines.
- lines _ self lines.
  numberOfLines := lines size.
+ currentLine := lines
- currentLine _ lines
  detect:[:lineInterval | lineInterval last >= start]
  ifNone:[lines last].
+ currentLineNumber := currentLine second].
+ column := start - currentLine first.
+ targetLineNumber := ((lineBlock value: currentLineNumber) max: 1) min: numberOfLines.
+ offsetAtTargetLine := (lines at: targetLineNumber) first.
+ targetEOL := (lines at: targetLineNumber) last + (targetLineNumber = numberOfLines ifTrue:[1]ifFalse:[0]).
- currentLineNumber _ currentLine second].
- column _ start - currentLine first.
- targetLineNumber _ ((lineBlock value: currentLineNumber) max: 1) min: numberOfLines.
- offsetAtTargetLine _ (lines at: targetLineNumber) first.
- targetEOL _ (lines at: targetLineNumber) last + (targetLineNumber = numberOfLines ifTrue:[1]ifFalse:[0]).
  targetLineNumber = currentLineNumber
  "No movement or movement failed. Move to beginning or end of line."
  ifTrue:[^isForward
  ifTrue:[targetEOL]
  ifFalse:[offsetAtTargetLine]].
  ^offsetAtTargetLine + column min: targetEOL.!

Item was changed:
  ----- Method: Editor>>moveCursor:forward:specialBlock: (in category 'private') -----
  moveCursor: directionBlock forward: forward specialBlock: specialBlock
  "Private - Move cursor.
  directionBlock is a one argument Block that computes the new Position from a given one.
  specialBlock is a one argumentBlock that computes the new position from a given one under the alternate semantics.
  Note that directionBlock always is evaluated first."
  | shift indices newPosition |
+ shift := sensor leftShiftDown.
+ indices := self setIndices: shift forward: forward.
+ newPosition := directionBlock value: (indices at: #moving).
- shift _ sensor leftShiftDown.
- indices _ self setIndices: shift forward: forward.
- newPosition _ directionBlock value: (indices at: #moving).
  (sensor commandKeyPressed or:[sensor controlKeyPressed])
+ ifTrue: [newPosition := specialBlock value: newPosition].
- ifTrue: [newPosition _ specialBlock value: newPosition].
  sensor keyboard.
  shift
  ifTrue: [self selectMark: (indices at: #fixed) point: newPosition - 1]
  ifFalse: [self selectAt: newPosition]!

Item was changed:
  ----- Method: TextEditor>>explainCtxt: (in category 'explain') -----
  explainCtxt: symbol
  "Is symbol a context variable?"
 
  | reply classes text cls |
+ symbol = #nil ifTrue: [reply := '"is a constant.  It is the only instance of class UndefinedObject.  nil is the initial value of all variables."'].
+ symbol = #true ifTrue: [reply := '"is a constant.  It is the only instance of class True and is the receiver of many control messages."'].
+ symbol = #false ifTrue: [reply := '"is a constant.  It is the only instance of class False and is the receiver of many control messages."'].
+ symbol = #thisContext ifTrue: [reply := '"is a context variable.  Its value is always the MethodContext which is executing this method."'].
- symbol = #nil ifTrue: [reply _ '"is a constant.  It is the only instance of class UndefinedObject.  nil is the initial value of all variables."'].
- symbol = #true ifTrue: [reply _ '"is a constant.  It is the only instance of class True and is the receiver of many control messages."'].
- symbol = #false ifTrue: [reply _ '"is a constant.  It is the only instance of class False and is the receiver of many control messages."'].
- symbol = #thisContext ifTrue: [reply _ '"is a context variable.  Its value is always the MethodContext which is executing this method."'].
  (model respondsTo: #selectedClassOrMetaClass) ifTrue: [
+ cls := model selectedClassOrMetaClass].
- cls _ model selectedClassOrMetaClass].
  cls ifNil: [^ reply].  "no class known"
  symbol = #self ifTrue:
+ [classes := cls withAllSubclasses.
- [classes _ cls withAllSubclasses.
  classes size > 12
+ ifTrue: [text := cls printString , ' or a subclass']
- ifTrue: [text _ cls printString , ' or a subclass']
  ifFalse:
+ [classes := classes printString.
+ text := 'one of these classes' , (classes copyFrom: 4 to: classes size)].
+ reply := '"is the receiver of this message; an instance of ' , text , '"'].
+ symbol = #super ifTrue: [reply := '"is just like self.  Messages to super are looked up in the superclass (' , cls superclass printString , ')"'].
- [classes _ classes printString.
- text _ 'one of these classes' , (classes copyFrom: 4 to: classes size)].
- reply _ '"is the receiver of this message; an instance of ' , text , '"'].
- symbol = #super ifTrue: [reply _ '"is just like self.  Messages to super are looked up in the superclass (' , cls superclass printString , ')"'].
  ^reply!

Item was changed:
  ----- Method: TextEditor>>encompassLine: (in category 'new selection') -----
  encompassLine: anInterval
  "Return an interval that encompasses the entire line"
  | string left right |
+ string := paragraph text string.
+ left := (string lastIndexOf: Character cr startingAt: anInterval first - 1 ifAbsent:[0]) + 1.
+ right := (string indexOf: Character cr startingAt: anInterval last + 1 ifAbsent: [string size + 1]) - 1.
- string _ paragraph text string.
- left _ (string lastIndexOf: Character cr startingAt: anInterval first - 1 ifAbsent:[0]) + 1.
- right _ (string indexOf: Character cr startingAt: anInterval last + 1 ifAbsent: [string size + 1]) - 1.
  ^left to: right!

Item was changed:
  ----- Method: TextEditor>>browseClassFromIt (in category 'menu messages') -----
  browseClassFromIt
  "Launch a hierarchy browser for the class indicated by the current selection.  If multiple classes matching the selection exist, let the user choose among them."
 
  | aClass |
  self lineSelectAndEmptyCheck: [^ self].
 
+ aClass := Utilities classFromPattern: (self selection string copyWithout: Character cr) withCaption: 'choose a class to browse...'.
- aClass _ Utilities classFromPattern: (self selection string copyWithout: Character cr) withCaption: 'choose a class to browse...'.
  aClass ifNil: [^ morph flash].
 
  Utilities spawnHierarchyForClass: aClass selector: nil!

Item was changed:
  ----- Method: Editor>>backspace: (in category 'typing/selecting keys') -----
  backspace: characterStream
  "Backspace over the last character."
 
  | startIndex |
  sensor leftShiftDown ifTrue: [^ self backWord: characterStream].
  characterStream isEmpty
  ifTrue:
+ [startIndex := self markIndex +
- [startIndex _ self markIndex +
  (self hasCaret ifTrue: [0] ifFalse: [1]).
  [sensor keyboardPressed and:
  [sensor keyboardPeek asciiValue = 8]] whileTrue: [
  "process multiple backspaces"
  sensor keyboard.
+ startIndex := 1 max: startIndex - 1.
- startIndex _ 1 max: startIndex - 1.
  ].
  self backTo: startIndex]
  ifFalse:
  [sensor keyboard.
  characterStream skip: -1].
  ^false!

Item was changed:
  ----- Method: TextEditor>>selectCurrentTypeIn: (in category 'nonediting/nontyping keys') -----
  selectCurrentTypeIn: characterStream
  "Select what would be replaced by an undo (e.g., the last typeIn)."
 
  | prior |
 
  self closeTypeIn: characterStream.
+ prior := otherInterval.
- prior _ otherInterval.
  sensor keyboard. "flush character"
  self closeTypeIn: characterStream.
  self selectInterval: UndoInterval.
+ otherInterval := prior.
- otherInterval _ prior.
  ^ true!

Item was changed:
  ----- Method: TextEditor>>closeTypeIn (in category 'typing support') -----
  closeTypeIn
  "See comment in openTypeIn.  It is important to call closeTypeIn before executing
  any non-typing key, making a new selection, etc.  It is called automatically for
  menu commands.
  Typing commands can call 'closeTypeIn: aCharacterStream' instead of this to
  save typeahead.  Undoer & Redoer: undoAndReselect:redoAndReselect:."
 
  | begin stop |
  beginTypeInBlock == nil ifFalse: [
  (UndoMessage sends: #noUndoer) ifTrue: "should always be true, but just in case..."
+ [begin := self startOfTyping.
+ stop := self stopIndex.
- [begin _ self startOfTyping.
- stop _ self stopIndex.
  self undoer: #undoAndReselect:redoAndReselect:
  with: (begin + UndoMessage argument to: begin + UndoSelection size - 1)
  with: (stop to: stop - 1).
+ UndoInterval := begin to: stop - 1].
+ beginTypeInBlock := nil]!
- UndoInterval _ begin to: stop - 1].
- beginTypeInBlock _ nil]!

Item was changed:
  ----- Method: TextEditor>>model: (in category 'model access') -----
  model: aModel
  "Controller|model: and Controller|view: are sent by View|controller: in
  order to coordinate the links between the model, view, and controller. In
  ordinary usage, the receiver is created and passed as the parameter to
  View|controller: so that the receiver's model and view links can be set
  up by the view."
 
+ model := aModel!
- model _ aModel!

Item was changed:
  ----- Method: TextEditor>>cursorHome: (in category 'nonediting/nontyping keys') -----
  cursorHome: characterStream
 
  "Private - Move cursor from position in current line to beginning of
  current line. If control key is pressed put cursor at beginning of text"
 
  | string |
 
+ string := paragraph text string.
- string _ paragraph text string.
  self
  moveCursor: [ :position | Preferences wordStyleCursorMovement
  ifTrue:[
  (paragraph lines at:(paragraph lineIndexOfCharacterIndex: position)) first]
  ifFalse:[
  (string
  lastIndexOf: Character cr
  startingAt: position - 1
  ifAbsent:[0]) + 1]]
  forward: false
  specialBlock: [:dummy | 1].
  ^true!

Item was changed:
  ----- Method: TextEditor>>forwardDelete: (in category 'typing/selecting keys') -----
  forwardDelete: characterStream
  "Delete forward over the next character.
   Make Undo work on the whole type-in, not just the one char.
  wod 11/3/1998: If there was a selection use #zapSelectionWith: rather than #backspace: which was 'one off' in deleting the selection. Handling of things like undo or typeIn area were not fully considered."
  | startIndex usel upara uinterval ind stopIndex |
+ startIndex := self markIndex.
- startIndex _ self markIndex.
  startIndex > paragraph text size ifTrue:
  [sensor keyboard.
  ^ false].
  self hasSelection ifTrue:
  ["there was a selection"
  sensor keyboard.
  self zapSelectionWith: self nullText.
  ^ false].
  "Null selection - do the delete forward"
  beginTypeInBlock == nil "no previous typing.  openTypeIn"
+ ifTrue: [self openTypeIn. UndoSelection := self nullText].
+ uinterval := UndoInterval deepCopy.
+ upara := UndoParagraph deepCopy.
- ifTrue: [self openTypeIn. UndoSelection _ self nullText].
- uinterval _ UndoInterval deepCopy.
- upara _ UndoParagraph deepCopy.
  stopIndex := startIndex.
  (sensor keyboard asciiValue = 127 and: [sensor leftShiftDown])
  ifTrue: [stopIndex := (self nextWord: stopIndex) - 1].
  self selectFrom: startIndex to: stopIndex.
  self replaceSelectionWith: self nullText.
  self selectFrom: startIndex to: startIndex-1.
+ UndoParagraph := upara.  UndoInterval := uinterval.
- UndoParagraph _ upara.  UndoInterval _ uinterval.
  UndoMessage selector == #noUndoer ifTrue: [
  (UndoSelection isText) ifTrue: [
+ usel := UndoSelection.
+ ind := startIndex. "UndoInterval startIndex"
- usel _ UndoSelection.
- ind _ startIndex. "UndoInterval startIndex"
  usel replaceFrom: usel size + 1 to: usel size with:
  (UndoParagraph text copyFrom: ind to: ind).
  UndoParagraph text replaceFrom: ind to: ind with:
  self nullText]].
  ^false!

Item was changed:
  ----- Method: Editor>>nextWord: (in category 'private') -----
  nextWord: position
  | string index |
+ string := self string.
+ index := position.
- string _ self string.
- index _ position.
  [(index between: 1 and: string size) and: [(string at: index) isAlphaNumeric]]
+ whileTrue: [index := index + 1].
- whileTrue: [index _ index + 1].
  [(index between: 1 and: string size) and: [(string at: index) isAlphaNumeric not]]
+ whileTrue: [index := index + 1].
- whileTrue: [index _ index + 1].
  ^ index!

Item was changed:
  ----- Method: Editor>>setIndices:forward: (in category 'private') -----
  setIndices: shiftPressed forward: forward
  "Little helper method that sets the moving and fixed indices according to some flags."
  | indices |
+ indices := Dictionary new.
- indices _ Dictionary new.
  (shiftPressed and:[self class selectionsMayShrink])
  ifTrue: [
  indices at: #moving put: self pointIndex.
  indices at: #fixed put: self markIndex
  ] ifFalse: [
  forward
  ifTrue:[
  indices at: #moving put: self stopIndex.
  indices at: #fixed put: self startIndex.
  ] ifFalse: [
  indices at: #moving put: self startIndex.
  indices at: #fixed put: self stopIndex.
  ]
  ].
  ^indices!

Item was changed:
  ----- Method: TextEditor>>argAdvance: (in category 'typing/selecting keys') -----
  argAdvance: characterStream
  "Invoked by Ctrl-a.  Useful after Ctrl-q.
  Search forward from the end of the selection for a colon followed by
  a space.  Place the caret after the space.  If none are found, place the
  caret at the end of the text.  Does not affect the undoability of the
  previous command."
 
  | start |
  sensor keyboard. "flush character"
  self closeTypeIn: characterStream.
+ start := paragraph text findString: ': ' startingAt: self stopIndex.
+ start = 0 ifTrue: [start := paragraph text size + 1].
- start _ paragraph text findString: ': ' startingAt: self stopIndex.
- start = 0 ifTrue: [start _ paragraph text size + 1].
  self selectAt: start + 2.
  ^true!

Item was changed:
  ----- Method: TextEditor class>>initializeShiftedYellowButtonMenu (in category 'keyboard shortcut tables') -----
  initializeShiftedYellowButtonMenu
  "Initialize the yellow button pop-up menu and corresponding messages."
 
  "TextEditor initialize"
  "
  shiftedYellowButtonMenu := {
  {'set font... (k)' translated. #offerFontMenu}.
  {'set style... (K)' translated. #changeStyle}.
  {'set alignment...' translated. #chooseAlignment}.
  #-.
  {'more...' translated. #yellowButtonActivity}.
  }
  "
+ shiftedYellowButtonMenu := yellowButtonMenu!
- shiftedYellowButtonMenu _ yellowButtonMenu!

Item was changed:
  ----- Method: SmalltalkEditor>>handleEmphasisExtra:with: (in category 'editing keys') -----
  handleEmphasisExtra: index with: characterStream
  "Handle an extra emphasis menu item"
  | action attribute thisSel |
  action := {
  [attribute := TextDoIt new.
  thisSel := attribute analyze: self selection asString].
  [attribute := TextPrintIt new.
  thisSel := attribute analyze: self selection asString].
  [attribute := TextLink new.
  thisSel := attribute analyze: self selection asString with: 'Comment'].
  [attribute := TextLink new.
  thisSel := attribute analyze: self selection asString with: 'Definition'].
  [attribute := TextLink new.
  thisSel := attribute analyze: self selection asString with: 'Hierarchy'].
  [attribute := TextLink new.
  thisSel := attribute analyze: self selection asString].
  [attribute := TextURL new.
  thisSel := attribute analyze: self selection asString].
  ["Edit hidden info"
  thisSel := self hiddenInfo. "includes selection"
  attribute := TextEmphasis normal].
  ["Copy hidden info"
  self copyHiddenInfo.
  ^true]. "no other action"
  } at: index.
  action value.
 
  thisSel ifNil: [^true]. "Could not figure out what to link to"
 
  attribute ifNotNil: [
  thisSel ifEmpty:[ | oldAttributes |
  "only change emphasisHere while typing"
  oldAttributes := paragraph text attributesAt: self pointIndex.
  self insertTypeAhead: characterStream.
+ emphasisHere := Text addAttribute: attribute toArray: oldAttributes.
- emphasisHere _ Text addAttribute: attribute toArray: oldAttributes.
  ] ifNotEmpty: [
  self replaceSelectionWith: (thisSel asText addAttribute: attribute).
  ]
  ].
  ^true!

Item was changed:
  ----- Method: TextEditor>>nextTokenFrom:direction: (in category 'new selection') -----
  nextTokenFrom: start direction: dir
  "simple token-finder for compiler automated corrections"
  | loc str |
+ loc := start + dir.
+ str := paragraph text string.
- loc _ start + dir.
- str _ paragraph text string.
  [(loc between: 1 and: str size) and: [(str at: loc) isSeparator]]
+ whileTrue: [loc := loc + dir].
- whileTrue: [loc _ loc + dir].
  ^ loc!

Item was changed:
  ----- Method: TextEditor>>dispatchOnCharacter:with: (in category 'typing support') -----
  dispatchOnCharacter: char with: typeAheadStream
  "Carry out the action associated with this character, if any.
  Type-ahead is passed so some routines can flush or use it."
 
  | honorCommandKeys |
  ((char == Character cr) and: [morph acceptOnCR])
  ifTrue: [
  sensor keyboard.  "Gobble cr -- probably unnecessary."
  self closeTypeIn.
  ^ true].
 
  self clearParens.
   
  char asciiValue = 13 ifTrue: [
  sensor controlKeyPressed ifTrue: [
  ^ self normalCharacter: typeAheadStream ].
  sensor leftShiftDown ifTrue: [
  ^ self lf: typeAheadStream ].
  sensor commandKeyPressed ifTrue: [
  ^ self crlf: typeAheadStream ].
  ^ self crWithIndent: typeAheadStream ].
 
+ ((honorCommandKeys := Preferences cmdKeysInText) and: [char = Character enter])
- ((honorCommandKeys _ Preferences cmdKeysInText) and: [char = Character enter])
  ifTrue: [^ self dispatchOnEnterWith: typeAheadStream].
 
  "Special keys overwrite crtl+key combinations - at least on Windows. To resolve this
  conflict, assume that keys other than cursor keys aren't used together with Crtl."
  ((self class specialShiftCmdKeys includes: char asciiValue) and: [char asciiValue < 27])
  ifTrue: [^ sensor controlKeyPressed
  ifTrue: [self perform: (self class shiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
  ifFalse: [self perform: (self class cmdActions at: char asciiValue + 1) with: typeAheadStream]].
 
  "backspace, and escape keys (ascii 8 and 27) are command keys"
  ((honorCommandKeys and: [sensor commandKeyPressed]) or: [self class specialShiftCmdKeys includes: char asciiValue]) ifTrue:
  [^ sensor leftShiftDown
  ifTrue: [
  self perform: (self class shiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
  ifFalse: [
  self perform: (self class cmdActions at: char asciiValue + 1) with: typeAheadStream]].
 
  "the control key can be used to invoke shift-cmd shortcuts"
  (honorCommandKeys and: [sensor controlKeyPressed])
  ifTrue: [
  ^ self perform: (self class shiftCmdActions at: char asciiValue + 1) with: typeAheadStream].
 
  (')]}' includes: char)
  ifTrue: [self blinkPrevParen].
 
  ^ self normalCharacter: typeAheadStream!

Item was changed:
  ----- Method: TextEditor>>debug:receiver:in: (in category 'do-its') -----
  debug: aCompiledMethod receiver: anObject in: evalContext
 
  | selector guineaPig debugger context |
+ selector := evalContext isNil ifTrue: [#DoIt] ifFalse: [#DoItIn:].
- selector _ evalContext isNil ifTrue: [#DoIt] ifFalse: [#DoItIn:].
  anObject class addSelectorSilently: selector withMethod: aCompiledMethod.
+ guineaPig := evalContext isNil
- guineaPig _ evalContext isNil
  ifTrue: [[anObject DoIt] newProcess]
  ifFalse: [[anObject DoItIn: evalContext] newProcess].
+ context := guineaPig suspendedContext.
+ debugger := Debugger new
- context _ guineaPig suspendedContext.
- debugger _ Debugger new
  process: guineaPig
  controller: nil
  context: context.
  debugger openFullNoSuspendLabel: 'Debug it'.
  [debugger interruptedContext method == aCompiledMethod]
  whileFalse: [debugger send].
  anObject class basicRemoveSelector: selector!

Item was changed:
  ----- Method: TextEditor>>blinkParenAt: (in category 'parenblinking') -----
  blinkParenAt: parenLocation
  self text
  addAttribute: TextEmphasis bold
  from: parenLocation
  to: parenLocation.
+ lastParenLocation := parenLocation.!
- lastParenLocation _ parenLocation.!

Item was changed:
  ----- Method: TextEditor>>setSearch: (in category 'accessing') -----
  setSearch: aString
  "Set the FindText and ChangeText to seek aString; except if already seeking aString, leave ChangeText alone so again will repeat last replacement."
 
  FindText string = aString
+ ifFalse: [FindText := ChangeText := aString asText]!
- ifFalse: [FindText _ ChangeText _ aString asText]!

Item was changed:
  ----- Method: TextEditor>>browseChangeSetsWithSelector (in category 'menu messages') -----
  browseChangeSetsWithSelector
  "Determine which, if any, change sets have at least one change for the selected selector, independent of class"
 
  | aSelector |
  self lineSelectAndEmptyCheck: [^ self].
+ (aSelector := self selectedSelector) == nil ifTrue: [^ morph flash].
- (aSelector _ self selectedSelector) == nil ifTrue: [^ morph flash].
  ChangeSorter browseChangeSetsWithSelector: aSelector!

Item was changed:
  ----- Method: TextEditor>>zapSelectionWith: (in category 'mvc compatibility') -----
  zapSelectionWith: aText
 
  | start stop |
  self deselect.
+ start := self startIndex.
+ stop := self stopIndex.
- start _ self startIndex.
- stop _ self stopIndex.
  (aText isEmpty and: [stop > start]) ifTrue: [
  "If deleting, then set emphasisHere from 1st character of the deletion"
+ emphasisHere := (paragraph text attributesAt: start) select: [:att | att mayBeExtended]].
- emphasisHere _ (paragraph text attributesAt: start) select: [:att | att mayBeExtended]].
  (start = stop and: [ aText size = 0 ]) ifFalse: [
  paragraph replaceFrom: start to: stop - 1 with: aText.
  self markIndex: start; pointIndex: start + aText size.
+ UndoInterval := otherInterval := self selectionInterval].
- UndoInterval _ otherInterval _ self selectionInterval].
 
  self userHasEdited  " -- note text now dirty"!

Item was changed:
  ----- Method: TextEditor>>pointBlock: (in category 'accessing-selection') -----
  pointBlock: aCharacterBlock
+ pointBlock := aCharacterBlock.
- pointBlock _ aCharacterBlock.
  !

Item was changed:
  ----- Method: FileList>>askServerInfo (in category 'server list') -----
  askServerInfo
  "Get the user to create a ServerDirectory for a new server.  Fill in and say Accept."
  | template |
+ template := '"Please fill in the following info, then select all text and choose DoIt."
- template _ '"Please fill in the following info, then select all text and choose DoIt."
 
  | aa |
  self flag: #ViolateNonReferenceToOtherClasses.
+ aa := ServerDirectory new.
- aa _ ServerDirectory new.
  aa server: ''st.cs.uiuc.edu''.    "host"
  aa user: ''anonymous''.
  aa password: ''[hidden email]''.
  aa directory: ''/Smalltalk/Squeak/Goodies''.
  aa url: ''''.    "<- this is optional.  Only used when *writing* update files."
  ServerDirectory addServer: aa named: ''UIUCArchive''.  "<- known by this name in Squeak"'.
 
  (StringHolder new contents: template) openLabel: 'FTP Server Form'
  !

Item was changed:
  ----- Method: TextEditor class>>initializeShiftCmdKeyShortcuts (in category 'keyboard shortcut tables') -----
  initializeShiftCmdKeyShortcuts
  "Initialize the shift-command-key (or control-key) shortcut table."
  "NOTE: if you don't know what your keyboard generates, use Sensor kbdTest"
  "wod 11/3/1998: Fix setting of cmdMap for shifted keys to actually use the
  capitalized versions of the letters.
  TPR 2/18/99: add the plain ascii values back in for those VMs that don't return the shifted values."
 
  "TextEditor initialize"
 
  | cmdMap cmds |
 
  "shift-command and control shortcuts"
+ cmdMap := Array new: 256 withAll: #noop:.   "use temp in case of a crash"
- cmdMap _ Array new: 256 withAll: #noop:.   "use temp in case of a crash"
  cmdMap at: ( 1 + 1) put: #cursorHome:. "home key"
  cmdMap at: ( 4 + 1) put: #cursorEnd:. "end key"
  cmdMap at: ( 8 + 1) put: #forwardDelete:. "ctrl-H or delete key"
  cmdMap at: (11 + 1) put: #cursorPageUp:. "page up key"
  cmdMap at: (12 + 1) put: #cursorPageDown:. "page down key"
  cmdMap at: (13 + 1) put: #crWithIndent:. "ctrl-Return"
  cmdMap at: (27 + 1) put: #offerMenuFromEsc:. "escape key"
  cmdMap at: (28 + 1) put: #cursorLeft:. "left arrow key"
  cmdMap at: (29 + 1) put: #cursorRight:. "right arrow key"
  cmdMap at: (30 + 1) put: #cursorUp:. "up arrow key"
  cmdMap at: (31 + 1) put: #cursorDown:. "down arrow key"
  cmdMap at: (32 + 1) put: #selectWord:. "space bar key"
  cmdMap at: (45 + 1) put: #changeEmphasis:. "cmd-sh-minus"
  cmdMap at: (61 + 1) put: #changeEmphasis:. "cmd-sh-plus"
  cmdMap at: (127 + 1) put: #forwardDelete:. "del key"
 
  "Note: Command key overrides shift key, so, for example, cmd-shift-9 produces $9 not $("
  '9[,''' do: [ :char | cmdMap at: (char asciiValue + 1) put: #shiftEnclose: ]. "({< and double-quote"
  "Note: Must use cmd-9 or ctrl-9 to get '()' since cmd-shift-9 is a Mac FKey command."
 
  "NB: sw 12/9/2001 commented out the idiosyncratic line just below, which was grabbing shift-esc in the text editor and hence which argued with the wish to have shift-esc be a universal gesture for escaping the local context and calling up the desktop menu."  
  "cmdMap at: (27 + 1) put: #shiftEnclose:." "ctrl-["
 
  "'""''(' do: [ :char | cmdMap at: (char asciiValue + 1) put: #enclose:]."
 
+ cmds := #(
- cmds _ #(
  $c compareToClipboard:
  $d duplicate:
  $h cursorTopHome:
  $j doAgainMany:
  $k changeStyle:
  $l outdent:
  $m selectCurrentTypeIn:
  $r indent:
  $s search:
  $u changeLfToCr:
  $x makeLowercase:
  $y makeUppercase:
  $z makeCapitalized:
  ).
  1 to: cmds size by: 2 do: [ :i |
  cmdMap at: ((cmds at: i) asciiValue + 1) put: (cmds at: i + 1). "plain keys"
  cmdMap at: ((cmds at: i) asciiValue - 32 + 1) put: (cmds at: i + 1). "shifted keys"
  cmdMap at: ((cmds at: i) asciiValue - 96 + 1) put: (cmds at: i + 1). "ctrl keys"
  ].
+ shiftCmdActions := cmdMap!
- shiftCmdActions _ cmdMap!

Item was changed:
  ----- Method: TextEditor>>spawn (in category 'menu messages') -----
  spawn
  "Create and schedule a message browser for the code of the model's
  selected message. Retain any edits that have not yet been accepted."
  | code |
+ code := paragraph text string.
- code _ paragraph text string.
  self cancel.
  model spawn: code.!

Item was changed:
  ----- Method: TextEditor>>changeSelectionFontTo: (in category 'attributes') -----
  changeSelectionFontTo: aFont
  | attr |
  aFont ifNil:[^self].
+ attr := TextFontReference toFont: aFont.
- attr _ TextFontReference toFont: aFont.
  paragraph text addAttribute: attr from: self startIndex to: (self stopIndex-1 min: paragraph text size).
  paragraph composeAll.
  self recomputeInterval.
  morph changed.!

Item was changed:
  ----- Method: TextEditor>>browseItHere (in category 'menu messages') -----
  browseItHere
  "Retarget the receiver's window to look at the selected class, if appropriate.  3/1/96 sw"
  | aSymbol foundClass b |
+ (((b := model) isKindOf: Browser) and: [b couldBrowseAnyClass])
- (((b _ model) isKindOf: Browser) and: [b couldBrowseAnyClass])
  ifFalse: [^ morph flash].
  model okToChange ifFalse: [^ morph flash].
  self selectionInterval isEmpty ifTrue: [self selectWord].
+ (aSymbol := self selectedSymbol) isNil ifTrue: [^ morph flash].
- (aSymbol _ self selectedSymbol) isNil ifTrue: [^ morph flash].
 
+ foundClass := (Smalltalk at: aSymbol ifAbsent: [nil]).
- foundClass _ (Smalltalk at: aSymbol ifAbsent: [nil]).
  foundClass isNil ifTrue: [^ morph flash].
  (foundClass isKindOf: Class)
  ifTrue:
  [model systemCategoryListIndex:
  (model systemCategoryList indexOf: foundClass category).
  model classListIndex: (model classList indexOf: foundClass name)]!

Item was changed:
  ----- Method: TextEditor>>changeParagraph: (in category 'initialize-release') -----
  changeParagraph: aParagraph
  "Install aParagraph as the one to be edited by the receiver."
 
+ UndoParagraph == paragraph ifTrue: [UndoParagraph := nil].
+ paragraph := aParagraph.
- UndoParagraph == paragraph ifTrue: [UndoParagraph _ nil].
- paragraph _ aParagraph.
  self resetState!

Item was changed:
  ----- Method: TextEditor class>>abandonChangeText (in category 'class initialization') -----
  abandonChangeText
  "Call this to get out of the maddening situation in which the system keeps aggressively trying to do a replacement that you no longer wish to make, every time you make choose a new method in a list."
+ ChangeText := FindText
- ChangeText _ FindText
 
  "
  TextEditor abandonChangeText
  "!

Item was changed:
  ----- Method: TextEditor>>openTypeIn (in category 'typing support') -----
  openTypeIn
  "Set up UndoSelection to null text (to be added to by readKeyboard and backTo:),
  beginTypeInBlock to keep track of the leftmost backspace, and UndoParameter to tally
  how many deleted characters were backspaced over rather than 'cut'.
  You can't undo typing until after closeTypeIn."
 
  beginTypeInBlock ifNil: [
+ UndoSelection := self nullText.
- UndoSelection _ self nullText.
  self undoer: #noUndoer with: 0.
+ beginTypeInBlock := self startIndex]!
- beginTypeInBlock _ self startIndex]!

Item was changed:
  ----- Method: TextEditor>>compareToClipboard (in category 'menu messages') -----
  compareToClipboard
  "Check to see if whether the receiver's text is the same as the text currently on the clipboard, and inform the user."
  | s1 s2 |
+ s1 := self clipboardText string.
+ s2 := paragraph text string.
- s1 _ self clipboardText string.
- s2 _ paragraph text string.
  s1 = s2 ifTrue: [^ self inform: 'Exact match'].
 
  (StringHolder new textContents:
  (TextDiffBuilder buildDisplayPatchFrom: s1 to: s2))
  openLabel: 'Comparison to Clipboard Text'!

Item was changed:
  ----- Method: TextEditor>>evaluateSelection (in category 'do-its') -----
  evaluateSelection
  "Treat the current selection as an expression; evaluate it and return the result"
  | result rcvr ctxt |
  self lineSelectAndEmptyCheck: [^ ''].
 
  (model respondsTo: #doItReceiver)
  ifTrue: [FakeClassPool adopt: model selectedClass.  "Include model pool vars if any"
+ rcvr := model doItReceiver.
+ ctxt := model doItContext]
+ ifFalse: [rcvr := ctxt := nil].
+ result := [
- rcvr _ model doItReceiver.
- ctxt _ model doItContext]
- ifFalse: [rcvr _ ctxt _ nil].
- result _ [
  rcvr class evaluatorClass new
  evaluate: self selectionAsStream
  in: ctxt
  to: rcvr
  notifying: self
  ifFail: [FakeClassPool adopt: nil. ^ #failedDoit]
  logged: true.
  ]
  on: OutOfScopeNotification
  do: [ :ex | ex resume: true].
  FakeClassPool adopt: nil.
  ^ result!

Item was changed:
  ----- Method: TextEditor>>markBlock: (in category 'accessing-selection') -----
  markBlock: aCharacterBlock
+ markBlock := aCharacterBlock!
- markBlock _ aCharacterBlock!

Item was changed:
  ----- Method: TextEditor>>isDisjointFrom: (in category 'private') -----
  isDisjointFrom: anInterval
  "Answer true if anInterval is a caret not touching or within the current
  interval, or if anInterval is a non-caret that does not overlap the current
  selection."
 
  | fudge |
+ fudge := anInterval size = 0 ifTrue: [1] ifFalse: [0].
- fudge _ anInterval size = 0 ifTrue: [1] ifFalse: [0].
  ^(anInterval last + fudge < self startIndex or:
  [anInterval first - fudge >= self stopIndex])
  !

Item was changed:
  ----- Method: TextEditor>>exploreIt (in category 'do-its') -----
  exploreIt
  | result |
+ result := self evaluateSelection.
- result _ self evaluateSelection.
  ((result isKindOf: FakeClassPool) or: [result == #failedDoit])
  ifTrue: [morph flash]
  ifFalse: [result explore]!

Item was changed:
  ----- Method: TextEditor>>readKeyboard (in category 'typing support') -----
  readKeyboard
  "Key struck on the keyboard. Find out which one and, if special, carry
  out the associated special action. Otherwise, add the character to the
  stream of characters.  Undoer & Redoer: see closeTypeIn."
 
  | typeAhead char |
+ typeAhead := WriteStream on: (String new: 128).
- typeAhead _ WriteStream on: (String new: 128).
  [ sensor keyboardPressed ] whileTrue: [
  self deselect.
  [ sensor keyboardPressed ] whileTrue: [
+ char := sensor keyboardPeek.
- char _ sensor keyboardPeek.
  (self dispatchOnCharacter: char with: typeAhead) ifTrue: [
  self doneTyping.
  self storeSelectionInParagraph.
  ^self].
  self openTypeIn].
  self hasSelection ifTrue: [ "save highlighted characters"
+ UndoSelection := self selection].
- UndoSelection _ self selection].
  self zapSelectionWith:
  (Text string: typeAhead contents attributes: emphasisHere).
  typeAhead reset.
  self unselect].
  self storeSelectionInParagraph!

Item was changed:
  ----- Method: TextEditor>>pasteRecent (in category 'menu messages') -----
  pasteRecent
  "Paste an item chose from RecentClippings."
 
  | clipping |
+ (clipping := Clipboard chooseRecentClipping) ifNil: [^ self].
- (clipping _ Clipboard chooseRecentClipping) ifNil: [^ self].
  Clipboard clipboardText: clipping.
  ^ self paste!

Item was changed:
  ----- Method: TextEditor>>swapChars: (in category 'editing keys') -----
  swapChars: characterStream
  "Triggered byCmd-Y;.  Swap two characters, either those straddling the insertion point, or the two that comprise the selection.  Suggested by Ted Kaehler.  "
 
  | currentSelection aString chars |
  sensor keyboard. "flush the triggering cmd-key character"
+ (chars := self selection) size = 0
- (chars _ self selection) size = 0
  ifTrue:
+ [currentSelection := self pointIndex.
- [currentSelection _ self pointIndex.
  self selectMark: currentSelection - 1 point: currentSelection]
  ifFalse:
  [chars size = 2
  ifFalse:
  [morph flash. ^ true]
  ifTrue:
+ [currentSelection := self pointIndex - 1]].
+ aString := self selection string.
- [currentSelection _ self pointIndex - 1]].
- aString _ self selection string.
  self replaceSelectionWith: (Text string: aString reversed attributes: emphasisHere).
  self selectAt: currentSelection + 1.
  ^ true!

Item was changed:
  ----- Method: TextEditor>>explainScan: (in category 'explain') -----
  explainScan: string
  "Remove beginning and trailing space, tab, cr.
  1/15/96 sw: copied intact from BrowserCodeController"
 
  | c beg end |
+ beg := 1.
+ end := string size.
- beg _ 1.
- end _ string size.
 
  [beg = end ifTrue: [^string copyFrom: 1 to: 1].
  "if all blank, tell about the first"
+ c := string at: beg.
- c _ string at: beg.
  c = Character space or: [c = Character tab or: [c = Character cr]]]
+ whileTrue: [beg := beg + 1].
- whileTrue: [beg _ beg + 1].
 
+ [c := string at: end.
- [c _ string at: end.
  c = Character space or: [c = Character tab or: [c = Character cr]]]
+ whileTrue: [end := end - 1].
- whileTrue: [end _ end - 1].
  ^string copyFrom: beg to: end "Return purely visible characters"!

Item was changed:
  ----- Method: TextEditor>>notify:at:in: (in category 'new selection') -----
  notify: aString at: anInteger in: aStream
  "The compilation of text failed. The syntax error is noted as the argument,
  aString. Insert it in the text at starting character position anInteger."
 
  | pos |
+ pos := self selectionInterval notEmpty
- pos _ self selectionInterval notEmpty
  ifTrue: [
  self startIndex + anInteger - 1 ]
  ifFalse: [anInteger].
  self insertAndSelect: aString at: (pos max: 1)!

Item was changed:
  ----- Method: TextMorphEditor>>changeSelectionFontTo: (in category 'attributes') -----
  changeSelectionFontTo: aFont
  | attr |
  aFont ifNil:[^self].
+ attr := TextFontReference toFont: aFont.
- attr _ TextFontReference toFont: aFont.
  paragraph text addAttribute: attr from: self startIndex to: (self stopIndex-1 min: paragraph text size).
  paragraph composeAll.
  self recomputeInterval.
  morph changed.!

Item was changed:
  ----- Method: TextEditor>>printIt (in category 'do-its') -----
  printIt
  "Treat the current text selection as an expression; evaluate it. Insert the
  description of the result of evaluation after the selection and then make
  this description the new text selection."
  | result |
+ result := self evaluateSelection.
- result _ self evaluateSelection.
  ((result isKindOf: FakeClassPool) or: [result == #failedDoit])
  ifTrue: [morph flash]
  ifFalse: [self afterSelectionInsertAndSelect: result printString]!

Item was changed:
  ----- Method: TextEditor>>mouseDown: (in category 'events') -----
  mouseDown: evt
  "An attempt to break up the old processRedButton code into threee phases"
  | clickPoint b |
 
+ oldInterval := self selectionInterval.
+ clickPoint := evt cursorPoint.
+ b := paragraph characterBlockAtPoint: clickPoint.
- oldInterval _ self selectionInterval.
- clickPoint _ evt cursorPoint.
- b _ paragraph characterBlockAtPoint: clickPoint.
 
  (paragraph clickAt: clickPoint for: model controller: self) ifTrue: [
  self markBlock: b.
  self pointBlock: b.
  evt hand releaseKeyboardFocus: self.
  ^ self ].
 
  evt shiftPressed
  ifFalse: [
  self closeTypeIn.
  self markBlock: b.
  self pointBlock: b ]!

Item was changed:
  ----- Method: Editor>>morph: (in category 'accessing') -----
  morph: aMorph
  "Install a link back to the morph being edited (esp for text links)"
+ morph := aMorph !
- morph _ aMorph !

Item was changed:
  ----- Method: TextMorph>>keyStroke: (in category 'event handling') -----
  keyStroke: evt
  "Handle a keystroke event."
  | action |
  self resetBlinkCursor. "don't blink during type-in"
  evt keyValue = 13 ifTrue:["CR - check for special action"
+ action := self crAction.
- action _ self crAction.
  action ifNotNil:[
  "Note: Code below assumes that this was some
  input field reacting on CR. Break the keyboard
  focus so that the receiver can be safely deleted."
  evt hand newKeyboardFocus: nil.
  ^action value]].
  self handleInteraction: [editor readKeyboard] fromEvent: evt.
  "self updateFromParagraph."
  super keyStroke: evt  "sends to keyStroke event handler, if any"!

Item was changed:
  ----- Method: TextEditor>>setEmphasis: (in category 'editing keys') -----
  setEmphasis: emphasisSymbol
  "Change the emphasis of the current selection."
 
  | oldAttributes attribute |
+ oldAttributes := paragraph text attributesAt: self selectionInterval first.
- oldAttributes _ paragraph text attributesAt: self selectionInterval first.
 
+ attribute := TextEmphasis perform: emphasisSymbol.
- attribute _ TextEmphasis perform: emphasisSymbol.
  (emphasisSymbol == #normal)
  ifFalse: [oldAttributes do:
  [:att | (att dominates: attribute) ifTrue: [attribute turnOff]]].
  self replaceSelectionWith: (self selection addAttribute: attribute)!


Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Morphic-dtl.297.mcz

Levente Uzonyi-2
On Mon, 4 Jan 2010, [hidden email] wrote:

> David T. Lewis uploaded a new version of Morphic to project The Trunk:
> http://source.squeak.org/trunk/Morphic-dtl.297.mcz
>
> ==================== Summary ====================
>
> Name: Morphic-dtl.297
> Author: dtl
> Time: 3 January 2010, 11:54:26 am
> UUID: b656a757-aedc-47a4-9014-21327212c021
> Ancestors: Morphic-ar.296
>
> Add TextEditor>>explainDelimitor: copied from ParagraphEditor, required for explain function in code panes.
>
> Run FixUnderscores on package Morphic to update methods adopted from Cuis.
> Note: Did not fix underscores in MorphicModel class>>compileAccessorsFor:

Be careful with FixUnderscores, last time I tried it, it replaced _ to :=
in string literals. (FixUnderscores-cmm.10)


Levente

>
>
> =============== Diff against Morphic-ar.296 ===============
>
> Item was changed:
>  ----- Method: TextEditor>>reverseSelection (in category 'current selection') -----
>  reverseSelection
>   "Reverse the valence of the current selection highlighting."
> + selectionShowing := selectionShowing not.
> - selectionShowing _ selectionShowing not.
>   paragraph reverseFrom: self pointBlock to: self markBlock!
>
> Item was changed:
>  ----- Method: TextEditor>>completeSymbol:lastOffering: (in category 'private') -----
>  completeSymbol: hintText lastOffering: selectorOrNil
>   "Invoked by Ctrl-q when there is only a caret.
>   Do selector-completion, i.e., try to replace the preceding identifier by a
>   selector that begins with those characters & has as many keywords as possible.
>   Leave two spaces after each colon (only one after the last) as space for
>   arguments.  Put the caret after the space after the first keyword.  If the
>   user types Ctrl-q again immediately, choose a different selector.
>   Undoer: #undoQuery:lastOffering:; Redoer: itself.
>   If redoing, just redisplay the last offering, selector[OrNil]."
>
>   | firstTime input prior caret newStart sym kwds outStream |
> + firstTime := self isRedoing
> + ifTrue: [prior := sym := selectorOrNil. true]
> - firstTime _ self isRedoing
> - ifTrue: [prior _ sym _ selectorOrNil. true]
>   ifFalse: [hintText isNil].
>   firstTime
>   ifTrue: "Initial Ctrl-q (or redo)"
> + [caret := self startIndex.
> - [caret _ self startIndex.
>   self selectPrecedingIdentifier.
> + input := self selection]
> - input _ self selection]
>   ifFalse: "Repeated Ctrl-q"
> + [caret := UndoInterval first + hintText size.
> - [caret _ UndoInterval first + hintText size.
>   self selectInvisiblyFrom: UndoInterval first to: UndoInterval last.
> + input := hintText.
> + prior := selectorOrNil].
> - input _ hintText.
> - prior _ selectorOrNil].
>   (input size ~= 0 and: [sym ~~ nil or:
> + [(sym := Symbol thatStarts: input string skipping: prior) ~~ nil]])
> - [(sym _ Symbol thatStarts: input string skipping: prior) ~~ nil]])
>   ifTrue: "found something to offer"
> + [newStart := self startIndex.
> + outStream := WriteStream on: (String new: 2 * sym size).
> + 1 to: (kwds := sym keywords) size do:
> - [newStart _ self startIndex.
> - outStream _ WriteStream on: (String new: 2 * sym size).
> - 1 to: (kwds _ sym keywords) size do:
>   [:i |
>   outStream nextPutAll: (kwds at: i).
> + i = 1 ifTrue: [caret := newStart + outStream contents size + 1].
> - i = 1 ifTrue: [caret _ newStart + outStream contents size + 1].
>   outStream nextPutAll:
>   (i < kwds size ifTrue: ['  '] ifFalse: [' '])].
> + UndoSelection := input.
> - UndoSelection _ input.
>   self deselect; zapSelectionWith: outStream contents asText.
>   self undoer: #undoQuery:lastOffering: with: input with: sym]
>   ifFalse: "no more matches"
>   [firstTime ifFalse: "restore original text & set up for a redo"
> + [UndoSelection := self selection.
> - [UndoSelection _ self selection.
>   self deselect; zapSelectionWith: input.
>   self undoer: #completeSymbol:lastOffering: with: input with: prior.
> + Undone := true].
> - Undone _ true].
>   morph flash].
>   self selectAt: caret!
>
> Item was changed:
>  ----- Method: SmalltalkEditor class>>initializeShiftCmdKeyShortcuts (in category 'keyboard shortcut tables') -----
>  initializeShiftCmdKeyShortcuts
>   "Initialize the shift-command-key (or control-key) shortcut table."
>   "NOTE: if you don't know what your keyboard generates, use Sensor kbdTest"
>   "wod 11/3/1998: Fix setting of cmdMap for shifted keys to actually use the
>   capitalized versions of the letters.
>   TPR 2/18/99: add the plain ascii values back in for those VMs that don't return the shifted values."
>
>   "SmalltalkEditor initialize"
>
>   | cmds |
>   super initializeShiftCmdKeyShortcuts.
>
> + cmds := #(
> - cmds _ #(
>   $a argAdvance:
>   $b browseItHere:
>   $e methodStringsContainingIt:
>   $f displayIfFalse:
>   $g fileItIn:
>   $i exploreIt:
>   $n referencesToIt:
>   $t displayIfTrue:
>   $v pasteInitials:
>   $w methodNamesContainingIt:
>   ).
>   1 to: cmds size by: 2 do: [ :i |
>   shiftCmdActions at: ((cmds at: i) asciiValue + 1) put: (cmds at: i + 1). "plain keys"
>   shiftCmdActions at: ((cmds at: i) asciiValue - 32 + 1) put: (cmds at: i + 1). "shifted keys"
>   shiftCmdActions at: ((cmds at: i) asciiValue - 96 + 1) put: (cmds at: i + 1). "ctrl keys"
>   ].!
>
> Item was changed:
>  ----- Method: TextEditor>>crWithIndent: (in category 'typing/selecting keys') -----
>  crWithIndent: characterStream
>   "Replace the current text selection with CR followed by as many tabs
>   as on the current line (+/- bracket count) -- initiated by Shift-Return."
>   | char s i tabCount |
>   sensor keyboard. "flush character"
> + s := paragraph string.
> + i := self stopIndex.
> + tabCount := 0.
> + [(i := i-1) > 0 and: [(char := s at: i) ~= Character cr]]
> - s _ paragraph string.
> - i _ self stopIndex.
> - tabCount _ 0.
> - [(i _ i-1) > 0 and: [(char _ s at: i) ~= Character cr]]
>   whileTrue:  "Count tabs and brackets (but not a leading bracket)"
> + [(char = Character tab and: [i < s size and: [(s at: i+1) ~= $[ ]]) ifTrue: [tabCount := tabCount + 1].
> + char = $[ ifTrue: [tabCount := tabCount + 1].
> + char = $] ifTrue: [tabCount := tabCount - 1]].
> - [(char = Character tab and: [i < s size and: [(s at: i+1) ~= $[ ]]) ifTrue: [tabCount _ tabCount + 1].
> - char = $[ ifTrue: [tabCount _ tabCount + 1].
> - char = $] ifTrue: [tabCount _ tabCount - 1]].
>   characterStream crtab: tabCount.  "Now inject CR with tabCount tabs"
>   ^ false!
>
> Item was changed:
>  ----- Method: Editor>>selectWord (in category 'new selection') -----
>  selectWord
>   "Select delimited text or word--the result of double-clicking."
>
>   | openDelimiter closeDelimiter direction match level leftDelimiters rightDelimiters
>   string here hereChar start stop |
> + string := self string.
> + here := self pointIndex.
> - string _ self string.
> - here _ self pointIndex.
>   (here between: 2 and: string size)
>   ifFalse: ["if at beginning or end, select entire string"
>   ^self selectFrom: 1 to: string size].
> + leftDelimiters := '([{<''"
> - leftDelimiters _ '([{<''"
>  '.
> + rightDelimiters := ')]}>''"
> - rightDelimiters _ ')]}>''"
>  '.
> + openDelimiter := string at: here - 1.
> + match := leftDelimiters indexOf: openDelimiter.
> - openDelimiter _ string at: here - 1.
> - match _ leftDelimiters indexOf: openDelimiter.
>   match > 0
>   ifTrue:
>   ["delimiter is on left -- match to the right"
> + start := here.
> + direction := 1.
> + here := here - 1.
> + closeDelimiter := rightDelimiters at: match]
> - start _ here.
> - direction _ 1.
> - here _ here - 1.
> - closeDelimiter _ rightDelimiters at: match]
>   ifFalse:
> + [openDelimiter := string at: here.
> + match := rightDelimiters indexOf: openDelimiter.
> - [openDelimiter _ string at: here.
> - match _ rightDelimiters indexOf: openDelimiter.
>   match > 0
>   ifTrue:
>   ["delimiter is on right -- match to the left"
> + stop := here - 1.
> + direction := -1.
> + closeDelimiter := leftDelimiters at: match]
> - stop _ here - 1.
> - direction _ -1.
> - closeDelimiter _ leftDelimiters at: match]
>   ifFalse: ["no delimiters -- select a token"
> + direction := -1]].
> + level := 1.
> - direction _ -1]].
> - level _ 1.
>   [level > 0 and: [direction > 0
>   ifTrue: [here < string size]
>   ifFalse: [here > 1]]]
>   whileTrue:
> + [hereChar := string at: (here := here + direction).
> - [hereChar _ string at: (here _ here + direction).
>   match = 0
>   ifTrue: ["token scan goes left, then right"
>   hereChar tokenish
>   ifTrue: [here = 1
>   ifTrue:
> + [start := 1.
> - [start _ 1.
>   "go right if hit string start"
> + direction := 1]]
> - direction _ 1]]
>   ifFalse: [direction < 0
>   ifTrue:
> + [start := here + 1.
> - [start _ here + 1.
>   "go right if hit non-token"
> + direction := 1]
> + ifFalse: [level := 0]]]
> - direction _ 1]
> - ifFalse: [level _ 0]]]
>   ifFalse: ["bracket match just counts nesting level"
>   hereChar = closeDelimiter
> + ifTrue: [level := level - 1"leaving nest"]
> - ifTrue: [level _ level - 1"leaving nest"]
>   ifFalse: [hereChar = openDelimiter
> + ifTrue: [level := level + 1"entering deeper nest"]]]].
> - ifTrue: [level _ level + 1"entering deeper nest"]]]].
>
> + level > 0 ifTrue: ["in case ran off string end" here := here + direction].
> - level > 0 ifTrue: ["in case ran off string end" here _ here + direction].
>   direction > 0
>   ifTrue: [self selectFrom: start to: here - 1]
>   ifFalse: [self selectFrom: here + 1 to: stop]!
>
> Item was changed:
>  ----- Method: TextEditor>>exchangeWith: (in category 'private') -----
>  exchangeWith: prior
>   "If the prior selection is non-overlapping and legal, exchange the text of
>   it with the current selection and leave the currently selected text selected
>   in the location of the prior selection (or leave a caret after a non-caret if it was
>   exchanged with a caret).  If both selections are carets, flash & do nothing.
>   Don't affect the paste buffer.  Undoer: itself; Redoer: Undoer."
>
>   | start stop before selection priorSelection delta altInterval |
> + start := self startIndex.
> + stop := self stopIndex - 1.
> - start _ self startIndex.
> - stop _ self stopIndex - 1.
>   ((prior first <= prior last) | (start <= stop) "Something to exchange" and:
>   [self isDisjointFrom: prior])
>   ifTrue:
> + [before := prior last < start.
> + selection := self selection.
> + priorSelection := paragraph text copyFrom: prior first to: prior last.
> - [before _ prior last < start.
> - selection _ self selection.
> - priorSelection _ paragraph text copyFrom: prior first to: prior last.
>
> + delta := before ifTrue: [0] ifFalse: [priorSelection size - selection size].
> - delta _ before ifTrue: [0] ifFalse: [priorSelection size - selection size].
>   self zapSelectionWith: priorSelection.
>   self selectFrom: prior first + delta to: prior last + delta.
>
> + delta := before ifTrue: [stop - prior last] ifFalse: [start - prior first].
> - delta _ before ifTrue: [stop - prior last] ifFalse: [start - prior first].
>   self zapSelectionWith: selection.
> + altInterval := prior first + delta to: prior last + delta.
> - altInterval _ prior first + delta to: prior last + delta.
>   self undoer: #exchangeWith: with: altInterval.
>   "If one was a caret, make it otherInterval & leave the caret after the other"
>   prior first > prior last ifTrue: [self selectAt: UndoInterval last + 1].
> + otherInterval := start > stop
> - otherInterval _ start > stop
>   ifTrue: [self selectAt: altInterval last + 1. UndoInterval]
>   ifFalse: [altInterval]]
>   ifFalse:
>   [morph flash]!
>
> Item was changed:
>  ----- Method: TextEditor>>shiftEnclose: (in category 'editing keys') -----
>  shiftEnclose: characterStream
>   "Insert or remove bracket characters around the current selection.
>   Flushes typeahead."
>
>   | char left right startIndex stopIndex oldSelection which text |
> + char := sensor keyboard.
> + char = $9 ifTrue: [ char := $( ].
> + char = $, ifTrue: [ char := $< ].
> + char = $[ ifTrue: [ char := ${ ].
> + char = $' ifTrue: [ char := $" ].
> + char asciiValue = 27 ifTrue: [ char := ${ ]. "ctrl-["
> - char _ sensor keyboard.
> - char = $9 ifTrue: [ char _ $( ].
> - char = $, ifTrue: [ char _ $< ].
> - char = $[ ifTrue: [ char _ ${ ].
> - char = $' ifTrue: [ char _ $" ].
> - char asciiValue = 27 ifTrue: [ char _ ${ ]. "ctrl-["
>
>   self closeTypeIn.
> + startIndex := self startIndex.
> + stopIndex := self stopIndex.
> + oldSelection := self selection.
> + which := '([<{"''' indexOf: char ifAbsent: [1].
> + left := '([<{"''' at: which.
> + right := ')]>}"''' at: which.
> + text := paragraph text.
> - startIndex _ self startIndex.
> - stopIndex _ self stopIndex.
> - oldSelection _ self selection.
> - which _ '([<{"''' indexOf: char ifAbsent: [1].
> - left _ '([<{"''' at: which.
> - right _ ')]>}"''' at: which.
> - text _ paragraph text.
>   ((startIndex > 1 and: [stopIndex <= text size])
>   and: [ (text at: startIndex-1) = left and: [(text at: stopIndex) = right]])
>   ifTrue: [
>   "already enclosed; strip off brackets"
>   self selectFrom: startIndex-1 to: stopIndex.
>   self replaceSelectionWith: oldSelection]
>   ifFalse: [
>   "not enclosed; enclose by matching brackets"
>   self replaceSelectionWith:
>   (Text string: (String with: left), oldSelection string, (String with: right) attributes: emphasisHere).
>   self selectFrom: startIndex+1 to: stopIndex].
>   ^true!
>
> Item was changed:
>  ----- Method: Editor>>backWord: (in category 'typing/selecting keys') -----
>  backWord: characterStream
>   "If the selection is not a caret, delete it and leave it in the backspace buffer.
>   Else if there is typeahead, delete it.
>   Else, delete the word before the caret."
>
>   | startIndex |
>   sensor keyboard.
>   characterStream isEmpty
>   ifTrue:
>   [self hasCaret
>   ifTrue: "a caret, delete at least one character"
> + [startIndex := 1 max: self markIndex - 1.
> - [startIndex _ 1 max: self markIndex - 1.
>   [startIndex > 1 and:
>   [(self string at: startIndex - 1) tokenish]]
>   whileTrue:
> + [startIndex := startIndex - 1]]
> - [startIndex _ startIndex - 1]]
>   ifFalse: "a non-caret, just delete it"
> + [startIndex := self markIndex].
> - [startIndex _ self markIndex].
>   self backTo: startIndex]
>   ifFalse:
>   [characterStream reset].
>   ^false!
>
> Item was changed:
>  ----- Method: TextEditor>>indent:fromStream:toStream: (in category 'private') -----
>  indent: delta fromStream: inStream toStream: outStream
>   "Append the contents of inStream to outStream, adding or deleting delta or -delta
>   tabs at the beginning, and after every CR except a final CR.  Do not add tabs
>   to totally empty lines, and be sure nothing but tabs are removed from lines."
>
>   | ch skip cr tab prev atEnd |
> + cr := Character cr.
> + tab := Character tab.
> - cr _ Character cr.
> - tab _ Character tab.
>   delta > 0
>   ifTrue: "shift right"
> + [prev := cr.
> + [ch := (atEnd := inStream atEnd) ifTrue: [cr] ifFalse: [inStream next].
> - [prev _ cr.
> - [ch _ (atEnd _ inStream atEnd) ifTrue: [cr] ifFalse: [inStream next].
>    (prev == cr and: [ch ~~ cr]) ifTrue:
>   [delta timesRepeat: [outStream nextPut: tab]].
>    atEnd]
>   whileFalse:
>   [outStream nextPut: ch.
> + prev := ch]]
> - prev _ ch]]
>   ifFalse: "shift left"
> + [skip := delta. "a negative number"
> - [skip _ delta. "a negative number"
>   [inStream atEnd] whileFalse:
> + [((ch := inStream next) == tab and: [skip < 0]) ifFalse:
> - [((ch _ inStream next) == tab and: [skip < 0]) ifFalse:
>   [outStream nextPut: ch].
> + skip := ch == cr ifTrue: [delta] ifFalse: [skip + 1]]]!
> - skip _ ch == cr ifTrue: [delta] ifFalse: [skip + 1]]]!
>
> Item was changed:
>  ----- Method: TextEditor>>prettyPrint: (in category 'menu messages') -----
>  prettyPrint: decorated
>   "Reformat the contents of the receiver's view (a Browser)."
>
>   | selectedClass newText |
>   model selectedMessageName ifNil: [^ morph flash].
> + selectedClass := model selectedClassOrMetaClass.
> + newText := selectedClass compilerClass new
> - selectedClass _ model selectedClassOrMetaClass.
> - newText _ selectedClass compilerClass new
>   format: self text
>   in: selectedClass
>   notifying: self
>   decorated: decorated.
>   newText ifNotNil:
>   [self deselect; selectInvisiblyFrom: 1 to: paragraph text size.
>   self replaceSelectionWith: (newText asText makeSelectorBoldIn: selectedClass).
>   self selectAt: 1]!
>
> Item was changed:
>  ----- Method: TextLine>>justifiedPadFor:font: (in category 'scanning') -----
>  justifiedPadFor: spaceIndex font: aFont
>   "Compute the width of pad for a given space in a line of justified text."
>
>   | pad |
>   internalSpaces = 0 ifTrue: [^0].
>   ^(aFont notNil and:[aFont isSubPixelPositioned])
>   ifTrue:[paddingWidth * 1.0 / internalSpaces]
>   ifFalse:[
> + pad := paddingWidth // internalSpaces.
> - pad _ paddingWidth // internalSpaces.
>   spaceIndex <= (paddingWidth \\ internalSpaces)
>   ifTrue: [pad + 1]
>   ifFalse: [pad]]
>   !
>
> Item was changed:
>  ----- Method: TextEditor>>selectedSymbol (in category 'menu messages') -----
>  selectedSymbol
>   "Return the currently selected symbol, or nil if none.  Spaces, tabs and returns are ignored"
>
>   | aString |
>   self hasCaret ifTrue: [^ nil].
> + aString := self selection string copyWithoutAll:
> - aString _ self selection string copyWithoutAll:
>   {Character space.  Character cr.  Character tab}.
>   aString size = 0 ifTrue: [^ nil].
>   Symbol hasInterned: aString  ifTrue: [:sym | ^ sym].
>
>   ^ nil!
>
> Item was changed:
>  ----- Method: TextEditor>>explainTemp: (in category 'explain') -----
>  explainTemp: string
>   "Is string the name of a temporary variable (or block argument variable)?"
>
>   | selectedClass tempNames i reply methodNode method msg |
>   (model respondsTo: #selectedMessageName) ifFalse: [^ nil].
> + (msg := model selectedMessageName) ifNil: [^nil]. "not in a message"
> + selectedClass := model selectedClassOrMetaClass.
> + tempNames := selectedClass parserClass new
> - (msg _ model selectedMessageName) ifNil: [^nil]. "not in a message"
> - selectedClass _ model selectedClassOrMetaClass.
> - tempNames _ selectedClass parserClass new
>   parseArgsAndTemps: model selectedMessage notifying: nil.
> + method := selectedClass compiledMethodAt: msg.
> + (i := tempNames findFirst: [:each | each = string]) = 0 ifTrue: [
> - method _ selectedClass compiledMethodAt: msg.
> - (i _ tempNames findFirst: [:each | each = string]) = 0 ifTrue: [
>   (method numTemps > tempNames size)
>   ifTrue:
>   ["It must be an undeclared block argument temporary"
> + methodNode := selectedClass compilerClass new
> - methodNode _ selectedClass compilerClass new
>   parse: model selectedMessage
>   in: selectedClass
>   notifying: nil.
> + tempNames := methodNode tempNames]
> - tempNames _ methodNode tempNames]
>   ifFalse: [^nil]].
> + (i := tempNames findFirst: [:each | each = string]) > 0 ifTrue: [i > method numArgs
> + ifTrue: [reply := '"is a temporary variable in this method"']
> + ifFalse: [reply := '"is an argument to this method"']].
> - (i _ tempNames findFirst: [:each | each = string]) > 0 ifTrue: [i > method numArgs
> - ifTrue: [reply _ '"is a temporary variable in this method"']
> - ifFalse: [reply _ '"is an argument to this method"']].
>   ^reply!
>
> Item was changed:
>  ----- Method: TextEditor>>undoCutCopy: (in category 'undoers') -----
>  undoCutCopy: oldPasteBuffer
>   "Undo of a cut, copy, or any edit that changed CurrentSelection.  Be sure
>   undo-copy does not lock the model.  Redoer: itself, so never isRedoing."
>
>   | recentCut |
> + recentCut := self clipboardText.
> - recentCut _ self clipboardText.
>   UndoSelection size = UndoInterval size
>   ifFalse: [self replaceSelectionWith: UndoSelection].
>   self clipboardTextPut: oldPasteBuffer.
>   self undoer: #undoCutCopy: with: recentCut!
>
> Item was changed:
>  ----- Method: TextEditor>>explainInst: (in category 'explain') -----
>  explainInst: string
>   "Is string an instance variable of this class?"
>   | classes cls |
>
>   (model respondsTo: #selectedClassOrMetaClass) ifTrue: [
> + cls := model selectedClassOrMetaClass].
> - cls _ model selectedClassOrMetaClass].
>   cls ifNil: [^ nil].  "no class known"
> + classes := (Array with: cls)
> - classes _ (Array with: cls)
>   , cls allSuperclasses.
> + classes := classes detect: [:each | (each instVarNames
> - classes _ classes detect: [:each | (each instVarNames
>   detect: [:name | name = string] ifNone: [])
>   ~~ nil] ifNone: [^nil].
> + classes := classes printString.
> - classes _ classes printString.
>   ^ '"is an instance variable of the receiver; defined in class ' , classes ,
>   '"\' withCRs , classes , ' systemNavigation browseAllAccessesTo: ''' , string , ''' from: ', classes, '.'!
>
> Item was changed:
>  ----- Method: TextEditor>>makeCapitalized: (in category 'editing keys') -----
>  makeCapitalized: characterStream
>   "Force the current selection to uppercase.  Triggered by Cmd-X."
>   | prev |
>   sensor keyboard. "flush the triggering cmd-key character"
> + prev := $-.  "not a letter"
> - prev _ $-.  "not a letter"
>   self replaceSelectionWith: (Text fromString:
>   (self selection string collect:
> + [:c | prev := prev isLetter ifTrue: [c asLowercase] ifFalse: [c asUppercase]])).
> - [:c | prev _ prev isLetter ifTrue: [c asLowercase] ifFalse: [c asUppercase]])).
>   ^ true!
>
> Item was changed:
>  ----- Method: TextEditor>>blinkPrevParen (in category 'parenblinking') -----
>  blinkPrevParen
>   | openDelimiter closeDelimiter level string here hereChar |
> + string := paragraph text string.
> + here := pointBlock stringIndex.
> + openDelimiter := sensor keyboardPeek.
> + closeDelimiter := '([{' at: (')]}' indexOf: openDelimiter).
> + level := 1.
> - string _ paragraph text string.
> - here _ pointBlock stringIndex.
> - openDelimiter _ sensor keyboardPeek.
> - closeDelimiter _ '([{' at: (')]}' indexOf: openDelimiter).
> - level _ 1.
>   [level > 0 and: [here > 2]]
>   whileTrue:
> + [hereChar := string at: (here := here - 1).
> - [hereChar _ string at: (here _ here - 1).
>   hereChar = closeDelimiter
>   ifTrue:
> + [level := level - 1.
> - [level _ level - 1.
>   level = 0
>   ifTrue: [^ self blinkParenAt: here]]
>   ifFalse:
>   [hereChar = openDelimiter
> + ifTrue: [level := level + 1]]]!
> - ifTrue: [level _ level + 1]]]!
>
> Item was changed:
>  ----- Method: TextEditor>>doneTyping (in category 'typing support') -----
>  doneTyping
> + beginTypeInBlock := nil!
> - beginTypeInBlock _ nil!
>
> Item was changed:
>  ----- Method: TextEditor>>explainChar: (in category 'explain') -----
>  explainChar: string
>   "Does string start with a special character?"
>
>   | char |
> + char := string at: 1.
> - char _ string at: 1.
>   char = $. ifTrue: [^'"Period marks the end of a Smalltalk statement.  A period in the middle of a number means a decimal point.  (The number is an instance of class Float)."'].
>   char = $' ifTrue: [^'"The characters between two single quotes are made into an instance of class String"'].
>   char = $" ifTrue: [^'"Double quotes enclose a comment.  Smalltalk ignores everything between double quotes."'].
>   char = $# ifTrue: [^'"The characters following a hash mark are made into an instance of class Symbol.  If parenthesis follow a hash mark, an instance of class Array is made.  It contains literal constants."'].
>   (char = $( or: [char = $)]) ifTrue: [^'"Expressions enclosed in parenthesis are evaluated first"'].
>   (char = $[ or: [char = $]]) ifTrue: [^'"The code inside square brackets is an unevaluated block of code.  It becomes an instance of BlockContext and is usually passed as an argument."'].
>   (char = ${ or: [char = $}]) ifTrue: [^ '"A sequence of expressions separated by periods, when enclosed in curly braces, are evaluated to yield the elements of a new Array"'].
>   (char = $< or: [char = $>]) ifTrue: [^'"<primitive: xx> means that this method is usually preformed directly by the virtual machine.  If this method is primitive, its Smalltalk code is executed only when the primitive fails."'].
>   char = $^ ifTrue: [^'"Uparrow means return from this method.  The value returned is the expression following the ^"'].
>   char = $| ifTrue: [^'"Vertical bars enclose the names of the temporary variables used in this method.  In a block, the vertical bar separates the argument names from the rest of the code."'].
>   char = $_ ifTrue: [^'"Left arrow means assignment.  The value of the expression after the left arrow is stored into the variable before it."'].
>   char = $; ifTrue: [^'"Semicolon means cascading.  The message after the semicolon is sent to the same object which received the message before the semicolon."'].
>   char = $: ifTrue: [^'"A colon at the end of a keyword means that an argument is expected to follow.  Methods which take more than one argument have selectors with more than one keyword.  (One keyword, ending with a colon, appears before each argument).', '\\' withCRs, 'A colon before a variable name just inside a block means that the block takes an agrument.  (When the block is evaluated, the argument will be assigned to the variable whose name appears after the colon)."'].
>   char = $$ ifTrue: [^'"The single character following a dollar sign is made into an instance of class Character"'].
>   char = $- ifTrue: [^'"A minus sign in front of a number means a negative number."'].
>   char = $e ifTrue: [^'"An e in the middle of a number means that the exponent follows."'].
>   char = $r ifTrue: [^'"An r in the middle of a bunch of digits is an instance of Integer expressed in a certain radix.  The digits before the r denote the base and the digits after it express a number in that base."'].
>   char = Character space ifTrue: [^'"the space Character"'].
>   char = Character tab ifTrue: [^'"the tab Character"'].
>   char = Character cr ifTrue: [^'"the carriage return Character"'].
>   ^nil!
>
> Item was changed:
>  ----- Method: TextEditor>>hiddenInfo (in category 'editing keys') -----
>  hiddenInfo
>   "In TextLinks, TextDoits, TextColor, and TextURLs, there is hidden info.  Return the entire string that was used by Cmd-6 to create this text attribute.  Usually enclosed in < >."
>
>   | attrList |
> + attrList := paragraph text attributesAt: (self pointIndex + self markIndex)//2.
> - attrList _ paragraph text attributesAt: (self pointIndex + self markIndex)//2.
>   attrList do: [:attr |
>   (attr isKindOf: TextAction) ifTrue:
>   [^ self selection asString, '<', attr info, '>']].
>   "If none of the above"
>   attrList do: [:attr |
>   attr class == TextColor ifTrue:
>   [^ self selection asString, '<', attr color printString, '>']].
>   ^ self selection asString, '[No hidden info]'!
>
> Item was changed:
>  ----- Method: TextEditor>>selectPrecedingIdentifier (in category 'new selection') -----
>  selectPrecedingIdentifier
>   "Invisibly select the identifier that ends at the end of the selection, if any."
>
>   | string sep stop tok |
> + tok := false.
> + string := paragraph text string.
> + stop := self stopIndex - 1.
> + [stop > 0 and: [(string at: stop) isSeparator]] whileTrue: [stop := stop - 1].
> + sep := stop.
> + [sep > 0 and: [(string at: sep) tokenish]] whileTrue: [tok := true. sep := sep - 1].
> - tok _ false.
> - string _ paragraph text string.
> - stop _ self stopIndex - 1.
> - [stop > 0 and: [(string at: stop) isSeparator]] whileTrue: [stop _ stop - 1].
> - sep _ stop.
> - [sep > 0 and: [(string at: sep) tokenish]] whileTrue: [tok _ true. sep _ sep - 1].
>   tok ifTrue: [self selectInvisiblyFrom: sep + 1 to: stop]!
>
> Item was changed:
>  ----- Method: TextEditor>>fileItIn (in category 'menu messages') -----
>  fileItIn
>   "Make a Stream on the text selection and fileIn it.
>   1/24/96 sw: moved here from FileController; this function can be useful from any text window that shows stuff in chunk format"
>
>   | selection |
> + selection := self selection.
> - selection _ self selection.
>   (ReadWriteStream on: selection string from: 1 to: selection size) fileIn
>  !
>
> Item was changed:
>  ----- Method: TextEditor>>changeLfToCr: (in category 'editing keys') -----
>  changeLfToCr: characterStream
>   "Replace all LFs by CRs.
>   Triggered by Cmd-U -- useful when getting code from FTP sites
>   jmv- Modified to als change crlf by cr"
>
>   | fixed |
>   sensor keyboard. "flush the triggering cmd-key character"
>
> + fixed := self selection string.
> + fixed := fixed copyReplaceAll: String crlf with: String cr.
> + fixed := fixed copyReplaceAll: String lf with: String cr.
> - fixed _ self selection string.
> - fixed _ fixed copyReplaceAll: String crlf with: String cr.
> - fixed _ fixed copyReplaceAll: String lf with: String cr.
>   self replaceSelectionWith: (Text fromString: fixed).
>   ^ true!
>
> Item was changed:
>  ----- Method: TextEditor>>correctFrom:to:with: (in category 'new selection') -----
>  correctFrom: start to: stop with: aString
>   "Make a correction in the model that the user has authorised from somewhere else in the system (such as from the compilier).  The user's selection is not changed, only corrected."
>   | wasShowing userSelection delta loc |
>   aString = '#insert period' ifTrue:
> + [loc := start.
> + [(loc := loc-1)>0 and: [(paragraph text string at: loc) isSeparator]]
> + whileTrue: [loc := loc-1].
> - [loc _ start.
> - [(loc _ loc-1)>0 and: [(paragraph text string at: loc) isSeparator]]
> - whileTrue: [loc _ loc-1].
>   ^ self correctFrom: loc+1 to: loc with: '.'].
> + (wasShowing := selectionShowing) ifTrue: [ self reverseSelection ].
> + userSelection := self selectionInterval.
> - (wasShowing _ selectionShowing) ifTrue: [ self reverseSelection ].
> - userSelection _ self selectionInterval.
>
>   self selectInvisiblyFrom: start to: stop.
>   self replaceSelectionWith: aString asText.
>
> + delta := aString size - (stop - start + 1).
> - delta _ aString size - (stop - start + 1).
>   self selectInvisiblyFrom:
>   userSelection first + (userSelection first > start ifFalse: [ 0 ] ifTrue: [ delta ])
>   to: userSelection last + (userSelection last > start ifFalse: [ 0 ] ifTrue: [ delta ]).
>   wasShowing ifTrue: [ self reverseSelection ].
>  !
>
> Item was changed:
>  ----- Method: Morph>>openModal: (in category 'polymorph') -----
>  openModal: aSystemWindow
>   "Open the given window locking the receiver until it is dismissed.
>   Answer the system window.
>   Restore the original keyboard focus when closed."
>
>   |area mySysWin keyboardFocus|
> + keyboardFocus := self activeHand keyboardFocus.
> - keyboardFocus _ self activeHand keyboardFocus.
>   mySysWin := self isSystemWindow ifTrue: [self] ifFalse: [self ownerThatIsA: SystemWindow].
>   mySysWin ifNil: [mySysWin := self].
>   mySysWin modalLockTo: aSystemWindow.
>   ( RealEstateAgent respondsTo: #reduceByFlaps: )
>   ifTrue:[
>   area := RealEstateAgent reduceByFlaps: RealEstateAgent maximumUsableArea]
>   ifFalse:[
>   area := RealEstateAgent maximumUsableArea].
>   aSystemWindow extent: aSystemWindow initialExtent.
>   aSystemWindow position = (0@0)
>   ifTrue: [aSystemWindow
>   position: self activeHand position - (aSystemWindow extent // 2)].
>   aSystemWindow
>   bounds: (aSystemWindow bounds translatedToBeWithin: area).
>   [ToolBuilder default runModal: aSystemWindow openAsIs]
>   ensure: [mySysWin modalUnlockFrom: aSystemWindow.
>   self activeHand newKeyboardFocus: keyboardFocus].
>   ^aSystemWindow!
>
> Item was changed:
>  ----- Method: TextEditor>>againOnce: (in category 'private') -----
>  againOnce: indices
>   "Find the next occurrence of FindText.  If none, answer false.
>   Append the start index of the occurrence to the stream indices, and, if
>   ChangeText is not the same object as FindText, replace the occurrence by it.
>   Note that the search is case-sensitive for replacements, otherwise not."
>
>   | where |
> + where := paragraph text findString: FindText startingAt: self stopIndex
> - where _ paragraph text findString: FindText startingAt: self stopIndex
>   caseSensitive: ((ChangeText ~~ FindText) or: [Preferences caseSensitiveFinds]).
>   where = 0 ifTrue: [^ false].
>   self deselect; selectInvisiblyFrom: where to: where + FindText size - 1.
>   ChangeText ~~ FindText ifTrue: [self zapSelectionWith: ChangeText].
>   indices nextPut: where.
>   ^ true!
>
> Item was changed:
>  ----- Method: TextEditor>>pageHeight (in category 'private') -----
>  pageHeight
>   | howManyLines visibleHeight totalHeight ratio |
> + howManyLines := paragraph numberOfLines.
> + visibleHeight := self visibleHeight.
> + totalHeight := self totalTextHeight.
> + ratio := visibleHeight / totalHeight.
> - howManyLines _ paragraph numberOfLines.
> - visibleHeight _ self visibleHeight.
> - totalHeight _ self totalTextHeight.
> - ratio _ visibleHeight / totalHeight.
>   ^(ratio * howManyLines) rounded - 2!
>
> Item was changed:
>  ----- Method: TextEditor>>againOrSame:many: (in category 'private') -----
>  againOrSame: useOldKeys many: many
>   "Subroutine of search: and again.  If useOldKeys, use same FindText and ChangeText as before.  If many is true, do it repeatedly.  Created 1/26/96 sw by adding the many argument to #againOrSame."
>
>   |  home indices wasTypedKey |
>
> + home := self selectionInterval.  "what was selected when 'again' was invoked"
> - home _ self selectionInterval.  "what was selected when 'again' was invoked"
>
>   "If new keys are to be picked..."
>   useOldKeys ifFalse: "Choose as FindText..."
> + [FindText := UndoSelection.  "... the last thing replaced."
> - [FindText _ UndoSelection.  "... the last thing replaced."
>   "If the last command was in another paragraph, ChangeText is set..."
>   paragraph == UndoParagraph ifTrue: "... else set it now as follows."
>   [UndoInterval ~= home ifTrue: [self selectInterval: UndoInterval]. "blink"
> + ChangeText := ((UndoMessage sends: #undoCutCopy:) and: [self hasSelection])
> - ChangeText _ ((UndoMessage sends: #undoCutCopy:) and: [self hasSelection])
>   ifTrue: [FindText] "== objects signal no model-locking by 'undo copy'"
>   ifFalse: [self selection]]]. "otherwise, change text is last-replaced text"
>
> + (wasTypedKey := FindText size = 0)
> - (wasTypedKey _ FindText size = 0)
>   ifTrue: "just inserted at a caret"
> + [home := self selectionInterval.
> - [home _ self selectionInterval.
>   self replaceSelectionWith: self nullText.  "delete search key..."
> + FindText := ChangeText] "... and search for it, without replacing"
> - FindText _ ChangeText] "... and search for it, without replacing"
>   ifFalse: "Show where the search will start"
>   [home last = self selectionInterval last ifFalse:
>   [self selectInterval: home]].
>
>   "Find and Change, recording start indices in the array"
> + indices := WriteStream on: (Array new: 20). "an array to store change locs"
> - indices _ WriteStream on: (Array new: 20). "an array to store change locs"
>   [(self againOnce: indices) & many] whileTrue. "<-- this does the work"
>   indices isEmpty ifTrue:  "none found"
>   [self flash.
>   wasTypedKey ifFalse: [^self]].
>
>   (many | wasTypedKey) ifFalse: "after undo, select this replacement"
> + [home := self startIndex to:
> - [home _ self startIndex to:
>   self startIndex + UndoSelection size - 1].
>
>   self undoer: #undoAgain:andReselect:typedKey: with: indices contents with: home with: wasTypedKey!
>
> Item was changed:
>  ----- Method: Editor>>previousWord: (in category 'private') -----
>  previousWord: position
>   | string index |
> + string := self string.
> + index := position.
> - string _ self string.
> - index _ position.
>   [(index between: 1 and: string size) and: [(string at: index) isAlphaNumeric not]]
> + whileTrue: [index := index - 1].
> - whileTrue: [index _ index - 1].
>   [(index between: 1 and: string size) and: [(string at: index) isAlphaNumeric]]
> + whileTrue: [index := index - 1].
> - whileTrue: [index _ index - 1].
>   ^ index + 1!
>
> Item was changed:
>  ----- 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."
>
>   beginTypeInBlock ~~ nil ifTrue: [^self zapSelectionWith: aText]. "called from old code"
> + UndoSelection := self selection.
> - UndoSelection _ self selection.
>   self zapSelectionWith: aText.
>   self undoer: #undoReplace!
>
> Item was changed:
>  ----- Method: TextEditor>>changeEmphasis: (in category 'editing keys') -----
>  changeEmphasis: characterStream
>   "Change the emphasis of the current selection or prepare to accept characters with the change in emphasis. Emphasis change amounts to a font change.  Keeps typeahead."
>
>   "control 0..9 -> 0..9"
>
>   | keyCode attribute oldAttributes index thisSel colors extras |
>   keyCode := ('0123456789-=' indexOf: sensor keyboard ifAbsent: [1]) - 1.
>   oldAttributes := paragraph text attributesAt: self pointIndex.
>   thisSel := self selection.
>
>   "Decipher keyCodes for Command 0-9..."
>   (keyCode between: 1 and: 5)
>   ifTrue: [attribute := TextFontChange fontNumber: keyCode].
>
>   keyCode = 6
>   ifTrue: [
>   colors := #(#black #magenta #red #yellow #green #blue #cyan #white).
>   extras := self emphasisExtras.
>   index := UIManager default chooseFrom:colors , #('choose color...' ), extras
>   lines: (Array with: colors size + 1).
>   index = 0 ifTrue: [^true].
>   index <= colors size
>   ifTrue: [attribute := TextColor color: (Color perform: (colors at: index))]
>   ifFalse: [
>   index := index - colors size - 1. "Re-number!!!!!!"
>   index = 0
>   ifTrue: [attribute := self chooseColor]
>   ifFalse:[^self handleEmphasisExtra: index with: characterStream] "handle an extra"]].
>   (keyCode between: 7 and: 11)
>   ifTrue: [
>   sensor leftShiftDown
>   ifTrue: [
>   keyCode = 10 ifTrue: [attribute := TextKern kern: -1].
>   keyCode = 11 ifTrue: [attribute := TextKern kern: 1]]
>   ifFalse: [
>   attribute := TextEmphasis
>   perform: (#(#bold #italic #narrow #underlined #struckOut) at: keyCode - 6).
>   oldAttributes
>   do: [:att | (att dominates: attribute) ifTrue: [attribute turnOff]]]].
>   keyCode = 0 ifTrue: [attribute := TextEmphasis normal].
>   attribute ifNotNil: [
>   thisSel size = 0
>   ifTrue: [
>   "only change emphasisHere while typing"
>   self insertTypeAhead: characterStream.
> + emphasisHere := Text addAttribute: attribute toArray: oldAttributes ]
> - emphasisHere _ Text addAttribute: attribute toArray: oldAttributes ]
>   ifFalse: [
>   self replaceSelectionWith: (thisSel asText addAttribute: attribute) ]].
>   ^true!
>
> Item was changed:
>  ----- Method: TextEditor>>cursorEnd: (in category 'nonediting/nontyping keys') -----
>  cursorEnd: characterStream
>
>   "Private - Move cursor end of current line."
>   | string |
>   self closeTypeIn: characterStream.
> + string := paragraph text string.
> - string _ paragraph text string.
>   self
>   moveCursor:
>   [:position | Preferences wordStyleCursorMovement
>   ifTrue:[| targetLine |
> + targetLine := paragraph lines at:(paragraph lineIndexOfCharacterIndex: position).
> - targetLine _ paragraph lines at:(paragraph lineIndexOfCharacterIndex: position).
>   targetLine = paragraph lastLine
>   ifTrue:[targetLine last + 1]
>   ifFalse:[targetLine last]]
>   ifFalse:[
>   string
>   indexOf: Character cr
>   startingAt: position
>   ifAbsent:[string size + 1]]]
>   forward: true
>   specialBlock:[:dummy | string size + 1].
>   ^true!
>
> Item was changed:
>  ----- Method: TextEditor>>undo (in category 'menu messages') -----
>  undo
>   "Reset the state of the paragraph prior to the previous edit.
>   If another ParagraphEditor instance did that edit, UndoInterval is invalid;
>   just recover the contents of the undo-buffer at the start of the paragraph."
>
>   sensor flushKeyboard. "a way to flush stuck keys"
>   self closeTypeIn.
>
>   UndoParagraph == paragraph ifFalse: "Can't undo another paragraph's edit"
> + [UndoMessage := Message selector: #undoReplace.
> + UndoInterval := 1 to: 0.
> + Undone := true].
> - [UndoMessage _ Message selector: #undoReplace.
> - UndoInterval _ 1 to: 0.
> - Undone _ true].
>   UndoInterval ~= self selectionInterval ifTrue: "blink the actual target"
>   [self selectInterval: UndoInterval; deselect].
>
>   "Leave a signal of which phase is in progress"
> + UndoParagraph := Undone ifTrue: [#redoing] ifFalse: [#undoing].
> - UndoParagraph _ Undone ifTrue: [#redoing] ifFalse: [#undoing].
>   UndoMessage sentTo: self.
> + UndoParagraph := paragraph!
> - UndoParagraph _ paragraph!
>
> Item was changed:
>  ----- Method: TextEditor>>undoMessage:forRedo: (in category 'undo support') -----
>  undoMessage: aMessage forRedo: aBoolean
>   "Call this from an undoer/redoer to set up UndoMessage as the
>   corresponding redoer/undoer.  Also set up UndoParagraph, as well
>   as the state variable Undone.  It is assumed that UndoInterval has been
>   established (generally by zapSelectionWith:) and that UndoSelection has been
>   saved (generally by replaceSelectionWith: or replace:With:and:)."
>
> + self isDoing ifTrue: [UndoParagraph := paragraph].
> + UndoMessage := aMessage.
> + Undone := aBoolean!
> - self isDoing ifTrue: [UndoParagraph _ paragraph].
> - UndoMessage _ aMessage.
> - Undone _ aBoolean!
>
> Item was changed:
>  ----- Method: TextEditor>>inspectIt (in category 'do-its') -----
>  inspectIt
>   "1/13/96 sw: minor fixup"
>   | result |
> + result := self evaluateSelection.
> - result _ self evaluateSelection.
>   ((result isKindOf: FakeClassPool) or: [result == #failedDoit])
>   ifTrue: [morph flash]
>   ifFalse: [result inspect]!
>
> Item was changed:
>  ----- Method: Editor>>initialize (in category 'initialize-release') -----
>  initialize
>   "Initialize the state of the receiver. Subclasses should include 'super
>   initialize' when redefining this message to insure proper initialization."
>
> + sensor := InputSensor default!
> - sensor _ InputSensor default!
>
> Item was changed:
>  ----- 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 _ self selectionInterval.
>   undoInterval = xoldInterval ifFalse: [self selectInterval: xoldInterval].
> + UndoSelection := self selection.
> - UndoSelection _ self selection.
>   self zapSelectionWith: newText.
>   selectingBlock value.
> + otherInterval := self selectionInterval.
> - otherInterval _ self selectionInterval.
>   self undoer: #undoAndReselect:redoAndReselect: with: undoInterval with: otherInterval!
>
> Item was changed:
>  ----- Method: TextEditor>>stateArrayPut: (in category 'initialize-release') -----
>  stateArrayPut: stateArray
>   | sel |
> + ChangeText := stateArray at: 1.
> + FindText := stateArray at: 2.
> + UndoInterval := stateArray at: 3.
> + UndoMessage := stateArray at: 4.
> + UndoParagraph := stateArray at: 5.
> + UndoSelection := stateArray at: 6.
> + Undone := stateArray at: 7.
> + sel := stateArray at: 8.
> - ChangeText _ stateArray at: 1.
> - FindText _ stateArray at: 2.
> - UndoInterval _ stateArray at: 3.
> - UndoMessage _ stateArray at: 4.
> - UndoParagraph _ stateArray at: 5.
> - UndoSelection _ stateArray at: 6.
> - Undone _ stateArray at: 7.
> - sel _ stateArray at: 8.
>   self selectFrom: sel first to: sel last.
> + beginTypeInBlock := stateArray at: 9.
> + emphasisHere := stateArray at: 10!
> - beginTypeInBlock _ stateArray at: 9.
> - emphasisHere _ stateArray at: 10!
>
> Item was changed:
>  ----- Method: TextEditor>>copySelection (in category 'menu messages') -----
>  copySelection
>   "Copy the current selection and store it in the paste buffer, unless a caret.  Undoer & Redoer: undoCutCopy"
>
>   self lineSelectAndEmptyCheck: [^ self].
>
>   "Simulate 'substitute: self selection' without locking the controller"
> + UndoSelection := self selection.
> - UndoSelection _ self selection.
>   self undoer: #undoCutCopy: with: self clipboardText.
> + UndoInterval := self selectionInterval.
> - UndoInterval _ self selectionInterval.
>   self clipboardTextPut: UndoSelection!
>
> Item was added:
> + ----- Method: TextEditor>>explainDelimitor: (in category 'explain') -----
> + explainDelimitor: string
> + "Is string enclosed in delimitors?"
> +
> + | str |
> + (string at: 1) isLetter ifTrue: [^nil].  "only special chars"
> + (string first = string last) ifTrue:
> + [^ self explainChar: (String with: string first)]
> + ifFalse:
> + [(string first = $( and: [string last = $)]) ifTrue:
> + [^ self explainChar: (String with: string first)].
> + (string first = $[ and: [string last = $]]) ifTrue:
> + [^ self explainChar: (String with: string first)].
> + (string first = ${ and: [string last = $}]) ifTrue:
> + [^ self explainChar: (String with: string first)].
> + (string first = $< and: [string last = $>]) ifTrue:
> + [^ self explainChar: (String with: string first)].
> + (string first = $# and: [string last = $)]) ifTrue:
> + [^'"An instance of class Array.  The Numbers, Characters, or Symbols between the parenthesis are the elements of the Array."'].
> + string first = $# ifTrue:
> + [^'"An instance of class Symbol."'].
> + (string first = $$ and: [string size = 2]) ifTrue:
> + [^'"An instance of class Character.  This one is the character ', (String with: string last), '."'].
> + (string first = $:) ifTrue:
> + [str := string allButFirst.
> + (self explainTemp: str) ~~ nil ifTrue:
> + [^'"An argument to this block will be bound to the temporary variable ',
> + str, '."']]].
> + ^ nil!
>
> Item was changed:
>  ----- Method: TextEditor>>mouseUp: (in category 'events') -----
>  mouseUp: evt
>   "An attempt to break up the old processRedButton code into threee phases"
>   oldInterval ifNil: [^ self].  "Patched during clickAt: repair"
>   (self hasCaret
>   and: [oldInterval = self selectionInterval])
>   ifTrue: [self selectWord].
>   self setEmphasisHere.
>   (self isDisjointFrom: oldInterval) ifTrue:
> + [otherInterval := oldInterval].
> - [otherInterval _ oldInterval].
>   self storeSelectionInParagraph!
>
> Item was changed:
>  ----- Method: TextEditor>>enclose: (in category 'editing keys') -----
>  enclose: characterStream
>   "Insert or remove bracket characters around the current selection.
>   Flushes typeahead."
>
>   | char left right startIndex stopIndex oldSelection which text |
> + char := sensor keyboard.
> - char _ sensor keyboard.
>   self closeTypeIn.
> + startIndex := self startIndex.
> + stopIndex := self stopIndex.
> + oldSelection := self selection.
> + which := '([<{"''' indexOf: char ifAbsent: [ ^true ].
> + left := '([<{"''' at: which.
> + right := ')]>}"''' at: which.
> + text := paragraph text.
> - startIndex _ self startIndex.
> - stopIndex _ self stopIndex.
> - oldSelection _ self selection.
> - which _ '([<{"''' indexOf: char ifAbsent: [ ^true ].
> - left _ '([<{"''' at: which.
> - right _ ')]>}"''' at: which.
> - text _ paragraph text.
>   ((startIndex > 1 and: [stopIndex <= text size])
>   and: [ (text at: startIndex-1) = left and: [(text at: stopIndex) = right]])
>   ifTrue: [
>   "already enclosed; strip off brackets"
>   self selectFrom: startIndex-1 to: stopIndex.
>   self replaceSelectionWith: oldSelection]
>   ifFalse: [
>   "not enclosed; enclose by matching brackets"
>   self replaceSelectionWith:
>   (Text string: (String with: left), oldSelection string, (String with: right) attributes: emphasisHere).
>   self selectFrom: startIndex+1 to: stopIndex].
>   ^true!
>
> Item was changed:
>  ----- Method: TextEditor>>debugIt (in category 'do-its') -----
>  debugIt
>
>   | method receiver context |
>   (model respondsTo: #doItReceiver)
>   ifTrue:
>   [FakeClassPool adopt: model selectedClass.
> + receiver := model doItReceiver.
> + context := model doItContext]
> - receiver _ model doItReceiver.
> - context _ model doItContext]
>   ifFalse:
> + [receiver := context := nil].
> - [receiver _ context _ nil].
>   self lineSelectAndEmptyCheck: [^self].
> + method := self compileSelectionFor: receiver in: context.
> - method _ self compileSelectionFor: receiver in: context.
>   method notNil ifTrue:
>   [self debug: method receiver: receiver in: context].
>   FakeClassPool adopt: nil!
>
> Item was changed:
>  ----- Method: TextEditor>>setAlignment: (in category 'menu messages') -----
>  setAlignment: aSymbol
>   | attr interval |
> + attr := TextAlignment perform: aSymbol.
> + interval := self encompassLine: self selectionInterval.
> - attr _ TextAlignment perform: aSymbol.
> - interval _ self encompassLine: self selectionInterval.
>   paragraph
>   replaceFrom: interval first
>   to: interval last
>   with: ((paragraph text copyFrom: interval first to: interval last) addAttribute: attr)!
>
> Item was changed:
>  ----- Method: TextEditor>>setSearchString: (in category 'nonediting/nontyping keys') -----
>  setSearchString: characterStream
>   "Establish the current selection as the current search string."
>
>   | aString |
>   self closeTypeIn: characterStream.
>   sensor keyboard.
>   self lineSelectAndEmptyCheck: [^ true].
> + aString :=  self selection string.
> - aString _  self selection string.
>   aString size = 0
>   ifTrue:
>   [self flash]
>   ifFalse:
>   [self setSearch: aString].
>   ^ true!
>
> Item was changed:
>  ----- Method: TextEditor>>resetState (in category 'initialize-release') -----
>  resetState
>   "Establish the initial conditions for editing the paragraph: place caret
>   before first character, set the emphasis to that of the first character,
>   and save the paragraph for purposes of canceling."
>
> + markBlock := paragraph defaultCharacterBlock.
> - markBlock _ paragraph defaultCharacterBlock.
>   self pointBlock: markBlock copy.
> + beginTypeInBlock := nil.
> + UndoInterval := otherInterval := 1 to: 0.
> - beginTypeInBlock _ nil.
> - UndoInterval _ otherInterval _ 1 to: 0.
>   self setEmphasisHere.
> + selectionShowing := false!
> - selectionShowing _ false!
>
> Item was changed:
>  ----- Method: TextEditor>>backTo: (in category 'typing support') -----
>  backTo: startIndex
>   "During typing, backspace to startIndex.  Deleted characters fall into three
>   clusters, from left to right in the text: (1) preexisting characters that were
>   backed over; (2) newly typed characters that were backed over (excluding
>   typeahead, which never even appears); (3) preexisting characters that
>   were highlighted before typing began.  If typing has not yet been opened,
>   open it and watch for the first and third cluster.  If typing has been opened,
>   watch for the first and second cluster.  Save characters from the first and third
>   cluster in UndoSelection.  Tally characters from the first cluster in UndoMessage's parameter.
>   Delete all the clusters.  Do not alter Undoer or UndoInterval (except via
>   openTypeIn).  The code is shorter than the comment."
>
>   | saveLimit newBackovers |
> + saveLimit := beginTypeInBlock
> + ifNil: [self openTypeIn. UndoSelection := self nullText. self stopIndex]
> - saveLimit _ beginTypeInBlock
> - ifNil: [self openTypeIn. UndoSelection _ self nullText. self stopIndex]
>   ifNotNil: [self startOfTyping].
>   self markIndex: startIndex.
>   startIndex < saveLimit ifTrue: [
> + newBackovers := self startOfTyping - startIndex.
> + beginTypeInBlock := self startIndex.
> - newBackovers _ self startOfTyping - startIndex.
> - beginTypeInBlock _ self startIndex.
>   UndoSelection replaceFrom: 1 to: 0 with:
>   (paragraph text copyFrom: startIndex to: saveLimit - 1).
>   UndoMessage argument: (UndoMessage argument ifNil: [1]) + newBackovers].
>   self zapSelectionWith: self nullText.
>   self unselect!
>
> Item was changed:
>  ----- Method: Editor>>sensor: (in category 'private') -----
>  sensor: aSensor
>   "Set the receiver's sensor to aSensor."
>
> + sensor := aSensor!
> - sensor _ aSensor!
>
> Item was changed:
>  ----- Method: PasteUpMorph>>modalLockTo: (in category 'polymorph') -----
>  modalLockTo: aSystemWindow
>   "Don't lock the world!! Lock the submorphs.
>   The modal window gets opened afterwards so is OK."
>
>   |lockStates|
> + lockStates := IdentityDictionary new.
> - lockStates _ IdentityDictionary new.
>   self submorphsDo: [:m |
>   lockStates at: m put: m isLocked.
>   m lock].
>   self
>   setProperty: #submorphLockStates
>   toValue: lockStates!
>
> Item was changed:
>  ----- Method: TextEditor>>noUndoer (in category 'undo support') -----
>  noUndoer
>   "The Undoer to use when the command can not be undone.  Checked for
>   specially by readKeyboard."
>
> + UndoMessage := Message selector: #noUndoer!
> - UndoMessage _ Message selector: #noUndoer!
>
> Item was changed:
>  ----- Method: TextEditor>>explainNumber: (in category 'explain') -----
>  explainNumber: string
>   "Is string a Number?"
>
>   | strm c |
> + (c := string at: 1) isDigit ifFalse: [(c = $- and: [string size > 1 and: [(string at: 2) isDigit]])
> - (c _ string at: 1) isDigit ifFalse: [(c = $- and: [string size > 1 and: [(string at: 2) isDigit]])
>   ifFalse: [^nil]].
> + strm := ReadStream on: string.
> + c := Number readFrom: strm.
> - strm _ ReadStream on: string.
> - c _ Number readFrom: strm.
>   strm atEnd ifFalse: [^nil].
>   c printString = string
>   ifTrue: [^'"' , string , ' is a ' , c class name , '"']
>   ifFalse: [^'"' , string , ' (= ' , c printString , ') is a ' , c class name , '"']!
>
> Item was changed:
>  ----- Method: TextEditor>>sameColumn:newLine:forward: (in category 'private') -----
>  sameColumn: start newLine: lineBlock forward: isForward
>   "Private - Compute the index in my text
>   with the line number derived from lineBlock,"
>   " a one argument block accepting the old line number.
>   The position inside the line will be preserved as good as possible"
>   "The boolean isForward is used in the border case to determine if
>   we should move to the beginning or the end of the line."
>   | wordStyle column currentLine offsetAtTargetLine targetEOL lines numberOfLines currentLineNumber targetLineNumber |
> + wordStyle := Preferences wordStyleCursorMovement.
> - wordStyle _ Preferences wordStyleCursorMovement.
>   wordStyle
>   ifTrue: [
> + lines := paragraph lines.
> - lines _ paragraph lines.
>   numberOfLines := paragraph numberOfLines.
> + currentLineNumber  := paragraph lineIndexOfCharacterIndex: start.
> + currentLine := lines at: currentLineNumber]
> - currentLineNumber  _ paragraph lineIndexOfCharacterIndex: start.
> - currentLine _ lines at: currentLineNumber]
>   ifFalse: [
> + lines := self lines.
> - lines _ self lines.
>   numberOfLines := lines size.
> + currentLine := lines
> - currentLine _ lines
>   detect:[:lineInterval | lineInterval last >= start]
>   ifNone:[lines last].
> + currentLineNumber := currentLine second].
> + column := start - currentLine first.
> + targetLineNumber := ((lineBlock value: currentLineNumber) max: 1) min: numberOfLines.
> + offsetAtTargetLine := (lines at: targetLineNumber) first.
> + targetEOL := (lines at: targetLineNumber) last + (targetLineNumber = numberOfLines ifTrue:[1]ifFalse:[0]).
> - currentLineNumber _ currentLine second].
> - column _ start - currentLine first.
> - targetLineNumber _ ((lineBlock value: currentLineNumber) max: 1) min: numberOfLines.
> - offsetAtTargetLine _ (lines at: targetLineNumber) first.
> - targetEOL _ (lines at: targetLineNumber) last + (targetLineNumber = numberOfLines ifTrue:[1]ifFalse:[0]).
>   targetLineNumber = currentLineNumber
>   "No movement or movement failed. Move to beginning or end of line."
>   ifTrue:[^isForward
>   ifTrue:[targetEOL]
>   ifFalse:[offsetAtTargetLine]].
>   ^offsetAtTargetLine + column min: targetEOL.!
>
> Item was changed:
>  ----- Method: Editor>>moveCursor:forward:specialBlock: (in category 'private') -----
>  moveCursor: directionBlock forward: forward specialBlock: specialBlock
>   "Private - Move cursor.
>   directionBlock is a one argument Block that computes the new Position from a given one.
>   specialBlock is a one argumentBlock that computes the new position from a given one under the alternate semantics.
>   Note that directionBlock always is evaluated first."
>   | shift indices newPosition |
> + shift := sensor leftShiftDown.
> + indices := self setIndices: shift forward: forward.
> + newPosition := directionBlock value: (indices at: #moving).
> - shift _ sensor leftShiftDown.
> - indices _ self setIndices: shift forward: forward.
> - newPosition _ directionBlock value: (indices at: #moving).
>   (sensor commandKeyPressed or:[sensor controlKeyPressed])
> + ifTrue: [newPosition := specialBlock value: newPosition].
> - ifTrue: [newPosition _ specialBlock value: newPosition].
>   sensor keyboard.
>   shift
>   ifTrue: [self selectMark: (indices at: #fixed) point: newPosition - 1]
>   ifFalse: [self selectAt: newPosition]!
>
> Item was changed:
>  ----- Method: TextEditor>>explainCtxt: (in category 'explain') -----
>  explainCtxt: symbol
>   "Is symbol a context variable?"
>
>   | reply classes text cls |
> + symbol = #nil ifTrue: [reply := '"is a constant.  It is the only instance of class UndefinedObject.  nil is the initial value of all variables."'].
> + symbol = #true ifTrue: [reply := '"is a constant.  It is the only instance of class True and is the receiver of many control messages."'].
> + symbol = #false ifTrue: [reply := '"is a constant.  It is the only instance of class False and is the receiver of many control messages."'].
> + symbol = #thisContext ifTrue: [reply := '"is a context variable.  Its value is always the MethodContext which is executing this method."'].
> - symbol = #nil ifTrue: [reply _ '"is a constant.  It is the only instance of class UndefinedObject.  nil is the initial value of all variables."'].
> - symbol = #true ifTrue: [reply _ '"is a constant.  It is the only instance of class True and is the receiver of many control messages."'].
> - symbol = #false ifTrue: [reply _ '"is a constant.  It is the only instance of class False and is the receiver of many control messages."'].
> - symbol = #thisContext ifTrue: [reply _ '"is a context variable.  Its value is always the MethodContext which is executing this method."'].
>   (model respondsTo: #selectedClassOrMetaClass) ifTrue: [
> + cls := model selectedClassOrMetaClass].
> - cls _ model selectedClassOrMetaClass].
>   cls ifNil: [^ reply].  "no class known"
>   symbol = #self ifTrue:
> + [classes := cls withAllSubclasses.
> - [classes _ cls withAllSubclasses.
>   classes size > 12
> + ifTrue: [text := cls printString , ' or a subclass']
> - ifTrue: [text _ cls printString , ' or a subclass']
>   ifFalse:
> + [classes := classes printString.
> + text := 'one of these classes' , (classes copyFrom: 4 to: classes size)].
> + reply := '"is the receiver of this message; an instance of ' , text , '"'].
> + symbol = #super ifTrue: [reply := '"is just like self.  Messages to super are looked up in the superclass (' , cls superclass printString , ')"'].
> - [classes _ classes printString.
> - text _ 'one of these classes' , (classes copyFrom: 4 to: classes size)].
> - reply _ '"is the receiver of this message; an instance of ' , text , '"'].
> - symbol = #super ifTrue: [reply _ '"is just like self.  Messages to super are looked up in the superclass (' , cls superclass printString , ')"'].
>   ^reply!
>
> Item was changed:
>  ----- Method: TextEditor>>encompassLine: (in category 'new selection') -----
>  encompassLine: anInterval
>   "Return an interval that encompasses the entire line"
>   | string left right |
> + string := paragraph text string.
> + left := (string lastIndexOf: Character cr startingAt: anInterval first - 1 ifAbsent:[0]) + 1.
> + right := (string indexOf: Character cr startingAt: anInterval last + 1 ifAbsent: [string size + 1]) - 1.
> - string _ paragraph text string.
> - left _ (string lastIndexOf: Character cr startingAt: anInterval first - 1 ifAbsent:[0]) + 1.
> - right _ (string indexOf: Character cr startingAt: anInterval last + 1 ifAbsent: [string size + 1]) - 1.
>   ^left to: right!
>
> Item was changed:
>  ----- Method: TextEditor>>browseClassFromIt (in category 'menu messages') -----
>  browseClassFromIt
>   "Launch a hierarchy browser for the class indicated by the current selection.  If multiple classes matching the selection exist, let the user choose among them."
>
>   | aClass |
>   self lineSelectAndEmptyCheck: [^ self].
>
> + aClass := Utilities classFromPattern: (self selection string copyWithout: Character cr) withCaption: 'choose a class to browse...'.
> - aClass _ Utilities classFromPattern: (self selection string copyWithout: Character cr) withCaption: 'choose a class to browse...'.
>   aClass ifNil: [^ morph flash].
>
>   Utilities spawnHierarchyForClass: aClass selector: nil!
>
> Item was changed:
>  ----- Method: Editor>>backspace: (in category 'typing/selecting keys') -----
>  backspace: characterStream
>   "Backspace over the last character."
>
>   | startIndex |
>   sensor leftShiftDown ifTrue: [^ self backWord: characterStream].
>   characterStream isEmpty
>   ifTrue:
> + [startIndex := self markIndex +
> - [startIndex _ self markIndex +
>   (self hasCaret ifTrue: [0] ifFalse: [1]).
>   [sensor keyboardPressed and:
>   [sensor keyboardPeek asciiValue = 8]] whileTrue: [
>   "process multiple backspaces"
>   sensor keyboard.
> + startIndex := 1 max: startIndex - 1.
> - startIndex _ 1 max: startIndex - 1.
>   ].
>   self backTo: startIndex]
>   ifFalse:
>   [sensor keyboard.
>   characterStream skip: -1].
>   ^false!
>
> Item was changed:
>  ----- Method: TextEditor>>selectCurrentTypeIn: (in category 'nonediting/nontyping keys') -----
>  selectCurrentTypeIn: characterStream
>   "Select what would be replaced by an undo (e.g., the last typeIn)."
>
>   | prior |
>
>   self closeTypeIn: characterStream.
> + prior := otherInterval.
> - prior _ otherInterval.
>   sensor keyboard. "flush character"
>   self closeTypeIn: characterStream.
>   self selectInterval: UndoInterval.
> + otherInterval := prior.
> - otherInterval _ prior.
>   ^ true!
>
> Item was changed:
>  ----- Method: TextEditor>>closeTypeIn (in category 'typing support') -----
>  closeTypeIn
>   "See comment in openTypeIn.  It is important to call closeTypeIn before executing
>   any non-typing key, making a new selection, etc.  It is called automatically for
>   menu commands.
>   Typing commands can call 'closeTypeIn: aCharacterStream' instead of this to
>   save typeahead.  Undoer & Redoer: undoAndReselect:redoAndReselect:."
>
>   | begin stop |
>   beginTypeInBlock == nil ifFalse: [
>   (UndoMessage sends: #noUndoer) ifTrue: "should always be true, but just in case..."
> + [begin := self startOfTyping.
> + stop := self stopIndex.
> - [begin _ self startOfTyping.
> - stop _ self stopIndex.
>   self undoer: #undoAndReselect:redoAndReselect:
>   with: (begin + UndoMessage argument to: begin + UndoSelection size - 1)
>   with: (stop to: stop - 1).
> + UndoInterval := begin to: stop - 1].
> + beginTypeInBlock := nil]!
> - UndoInterval _ begin to: stop - 1].
> - beginTypeInBlock _ nil]!
>
> Item was changed:
>  ----- Method: TextEditor>>model: (in category 'model access') -----
>  model: aModel
>   "Controller|model: and Controller|view: are sent by View|controller: in
>   order to coordinate the links between the model, view, and controller. In
>   ordinary usage, the receiver is created and passed as the parameter to
>   View|controller: so that the receiver's model and view links can be set
>   up by the view."
>
> + model := aModel!
> - model _ aModel!
>
> Item was changed:
>  ----- Method: TextEditor>>cursorHome: (in category 'nonediting/nontyping keys') -----
>  cursorHome: characterStream
>
>   "Private - Move cursor from position in current line to beginning of
>   current line. If control key is pressed put cursor at beginning of text"
>
>   | string |
>
> + string := paragraph text string.
> - string _ paragraph text string.
>   self
>   moveCursor: [ :position | Preferences wordStyleCursorMovement
>   ifTrue:[
>   (paragraph lines at:(paragraph lineIndexOfCharacterIndex: position)) first]
>   ifFalse:[
>   (string
>   lastIndexOf: Character cr
>   startingAt: position - 1
>   ifAbsent:[0]) + 1]]
>   forward: false
>   specialBlock: [:dummy | 1].
>   ^true!
>
> Item was changed:
>  ----- Method: TextEditor>>forwardDelete: (in category 'typing/selecting keys') -----
>  forwardDelete: characterStream
>   "Delete forward over the next character.
>    Make Undo work on the whole type-in, not just the one char.
>   wod 11/3/1998: If there was a selection use #zapSelectionWith: rather than #backspace: which was 'one off' in deleting the selection. Handling of things like undo or typeIn area were not fully considered."
>   | startIndex usel upara uinterval ind stopIndex |
> + startIndex := self markIndex.
> - startIndex _ self markIndex.
>   startIndex > paragraph text size ifTrue:
>   [sensor keyboard.
>   ^ false].
>   self hasSelection ifTrue:
>   ["there was a selection"
>   sensor keyboard.
>   self zapSelectionWith: self nullText.
>   ^ false].
>   "Null selection - do the delete forward"
>   beginTypeInBlock == nil "no previous typing.  openTypeIn"
> + ifTrue: [self openTypeIn. UndoSelection := self nullText].
> + uinterval := UndoInterval deepCopy.
> + upara := UndoParagraph deepCopy.
> - ifTrue: [self openTypeIn. UndoSelection _ self nullText].
> - uinterval _ UndoInterval deepCopy.
> - upara _ UndoParagraph deepCopy.
>   stopIndex := startIndex.
>   (sensor keyboard asciiValue = 127 and: [sensor leftShiftDown])
>   ifTrue: [stopIndex := (self nextWord: stopIndex) - 1].
>   self selectFrom: startIndex to: stopIndex.
>   self replaceSelectionWith: self nullText.
>   self selectFrom: startIndex to: startIndex-1.
> + UndoParagraph := upara.  UndoInterval := uinterval.
> - UndoParagraph _ upara.  UndoInterval _ uinterval.
>   UndoMessage selector == #noUndoer ifTrue: [
>   (UndoSelection isText) ifTrue: [
> + usel := UndoSelection.
> + ind := startIndex. "UndoInterval startIndex"
> - usel _ UndoSelection.
> - ind _ startIndex. "UndoInterval startIndex"
>   usel replaceFrom: usel size + 1 to: usel size with:
>   (UndoParagraph text copyFrom: ind to: ind).
>   UndoParagraph text replaceFrom: ind to: ind with:
>  self nullText]].
>   ^false!
>
> Item was changed:
>  ----- Method: Editor>>nextWord: (in category 'private') -----
>  nextWord: position
>   | string index |
> + string := self string.
> + index := position.
> - string _ self string.
> - index _ position.
>   [(index between: 1 and: string size) and: [(string at: index) isAlphaNumeric]]
> + whileTrue: [index := index + 1].
> - whileTrue: [index _ index + 1].
>   [(index between: 1 and: string size) and: [(string at: index) isAlphaNumeric not]]
> + whileTrue: [index := index + 1].
> - whileTrue: [index _ index + 1].
>   ^ index!
>
> Item was changed:
>  ----- Method: Editor>>setIndices:forward: (in category 'private') -----
>  setIndices: shiftPressed forward: forward
>   "Little helper method that sets the moving and fixed indices according to some flags."
>   | indices |
> + indices := Dictionary new.
> - indices _ Dictionary new.
>   (shiftPressed and:[self class selectionsMayShrink])
>   ifTrue: [
>   indices at: #moving put: self pointIndex.
>   indices at: #fixed put: self markIndex
>   ] ifFalse: [
>   forward
>   ifTrue:[
>   indices at: #moving put: self stopIndex.
>   indices at: #fixed put: self startIndex.
>   ] ifFalse: [
>   indices at: #moving put: self startIndex.
>   indices at: #fixed put: self stopIndex.
>   ]
>   ].
>   ^indices!
>
> Item was changed:
>  ----- Method: TextEditor>>argAdvance: (in category 'typing/selecting keys') -----
>  argAdvance: characterStream
>   "Invoked by Ctrl-a.  Useful after Ctrl-q.
>   Search forward from the end of the selection for a colon followed by
>   a space.  Place the caret after the space.  If none are found, place the
>   caret at the end of the text.  Does not affect the undoability of the
>   previous command."
>
>   | start |
>   sensor keyboard. "flush character"
>   self closeTypeIn: characterStream.
> + start := paragraph text findString: ': ' startingAt: self stopIndex.
> + start = 0 ifTrue: [start := paragraph text size + 1].
> - start _ paragraph text findString: ': ' startingAt: self stopIndex.
> - start = 0 ifTrue: [start _ paragraph text size + 1].
>   self selectAt: start + 2.
>   ^true!
>
> Item was changed:
>  ----- Method: TextEditor class>>initializeShiftedYellowButtonMenu (in category 'keyboard shortcut tables') -----
>  initializeShiftedYellowButtonMenu
>   "Initialize the yellow button pop-up menu and corresponding messages."
>
>   "TextEditor initialize"
>   "
>   shiftedYellowButtonMenu := {
>   {'set font... (k)' translated. #offerFontMenu}.
>   {'set style... (K)' translated. #changeStyle}.
>   {'set alignment...' translated. #chooseAlignment}.
>   #-.
>   {'more...' translated. #yellowButtonActivity}.
>   }
>   "
> + shiftedYellowButtonMenu := yellowButtonMenu!
> - shiftedYellowButtonMenu _ yellowButtonMenu!
>
> Item was changed:
>  ----- Method: SmalltalkEditor>>handleEmphasisExtra:with: (in category 'editing keys') -----
>  handleEmphasisExtra: index with: characterStream
>   "Handle an extra emphasis menu item"
>   | action attribute thisSel |
>   action := {
>   [attribute := TextDoIt new.
>   thisSel := attribute analyze: self selection asString].
>   [attribute := TextPrintIt new.
>   thisSel := attribute analyze: self selection asString].
>   [attribute := TextLink new.
>   thisSel := attribute analyze: self selection asString with: 'Comment'].
>   [attribute := TextLink new.
>   thisSel := attribute analyze: self selection asString with: 'Definition'].
>   [attribute := TextLink new.
>   thisSel := attribute analyze: self selection asString with: 'Hierarchy'].
>   [attribute := TextLink new.
>   thisSel := attribute analyze: self selection asString].
>   [attribute := TextURL new.
>   thisSel := attribute analyze: self selection asString].
>   ["Edit hidden info"
>   thisSel := self hiddenInfo. "includes selection"
>   attribute := TextEmphasis normal].
>   ["Copy hidden info"
>   self copyHiddenInfo.
>   ^true]. "no other action"
>   } at: index.
>   action value.
>
>   thisSel ifNil: [^true]. "Could not figure out what to link to"
>
>   attribute ifNotNil: [
>   thisSel ifEmpty:[ | oldAttributes |
>   "only change emphasisHere while typing"
>   oldAttributes := paragraph text attributesAt: self pointIndex.
>   self insertTypeAhead: characterStream.
> + emphasisHere := Text addAttribute: attribute toArray: oldAttributes.
> - emphasisHere _ Text addAttribute: attribute toArray: oldAttributes.
>   ] ifNotEmpty: [
>   self replaceSelectionWith: (thisSel asText addAttribute: attribute).
>   ]
>   ].
>   ^true!
>
> Item was changed:
>  ----- Method: TextEditor>>nextTokenFrom:direction: (in category 'new selection') -----
>  nextTokenFrom: start direction: dir
>   "simple token-finder for compiler automated corrections"
>   | loc str |
> + loc := start + dir.
> + str := paragraph text string.
> - loc _ start + dir.
> - str _ paragraph text string.
>   [(loc between: 1 and: str size) and: [(str at: loc) isSeparator]]
> + whileTrue: [loc := loc + dir].
> - whileTrue: [loc _ loc + dir].
>   ^ loc!
>
> Item was changed:
>  ----- Method: TextEditor>>dispatchOnCharacter:with: (in category 'typing support') -----
>  dispatchOnCharacter: char with: typeAheadStream
>   "Carry out the action associated with this character, if any.
>   Type-ahead is passed so some routines can flush or use it."
>
>   | honorCommandKeys |
>   ((char == Character cr) and: [morph acceptOnCR])
>   ifTrue: [
>   sensor keyboard.  "Gobble cr -- probably unnecessary."
>   self closeTypeIn.
>   ^ true].
>
>   self clearParens.
>
>   char asciiValue = 13 ifTrue: [
>   sensor controlKeyPressed ifTrue: [
>   ^ self normalCharacter: typeAheadStream ].
>   sensor leftShiftDown ifTrue: [
>   ^ self lf: typeAheadStream ].
>   sensor commandKeyPressed ifTrue: [
>   ^ self crlf: typeAheadStream ].
>   ^ self crWithIndent: typeAheadStream ].
>
> + ((honorCommandKeys := Preferences cmdKeysInText) and: [char = Character enter])
> - ((honorCommandKeys _ Preferences cmdKeysInText) and: [char = Character enter])
>   ifTrue: [^ self dispatchOnEnterWith: typeAheadStream].
>
>   "Special keys overwrite crtl+key combinations - at least on Windows. To resolve this
>   conflict, assume that keys other than cursor keys aren't used together with Crtl."
>   ((self class specialShiftCmdKeys includes: char asciiValue) and: [char asciiValue < 27])
>   ifTrue: [^ sensor controlKeyPressed
>   ifTrue: [self perform: (self class shiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
>   ifFalse: [self perform: (self class cmdActions at: char asciiValue + 1) with: typeAheadStream]].
>
>   "backspace, and escape keys (ascii 8 and 27) are command keys"
>   ((honorCommandKeys and: [sensor commandKeyPressed]) or: [self class specialShiftCmdKeys includes: char asciiValue]) ifTrue:
>   [^ sensor leftShiftDown
>   ifTrue: [
>   self perform: (self class shiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
>   ifFalse: [
>   self perform: (self class cmdActions at: char asciiValue + 1) with: typeAheadStream]].
>
>   "the control key can be used to invoke shift-cmd shortcuts"
>   (honorCommandKeys and: [sensor controlKeyPressed])
>   ifTrue: [
>   ^ self perform: (self class shiftCmdActions at: char asciiValue + 1) with: typeAheadStream].
>
>   (')]}' includes: char)
>   ifTrue: [self blinkPrevParen].
>
>   ^ self normalCharacter: typeAheadStream!
>
> Item was changed:
>  ----- Method: TextEditor>>debug:receiver:in: (in category 'do-its') -----
>  debug: aCompiledMethod receiver: anObject in: evalContext
>
>   | selector guineaPig debugger context |
> + selector := evalContext isNil ifTrue: [#DoIt] ifFalse: [#DoItIn:].
> - selector _ evalContext isNil ifTrue: [#DoIt] ifFalse: [#DoItIn:].
>   anObject class addSelectorSilently: selector withMethod: aCompiledMethod.
> + guineaPig := evalContext isNil
> - guineaPig _ evalContext isNil
>   ifTrue: [[anObject DoIt] newProcess]
>   ifFalse: [[anObject DoItIn: evalContext] newProcess].
> + context := guineaPig suspendedContext.
> + debugger := Debugger new
> - context _ guineaPig suspendedContext.
> - debugger _ Debugger new
>   process: guineaPig
>   controller: nil
>   context: context.
>   debugger openFullNoSuspendLabel: 'Debug it'.
>   [debugger interruptedContext method == aCompiledMethod]
>   whileFalse: [debugger send].
>   anObject class basicRemoveSelector: selector!
>
> Item was changed:
>  ----- Method: TextEditor>>blinkParenAt: (in category 'parenblinking') -----
>  blinkParenAt: parenLocation
>   self text
>   addAttribute: TextEmphasis bold
>   from: parenLocation
>   to: parenLocation.
> + lastParenLocation := parenLocation.!
> - lastParenLocation _ parenLocation.!
>
> Item was changed:
>  ----- Method: TextEditor>>setSearch: (in category 'accessing') -----
>  setSearch: aString
>   "Set the FindText and ChangeText to seek aString; except if already seeking aString, leave ChangeText alone so again will repeat last replacement."
>
>   FindText string = aString
> + ifFalse: [FindText := ChangeText := aString asText]!
> - ifFalse: [FindText _ ChangeText _ aString asText]!
>
> Item was changed:
>  ----- Method: TextEditor>>browseChangeSetsWithSelector (in category 'menu messages') -----
>  browseChangeSetsWithSelector
>   "Determine which, if any, change sets have at least one change for the selected selector, independent of class"
>
>   | aSelector |
>   self lineSelectAndEmptyCheck: [^ self].
> + (aSelector := self selectedSelector) == nil ifTrue: [^ morph flash].
> - (aSelector _ self selectedSelector) == nil ifTrue: [^ morph flash].
>   ChangeSorter browseChangeSetsWithSelector: aSelector!
>
> Item was changed:
>  ----- Method: TextEditor>>zapSelectionWith: (in category 'mvc compatibility') -----
>  zapSelectionWith: aText
>
>   | start stop |
>   self deselect.
> + start := self startIndex.
> + stop := self stopIndex.
> - start _ self startIndex.
> - stop _ self stopIndex.
>   (aText isEmpty and: [stop > start]) ifTrue: [
>   "If deleting, then set emphasisHere from 1st character of the deletion"
> + emphasisHere := (paragraph text attributesAt: start) select: [:att | att mayBeExtended]].
> - emphasisHere _ (paragraph text attributesAt: start) select: [:att | att mayBeExtended]].
>   (start = stop and: [ aText size = 0 ]) ifFalse: [
>   paragraph replaceFrom: start to: stop - 1 with: aText.
>   self markIndex: start; pointIndex: start + aText size.
> + UndoInterval := otherInterval := self selectionInterval].
> - UndoInterval _ otherInterval _ self selectionInterval].
>
>   self userHasEdited  " -- note text now dirty"!
>
> Item was changed:
>  ----- Method: TextEditor>>pointBlock: (in category 'accessing-selection') -----
>  pointBlock: aCharacterBlock
> + pointBlock := aCharacterBlock.
> - pointBlock _ aCharacterBlock.
>  !
>
> Item was changed:
>  ----- Method: FileList>>askServerInfo (in category 'server list') -----
>  askServerInfo
>   "Get the user to create a ServerDirectory for a new server.  Fill in and say Accept."
>   | template |
> + template := '"Please fill in the following info, then select all text and choose DoIt."
> - template _ '"Please fill in the following info, then select all text and choose DoIt."
>
>   | aa |
>   self flag: #ViolateNonReferenceToOtherClasses.
> + aa := ServerDirectory new.
> - aa _ ServerDirectory new.
>   aa server: ''st.cs.uiuc.edu''.    "host"
>   aa user: ''anonymous''.
>   aa password: ''[hidden email]''.
>   aa directory: ''/Smalltalk/Squeak/Goodies''.
>   aa url: ''''.    "<- this is optional.  Only used when *writing* update files."
>   ServerDirectory addServer: aa named: ''UIUCArchive''.  "<- known by this name in Squeak"'.
>
>   (StringHolder new contents: template) openLabel: 'FTP Server Form'
>   !
>
> Item was changed:
>  ----- Method: TextEditor class>>initializeShiftCmdKeyShortcuts (in category 'keyboard shortcut tables') -----
>  initializeShiftCmdKeyShortcuts
>   "Initialize the shift-command-key (or control-key) shortcut table."
>   "NOTE: if you don't know what your keyboard generates, use Sensor kbdTest"
>   "wod 11/3/1998: Fix setting of cmdMap for shifted keys to actually use the
>   capitalized versions of the letters.
>   TPR 2/18/99: add the plain ascii values back in for those VMs that don't return the shifted values."
>
>   "TextEditor initialize"
>
>   | cmdMap cmds |
>
>   "shift-command and control shortcuts"
> + cmdMap := Array new: 256 withAll: #noop:.   "use temp in case of a crash"
> - cmdMap _ Array new: 256 withAll: #noop:.   "use temp in case of a crash"
>   cmdMap at: ( 1 + 1) put: #cursorHome:. "home key"
>   cmdMap at: ( 4 + 1) put: #cursorEnd:. "end key"
>   cmdMap at: ( 8 + 1) put: #forwardDelete:. "ctrl-H or delete key"
>   cmdMap at: (11 + 1) put: #cursorPageUp:. "page up key"
>   cmdMap at: (12 + 1) put: #cursorPageDown:. "page down key"
>   cmdMap at: (13 + 1) put: #crWithIndent:. "ctrl-Return"
>   cmdMap at: (27 + 1) put: #offerMenuFromEsc:. "escape key"
>   cmdMap at: (28 + 1) put: #cursorLeft:. "left arrow key"
>   cmdMap at: (29 + 1) put: #cursorRight:. "right arrow key"
>   cmdMap at: (30 + 1) put: #cursorUp:. "up arrow key"
>   cmdMap at: (31 + 1) put: #cursorDown:. "down arrow key"
>   cmdMap at: (32 + 1) put: #selectWord:. "space bar key"
>   cmdMap at: (45 + 1) put: #changeEmphasis:. "cmd-sh-minus"
>   cmdMap at: (61 + 1) put: #changeEmphasis:. "cmd-sh-plus"
>   cmdMap at: (127 + 1) put: #forwardDelete:. "del key"
>
>   "Note: Command key overrides shift key, so, for example, cmd-shift-9 produces $9 not $("
>   '9[,''' do: [ :char | cmdMap at: (char asciiValue + 1) put: #shiftEnclose: ]. "({< and double-quote"
>   "Note: Must use cmd-9 or ctrl-9 to get '()' since cmd-shift-9 is a Mac FKey command."
>
>   "NB: sw 12/9/2001 commented out the idiosyncratic line just below, which was grabbing shift-esc in the text editor and hence which argued with the wish to have shift-esc be a universal gesture for escaping the local context and calling up the desktop menu."
>   "cmdMap at: (27 + 1) put: #shiftEnclose:." "ctrl-["
>
>   "'""''(' do: [ :char | cmdMap at: (char asciiValue + 1) put: #enclose:]."
>
> + cmds := #(
> - cmds _ #(
>   $c compareToClipboard:
>   $d duplicate:
>   $h cursorTopHome:
>   $j doAgainMany:
>   $k changeStyle:
>   $l outdent:
>   $m selectCurrentTypeIn:
>   $r indent:
>   $s search:
>   $u changeLfToCr:
>   $x makeLowercase:
>   $y makeUppercase:
>   $z makeCapitalized:
>   ).
>   1 to: cmds size by: 2 do: [ :i |
>   cmdMap at: ((cmds at: i) asciiValue + 1) put: (cmds at: i + 1). "plain keys"
>   cmdMap at: ((cmds at: i) asciiValue - 32 + 1) put: (cmds at: i + 1). "shifted keys"
>   cmdMap at: ((cmds at: i) asciiValue - 96 + 1) put: (cmds at: i + 1). "ctrl keys"
>   ].
> + shiftCmdActions := cmdMap!
> - shiftCmdActions _ cmdMap!
>
> Item was changed:
>  ----- Method: TextEditor>>spawn (in category 'menu messages') -----
>  spawn
>   "Create and schedule a message browser for the code of the model's
>   selected message. Retain any edits that have not yet been accepted."
>   | code |
> + code := paragraph text string.
> - code _ paragraph text string.
>   self cancel.
>   model spawn: code.!
>
> Item was changed:
>  ----- Method: TextEditor>>changeSelectionFontTo: (in category 'attributes') -----
>  changeSelectionFontTo: aFont
>   | attr |
>   aFont ifNil:[^self].
> + attr := TextFontReference toFont: aFont.
> - attr _ TextFontReference toFont: aFont.
>   paragraph text addAttribute: attr from: self startIndex to: (self stopIndex-1 min: paragraph text size).
>   paragraph composeAll.
>   self recomputeInterval.
>   morph changed.!
>
> Item was changed:
>  ----- Method: TextEditor>>browseItHere (in category 'menu messages') -----
>  browseItHere
>   "Retarget the receiver's window to look at the selected class, if appropriate.  3/1/96 sw"
>   | aSymbol foundClass b |
> + (((b := model) isKindOf: Browser) and: [b couldBrowseAnyClass])
> - (((b _ model) isKindOf: Browser) and: [b couldBrowseAnyClass])
>   ifFalse: [^ morph flash].
>   model okToChange ifFalse: [^ morph flash].
>   self selectionInterval isEmpty ifTrue: [self selectWord].
> + (aSymbol := self selectedSymbol) isNil ifTrue: [^ morph flash].
> - (aSymbol _ self selectedSymbol) isNil ifTrue: [^ morph flash].
>
> + foundClass := (Smalltalk at: aSymbol ifAbsent: [nil]).
> - foundClass _ (Smalltalk at: aSymbol ifAbsent: [nil]).
>   foundClass isNil ifTrue: [^ morph flash].
>   (foundClass isKindOf: Class)
>   ifTrue:
>   [model systemCategoryListIndex:
>   (model systemCategoryList indexOf: foundClass category).
>   model classListIndex: (model classList indexOf: foundClass name)]!
>
> Item was changed:
>  ----- Method: TextEditor>>changeParagraph: (in category 'initialize-release') -----
>  changeParagraph: aParagraph
>   "Install aParagraph as the one to be edited by the receiver."
>
> + UndoParagraph == paragraph ifTrue: [UndoParagraph := nil].
> + paragraph := aParagraph.
> - UndoParagraph == paragraph ifTrue: [UndoParagraph _ nil].
> - paragraph _ aParagraph.
>   self resetState!
>
> Item was changed:
>  ----- Method: TextEditor class>>abandonChangeText (in category 'class initialization') -----
>  abandonChangeText
>   "Call this to get out of the maddening situation in which the system keeps aggressively trying to do a replacement that you no longer wish to make, every time you make choose a new method in a list."
> + ChangeText := FindText
> - ChangeText _ FindText
>
>   "
>   TextEditor abandonChangeText
>   "!
>
> Item was changed:
>  ----- Method: TextEditor>>openTypeIn (in category 'typing support') -----
>  openTypeIn
>   "Set up UndoSelection to null text (to be added to by readKeyboard and backTo:),
>   beginTypeInBlock to keep track of the leftmost backspace, and UndoParameter to tally
>   how many deleted characters were backspaced over rather than 'cut'.
>   You can't undo typing until after closeTypeIn."
>
>   beginTypeInBlock ifNil: [
> + UndoSelection := self nullText.
> - UndoSelection _ self nullText.
>   self undoer: #noUndoer with: 0.
> + beginTypeInBlock := self startIndex]!
> - beginTypeInBlock _ self startIndex]!
>
> Item was changed:
>  ----- Method: TextEditor>>compareToClipboard (in category 'menu messages') -----
>  compareToClipboard
>   "Check to see if whether the receiver's text is the same as the text currently on the clipboard, and inform the user."
>   | s1 s2 |
> + s1 := self clipboardText string.
> + s2 := paragraph text string.
> - s1 _ self clipboardText string.
> - s2 _ paragraph text string.
>   s1 = s2 ifTrue: [^ self inform: 'Exact match'].
>
>   (StringHolder new textContents:
>   (TextDiffBuilder buildDisplayPatchFrom: s1 to: s2))
>   openLabel: 'Comparison to Clipboard Text'!
>
> Item was changed:
>  ----- Method: TextEditor>>evaluateSelection (in category 'do-its') -----
>  evaluateSelection
>   "Treat the current selection as an expression; evaluate it and return the result"
>   | result rcvr ctxt |
>   self lineSelectAndEmptyCheck: [^ ''].
>
>   (model respondsTo: #doItReceiver)
>   ifTrue: [FakeClassPool adopt: model selectedClass.  "Include model pool vars if any"
> + rcvr := model doItReceiver.
> + ctxt := model doItContext]
> + ifFalse: [rcvr := ctxt := nil].
> + result := [
> - rcvr _ model doItReceiver.
> - ctxt _ model doItContext]
> - ifFalse: [rcvr _ ctxt _ nil].
> - result _ [
>   rcvr class evaluatorClass new
>   evaluate: self selectionAsStream
>   in: ctxt
>   to: rcvr
>   notifying: self
>   ifFail: [FakeClassPool adopt: nil. ^ #failedDoit]
>   logged: true.
>   ]
>   on: OutOfScopeNotification
>   do: [ :ex | ex resume: true].
>   FakeClassPool adopt: nil.
>   ^ result!
>
> Item was changed:
>  ----- Method: TextEditor>>markBlock: (in category 'accessing-selection') -----
>  markBlock: aCharacterBlock
> + markBlock := aCharacterBlock!
> - markBlock _ aCharacterBlock!
>
> Item was changed:
>  ----- Method: TextEditor>>isDisjointFrom: (in category 'private') -----
>  isDisjointFrom: anInterval
>   "Answer true if anInterval is a caret not touching or within the current
>   interval, or if anInterval is a non-caret that does not overlap the current
>   selection."
>
>   | fudge |
> + fudge := anInterval size = 0 ifTrue: [1] ifFalse: [0].
> - fudge _ anInterval size = 0 ifTrue: [1] ifFalse: [0].
>   ^(anInterval last + fudge < self startIndex or:
>   [anInterval first - fudge >= self stopIndex])
>  !
>
> Item was changed:
>  ----- Method: TextEditor>>exploreIt (in category 'do-its') -----
>  exploreIt
>   | result |
> + result := self evaluateSelection.
> - result _ self evaluateSelection.
>   ((result isKindOf: FakeClassPool) or: [result == #failedDoit])
>   ifTrue: [morph flash]
>   ifFalse: [result explore]!
>
> Item was changed:
>  ----- Method: TextEditor>>readKeyboard (in category 'typing support') -----
>  readKeyboard
>   "Key struck on the keyboard. Find out which one and, if special, carry
>   out the associated special action. Otherwise, add the character to the
>   stream of characters.  Undoer & Redoer: see closeTypeIn."
>
>   | typeAhead char |
> + typeAhead := WriteStream on: (String new: 128).
> - typeAhead _ WriteStream on: (String new: 128).
>   [ sensor keyboardPressed ] whileTrue: [
>   self deselect.
>   [ sensor keyboardPressed ] whileTrue: [
> + char := sensor keyboardPeek.
> - char _ sensor keyboardPeek.
>   (self dispatchOnCharacter: char with: typeAhead) ifTrue: [
>   self doneTyping.
>   self storeSelectionInParagraph.
>   ^self].
>   self openTypeIn].
>   self hasSelection ifTrue: [ "save highlighted characters"
> + UndoSelection := self selection].
> - UndoSelection _ self selection].
>   self zapSelectionWith:
>   (Text string: typeAhead contents attributes: emphasisHere).
>   typeAhead reset.
>   self unselect].
>   self storeSelectionInParagraph!
>
> Item was changed:
>  ----- Method: TextEditor>>pasteRecent (in category 'menu messages') -----
>  pasteRecent
>   "Paste an item chose from RecentClippings."
>
>   | clipping |
> + (clipping := Clipboard chooseRecentClipping) ifNil: [^ self].
> - (clipping _ Clipboard chooseRecentClipping) ifNil: [^ self].
>   Clipboard clipboardText: clipping.
>   ^ self paste!
>
> Item was changed:
>  ----- Method: TextEditor>>swapChars: (in category 'editing keys') -----
>  swapChars: characterStream
>   "Triggered byCmd-Y;.  Swap two characters, either those straddling the insertion point, or the two that comprise the selection.  Suggested by Ted Kaehler.  "
>
>   | currentSelection aString chars |
>   sensor keyboard. "flush the triggering cmd-key character"
> + (chars := self selection) size = 0
> - (chars _ self selection) size = 0
>   ifTrue:
> + [currentSelection := self pointIndex.
> - [currentSelection _ self pointIndex.
>   self selectMark: currentSelection - 1 point: currentSelection]
>   ifFalse:
>   [chars size = 2
>   ifFalse:
>   [morph flash. ^ true]
>   ifTrue:
> + [currentSelection := self pointIndex - 1]].
> + aString := self selection string.
> - [currentSelection _ self pointIndex - 1]].
> - aString _ self selection string.
>   self replaceSelectionWith: (Text string: aString reversed attributes: emphasisHere).
>   self selectAt: currentSelection + 1.
>   ^ true!
>
> Item was changed:
>  ----- Method: TextEditor>>explainScan: (in category 'explain') -----
>  explainScan: string
>   "Remove beginning and trailing space, tab, cr.
>   1/15/96 sw: copied intact from BrowserCodeController"
>
>   | c beg end |
> + beg := 1.
> + end := string size.
> - beg _ 1.
> - end _ string size.
>
>   [beg = end ifTrue: [^string copyFrom: 1 to: 1].
>   "if all blank, tell about the first"
> + c := string at: beg.
> - c _ string at: beg.
>   c = Character space or: [c = Character tab or: [c = Character cr]]]
> + whileTrue: [beg := beg + 1].
> - whileTrue: [beg _ beg + 1].
>
> + [c := string at: end.
> - [c _ string at: end.
>   c = Character space or: [c = Character tab or: [c = Character cr]]]
> + whileTrue: [end := end - 1].
> - whileTrue: [end _ end - 1].
>   ^string copyFrom: beg to: end "Return purely visible characters"!
>
> Item was changed:
>  ----- Method: TextEditor>>notify:at:in: (in category 'new selection') -----
>  notify: aString at: anInteger in: aStream
>   "The compilation of text failed. The syntax error is noted as the argument,
>   aString. Insert it in the text at starting character position anInteger."
>
>   | pos |
> + pos := self selectionInterval notEmpty
> - pos _ self selectionInterval notEmpty
>   ifTrue: [
>   self startIndex + anInteger - 1 ]
>   ifFalse: [anInteger].
>   self insertAndSelect: aString at: (pos max: 1)!
>
> Item was changed:
>  ----- Method: TextMorphEditor>>changeSelectionFontTo: (in category 'attributes') -----
>  changeSelectionFontTo: aFont
>   | attr |
>   aFont ifNil:[^self].
> + attr := TextFontReference toFont: aFont.
> - attr _ TextFontReference toFont: aFont.
>   paragraph text addAttribute: attr from: self startIndex to: (self stopIndex-1 min: paragraph text size).
>   paragraph composeAll.
>   self recomputeInterval.
>   morph changed.!
>
> Item was changed:
>  ----- Method: TextEditor>>printIt (in category 'do-its') -----
>  printIt
>   "Treat the current text selection as an expression; evaluate it. Insert the
>   description of the result of evaluation after the selection and then make
>   this description the new text selection."
>   | result |
> + result := self evaluateSelection.
> - result _ self evaluateSelection.
>   ((result isKindOf: FakeClassPool) or: [result == #failedDoit])
>   ifTrue: [morph flash]
>   ifFalse: [self afterSelectionInsertAndSelect: result printString]!
>
> Item was changed:
>  ----- Method: TextEditor>>mouseDown: (in category 'events') -----
>  mouseDown: evt
>   "An attempt to break up the old processRedButton code into threee phases"
>   | clickPoint b |
>
> + oldInterval := self selectionInterval.
> + clickPoint := evt cursorPoint.
> + b := paragraph characterBlockAtPoint: clickPoint.
> - oldInterval _ self selectionInterval.
> - clickPoint _ evt cursorPoint.
> - b _ paragraph characterBlockAtPoint: clickPoint.
>
>   (paragraph clickAt: clickPoint for: model controller: self) ifTrue: [
>   self markBlock: b.
>   self pointBlock: b.
>   evt hand releaseKeyboardFocus: self.
>   ^ self ].
>
>   evt shiftPressed
>   ifFalse: [
>   self closeTypeIn.
>   self markBlock: b.
>   self pointBlock: b ]!
>
> Item was changed:
>  ----- Method: Editor>>morph: (in category 'accessing') -----
>  morph: aMorph
>   "Install a link back to the morph being edited (esp for text links)"
> + morph := aMorph !
> - morph _ aMorph !
>
> Item was changed:
>  ----- Method: TextMorph>>keyStroke: (in category 'event handling') -----
>  keyStroke: evt
>   "Handle a keystroke event."
>   | action |
>   self resetBlinkCursor. "don't blink during type-in"
>   evt keyValue = 13 ifTrue:["CR - check for special action"
> + action := self crAction.
> - action _ self crAction.
>   action ifNotNil:[
>   "Note: Code below assumes that this was some
>   input field reacting on CR. Break the keyboard
>   focus so that the receiver can be safely deleted."
>   evt hand newKeyboardFocus: nil.
>   ^action value]].
>   self handleInteraction: [editor readKeyboard] fromEvent: evt.
>   "self updateFromParagraph."
>   super keyStroke: evt  "sends to keyStroke event handler, if any"!
>
> Item was changed:
>  ----- Method: TextEditor>>setEmphasis: (in category 'editing keys') -----
>  setEmphasis: emphasisSymbol
>   "Change the emphasis of the current selection."
>
>   | oldAttributes attribute |
> + oldAttributes := paragraph text attributesAt: self selectionInterval first.
> - oldAttributes _ paragraph text attributesAt: self selectionInterval first.
>
> + attribute := TextEmphasis perform: emphasisSymbol.
> - attribute _ TextEmphasis perform: emphasisSymbol.
>   (emphasisSymbol == #normal)
>   ifFalse: [oldAttributes do:
>   [:att | (att dominates: attribute) ifTrue: [attribute turnOff]]].
>   self replaceSelectionWith: (self selection addAttribute: attribute)!
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Morphic-dtl.297.mcz

David T. Lewis
On Mon, Jan 04, 2010 at 06:02:34AM +0100, Levente Uzonyi wrote:

> On Mon, 4 Jan 2010, [hidden email] wrote:
>
> >David T. Lewis uploaded a new version of Morphic to project The Trunk:
> >http://source.squeak.org/trunk/Morphic-dtl.297.mcz
> >
> >==================== Summary ====================
> >
> >Name: Morphic-dtl.297
> >Author: dtl
> >Time: 3 January 2010, 11:54:26 am
> >UUID: b656a757-aedc-47a4-9014-21327212c021
> >Ancestors: Morphic-ar.296
> >
> >Add TextEditor>>explainDelimitor: copied from ParagraphEditor, required
> >for explain function in code panes.
> >
> >Run FixUnderscores on package Morphic to update methods adopted from Cuis.
> >Note: Did not fix underscores in MorphicModel class>>compileAccessorsFor:
>
> Be careful with FixUnderscores, last time I tried it, it replaced _ to :=
> in string literals. (FixUnderscores-cmm.10)

I have never had problems with it. I used FixUnderscores-cmm.9 for this
update, and it seemed to do all the right things, refusing to update
any methods with _ in string literals. To be honest, I don't recall what
repository I got the FixUnderscores-cmm.9.mcz file from, it's just a
copy I had on my hard drive that has worked well in the past.

Dave