'From Cuis 1.0 of 26 March 2009 [latest update: #154] on 27 March 2009 at 1:48:40 pm'!

!CharacterScanner methodsFor: 'stop conditions' stamp: 'jmv 3/21/2009 14:50'!
cr
	^self subclassResponsibility! !

!CharacterScanner methodsFor: 'stop conditions' stamp: 'jmv 3/26/2009 15:11'!
lf
	(lastIndex > 1 and: [ (text at: lastIndex-1) = CR ])
		ifTrue: [ 
			destX _ destX + (font widthOf: Character lf).
			lastIndex _ lastIndex + 1.
			^ false ].
	^self cr! !

!CharacterScanner methodsFor: 'stop conditions' stamp: 'jmv 3/21/2009 15:26'!
tab
	^self subclassResponsibility! !


!CharacterScanner class methodsFor: 'class initialization' stamp: 'jmv 3/21/2009 14:48'!
initialize
	"CharacterScanner initialize"
	"NewCharacterScanner initialize"
	| stopConditions |
	stopConditions _ Array new: 258.
	stopConditions atAllPut: nil.
	stopConditions at: 1+1 put: #embeddedObject.
	stopConditions at: Space asciiValue + 1 put: nil.
	stopConditions at: Tab asciiValue + 1 put: #tab.
	stopConditions at: Character lf asciiValue + 1 put: #lf.
	stopConditions at: CR asciiValue + 1 put: #cr.
	stopConditions at: EndOfRun put: #endOfRun.
	stopConditions at: CrossedX put: #crossedX.
	DefaultStopConditions _ stopConditions.! !


!Editor methodsFor: 'typing/selecting keys' stamp: 'jmv 3/27/2009 08:41'!
crlf: characterStream 
	"Append a line feed character to the stream of characters."

	sensor keyboard.
	characterStream
		nextPut: Character cr;
		nextPut: Character lf.
	^false! !

!Editor methodsFor: 'typing/selecting keys' stamp: 'jmv 3/27/2009 08:36'!
lf: characterStream 
	"Append a line feed character to the stream of characters."

	sensor keyboard.
	characterStream nextPut: Character lf.
	^false! !


