'From Squeak5.3alpha of 22 November 2019 [latest update: #19219] on 25 November 2019 at 9:31:55 am'!
"Change Set:		MessageBowserLabelling
Date:			23 November 2019
Author:			tim@rowledge.org

Improve MessageBrowser labelling a bit; it will actually show the full message name being browsed instead of truncating it to the first part of any keyword"!


!MessageSet methodsFor: 'private' stamp: 'mt 11/25/2019 09:31'!
autoSelectString
	"Return the string to be highlighted when making new selections. For actual keyword selectors, only select the first keyword."

	^ autoSelectString ifNotNil: [:stringOrSelector |
		(Symbol lookup: stringOrSelector)
			ifNil: [stringOrSelector "no change"]
			ifNotNil: [:selector | selector precedence = 3
				"only the first part of the keyword message"
				ifTrue: [selector copyFrom: 1 to: (selector indexOf: $:)]
				"no change"
				ifFalse: [stringOrSelector]]]
! !


!MessageTrace methodsFor: 'building' stamp: 'tpr 11/23/2019 17:23'!
addChildMessages: methodReferences autoSelectString: aString 
	| currentIndentionLevel addables selectables selectableString newAnchor |
	selectableString := aString keywords 
		ifEmpty: [ String empty ] 
		ifNotEmptyDo: [ : keywords |
			"we can probably do something more precise here; perhaps recombining the extracted keywords into a single selector? Then again all usages of this method seem to already enforce use of a selector"
			aString ].
	[ (messageListIndex between: 1 and: autoSelectStrings size) ]
		whileFalse: [ autoSelectStrings add: selectableString ].
	currentIndentionLevel := self currentIndentionLevel.
	"Don't add mulitple copies of the same method, if a method is already in the list we will merely select it."
	addables := methodReferences reject: [ : each | messageList includes: each ].
	addables do: 
		[ : each | 
		each stringVersion: (self indentionPrefixOfSize: currentIndentionLevel + 1) , each asStringOrText.
		messageList 
			add: each
			afterIndex: self messageListIndex.
		autoSelectStrings 
			add: nil
			afterIndex: self messageListIndex.
		messageSelections 
			add: false
			afterIndex: self messageListIndex ].
	selectables := 
		addables copy
			addAll: (methodReferences select: [ : each | messageList includes: each ]) ;
			yourself.
	self deselectAll.
	anchorIndex := nil.
	selectables do:
		[ : each |
		self
			messageAt: (newAnchor := messageList indexOf: each) 
			beSelected: true.
		anchorIndex ifNil: [ anchorIndex := newAnchor ] ].
	self changed: #messageList.
	"Select the first child method."
	self messageListIndex: 
		(selectables size > 0
			ifTrue: [ messageList indexOf: selectables last ]
			ifFalse: [ messageList ifEmpty: [ 0 ] ifNotEmpty: [ 1 ] ])! !

!MessageTrace methodsFor: 'building' stamp: 'tpr 11/23/2019 17:24'!
addParentMessages: methodReferences autoSelectString: aString 
	| currentIndentionLevel addables selectables |
	addables := methodReferences reject: [ : each | messageList includes: each ].
	"we may need to process aString here in a similar manner to that in #addChildMessages:autoSelectString:"
	selectables := addables copy
		addAll: (methodReferences select: [ : each | messageList includes: each ]) ;
		yourself.
	currentIndentionLevel := self currentIndentionLevel.
	(currentIndentionLevel = 0 and: [ addables notEmpty ]) ifTrue: 
		[ self indentEverything.
		currentIndentionLevel := 1 ].
	addables do: 
		[ : each | 
		each stringVersion: (self indentionPrefixOfSize: currentIndentionLevel - 1) , each asStringOrText.
		messageList 
			add: each
			afterIndex: self messageListIndex - 1.
		autoSelectStrings 
			add: aString
			afterIndex: self messageListIndex - 1.
		messageSelections 
			add: false
			afterIndex: self messageListIndex - 1 ].
	self deselectAll.
	selectables do:
		[ : each | | messageIndex |
		messageIndex := messageList indexOf: each.
		self
			messageAt: messageIndex 
			beSelected: true.
		autoSelectStrings
			at: messageIndex
			put: aString ].
	self changed: #messageList.
	anchorIndex := messageListIndex.
	selectables size > 0 ifTrue:
		[ self messageListIndex: (messageList indexOf: selectables first) ]! !

!MessageTrace methodsFor: 'actions' stamp: 'tpr 11/23/2019 17:17'!
messageListIndex: anInteger
	autoSelectStrings ifNotEmpty: 
		[ autoSelectString :=
			anInteger = 0
				ifTrue:
					[ defaultSelectString ifNotNil: [:default| self containingWindow setLabel: default].
					"clear the autoSelectString"
					'' ]
				ifFalse:
					[ messageListIndex := anInteger.  
					"setting the window label, below, can't wait for this.."
					self containingWindow setLabel: (self windowLabelAt: anInteger).
					"work out the string to ask the text view to pre-select. We should do better than this; after all the debugger does"
					(autoSelectStrings at: anInteger) ifNotNil: [ : fullSelector | fullSelector keywords first ] ] ].
	anInteger > 0 ifTrue:
		[ self
			messageAt: anInteger
			beSelected: true ].
	super messageListIndex: anInteger
! !


!SystemNavigation methodsFor: 'private' stamp: 'tpr 11/22/2019 21:05'!
headingAndAutoselectForLiteral: aLiteral do: binaryBlock 
	"Evaluate binaryBlock with either Users of ... or Senders of ... plus the auto-select string for the given literal.  aLiteral can be a Symbol, a VariableBinding or an arbitrary object."
	| autoSelect |
	^ aLiteral isSymbol
		ifTrue:
			[ binaryBlock
				value: 'Senders of ' , aLiteral
				value: aLiteral  ]
		ifFalse:
			[ autoSelect := aLiteral isVariableBinding
				ifTrue: [ aLiteral key ]
				ifFalse: [ aLiteral printString ].
			binaryBlock
				value: 'Users of ' , autoSelect
				value: autoSelect ]! !

