2
// FileSearchCategory.cs
5
// Mike Krüger <mkrueger@xamarin.com>
7
// Copyright (c) 2012 mkrueger
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
using System.Threading;
28
using System.Threading.Tasks;
29
using MonoDevelop.Core;
30
using System.Collections.Generic;
31
using MonoDevelop.Core.Instrumentation;
32
using MonoDevelop.Projects;
33
using MonoDevelop.Ide.Gui;
34
using MonoDevelop.Ide;
35
using ICSharpCode.NRefactory.TypeSystem;
36
using MonoDevelop.Ide.TypeSystem;
37
using MonoDevelop.Core.Text;
40
using MonoDevelop.Components.Commands;
42
namespace MonoDevelop.Components.MainToolbar
44
class CommandSearchCategory : SearchCategory
48
public CommandSearchCategory (Widget widget) : base (GettextCatalog.GetString("Commands"))
51
this.lastResult = new WorkerResult (widget);
54
WorkerResult lastResult;
55
string[] validTags = new [] { "cmd", "command" };
57
public override bool IsValidTag (string tag)
59
return validTags.Any (t => t == tag);
62
public override Task<ISearchDataSource> GetResults (SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token)
64
// NOTE: This is run on the UI thread as checking whether or not a command is enabled is not thread-safe
65
return Task.Factory.StartNew (delegate {
67
if (searchPattern.Tag != null && !validTags.Contains (searchPattern.Tag) || searchPattern.HasLineNumber)
69
WorkerResult newResult = new WorkerResult (widget);
70
newResult.pattern = searchPattern.Pattern;
72
newResult.matcher = StringMatcher.GetMatcher (searchPattern.Pattern, false);
73
newResult.FullSearch = true;
76
AllResults (lastResult, newResult, token);
77
newResult.results.SortUpToN (new DataItemComparer (token), resultsCount);
78
lastResult = newResult;
79
return (ISearchDataSource)newResult.results;
81
token.ThrowIfCancellationRequested ();
84
}, token, TaskCreationOptions.None, Xwt.Application.UITaskScheduler);
87
void AllResults (WorkerResult lastResult, WorkerResult newResult, CancellationToken token)
89
CommandTargetRoute route = new CommandTargetRoute (MainToolbar.LastCommandTarget);
90
newResult.filteredCommands = new List<Command> ();
91
bool startsWithLastFilter = lastResult != null && lastResult.pattern != null && newResult.pattern.StartsWith (lastResult.pattern) && lastResult.filteredCommands != null;
92
IEnumerable<Command> allCommands = startsWithLastFilter ? lastResult.filteredCommands : IdeApp.CommandService.GetCommands ();
93
foreach (Command cmd in allCommands) {
94
token.ThrowIfCancellationRequested ();
95
SearchResult curResult = newResult.CheckCommand (cmd, route);
96
if (curResult != null) {
97
newResult.filteredCommands.Add (cmd);
98
newResult.results.AddResult (curResult);
105
public List<Command> filteredCommands = null;
106
public string pattern = null;
107
public ResultsDataSource results;
108
public bool FullSearch;
109
public StringMatcher matcher = null;
111
public WorkerResult (Widget widget)
113
results = new ResultsDataSource (widget);
116
internal SearchResult CheckCommand (Command c, CommandTargetRoute route)
118
ActionCommand cmd = c as ActionCommand;
119
if (cmd == null || cmd.CommandArray)
123
string matchString = cmd.Text.Replace ("_", "");
124
if (MatchName (matchString, out rank)) {
126
var ci = IdeApp.CommandService.GetCommandInfo (cmd.Id, route);
127
if (ci.Enabled && ci.Visible)
128
return new CommandResult (cmd, ci, route, pattern, matchString, rank);
129
} catch (Exception ex) {
130
LoggingService.LogError ("Failure while checking command: " + cmd.Id, ex);
136
Dictionary<string, MatchResult> savedMatches = new Dictionary<string, MatchResult> ();
137
bool MatchName (string name, out int matchRank)
143
MatchResult savedMatch;
144
if (!savedMatches.TryGetValue (name, out savedMatch)) {
145
bool doesMatch = matcher.CalcMatchRank (name, out matchRank);
146
savedMatches[name] = savedMatch = new MatchResult (doesMatch, matchRank);
149
matchRank = savedMatch.Rank;
150
return savedMatch.Match;