Пример #1
0
        static ParseResult CreateTextFacetResult(ParseInput input, ParseRange range)
        {
            var textForRange = input.GetTextForRange(range).Trim();
            var moniker      = new FacetMoniker(typeof(EngineFacetsFactory), typeof(TextFacet), textForRange, textForRange);

            return(new ParseResult(input, range, moniker, ParseResult.ExactMatchRelevance));
        }
Пример #2
0
        protected override IEnumerable <ParseResult> ParseImpl(ParseInput input, IEnumerable <FacetMoniker> indexEntries)
        {
            var increment = 1.0 / input.Terms.Count;

            foreach (var entry in indexEntries)
            {
                var relevance = 0.0;
                var lower     = entry.DisplayName.ToLower();
                var range     = new ParseRange(0, 0);

                foreach (var term in input.Terms)
                {
                    if (lower.StartsWith(term.TextLower))
                    {
                        relevance += increment * 1.5;
                    }
                    else if (lower.Contains(term.TextLower))
                    {
                        relevance += increment;
                    }
                    else
                    {
                        // require constant progress
                        break;
                    }

                    range = range.Union(term.Range);

                    if (relevance > 0.0)
                    {
                        yield return(new ParseResult(input, range, entry, Math.Min(1.0, relevance)));
                    }
                }
            }
        }
Пример #3
0
        ParseResult CreateParseResult(ParseInput input, ParseRange range, bool isSuggestion, string path, double relevance, bool isDirectory)
        {
            var type = "Folder";

            if (!isDirectory)
            {
                switch (Path.GetExtension(path).ToLower())
                {
                case ".lnk":
                case ".exe":
                    type = "Program";
                    break;

                default:
                    type = "File";
                    break;
                }
            }

            var moniker = new FacetMoniker(GetType(), typeof(FileSystemItemFacet), path,
                                           path, extraData: FacetExtraData.BeginWith(typeof(IFileSystemItemFacet), "Type", type), iconPath: null);

            return(new ParseResult(input, range, moniker, relevance, isSuggestion));
        }
Пример #4
0
        static List <CommandArgument> CreateCommand(ParseInput input, List <ParseRange> rangeList,
                                                    IDictionary <ParseRange, ParseResult[]> groupedResults,
                                                    IEnumerable <CommandParameter> parameters)
        {
            var argList             = new List <CommandArgument>();
            var unusedRanges        = new List <ParseRange>(rangeList);
            var textFacetParamIndex = -1;

            // The arguments don't have to appear in the same order as the parameters, so we loop through
            // parameters and pull out the first eligible argument for each. At the end of the loop, if all
            // arguments have been used, we can proceed to the next step.

            foreach (var param in parameters)
            {
                if (param.Type == typeof(ITextFacet))
                {
                    textFacetParamIndex = argList.Count;
                    argList.Add(CommandArgument.Unspecified);
                    continue;
                }

                var anyInRangeQuery =
                    from r in unusedRanges
                    where r != null && !ReferenceEquals(r, RemainingTextRangeMarker)
                    from pr in groupedResults[r]
                    where param.IsUsableAsArgument(pr.FacetMoniker)
                    select pr;

                var found = anyInRangeQuery.FirstOrDefault();

                if (found == null)
                {
                    // No match in the parse results

                    // Try ambient facets
                    var ambient = Loader.AmbientFacets
                                  .Where(x => param.IsUsableAsArgument(x.Moniker))
                                  .Select(x => x.Moniker)
                                  .FirstOrDefault();

                    if (ambient != null)
                    {
                        argList.Add(new CommandArgument(ambient));
                        continue;
                    }

                    argList.Add(CommandArgument.Unspecified);
                    continue;
                }

                unusedRanges[unusedRanges.IndexOf(found.Range)] = null;

                // TODO: optimization: leave off the suggestion filtering until we've determined
                // the command is eligible

                // Do we have any eligible suggestions in the same ParseRange?
                IEnumerable <FacetMoniker> suggestions = null;

                if (groupedResults[found.Range].Length > 1)
                {
                    suggestions = groupedResults[found.Range]
                                  .Where(x => !ReferenceEquals(found, x))
                                  .Where(x => param.IsUsableAsArgument(x.FacetMoniker))
                                  .Select(x => x.FacetMoniker);
                }

                argList.Add(new CommandArgument(found, suggestions));
            }

            var unusedCount = unusedRanges.Count(x => x != null);

            if (unusedCount != 0)
            {
                if (textFacetParamIndex == -1)
                {
                    return(null);
                }

                // Can we use all of the unused up as a text facet, and are they all in line at the rightmost
                // part of the input?
                var unusedRightmostCount = Enumerable.Reverse(unusedRanges)
                                           .TakeWhile(x => x != null)
                                           .Count();

                if (unusedRightmostCount < unusedCount)
                {
                    // not all unused ranges are rightmost
                    return(null);
                }

                if (ReferenceEquals(unusedRanges.Last(), RemainingTextRangeMarker))
                {
                    // rangeList is original - same length and index values as unusedRanges
                    var prev = rangeList[rangeList.Count - 2];
                    unusedRanges[unusedRanges.Count - 1] = ParseRange.FromIndexes(prev.EndIndex + 1, input.Text.Length - 1);
                }

                var unusedIndexStart = unusedRanges.Count - unusedRightmostCount;
                var unusedIndexEnd   = unusedIndexStart + unusedRightmostCount - 1;
                var textRange        = unusedRanges[unusedIndexStart].Union(unusedRanges[unusedIndexEnd]);

                argList[textFacetParamIndex] = new CommandArgument(CreateTextFacetResult(input, textRange));
            }

            return(argList);
        }
