Marcel Taeumel uploaded a new version of ToolBuilder-Kernel to project The Trunk:
http://source.squeak.org/trunk/ToolBuilder-Kernel-mt.127.mcz
==================== Summary ====================
Name: ToolBuilder-Kernel-mt.127
Author: mt
Time: 16 July 2019, 1:58:39.352383 pm
UUID: 20626faf-8ab2-a649-b47e-6b56239d156f
Ancestors: ToolBuilder-Kernel-mt.126
500% faster implementation of uppercase-only search for classes. Thanks to Kjell Godo for the ideas!
=============== Diff against ToolBuilder-Kernel-mt.126 ===============
Item was changed:
----- Method: UIManager>>classOrTraitFrom:pattern:label: (in category 'system introspecting') -----
classOrTraitFrom: environment pattern: pattern label: label
"Given a pattern and an environment, try to find a class or trait using several strategies:
- EXACT: If there is a class or trait whose name exactly given by pattern, return it.
- UPPER: If the pattern is upper-case only, find camel-case letters with that sequence.
- WILD: Try the pattern as-is for regular wild-card search.
- FEATURE: Split patterns at feature boundaries and insert wild cards between.
- FUZZY: Split patterns at feature boundaries BUT treat each feature as a full class name.
If there is only one class or trait in the given environment whose name matches pattern, return it. Otherwise, put up a menu offering the names of all classes that match pattern, and return the class chosen, else nil if nothing chosen.
!!!! In any case, separator characters in the pattern are ignored."
| toMatch potentialNames names selectedIndex |
"If there's a class or trait named as pattern, then return it."
(environment classOrTraitNamed: pattern) ifNotNil: [:classOrTrait | ^ classOrTrait].
"Validate pattern."
toMatch := pattern copyWithoutAll: Character separators.
toMatch := toMatch asLowercase copyWithout: $..
toMatch ifEmpty: [ ^nil ].
"Fetch search space."
names := OrderedCollection new.
potentialNames := environment classAndTraitNames asOrderedCollection.
"Try uppercase-only patterns for patterns such as 'WKD' to find 'WeakIdentityKeyDictionary' etc."
names ifEmpty: [
+ (pattern allSatisfy: [:char | char isUppercase]) ifTrue: [
+ (potentialNames do: [:eachName |
+ | isMatch lookupIndex |
+ isMatch := true.
+ lookupIndex := 0.
+ 1 to: pattern size do: [:charIndex | | char |
+ char := pattern at: charIndex.
+ isMatch ifTrue: [
+ lookupIndex := (eachName findString: char asString startingAt: lookupIndex+1 caseSensitive: true).
+ isMatch := lookupIndex > 0]].
+ isMatch ifTrue: [names add: eachName] ])]].
+
- (pattern allSatisfy: [:char | char isUppercase]) ifTrue: [
- | patternStream |
- patternStream := pattern readStream.
- potentialNames do: [:each |
- patternStream reset.
- each detect: [:char |
- (patternStream atEnd not and: [patternStream peek = char])
- ifTrue: [
- patternStream next.
- patternStream atEnd
- ifTrue: [names add: each. true "Match!!"]
- ifFalse: [false "Not yet..."]]
- ifFalse: [false "No match..."] ] ifNone: [] ] ]].
-
"Try wildcard search for patterns such as 'Weak*Dict*' to find 'WeakIdentityKeyDictionary' etc."
names ifEmpty: [
+ potentialNames do: [ :each | (toMatch match: each) ifTrue: [names add: each] ]].
- names := potentialNames select: [ :each | toMatch match: each ]].
"Try feature-based search for patterns such as 'WeakDict' to find 'WeakIdentityKeyDictionary' etc."
names ifEmpty: [
toMatch := pattern copyWithoutAll: '.*#'.
toMatch findFeatures in: [:features |
"1) Insert wildcards between features and at the end."
toMatch := (features joinSeparatedBy: '*'), '*'.
names := potentialNames select: [ :each | toMatch match: each ].
names ifEmpty: [
"2) Insert wildcards before, between, and after features."
toMatch := '*', (features joinSeparatedBy: '*'), '*'.
names := potentialNames select: [ :each | toMatch match: each ] ]] ].
"Try some fuzzy matching."
names addAll: (pattern suggestedTypeNames select: [ :each | potentialNames includes: each ]).
"Still no match?"
names ifEmpty: [ ^ nil ].
"Let the user select if there's more than one possible match. This may give surprising results."
selectedIndex := names size = 1
ifTrue: [ 1 ]
ifFalse: [ self chooseFrom: names title: label ].
selectedIndex = 0 ifTrue: [ ^nil ].
^environment at: (names at: selectedIndex) asSymbol!
Marcel Taeumel uploaded a new version of ToolBuilder-Kernel to project The Trunk:
http://source.squeak.org/trunk/ToolBuilder-Kernel-mt.126.mcz
==================== Summary ====================
Name: ToolBuilder-Kernel-mt.126
Author: mt
Time: 15 July 2019, 6:00:39.98495 pm
UUID: d492e86b-b9f0-3b46-84c4-1a0d18da0d4d
Ancestors: ToolBuilder-Kernel-mt.125
Minor improvement of the latest class-search changes. Thanks to Kjell Godo.
=============== Diff against ToolBuilder-Kernel-mt.125 ===============
Item was changed:
----- Method: UIManager>>classOrTraitFrom:pattern:label: (in category 'system introspecting') -----
classOrTraitFrom: environment pattern: pattern label: label
"Given a pattern and an environment, try to find a class or trait using several strategies:
- EXACT: If there is a class or trait whose name exactly given by pattern, return it.
- UPPER: If the pattern is upper-case only, find camel-case letters with that sequence.
- WILD: Try the pattern as-is for regular wild-card search.
- FEATURE: Split patterns at feature boundaries and insert wild cards between.
- FUZZY: Split patterns at feature boundaries BUT treat each feature as a full class name.
If there is only one class or trait in the given environment whose name matches pattern, return it. Otherwise, put up a menu offering the names of all classes that match pattern, and return the class chosen, else nil if nothing chosen.
!!!! In any case, separator characters in the pattern are ignored."
| toMatch potentialNames names selectedIndex |
"If there's a class or trait named as pattern, then return it."
(environment classOrTraitNamed: pattern) ifNotNil: [:classOrTrait | ^ classOrTrait].
"Validate pattern."
toMatch := pattern copyWithoutAll: Character separators.
toMatch := toMatch asLowercase copyWithout: $..
toMatch ifEmpty: [ ^nil ].
"Fetch search space."
names := OrderedCollection new.
potentialNames := environment classAndTraitNames asOrderedCollection.
"Try uppercase-only patterns for patterns such as 'WKD' to find 'WeakIdentityKeyDictionary' etc."
names ifEmpty: [
(pattern allSatisfy: [:char | char isUppercase]) ifTrue: [
+ | patternStream |
+ patternStream := pattern readStream.
potentialNames do: [:each |
+ patternStream reset.
- | patternStream |
- patternStream := pattern readStream.
each detect: [:char |
(patternStream atEnd not and: [patternStream peek = char])
ifTrue: [
patternStream next.
patternStream atEnd
ifTrue: [names add: each. true "Match!!"]
ifFalse: [false "Not yet..."]]
ifFalse: [false "No match..."] ] ifNone: [] ] ]].
"Try wildcard search for patterns such as 'Weak*Dict*' to find 'WeakIdentityKeyDictionary' etc."
names ifEmpty: [
names := potentialNames select: [ :each | toMatch match: each ]].
"Try feature-based search for patterns such as 'WeakDict' to find 'WeakIdentityKeyDictionary' etc."
names ifEmpty: [
toMatch := pattern copyWithoutAll: '.*#'.
toMatch findFeatures in: [:features |
"1) Insert wildcards between features and at the end."
toMatch := (features joinSeparatedBy: '*'), '*'.
names := potentialNames select: [ :each | toMatch match: each ].
names ifEmpty: [
"2) Insert wildcards before, between, and after features."
toMatch := '*', (features joinSeparatedBy: '*'), '*'.
names := potentialNames select: [ :each | toMatch match: each ] ]] ].
"Try some fuzzy matching."
names addAll: (pattern suggestedTypeNames select: [ :each | potentialNames includes: each ]).
"Still no match?"
names ifEmpty: [ ^ nil ].
"Let the user select if there's more than one possible match. This may give surprising results."
selectedIndex := names size = 1
ifTrue: [ 1 ]
ifFalse: [ self chooseFrom: names title: label ].
selectedIndex = 0 ifTrue: [ ^nil ].
^environment at: (names at: selectedIndex) asSymbol!
Marcel Taeumel uploaded a new version of ToolBuilder-Kernel to project The Trunk:
http://source.squeak.org/trunk/ToolBuilder-Kernel-mt.125.mcz
==================== Summary ====================
Name: ToolBuilder-Kernel-mt.125
Author: mt
Time: 11 July 2019, 8:50:30.487838 am
UUID: 3f3a21f8-a141-734f-8aed-f0c21aff22b9
Ancestors: ToolBuilder-Kernel-mt.124
Updates the search for class names using the new find-features feature on strings. Find WeakIdentityKeyDictionary (in a small list of results) with any of the following patterns:
WKD
Weak*Dict*
WeakDict
WeakIdentityKeyDictionary
=============== Diff against ToolBuilder-Kernel-mt.124 ===============
Item was changed:
----- Method: UIManager>>classOrTraitFrom:pattern:label: (in category 'system introspecting') -----
classOrTraitFrom: environment pattern: pattern label: label
+ "Given a pattern and an environment, try to find a class or trait using several strategies:
+ - EXACT: If there is a class or trait whose name exactly given by pattern, return it.
+ - UPPER: If the pattern is upper-case only, find camel-case letters with that sequence.
+ - WILD: Try the pattern as-is for regular wild-card search.
+ - FEATURE: Split patterns at feature boundaries and insert wild cards between.
+ - FUZZY: Split patterns at feature boundaries BUT treat each feature as a full class name.
+ If there is only one class or trait in the given environment whose name matches pattern, return it. Otherwise, put up a menu offering the names of all classes that match pattern, and return the class chosen, else nil if nothing chosen.
- "If there is a class or trait whose name exactly given by pattern, return it.
- If there is only one class or trait in the given environment whose name matches pattern, return it.
- Otherwise, put up a menu offering the names of all classes that match pattern, and return the class chosen, else nil if nothing chosen.
- This method ignores separator characters in the pattern"
+ !!!! In any case, separator characters in the pattern are ignored."
+
+ | toMatch potentialNames names selectedIndex |
+
+ "If there's a class or trait named as pattern, then return it."
+ (environment classOrTraitNamed: pattern) ifNotNil: [:classOrTrait | ^ classOrTrait].
+
+ "Validate pattern."
- | toMatch potentialNames names exactMatch lines reducedIdentifiers selectedIndex |
toMatch := pattern copyWithoutAll: Character separators.
+ toMatch := toMatch asLowercase copyWithout: $..
toMatch ifEmpty: [ ^nil ].
+
+ "Fetch search space."
+ names := OrderedCollection new.
+ potentialNames := environment classAndTraitNames asOrderedCollection.
+
+ "Try uppercase-only patterns for patterns such as 'WKD' to find 'WeakIdentityKeyDictionary' etc."
+ names ifEmpty: [
+ (pattern allSatisfy: [:char | char isUppercase]) ifTrue: [
+ potentialNames do: [:each |
+ | patternStream |
+ patternStream := pattern readStream.
+ each detect: [:char |
+ (patternStream atEnd not and: [patternStream peek = char])
+ ifTrue: [
+ patternStream next.
+ patternStream atEnd
+ ifTrue: [names add: each. true "Match!!"]
+ ifFalse: [false "Not yet..."]]
+ ifFalse: [false "No match..."] ] ifNone: [] ] ]].
+
+ "Try wildcard search for patterns such as 'Weak*Dict*' to find 'WeakIdentityKeyDictionary' etc."
+ names ifEmpty: [
+ names := potentialNames select: [ :each | toMatch match: each ]].
- "If there's a class or trait named as pattern, then return it."
- Symbol hasInterned: pattern ifTrue: [ :symbol |
- environment at: symbol ifPresent: [ :maybeClassOrTrait |
- ((maybeClassOrTrait isKindOf: Class) or: [
- maybeClassOrTrait isTrait ])
- ifTrue: [ ^maybeClassOrTrait ] ] ].
- "No exact match, look for potential matches."
- toMatch := pattern asLowercase copyWithout: $..
- potentialNames := (environment classAndTraitNames) asOrderedCollection.
- names := pattern last = $. "This is some old hack, using String>>#match: may be better."
- ifTrue: [ potentialNames select: [ :each | each asLowercase = toMatch ] ]
- ifFalse: [
- potentialNames select: [ :each |
- each includesSubstring: toMatch caseSensitive: false ] ].
- exactMatch := names detect: [ :each | each asLowercase = toMatch ] ifNone: [ nil ].
- lines := OrderedCollection new.
- exactMatch ifNotNil: [ lines add: 1 ].
- "Also try some fuzzy matching."
- reducedIdentifiers := pattern suggestedTypeNames select: [ :each |
- potentialNames includes: each ].
- reducedIdentifiers ifNotEmpty: [
- names addAll: reducedIdentifiers.
- lines add: 1 + names size + reducedIdentifiers size ].
- "Let the user select if there's more than one possible match. This may give surprising results."
- names size = 0 ifTrue: [^ nil "nothing matches"].
+ "Try feature-based search for patterns such as 'WeakDict' to find 'WeakIdentityKeyDictionary' etc."
+ names ifEmpty: [
+ toMatch := pattern copyWithoutAll: '.*#'.
+ toMatch findFeatures in: [:features |
+ "1) Insert wildcards between features and at the end."
+ toMatch := (features joinSeparatedBy: '*'), '*'.
+ names := potentialNames select: [ :each | toMatch match: each ].
+ names ifEmpty: [
+ "2) Insert wildcards before, between, and after features."
+ toMatch := '*', (features joinSeparatedBy: '*'), '*'.
+ names := potentialNames select: [ :each | toMatch match: each ] ]] ].
+
+ "Try some fuzzy matching."
+ names addAll: (pattern suggestedTypeNames select: [ :each | potentialNames includes: each ]).
+
+ "Still no match?"
+ names ifEmpty: [ ^ nil ].
+
+ "Let the user select if there's more than one possible match. This may give surprising results."
selectedIndex := names size = 1
ifTrue: [ 1 ]
+ ifFalse: [ self chooseFrom: names title: label ].
- ifFalse: [
- exactMatch ifNotNil: [ names addFirst: exactMatch ].
- self chooseFrom: names lines: lines title: label ].
selectedIndex = 0 ifTrue: [ ^nil ].
^environment at: (names at: selectedIndex) asSymbol!
Marcel Taeumel uploaded a new version of PreferenceBrowser to project The Trunk:
http://source.squeak.org/trunk/PreferenceBrowser-mt.86.mcz
==================== Summary ====================
Name: PreferenceBrowser-mt.86
Author: mt
Time: 12 July 2019, 10:04:40.745568 am
UUID: 6b577578-3b13-054a-9ad4-d24d1294ec3c
Ancestors: PreferenceBrowser-mt.85
Refactoring of #literalsDo: - Step 3 of 3.
For more information, see http://forum.world.st/Please-Review-Refactoring-for-literalsDo-etc-tp509975….
=============== Diff against PreferenceBrowser-mt.85 ===============
Item was changed:
----- Method: PBPreferenceView>>offerPreferenceNameMenu: (in category 'user interface') -----
offerPreferenceNameMenu: aPreferenceBrowser
"the user clicked on a preference name -- put up a menu"
| aMenu |
aMenu := MenuMorph new
defaultTarget: self preference;
addTitle: self preference name.
(Preferences okayToChangeProjectLocalnessOf: self preference name) ifTrue:
[aMenu addUpdating: #isProjectLocalString target: self preference action: #toggleProjectLocalness.
aMenu balloonTextForLastItem: 'Some preferences are best applied uniformly to all projects, and others are best set by each individual project. If this item is checked, then this preference will be printed in bold and will have a separate value for each project'].
+ aMenu add: 'browse senders' translated target: self systemNavigation selector: #browseAllSelect:name:autoSelect: argumentList: {[:m | self preference selectors anySatisfy: [:sel | m hasLiteral: sel]]. 'Preference senders: {1}' translated format: {self preference name}. self preference selectors first}.
- aMenu add: 'browse senders' translated target: self systemNavigation selector: #browseAllSelect:name:autoSelect: argumentList: {[:m | self preference selectors anySatisfy: [:sel | m hasLiteralThorough: sel]]. 'Preference senders: {1}' translated format: {self preference name}. self preference selectors first}.
aMenu balloonTextForLastItem: 'This will open a method-list browser on all methods that the send the preference "', self preference name, '".'.
aMenu add: 'show category...' target: aPreferenceBrowser selector: #findCategoryFromPreference: argument: self preference name.
aMenu balloonTextForLastItem: 'Allows you to find out which category, or categories, this preference belongs to.'.
Smalltalk isMorphic ifTrue:
[aMenu add: 'hand me a button for this preference' target: self selector: #tearOffButton.
aMenu balloonTextForLastItem: 'Will give you a button that governs this preference, which you may deposit wherever you wish'].
aMenu add: 'copy this name to clipboard' target: self preference selector: #copyName.
aMenu balloonTextForLastItem: 'Copy the name of the preference to the text clipboard, so that you can paste into code somewhere'.
aMenu popUpInWorld!