How to configure search filters in Spotter extensions

The class GtSpotterFiltersConfiguration Object << #GtSpotterFiltersConfiguration slots: { #configurationById }; tag: 'Model'; package: 'GToolkit-Spotter' allows users to specify custom configurations for search filters.

Some of its usages are:

- configuring searches for class names in the extension GtSpotterStart>>#gtSearchForClassesFor: gtSearchForClassesFor: aSearch <gtSearch> ^ aSearch list priority: 10; title: 'Classes'; items: [ SystemNavigation default allClassesAndTraits ]; itemName: [ :aClass | aClass name ]; filterBySubstringsWith: [ :aSearchFilter :aSpotterContext | aSearchFilter withWordsSplitter; beCaseSensitiveByCapitalization; applyConfigurationWithId: #classSearch inContext: aSpotterContext ]; wantsToDisplayOnEmptyQuery: false; yourself

- configuring searches for methods within a class, like in Class>>#gtSpotterMethodsFor: gtSpotterMethodsFor: aSearch <gtSearch> ^ aSearch list priority: 10; title: 'Instance methods'; items: [ self methods ]; itemName: [ :method | method selector ]; filterBySubstringsWith: [ :aSearchFilter :aSpotterContext | aSearchFilter withSelectorWordsSplitter; beCaseSensitiveByCapitalization; applyConfigurationWithId: #methodSelectorSearch inContext: aSpotterContext ]; sendCategory: [ :aCategory :aStep :thisSearch | (GtSearchCustomScopedMethodsFilter new filterLabel: self class instanceSide name , ' instance methods & ' , aStep searchQuery printString, ' implementors'; defaultFilterScope: aCategory items asyncSimilarCopy) ] "search: [ :aContext | GtPharoIndex current asyncImplementersForWord: aContext searchQuery convertUsing: [ :each | self compiledMethodAt: each ifAbsent: [ ] ] ]; itemName: [ :method | method selector ]" or Class>>#gtSpotterClassMethodsFor: gtSpotterClassMethodsFor: aSearch <gtSearch> ^ aSearch list priority: 15; title: 'Class methods'; items: [ self classSide metaMethods ]; itemName: [ :method | method selector ]; filterBySubstringsWith: [ :aSearchFilter :aSpotterContext | aSearchFilter withSelectorWordsSplitter; beCaseSensitiveByCapitalization; applyConfigurationWithId: #methodSelectorSearch inContext: aSpotterContext ]; sendCategory: [ :aCategory :aStep :thisSearch | (GtSearchCustomScopedMethodsFilter new filterLabel: self class instanceSide name , ' class methods & ' , aStep searchQuery printString, ' implementors'; defaultFilterScope: aCategory items asyncSimilarCopy) ] "search: [ :aContext | GtPharoIndex current asyncImplementersForWord: aContext searchQuery convertUsing: [ :each | self classSide compiledMethodAt: each ifAbsent: [ ] ] ]; itemName: [ :method | method selector ]"

GtSpotterFiltersConfiguration default 
  

Below is the current default configuration for class searches. This splits the query into words by capitalization and the matching of each word is case sensitive in case the first letter is uppercase.

GtSpotterFiltersConfiguration default 
	putSubstringsConfigurationWithId: #classSearch 
	with: [ :aSubstringsConfiguration |
		aSubstringsConfiguration
			withWordsSplitter;
			beCaseSensitiveByCapitalization ]
  

An example of a configuration where the query is split by space and asterisk, and the matching of each word is case sensitive in case the first letter is uppercase.

GtSpotterFiltersConfiguration default 
	putSubstringsConfigurationWithId: #classSearch 
	with: [ :aSubstringsConfiguration |
		aSubstringsConfiguration
			withCharacterSplitterBy: (Array 
				with: Character space
				with: $*);
			beCaseSensitiveByCapitalization ]
  

Using only spaces to separate query words and using case insensitive matching for each one.

GtSpotterFiltersConfiguration default 
	putSubstringsConfigurationWithId: #classSearch 
	with: [ :aSubstringsConfiguration |
		aSubstringsConfiguration
			withCharacterSplitter;
			beCaseInsensitive ]
  

Splitting by capitalization and using case insensitive matching for each query word.

GtSpotterFiltersConfiguration default 
	putSubstringsConfigurationWithId: #classSearch 
	with: [ :aSubstringsConfiguration |
		aSubstringsConfiguration
			withWordsSplitter;
			beCaseInsensitive ]
  

