Chris Muller uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-cmm.1020.mcz
==================== Summary ====================
Name: Collections-cmm.1020
Author: cmm
Time: 13 July 2022, 9:16:12.177315 pm
UUID: 4a9e11ba-f983-4c7b-b701-ddabf2f10c73
Ancestors: Collections-cmm.1019
In addition to ascii letters and numbers, let #format: accept _/-.,!@#$%^&*()[]=;: in the token names. There is no performance hit thanks to the use of a new CharacterSet.
=============== Diff against Collections-cmm.1019 ===============
Item was changed:
ArrayedCollection subclass: #String
instanceVariableNames: ''
+ classVariableNames: 'AsciiOrder CSMacroCharacters CaseInsensitiveOrder CaseSensitiveOrder CrLfExchangeTable FormatCharacterSet FormatTokenCharacters HtmlEntities LowercasingTable Tokenish UppercasingTable'
- classVariableNames: 'AsciiOrder CSMacroCharacters CaseInsensitiveOrder CaseSensitiveOrder CrLfExchangeTable FormatCharacterSet HtmlEntities LowercasingTable Tokenish UppercasingTable'
poolDictionaries: ''
category: 'Collections-Strings'!
!String commentStamp: '<historical>' prior: 0!
A String is an indexed collection of Characters. Class String provides the abstract super class for ByteString (that represents an array of 8-bit Characters) and WideString (that represents an array of 32-bit characters). In the similar manner of LargeInteger and SmallInteger, those subclasses are chosen accordingly for a string; namely as long as the system can figure out so, the String is used to represent the given string.
Strings support a vast array of useful methods, which can best be learned by browsing and trying out examples as you find them in the code.
Here are a few useful methods to look at...
String match:
String contractTo:
String also inherits many useful methods from its hierarchy, such as
SequenceableCollection ,
SequenceableCollection copyReplaceAll:with:
!
Item was changed:
----- Method: String class>>initialize (in category 'initialization') -----
initialize "self initialize"
| order |
AsciiOrder := (0 to: 255) as: ByteArray.
CaseInsensitiveOrder := AsciiOrder copy.
($a to: $z) do:
[:c | CaseInsensitiveOrder at: c asciiValue + 1
put: (CaseInsensitiveOrder at: c asUppercase asciiValue +1)].
"Case-sensitive compare sorts space, digits, letters, all the rest..."
CaseSensitiveOrder := ByteArray new: 256 withAll: 255.
order := -1.
' 0123456789' do: "0..10"
[:c | CaseSensitiveOrder at: c asciiValue + 1 put: (order := order+1)].
($a to: $z) do: "11-64"
[:c | CaseSensitiveOrder at: c asUppercase asciiValue + 1 put: (order := order+1).
CaseSensitiveOrder at: c asciiValue + 1 put: (order := order+1)].
1 to: CaseSensitiveOrder size do:
[:i | (CaseSensitiveOrder at: i) = 255 ifTrue:
[CaseSensitiveOrder at: i put: (order := order+1)]].
order = 255 ifFalse: [self error: 'order problem'].
"a table for translating to lower case"
LowercasingTable := String withAll: (Character allByteCharacters collect: [:c | c asLowercase]).
"a table for translating to upper case"
UppercasingTable := String withAll: (Character allByteCharacters collect: [:c | c asUppercase]).
"a table for testing tokenish (for fast numArgs)"
Tokenish := String withAll: (Character allByteCharacters collect:
[:c | c tokenish ifTrue: [c] ifFalse: [$~]]).
"% and < for #expandMacros*"
CSMacroCharacters := CharacterSet newFrom: '%<'.
"{\ used by #format:"
FormatCharacterSet := CharacterSet newFrom: '{\'.
+ FormatTokenCharacters := CharacterSet newFrom: ($A to: $Z), ($a to: $z), ($0 to: $9), '_/-.,!!@#$%^&*()[]=;:'.
"a table for exchanging cr with lf and vica versa"
CrLfExchangeTable := Character allByteCharacters collect: [ :each |
each
caseOf: {
[ Character cr ] -> [ Character lf ].
[ Character lf ] -> [ Character cr ] }
otherwise: [ each ] ]!
Item was changed:
----- Method: String>>format: (in category 'formatting') -----
format: aCollection
"Substitute tokens in the receiver with element values of aCollection. The tokens are indicated in curly-braces and may be either numeric, e.g., {1}, {2}, etc. and map to a SequenceableCollection, OR, alphanumeric, e.g., {name}, {date}, etc., in which case aCollection should be a Dictionary.
The values can be static or, with the specification of a Block element, dynamic.
Simplest examples:
'foo {date} bar' format: ({'date'->Date today} as: Dictionary).
Dynamic calculation is allowed via Blocks.
'foo {NOW} bar' format: ({'NOW'-> [DateAndTime now]} as: Dictionary).
Backward-compatible with numeric-only #format:
'foo {1} bar' format: {Date today}.
Now with block support:
'foo {1} bar' format: {[Date today]}.
Complete example with escaped characters:
'\{ \} \\ foo {1} bar {2}' format: {12. 'string'}.
'\{ \} \\ foo {FOO} bar {BAR}' format: ({'FOO'->12. 'BAR'->'string'} as: Dictionary)."
^ self class
new: self size * 11 // 10 "ready for +10% growth"
streamContents:
[ : output | | lastIndex nextIndex key |
lastIndex := 1.
key := 0.
[ "stream to output until first { or \"
(nextIndex := self indexOfAnyOf: FormatCharacterSet startingAt: lastIndex) = 0 ] whileFalse:
[ nextIndex = lastIndex ifFalse:
[ output next: nextIndex - lastIndex putAll: self startingAt: lastIndex ].
"special char hit, escape char?"
(self at: nextIndex) == $\
ifTrue:
[ "transfer the escaped character. "
output nextPut: (self at: (nextIndex := nextIndex + 1)) ]
ifFalse:
[ | nextKeyChar |
"${ char, parse the key"
[ nextKeyChar := self at: (nextIndex := nextIndex + 1).
+ FormatTokenCharacters includes: nextKeyChar ] whileTrue:
- nextKeyChar isAscii and: [ nextKeyChar isAlphaNumeric ] ] whileTrue:
[ (key isInteger and: [ nextKeyChar between: $0 and: $9 ])
ifTrue: [ key := key * 10 + nextKeyChar digitValue ]
ifFalse:
[ key isInteger ifTrue:
[ key := WriteStream with:
(key isZero
ifTrue: [ String empty ]
ifFalse: [ key asString ]) ].
key nextPut: nextKeyChar ] ].
nextKeyChar == $} ifFalse: [ self error: '$} expected' translated ].
key isInteger
ifTrue:
[ output nextPutAll: (aCollection at: key) value asString.
key := 0 ]
ifFalse:
[ output nextPutAll: (aCollection at: key contents) value asString.
key reset ] ].
lastIndex := nextIndex + 1 ].
lastIndex <= self size ifTrue:
[ output next: self size - lastIndex + 1 putAll: self startingAt: lastIndex ] ]!
Eliot Miranda uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-eem.1168.mcz
==================== Summary ====================
Name: Tools-eem.1168
Author: eem
Time: 13 July 2022, 4:29:53.654209 pm
UUID: 3ce13884-de6d-4e9d-8ada-6eca4fd59835
Ancestors: Tools-eem.1167
Refactor selectMethodsForThisClass & selectSuchThat: so that any of selectMethodsForThisClass, selectMethodsForExtantClasses, & selectContentsMatching can extend selections via the shift key.
=============== Diff against Tools-eem.1167 ===============
Item was changed:
----- Method: ChangeList>>mainChangeListMenu: (in category 'menu actions') -----
mainChangeListMenu: aMenu
"Fill aMenu up so that it comprises the primary changelist-browser menu"
<changeListMenu>
aMenu addTitle: 'change list' translated.
aMenu addStayUpItemSpecial.
aMenu addTranslatedList: #(
('fileIn selections' fileInSelections 'import the selected items into the image')
('fileOut selections...' fileOutSelections 'create a new file containing the selected items')
-
('compare to current' compareToCurrentVersion 'open a separate window which shows the text differences between the on-file version and the in-image version.' )
('toggle diffing (D)' toggleDiffing 'start or stop showing diffs in the code pane.')
-
('select conflicts with any changeset' selectAllConflicts 'select methods in the file which also occur in any change-set in the system')
('select conflicts with current changeset' selectConflicts 'select methods in the file which also occur in the current change-set')
('select conflicts with...' selectConflictsWith 'allows you to designate a file or change-set against which to check for code conflicts.')
-
('select unchanged definitions' selectUnchangedDefinitions 'select class definitions, class comments and methods in the file whose in-image versions are the same as their in-file counterparts' )
('select unchanged methods' selectUnchangedMethods 'select methods in the file whose in-image versions are the same as their in-file counterparts' )
('select new methods' selectNewMethods 'select methods in the file that do not current occur in the image')
+ ('select methods for this class' selectMethodsForThisClass 'select all methods in the file that belong to the currently-selected class\(shift to extend selections)')
+ ('select methods for extant classes' selectMethodsForExtantClasses 'select all methods in the file that belong to a class that exists in the image\(shift to extend selections)')
+ ('select changes with contents matching' selectContentsMatching 'select all changes in the file whose text includes a pattern\(shift to extend selections)')
- ('select methods for this class' selectMethodsForThisClass 'select all methods in the file that belong to the currently-selected class')
- ('select methods for extant classes' selectMethodsForExtantClasses 'select all methods in the file that belong to a class that exists in the image')
- ('select changes with contents matching' selectContentsMatching 'select all changes in the file whose text includes a pattern')
-
('select all (a)' selectAll 'select all the items in the list')
('deselect all' deselectAll 'deselect all the items in the list')
('invert selections' invertSelections 'select every item that is not currently selected, and deselect every item that *is* currently selected')
('select all before' selectAllBefore 'select every item before the current selection')
-
('browse all versions of single selection' browseVersions 'open a version browser showing the versions of the currently selected method')
('browse all versions of selections' browseAllVersionsOfSelections 'open a version browser showing all the versions of all the selected methods')
('browse current versions of selections' browseCurrentVersionsOfSelections 'open a message-list browser showing the current (in-image) counterparts of the selected methods')
('destroy current methods of selections' destroyCurrentCodeOfSelections 'remove (*destroy*) the in-image counterparts of all selected methods')
-
('remove doIts' removeDoIts 'remove all items that are doIts rather than methods')
('remove older versions' removeOlderMethodVersions 'remove all but the most recent versions of methods in the list')
('remove up-to-date versions' removeExistingMethodVersions 'remove all items whose code is the same as the counterpart in-image code')
('remove selected items' removeSelections 'remove the selected items from the change-list')
('remove unselected items' removeNonSelections 'remove all the items not currently selected from the change-list')).
^ aMenu!
Item was changed:
----- Method: ChangeList>>selectMethodsForThisClass (in category 'menu actions') -----
selectMethodsForThisClass
+ | name |
self currentChange ifNil: [ ^self ].
+ name := self currentChange methodClassName.
+ name ifNil: [ ^self ].
+ ^self selectSuchThat: [ :change |
+ change methodClassName = name ].!
- self currentChange methodClassName ifNotNil:
- [:name|
- self selectSuchThat:
- (Sensor leftShiftDown
- ifTrue: [[:change :index| (listSelections at: index) or: [change methodClassName = name]]]
- ifFalse: [[:change| change methodClassName = name]])]!
Item was changed:
----- Method: ChangeList>>selectSuchThat: (in category 'menu actions') -----
selectSuchThat: aBlock
+ "Select all changes for which block returns true.
+ If the shift key is down then extend the selections with those for which block returns true."
+ listSelections := Sensor leftShiftDown
+ ifTrue:
+ [changeList withIndexCollect: (aBlock numArgs = 2
+ ifTrue: [[:change :index| (listSelections at: index) or: [aBlock value: change value: index]]]
+ ifFalse: [[:change :index| (listSelections at: index) or: [aBlock value: change]]])]
+ ifFalse:
+ [aBlock numArgs = 2
+ ifTrue: [changeList withIndexCollect: aBlock]
+ ifFalse: [changeList collect: aBlock]].
- "select all changes for which block returns true"
- listSelections := aBlock numArgs = 2
- ifTrue: [changeList withIndexCollect: aBlock]
- ifFalse: [changeList collect: aBlock].
self changed: #allSelections!
Eliot Miranda uploaded a new version of ToolBuilder-Kernel to project The Trunk:
http://source.squeak.org/trunk/ToolBuilder-Kernel-eem.161.mcz
==================== Summary ====================
Name: ToolBuilder-Kernel-eem.161
Author: eem
Time: 13 July 2022, 4:28:54.356068 pm
UUID: 7f9d44e6-c980-4c58-8bfe-57108fb8f8e0
Ancestors: ToolBuilder-Kernel-tpr.160
Allow the help in a menu tuple contain \'s for carriage returns, to make balloon help easier to format/read.
=============== Diff against ToolBuilder-Kernel-tpr.160 ===============
Item was changed:
----- Method: PluggableMenuSpec>>addList: (in category 'construction') -----
addList: aList
"Add the given items to this menu, where each item is a pair (<string> <actionSelector>).. If an element of the list is simply the symobl $-, add a line to the receiver. The optional third element of each entry, if present, provides balloon help."
aList do: [:tuple |
+ tuple == #-
- (tuple == #-)
ifTrue: [self addSeparator]
ifFalse:[ | item |
item := self add: tuple first target: model selector: tuple second argumentList: #().
+ tuple size > 2 ifTrue:[item help: tuple third withCRs]]]!
- tuple size > 2 ifTrue:[item help: tuple third]]]!
Eliot Miranda uploaded a new version of MorphicExtras to project The Trunk:
http://source.squeak.org/trunk/MorphicExtras-eem.321.mcz
==================== Summary ====================
Name: MorphicExtras-eem.321
Author: eem
Time: 13 July 2022, 4:27:52.458073 pm
UUID: 7b3c5d64-9127-4ff0-af18-fcd383257a4b
Ancestors: MorphicExtras-eem.320
Fix a bug in the WebCamMorph where turning the camera off and on can change the resolution if not using frame size.
=============== Diff against MorphicExtras-eem.320 ===============
Item was changed:
----- Method: WebCamMorph>>on (in category 'accessing') -----
on
camIsOn ifTrue: [^true].
(CameraInterface cameraIsOpen: camNum) ifFalse:
+ [| extent |
+ extent := self class resolutionFor: resolution.
+ (CameraInterface openCamera: camNum width: extent x height: extent y) ifNil:
- [(CameraInterface openCamera: camNum width: frameExtent x height: frameExtent y) ifNil:
[^false]].
"The plugin/camera subsystem may end up choosing a different width and height.
So use the width and height it has selected; it may not be what was asked for."
self initializeDisplayForm.
CameraInterface waitForCameraStart: camNum.
camIsOn := true.
self startStepping!
Eliot Miranda uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-eem.2020.mcz
==================== Summary ====================
Name: Morphic-eem.2020
Author: eem
Time: 13 July 2022, 4:26:13.938059 pm
UUID: cc442f16-be3a-4aeb-846f-40e0f4fc3d8e
Ancestors: Morphic-mt.2019
Allow the help in a menu tuple contain \'s for carriage returns, to make balloon help easier to format/read.
=============== Diff against Morphic-mt.2019 ===============
Item was changed:
----- Method: MenuMorph>>addList: (in category 'construction') -----
addList: aList
"Add the given items to this menu, where each item is a pair (<string> <actionSelector>).. If an element of the list is simply the symobl $-, add a line to the receiver. The optional third element of each entry, if present, provides balloon help."
aList do: [:tuple |
+ tuple == #-
- (tuple == #-)
ifTrue: [self addLine]
ifFalse:
[self add: tuple first action: tuple second.
tuple size > 2 ifTrue:
+ [self balloonTextForLastItem: tuple third withCRs]]]!
- [self balloonTextForLastItem: tuple third]]]!
Eliot Miranda uploaded a new version of Files to project The Trunk:
http://source.squeak.org/trunk/Files-eem.194.mcz
==================== Summary ====================
Name: Files-eem.194
Author: eem
Time: 13 July 2022, 4:24:30.730576 pm
UUID: e93e9c68-370b-46ab-8cf7-b5ee4de65468
Ancestors: Files-ct.193
A changes file contains Smalltalk source code so it should be included in the set of sourceFileSuffixes. Otherwise there's no easy way to open a ChangeList or source code browser on an entire changes file.
=============== Diff against Files-ct.193 ===============
Item was added:
+ ----- Method: FileStream class>>changes (in category 'file reader services') -----
+ changes
+
+ ^'changes' shallowCopy!
Item was changed:
----- Method: FileStream class>>sourceFileSuffixes (in category 'file reader services') -----
sourceFileSuffixes
+ ^ {FileStream st. FileStream sources. FileStream changes. FileStream cs. FileStream multiSt. FileStream multiCs} asSet asArray!
- ^ {FileStream st. FileStream sources. FileStream cs. FileStream multiSt. FileStream multiCs} asSet asArray.
-
- !