Browse Source

Added search result sorting by fitness (can be disabled in DisplaySettings, enabled by default)

pull/668/head
OndrejPetrzilka 10 years ago
parent
commit
1696028252
  1. 16
      ILSpy/Options/DisplaySettings.cs
  2. 1
      ILSpy/Options/DisplaySettingsPanel.xaml
  3. 2
      ILSpy/Options/DisplaySettingsPanel.xaml.cs
  4. 25
      ILSpy/SearchPane.cs
  5. 36
      ILSpy/SearchStrategies.cs

16
ILSpy/Options/DisplaySettings.cs

@ -110,6 +110,21 @@ namespace ICSharpCode.ILSpy.Options @@ -110,6 +110,21 @@ namespace ICSharpCode.ILSpy.Options
}
}
bool sortResults;
public bool SortResults
{
get { return sortResults; }
set
{
if (sortResults != value)
{
sortResults = value;
OnPropertyChanged("SortResults");
}
}
}
public void CopyValues(DisplaySettings s)
{
this.SelectedFont = s.selectedFont;
@ -117,6 +132,7 @@ namespace ICSharpCode.ILSpy.Options @@ -117,6 +132,7 @@ namespace ICSharpCode.ILSpy.Options
this.ShowLineNumbers = s.showLineNumbers;
this.ShowMetadataTokens = s.showMetadataTokens;
this.EnableWordWrap = s.enableWordWrap;
this.SortResults = s.sortResults;
}
}
}

1
ILSpy/Options/DisplaySettingsPanel.xaml

@ -62,6 +62,7 @@ @@ -62,6 +62,7 @@
<CheckBox IsChecked="{Binding ShowLineNumbers}">Show line numbers</CheckBox>
<CheckBox IsChecked="{Binding ShowMetadataTokens}">Show metadata tokens</CheckBox>
<CheckBox IsChecked="{Binding EnableWordWrap}">Enable word wrap</CheckBox>
<CheckBox IsChecked="{Binding SortResults}">Sort results</CheckBox>
</StackPanel>
</GroupBox>
</Grid>

2
ILSpy/Options/DisplaySettingsPanel.xaml.cs

@ -102,6 +102,7 @@ namespace ICSharpCode.ILSpy.Options @@ -102,6 +102,7 @@ namespace ICSharpCode.ILSpy.Options
s.ShowLineNumbers = (bool?)e.Attribute("ShowLineNumbers") ?? false;
s.ShowMetadataTokens = (bool?) e.Attribute("ShowMetadataTokens") ?? false;
s.EnableWordWrap = (bool?)e.Attribute("EnableWordWrap") ?? false;
s.SortResults = (bool?)e.Attribute("SortResults") ?? true; // Enabled by default
return s;
}
@ -118,6 +119,7 @@ namespace ICSharpCode.ILSpy.Options @@ -118,6 +119,7 @@ namespace ICSharpCode.ILSpy.Options
section.SetAttributeValue("ShowLineNumbers", s.ShowLineNumbers);
section.SetAttributeValue("ShowMetadataTokens", s.ShowMetadataTokens);
section.SetAttributeValue("EnableWordWrap", s.EnableWordWrap);
section.SetAttributeValue("SortResults", s.SortResults);
XElement existingElement = root.Element("DisplaySettings");
if (existingElement != null)

25
ILSpy/SearchPane.cs

@ -242,10 +242,32 @@ namespace ICSharpCode.ILSpy @@ -242,10 +242,32 @@ namespace ICSharpCode.ILSpy
}
dispatcher.BeginInvoke(
DispatcherPriority.Normal,
new Action(delegate { this.Results.Insert(this.Results.Count - 1, result); }));
new Action(delegate { InsertResult(result); }));
cts.Token.ThrowIfCancellationRequested();
}
void InsertResult(SearchResult result)
{
if (Options.DisplaySettingsPanel.CurrentDisplaySettings.SortResults)
{
// Keep results collection sorted by "Fitness" by inserting result into correct place
// Inserts in the beginning shifts all elements, but there can be no more than 1000 items.
for (int i = 0; i < this.Results.Count; i++)
{
if (this.Results[i].Fitness < result.Fitness)
{
this.Results.Insert(i, result);
break;
}
}
}
else
{
// Original code
this.Results.Insert(this.Results.Count - 1, result);
}
}
AbstractSearchStrategy GetSearchStrategy(SearchMode mode, string[] terms)
{
if (terms.Length == 1) {
@ -281,6 +303,7 @@ namespace ICSharpCode.ILSpy @@ -281,6 +303,7 @@ namespace ICSharpCode.ILSpy
}
public MemberReference Member { get; set; }
public float Fitness { get; set; }
public string Location { get; set; }
public string Name { get; set; }

36
ILSpy/SearchStrategies.cs

@ -30,6 +30,37 @@ namespace ICSharpCode.ILSpy @@ -30,6 +30,37 @@ namespace ICSharpCode.ILSpy
searchTerm = terms;
}
protected float GetFitness(string text)
{
// TODO: Is it possible to get fitness for regex?
if (regex != null)
return 1;
float result = 0;
for (int i = 0; i < searchTerm.Length; ++i) {
// How to handle overlapping matches?
var term = searchTerm[i];
switch (term[0])
{
case '+': // must contain
term = term.Substring(1);
goto default;
case '-': // should not contain, ignore
break;
case '=': // exact match
term = term.Substring(1);
goto default;
default:
if (text.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0)
{
result += term.Length / (float)text.Length;
}
break;
}
}
return result;
}
protected bool IsMatch(string text)
{
if (regex != null)
@ -93,6 +124,7 @@ namespace ICSharpCode.ILSpy @@ -93,6 +124,7 @@ namespace ICSharpCode.ILSpy
addResult(new SearchResult
{
Member = item,
Fitness = GetFitness(item.Name),
Image = image(item),
Name = item.Name,
LocationImage = TypeTreeNode.GetIcon(type),
@ -340,10 +372,12 @@ namespace ICSharpCode.ILSpy @@ -340,10 +372,12 @@ namespace ICSharpCode.ILSpy
public override void Search(TypeDefinition type, Language language, Action<SearchResult> addResult)
{
if (IsMatch(type.Name) || IsMatch(type.FullName)) {
string name = language.TypeToString(type, includeNamespace: false);
addResult(new SearchResult {
Member = type,
Fitness = GetFitness(name),
Image = TypeTreeNode.GetIcon(type),
Name = language.TypeToString(type, includeNamespace: false),
Name = name,
LocationImage = type.DeclaringType != null ? TypeTreeNode.GetIcon(type.DeclaringType) : Images.Namespace,
Location = type.DeclaringType != null ? language.TypeToString(type.DeclaringType, includeNamespace: true) : type.Namespace
});

Loading…
Cancel
Save