Below is the current default configuration for method selector searches. This splits the query into words by capitalization and uses the character colon (:) as a separator that is included in the word. It does not spit for the character underscore (_), and characters for binary selectors (+-/\*~<>=@,%|&?!·÷±×). The matching of each word is case sensitive in case the first letter is uppercase.

GtSpotterFiltersConfiguration default 
	putSubstringsConfigurationWithId: #methodSelectorSearch 
	with: [ :aSubstringsConfiguration |
		aSubstringsConfiguration
			withSelectorWordsSplitter;
			beCaseSensitiveByCapitalization ]
  

We keep the split based selector words, but use case insensitive matching for each word.

GtSpotterFiltersConfiguration default 
	putSubstringsConfigurationWithId: #methodSelectorSearch 
	with: [ :aSubstringsConfiguration |
		aSubstringsConfiguration
			withSelectorWordsSplitter;
			beCaseSensitiveByCapitalization ]
  

Using only spaces to separate query words and using case insensitive matching for each word.

GtSpotterFiltersConfiguration default 
	putSubstringsConfigurationWithId: #methodSelectorSearch 
	with: [ :aSubstringsConfiguration |
		aSubstringsConfiguration
			withCharacterSplitter;
			beCaseInsensitive ]
  

Using only spaces to separate query words and using case sensitive matching for each one.

GtSpotterFiltersConfiguration default 
	putSubstringsConfigurationWithId: #methodSelectorSearch 
	with: [ :aSubstringsConfiguration |
		aSubstringsConfiguration
			withCharacterSplitter;
			beCaseSensitive ]
  
GtSpotterFiltersConfiguration default 
	removeConfigurationWithId: #classSearch
  
GtSpotterFiltersConfiguration default 
	removeConfigurationWithId: #methodSelectorSearch
  

The substrings filter splits a query into words. There are currently three available splitters:

GtSpotterByWordsQuerySplitter GtSpotterByWordsBasicQuerySplitter << #GtSpotterByWordsQuerySplitter slots: {}; tag: 'Model'; package: 'GToolkit-Spotter'

GtSpotterBySelectorWordsQuerySplitter GtSpotterByWordsBasicQuerySplitter << #GtSpotterBySelectorWordsQuerySplitter slots: {}; tag: 'Model'; package: 'GToolkit-Spotter'

GtSpotterByCharacterQuerySplitter GtSpotterQuerySplitter << #GtSpotterByCharacterQuerySplitter slots: { #wordSeparators }; tag: 'Model'; package: 'GToolkit-Spotter'

The character splitter in GtSpotterByCharacterQuerySplitter GtSpotterQuerySplitter << #GtSpotterByCharacterQuerySplitter slots: { #wordSeparators }; tag: 'Model'; package: 'GToolkit-Spotter' takes a list of characters by which it splits the query into words. By default space is used

splitter := GtSpotterByCharacterQuerySplitter new.
  
splitter splitQueryString: 'one two three'
  

The splitter GtSpotterByWordsQuerySplitter GtSpotterByWordsBasicQuerySplitter << #GtSpotterByWordsQuerySplitter slots: {}; tag: 'Model'; package: 'GToolkit-Spotter' splits by camel case, and also when there are non letter characters.

splitter := GtSpotterByWordsQuerySplitter new.
  
splitter splitQueryString: 'OneTwoThree'
  
splitter splitQueryString: 'one two three'
  
splitter splitQueryString: 'ONeTwoThree3 Four fiveSix'
  
splitter splitQueryString: 'One***Two---Three!@$Four'
  

The splitter GtSpotterBySelectorWordsQuerySplitter GtSpotterByWordsBasicQuerySplitter << #GtSpotterBySelectorWordsQuerySplitter slots: {}; tag: 'Model'; package: 'GToolkit-Spotter' splits by camel case and non letter characters, using also the character colon (:) as the end of a word. It does not split the character underscore (_), and characters for binary selectors (+-/\*~<>=@,%|&?!·÷±×).

So if there are no colon, underscore and special selectors characters it slipts likeGtSpotterByCharacterQuerySplitter GtSpotterQuerySplitter << #GtSpotterByCharacterQuerySplitter slots: { #wordSeparators }; tag: 'Model'; package: 'GToolkit-Spotter' .

splitter := GtSpotterBySelectorWordsQuerySplitter new.
  
splitter splitQueryString: 'printon:'
  
splitter splitQueryString: 'printOn:'
  
splitter splitQueryString: 'copyFrom:to:'
  
splitter splitQueryString: 'copy12From:to:'
  
splitter splitQueryString: 'copy_from:to:'
  
splitter splitQueryString: 'deprecated:on:in:transformWith:when:' 
  
splitter splitQueryString: '~~'