[squeak-dev] The Trunk: Morphic-dtl.297.mcz
Levente Uzonyi
leves at elte.hu
Mon Jan 4 05:02:34 UTC 2010
On Mon, 4 Jan 2010, commits at source.squeak.org 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 at 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: ''yourEmail at school.edu''.
> 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)!
>
>
>
More information about the Squeak-dev
mailing list
|