Пример #5
0
        protected override IEnumerable <ParseResult> ParseImpl(ParseInput input, ParseMode mode, IList <Type> facetTypes)
        {
            var startRegex = new Regex(@"\:\\");

            foreach (Match startMatch in startRegex.Matches(input.Text))
            {
                if (startMatch.Index == 0)
                {
                    continue;
                }

                var    startIndex = startMatch.Index - 1;
                string best       = null;
                var    bestIsFile = false;

                Func <char, bool> isBreak = ch => char.IsWhiteSpace(ch) || ch == '\\';

                for (var idx = startIndex; idx <= input.Text.Length; idx++)
                {
                    if (idx == input.Text.Length || isBreak(input.Text[idx]))
                    {
                        var len  = idx - startIndex;
                        var text = input.Text.Substring(startIndex, len);

                        if (File.Exists(text))
                        {
                            bestIsFile = true;
                            best       = text;
                        }
                        else if (Directory.Exists(text))
                        {
                            bestIsFile = false;
                            best       = text;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (best == null)
                {
                    continue;
                }

                var bestRange = new ParseRange(startIndex, best.Length);

                if (bestIsFile)
                {
                    yield return(CreateParseResult(input, bestRange, false, RecaseFilePath(best), ParseResult.ExactMatchRelevance, false));
                }

                yield return(CreateParseResult(input, bestRange, false, RecaseFilePath(best), ParseResult.ExactMatchRelevance, true));

                if (bestRange.EndIndex == input.Text.Length - 1 || (mode & ParseMode.Suggest) == 0 || input.Text[bestRange.EndIndex + 1] != '\\')
                {
                    continue;
                }

                var remain = new string(Enumerable.Skip <char>(input.Text, bestRange.EndIndex + 2).TakeWhile(ch => !char.IsWhiteSpace(ch)).ToArray());

                if (remain.Length > 0)
                {
                    var    bestAndRemainRange = new ParseRange(startIndex, bestRange.Length + 1 + remain.Length);
                    string directory;

                    try
                    {
                        directory = RecaseFilePath(best);
                    }
                    catch (Exception)
                    {
                        continue;
                    }

                    if (directory != null)
                    {
                        var query = Directory
                                    .EnumerateFileSystemEntries(directory, remain + "*.*")
                                    .Take(10)
                                    .Select(x => Path.Combine(directory, Path.GetFileName(x)))
                                    .Select(x => CreateParseResult(input, bestAndRemainRange, true, x, 0.5, Directory.Exists(x)));

                        foreach (var result in query)
                        {
                            yield return(result);
                        }
                    }
                }
            }
        }
Пример #6
0
        public static CommandUsage[] GetCommandUsages(IEnumerable <Command> commands, bool commandsOnly = false)
        {
            var rvl = new List <CommandUsage>();

            using (var selectCommandConnection = DatabaseUtil.GetConnection())
                using (var selectArgConnection = DatabaseUtil.GetConnection())
                {
                    const string selectCommandText =
                        @"SELECT cu.Id, cu.At, cu.Text AS ParseInput
                      FROM CommandUsages AS cu 
                      WHERE cu.CommandId = @CommandId";

                    const string selectArgText =
                        @"SELECT fm.FactoryTypeId, fm.FacetTypeId, fm.DisplayName, fm.DateTime, fm.FactoryData, fm.Source, fm.ExtraData, 
                             cua.Ordinal, cua.RangeStartIndex, cua.RangeLength, cua.Relevance, cua.MatchedText
                      FROM CommandUsageArguments AS cua
                      INNER JOIN FacetMonikers AS fm ON fm.Id = cua.FacetMonikerId
                      WHERE cua.CommandUsageId = @CommandUsageId
                      ORDER BY cua.Ordinal";

                    using (var selectCommandUsageCmd = new SqlCeCommand(selectCommandText, selectCommandConnection))
                        using (var selectUsageArgumentsCmd = new SqlCeCommand(selectArgText, selectArgConnection))
                        {
                            selectCommandUsageCmd.Parameters.AddWithValue("@CommandId", SqlDbType.Int);
                            selectUsageArgumentsCmd.Parameters.AddWithValue("@CommandUsageId", SqlDbType.Int);

                            foreach (var command in commands.Distinct())
                            {
                                selectCommandUsageCmd.Parameters["@CommandId"].Value = Loader.GetCommandInfo(command).DatabaseId;

                                foreach (var cmdRow in selectCommandUsageCmd.ExecuteReader().AsEnumerable())
                                {
                                    if (commandsOnly)
                                    {
                                        rvl.Add(new CommandUsage(command, (DateTime)cmdRow["At"]));
                                        continue;
                                    }

                                    var parseInput  = new ParseInput((string)cmdRow["ParseInput"]);
                                    var arguments   = new List <CommandArgument>();
                                    var lastOrdinal = -1;

                                    selectUsageArgumentsCmd.Parameters["@CommandUsageId"].Value = (int)cmdRow["Id"];

                                    foreach (var argRow in selectUsageArgumentsCmd.ExecuteReader().AsEnumerable())
                                    {
                                        var ordinal = (int)argRow["Ordinal"];

                                        while (++lastOrdinal < ordinal)
                                        {
                                            arguments.Add(CommandArgument.Unspecified);
                                        }

                                        // reconstruct facet moniker
                                        var moniker = FacetIndex.MaterializeMoniker(argRow);

                                        if (moniker == null)
                                        {
                                            arguments = null;
                                            break;
                                        }

                                        if ((int)argRow["RangeStartIndex"] != -1)
                                        {
                                            // reconstruct parse range
                                            var range = new ParseRange(
                                                (int)argRow["RangeStartIndex"],
                                                (int)argRow["RangeLength"]);

                                            // reconstruct parseresult
                                            var parseResult = new ParseResult(
                                                parseInput,
                                                range,
                                                moniker,
                                                (double)argRow["Relevance"]);

                                            arguments.Add(new CommandArgument(parseResult));
                                        }
                                        else
                                        {
                                            // moniker only
                                            arguments.Add(new CommandArgument(moniker));
                                        }
                                    }

                                    if (arguments != null)
                                    {
                                        while (++lastOrdinal < command.Parameters.Count)
                                        {
                                            arguments.Add(CommandArgument.Unspecified);
                                        }

                                        var cei = new CommandExecutor(parseInput, command, arguments);
                                        rvl.Add(new CommandUsage(cei, (DateTime)cmdRow["At"]));
                                    }
                                }
                            }
                        }
                }

            return(rvl.ToArray());
        }
        protected override IEnumerable <ParseResult> ParseImpl(ParseInput input, IEnumerable <FacetMoniker> indexEntries)
        {
            foreach (var entry in indexEntries)
            {
                var ci = ContactInfo.FromXml(entry.FactoryData);

                var relevance = 0.0;

                ParseRange firstNameRange = null;
                ParseRange lastNameRange  = null;
                ParseRange emailRange     = null;

                foreach (var term in input.Terms)
                {
                    if (firstNameRange == null)
                    {
                        if (ApplyRelevance(ref relevance, ci.FirstName, term.TextLower) > 0)
                        {
                            firstNameRange = term.Range;
                            continue;
                        }
                    }

                    if (lastNameRange == null)
                    {
                        if (ApplyRelevance(ref relevance, ci.LastName, term.TextLower) > 0)
                        {
                            lastNameRange = term.Range;
                            continue;
                        }
                    }

                    if (emailRange == null)
                    {
                        if (ApplyRelevance(ref relevance, ci.Email, term.TextLower) > 0)
                        {
                            emailRange = term.Range;
                            continue;
                        }
                    }
                }

                if (relevance == 0.0 ||
                    ((firstNameRange != null && lastNameRange != null) &&
                     lastNameRange.StartIndex <= firstNameRange.StartIndex))
                {
                    continue;
                }

                // determine the input range that caused the match
                ParseRange range;

                if (firstNameRange != null)
                {
                    if (lastNameRange != null)
                    {
                        range = firstNameRange.Union(lastNameRange);
                    }
                    else
                    {
                        range = firstNameRange;
                    }
                }
                else if (lastNameRange != null)
                {
                    range = lastNameRange;
                }
                else
                {
                    range = emailRange;
                }

                yield return(new ParseResult(input, range, entry, relevance));
            }
        }