!SimpleEditor methodsFor: 'typing support' stamp: 'jmv 3/27/2009 08:43'!
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 |
	"We don't support multiple lines. Therefore, we don't process cr as a #normalCharacter:"
	((char == Character cr) "and: [morph acceptOnCR]")
		ifTrue: [
			sensor keyboard.  "Gobble cr -- probably unnecessary."
			self closeTypeIn.
			^ true].

	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])
		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: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
			ifFalse: [self perform: (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: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
			ifFalse: [
				self perform: (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: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream].

	^ self normalCharacter: typeAheadStream! !


!StrikeFont methodsFor: 'accessing' stamp: 'jmv 3/26/2009 15:10'!
widthOf: aCharacter 
	"Answer the width of the argument as a character in the receiver."

	| ascii |
	ascii _ characterToGlyphMap isNil
		ifTrue: [ aCharacter asciiValue ]
		ifFalse: [ characterToGlyphMap at: aCharacter asciiValue + 1 ].
	(ascii >= minAscii and:[ascii <= maxAscii]) ifFalse: [ascii _ maxAscii + 1].
	^ (xTable at: ascii + 2) - (xTable at: ascii + 1)
! !

!StrikeFont methodsFor: 'character shapes' stamp: 'jmv 3/27/2009 09:46'!
makeControlCharsVisible
	| glyph d|
	self characterToGlyphMap.
	glyph _ self characterFormAt: (Character space).
	glyph border: glyph boundingBox width: 1 fillColor: Color blue.
	self characterFormAt: (Character value: 133) put: glyph.
	
	"Keep tab(9), lf(10), cr(13) and space(32) transparent or whatever the user chose"
	#(0 1 2 3 4 5 6 7 8 11 12 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31)
		do: [ :ascii |
			characterToGlyphMap at: ascii + 1 put: 133 ]! !

!StrikeFont methodsFor: 'character shapes' stamp: 'jmv 3/26/2009 14:40'!
makeLfInvisible
	self characterToGlyphMap.
	characterToGlyphMap at: 11 put: (11 < minAscii ifFalse: [11] ifTrue: [maxAscii+1])! !

!StrikeFont methodsFor: 'character shapes' stamp: 'jmv 3/27/2009 09:19'!
makeLfVisible
	| glyph |
	self characterToGlyphMap.
	glyph _ self characterFormAt: (Character value: 163).
	glyph border: glyph boundingBox width: 1 fillColor: Color blue.
"	glyph _ glyph reverse."
	self characterFormAt: (Character value: 132) put: glyph.
	characterToGlyphMap at: 11 put: 132! !

!StrikeFont methodsFor: 'character shapes' stamp: 'jmv 3/26/2009 14:40'!
makeTabInvisible
	self characterToGlyphMap.
	characterToGlyphMap at: 10 put: (10 < minAscii ifFalse: [10] ifTrue:[maxAscii+1])! !

!StrikeFont methodsFor: 'character shapes' stamp: 'jmv 3/26/2009 14:41'!
makeTabVisible
	self characterToGlyphMap.
	characterToGlyphMap at: 10 put: 172! !

!StrikeFont methodsFor: 'character shapes' stamp: 'jmv 3/26/2009 15:17'!
useLeftArrow
	self characterToGlyphMap.
	characterToGlyphMap at: 96 put: 95.
	characterToGlyphMap at: 95 put: 94! !

!StrikeFont methodsFor: 'character shapes' stamp: 'jmv 3/26/2009 14:49'!
useUnderscore
	self characterToGlyphMap.
	characterToGlyphMap at: 96 put: 129.
	characterToGlyphMap at: 95 put: 128! !


!StrikeFont class methodsFor: 'character shapes' stamp: 'jmv 3/27/2009 09:28'!
makeControlCharsVisible
	"
	Make normally not visible characters, visible
	StrikeFont makeControlCharsVisible
	"
	self allInstances do: [ :font | font makeControlCharsVisible ]! !

!StrikeFont class methodsFor: 'character shapes' stamp: 'jmv 3/26/2009 14:51'!
makeLfInvisible
	"
	Make line feed characters invisible
	StrikeFont makeLfInvisible
	"
	self allInstances do: [ :font | font makeLfInvisible ]! !

!StrikeFont class methodsFor: 'character shapes' stamp: 'jmv 3/26/2009 14:51'!
makeLfVisible
	"
	Make line feed characters visible
	StrikeFont makeLfVisible
	"
	self allInstances do: [ :font | font makeLfVisible ]! !

!StrikeFont class methodsFor: 'character shapes' stamp: 'jmv 3/26/2009 14:53'!
makeTabInvisible
	"
	Make tab characters invisible
	StrikeFont makeTabInvisible
	"
	self allInstances do: [ :font | font makeTabInvisible ]! !

!StrikeFont class methodsFor: 'character shapes' stamp: 'jmv 3/26/2009 14:53'!
makeTabVisible
	"
	Make tab characters visible
	StrikeFont makeTabVisible
	"
	self allInstances do: [ :font | font makeTabVisible ]! !

!StrikeFont class methodsFor: 'character shapes' stamp: 'jmv 3/26/2009 14:46'!
useLeftArrow
	"Sets left arrow for asignment (char 95) and up arrow for return (char 94).
	Classic Smalltalk-80 glyphs"
	"
	StrikeFont useLeftArrow
	"
	self allInstances do: [ :font | font useLeftArrow ]! !

!StrikeFont class methodsFor: 'character shapes' stamp: 'jmv 3/26/2009 14:46'!
useUnderscore
	"Sets underscore and caret glyphs for chars 95 and 94. 
	ASCII standard glyphs"
	"
	StrikeFont useUnderscore
	"
	self allInstances do: [ :font | font useUnderscore ]! !


!TextEditor methodsFor: 'editing keys' stamp: 'jmv 3/27/2009 09:55'!
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. 
	self replaceSelectionWith: (Text fromString: fixed).
	^ true! !

!TextEditor methodsFor: 'typing support' stamp: 'jmv 3/27/2009 08:42'!
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])
		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: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
			ifFalse: [self perform: (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: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
			ifFalse: [
				self perform: (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: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream].

	(')]}' includes: char)
		ifTrue: [self blinkPrevParen].

	^ self normalCharacter: typeAheadStream! !

CharacterScanner initialize!
