示例#1
0
        private void FormatCaptureGroups(Paragraph paragraph, GrepMatch match, string fmtLine)
        {
            if (paragraph == null || match == null || string.IsNullOrEmpty(fmtLine))
            {
                return;
            }

            GroupMap map = new GroupMap(match, fmtLine);

            foreach (var range in map.Ranges.Where(r => r.Length > 0))
            {
                var run = new Run(range.RangeText);
                if (range.Group == null)
                {
                    run.SetResourceReference(Run.ForegroundProperty, "Match.Highlight.Foreground");
                    run.SetResourceReference(Run.BackgroundProperty, "Match.Highlight.Background");
                    run.ToolTip = TranslationSource.Format(Resources.Main_ResultList_MatchToolTip1, Parent.MatchIdx, Environment.NewLine, fmtLine);
                    paragraph.Inlines.Add(run);
                }
                else
                {
                    if (!Parent.GroupColors.TryGetValue(range.Group.Name, out string bgColor))
                    {
                        int groupIdx = Parent.GroupColors.Count % 10;
                        bgColor = $"Match.Group.{groupIdx}.Highlight.Background";
                        Parent.GroupColors.Add(range.Group.Name, bgColor);
                    }
                    run.SetResourceReference(Run.ForegroundProperty, "Match.Highlight.Foreground");
                    run.SetResourceReference(Run.BackgroundProperty, bgColor);
                    run.ToolTip = TranslationSource.Format(Resources.Main_ResultList_MatchToolTip2,
                                                           Parent.MatchIdx, Environment.NewLine, range.Group.Name, range.Group.Value);
                    paragraph.Inlines.Add(run);
                }
            }
        }
示例#2
0
        public FormattedGrepMatch(GrepMatch match)
        {
            Match        = match;
            ReplaceMatch = Match.ReplaceMatch;

            Background = Match.ReplaceMatch ? Brushes.PaleGreen : Brushes.Bisque;
        }
示例#3
0
        protected override void ColorizeLine(DocumentLine line)
        {
            if (result.Matches == null || result.Matches.Count == 0)
            {
                return;
            }

            int lineStartOffset = line.Offset;
            int lineNumber      = line.LineNumber;

            var lineResult = result.SearchResults.FirstOrDefault(sr => sr.ClippedFileLineNumber == lineNumber && sr.IsContext == false);

            if (lineResult != null)
            {
                foreach (var grepMatch in lineResult.Matches)
                {
                    try
                    {
                        // get the global file match corresponding to this line match
                        // only the file match has a valid ReplaceMatch flag
                        GrepMatch fileMatch = result.Matches.FirstOrDefault(m => m.FileMatchId == grepMatch.FileMatchId);
                        Color     color     = fileMatch == null ? Colors.LightGray : fileMatch.ReplaceMatch ? Colors.PaleGreen : Colors.LightSalmon;

                        bool isSelected = grepMatch.FileMatchId.Equals(SelectedGrepMatch.FileMatchId);

                        base.ChangeLinePart(
                            lineStartOffset + grepMatch.StartLocation,                    // startOffset
                            lineStartOffset + grepMatch.StartLocation + grepMatch.Length, // endOffset
                            (VisualLineElement element) =>
                        {
                            // This lambda gets called once for every VisualLineElement
                            // between the specified offsets.
                            element.TextRunProperties.SetBackgroundBrush(new SolidColorBrush(color));

                            if (isSelected)
                            {
                                TextDecorationCollection coll = new TextDecorationCollection
                                {
                                    new TextDecoration(
                                        TextDecorationLocation.Underline,
                                        new Pen(Brushes.Black, 2), 0,
                                        TextDecorationUnit.Pixel,
                                        TextDecorationUnit.Pixel)
                                };
                                element.TextRunProperties.SetTextDecorations(coll);
                            }
                        });
                    }
                    catch
                    {
                        // Do nothing
                    }
                }
            }
        }
示例#4
0
            public GroupMap(GrepMatch match, string text)
            {
                start     = match.StartLocation;
                MatchText = text;
                ranges.Add(new Range(0, MatchText.Length, this, null));

                foreach (var group in match.Groups.OrderByDescending(g => g.Length))
                {
                    Insert(group);
                }
                ranges.Sort();
            }
示例#5
0
        /// <inheritdoc />
        public FormattedMatch FormatMatch(GrepMatch match)
        {
            var preMatch  = match.Context.Substring(0, match.Index - 1).TrimStart();
            var postMatch = match.Context.Substring(match.Index + match.Value.Length - 1).TrimEnd();

            return(new FormattedMatch(
                       match,
                       new List <FormattedSpan>
            {
                new FormattedSpan(preMatch, ConsoleColor.DarkGray),
                new FormattedSpan(match.Value, ConsoleColor.Blue),
                new FormattedSpan(postMatch, ConsoleColor.DarkGray),
            }));
        }
示例#6
0
        private IEnumerable <GrepMatch> TextSearchIteratorBoolean(int lineNumber, int filePosition, string text,
                                                                  BooleanExpression expression, List <int> lineEndIndexes, bool isWholeWord, StringComparison comparisonType)
        {
            List <GrepMatch> results = new List <GrepMatch>();

            foreach (var operand in expression.Operands)
            {
                var matches = TextSearchIterator(lineNumber, filePosition, text, operand.Value,
                                                 lineEndIndexes, isWholeWord, comparisonType);

                operand.EvaluatedResult = matches.Any();
                operand.Matches         = matches.ToList();

                if (!expression.IsComplete && expression.IsShortCircuitFalse())
                {
                    return(results);
                }
            }

            if (expression.IsComplete)
            {
                var evalResult = expression.Evaluate();
                if (evalResult == EvaluationResult.True)
                {
                    foreach (var operand in expression.Operands)
                    {
                        if (operand.Matches != null)
                        {
                            results.AddRange(operand.Matches);
                        }
                    }

                    // if the expression evaluated to true, then the expression is searching
                    // for things that do not match the operands. Return the whole line
                    if (results.Count == 0)
                    {
                        string temp = text.TrimEndOfLine();
                        results.Add(new GrepMatch(string.Empty, lineNumber, filePosition, temp.Length));
                    }

                    GrepMatch.Normalize(results);
                }
            }

            return(results);
        }
示例#7
0
        private IEnumerable <GrepMatch> TextSearchIteratorOr(int lineNumber, int filePosition, string text,
                                                             List <string> orClauses, List <int> lineEndIndexes, bool isWholeWord, StringComparison comparisonType)
        {
            List <GrepMatch> results = new List <GrepMatch>();

            foreach (string searchText in orClauses)
            {
                var matches = TextSearchIterator(lineNumber, filePosition, text, searchText,
                                                 lineEndIndexes, isWholeWord, comparisonType);

                if (matches.Any())
                {
                    results.AddRange(matches);
                }
            }
            GrepMatch.Normalize(results);
            return(results);
        }
示例#8
0
        private IEnumerable <GrepMatch> RegexSearchIteratorOr(int lineNumber, int filePosition, string text,
                                                              List <string> orClauses, bool isWholeWord, RegexOptions regexOptions)
        {
            List <GrepMatch> results = new List <GrepMatch>();

            foreach (string searchPattern in orClauses)
            {
                var matches = RegexSearchIterator(lineNumber, filePosition, text,
                                                  searchPattern, isWholeWord, regexOptions);

                if (matches.Any())
                {
                    results.AddRange(matches);
                }
            }
            GrepMatch.Normalize(results);
            return(results);
        }
示例#9
0
        private InlineCollection FormatLine(GrepLine line)
        {
            Paragraph paragraph = new Paragraph();

            string fullLine = line.LineText;

            if (line.LineText.Length > MaxLineLength)
            {
                fullLine = line.LineText.Substring(0, MaxLineLength);
            }

            if (line.Matches.Count == 0)
            {
                Run mainRun = new Run(fullLine);
                paragraph.Inlines.Add(mainRun);
            }
            else
            {
                int         counter     = 0;
                GrepMatch[] lineMatches = new GrepMatch[line.Matches.Count];
                line.Matches.CopyTo(lineMatches);
                foreach (GrepMatch m in lineMatches)
                {
                    Parent.MatchIdx++;
                    try
                    {
                        string regLine = null;
                        string fmtLine = null;
                        if (m.StartLocation < fullLine.Length)
                        {
                            regLine = fullLine.Substring(counter, m.StartLocation - counter);
                        }

                        if (m.StartLocation + m.Length <= fullLine.Length)
                        {
                            fmtLine = fullLine.Substring(m.StartLocation, m.Length);
                        }
                        else if (fullLine.Length > m.StartLocation)
                        {
                            // match may include the non-printing newline chars at the end of the line: don't overflow the length
                            fmtLine = fullLine.Substring(m.StartLocation, fullLine.Length - m.StartLocation);
                        }
                        else
                        {
                            // binary file?
                            regLine = fullLine;
                        }

                        if (regLine != null)
                        {
                            Run regularRun = new Run(regLine);
                            paragraph.Inlines.Add(regularRun);
                        }
                        if (fmtLine != null)
                        {
                            if (HighlightCaptureGroups && m.Groups.Count > 0)
                            {
                                FormatCaptureGroups(paragraph, m, fmtLine);
                            }
                            else
                            {
                                var run = new Run(fmtLine);
                                run.SetResourceReference(Run.ForegroundProperty, "Match.Highlight.Foreground");
                                run.SetResourceReference(Run.BackgroundProperty, "Match.Highlight.Background");
                                paragraph.Inlines.Add(run);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    catch
                    {
                        Run regularRun = new Run(fullLine);
                        paragraph.Inlines.Add(regularRun);
                    }
                    finally
                    {
                        counter = m.StartLocation + m.Length;
                    }
                }
                if (counter < fullLine.Length)
                {
                    try
                    {
                        string regLine    = fullLine.Substring(counter);
                        Run    regularRun = new Run(regLine);
                        paragraph.Inlines.Add(regularRun);
                    }
                    catch
                    {
                        Run regularRun = new Run(fullLine);
                        paragraph.Inlines.Add(regularRun);
                    }
                }
                if (line.LineText.Length > MaxLineLength)
                {
                    string msg = TranslationSource.Format(Resources.Main_ResultList_CountAdditionalCharacters, line.LineText.Length - MaxLineLength);

                    var msgRun = new Run(msg);
                    msgRun.SetResourceReference(Run.ForegroundProperty, "TreeView.Message.Highlight.Foreground");
                    msgRun.SetResourceReference(Run.BackgroundProperty, "TreeView.Message.Highlight.Background");
                    paragraph.Inlines.Add(msgRun);

                    var hiddenMatches = line.Matches.Where(m => m.StartLocation > MaxLineLength).Select(m => m);
                    int count         = hiddenMatches.Count();
                    if (count > 0)
                    {
                        paragraph.Inlines.Add(new Run(" " + Resources.Main_ResultList_AdditionalMatches));
                    }

                    // if close to getting them all, then take them all,
                    // otherwise, stop at 20 and just show the remaining count
                    int takeCount = count > 25 ? 20 : count;

                    foreach (GrepMatch m in hiddenMatches.Take(takeCount))
                    {
                        if (m.StartLocation + m.Length <= line.LineText.Length)
                        {
                            paragraph.Inlines.Add(new Run("  "));
                            string fmtLine = line.LineText.Substring(m.StartLocation, m.Length);
                            var    run     = new Run(fmtLine);
                            run.SetResourceReference(Run.ForegroundProperty, "Match.Highlight.Foreground");
                            run.SetResourceReference(Run.BackgroundProperty, "Match.Highlight.Background");
                            paragraph.Inlines.Add(run);

                            if (m.StartLocation + m.Length == line.LineText.Length)
                            {
                                paragraph.Inlines.Add(new Run(" " + Resources.Main_ResultList_AtEndOfLine));
                            }
                            else
                            {
                                paragraph.Inlines.Add(new Run(" " + TranslationSource.Format(Resources.Main_ResultList_AtPosition, m.StartLocation)));
                            }
                        }
                    }

                    if (count > takeCount)
                    {
                        paragraph.Inlines.Add(new Run(TranslationSource.Format(Resources.Main_ResultList_PlusCountMoreMatches, count - takeCount)));
                    }
                }
            }
            return(paragraph.Inlines);
        }
示例#10
0
        public GrepMatch[] GetFilePositions(string text, List <XPathPosition> positions)
        {
            bool[] endFound = new bool[positions.Count];
            // Getting line lengths
            List <int> lineLengths = new List <int>();

            using (StringReader baseReader = new StringReader(text))
            {
                using (EolReader reader = new EolReader(baseReader))
                {
                    while (!reader.EndOfStream)
                    {
                        lineLengths.Add(reader.ReadLine().Length);
                    }
                }
            }
            // These are absolute positions
            GrepMatch[] results = new GrepMatch[positions.Count];
            if (positions.Count == 0)
            {
                return(results);
            }

            using (StringReader textReader = new StringReader(text))
                using (XmlReader reader = XmlReader.Create(textReader))
                {
                    List <int> currPos = new List <int>();

                    try
                    {
                        IXmlLineInfo lineInfo = ((IXmlLineInfo)reader);
                        if (lineInfo.HasLineInfo())
                        {
                            // Parse the XML and display each node.
                            while (reader.Read())
                            {
                                switch (reader.NodeType)
                                {
                                case XmlNodeType.Element:
                                case XmlNodeType.Comment:

                                    if (currPos.Count <= reader.Depth)
                                    {
                                        currPos.Add(1);
                                    }
                                    else
                                    {
                                        currPos[reader.Depth]++;
                                    }

                                    break;

                                case XmlNodeType.EndElement:
                                    while (reader.Depth < currPos.Count - 1)
                                    {
                                        currPos.RemoveAt(reader.Depth + 1); // currPos.Count - 1 would work too.
                                    }

                                    for (int i = 0; i < positions.Count; i++)
                                    {
                                        if (XPathPositionsMatch(currPos, positions[i].Path))
                                        {
                                            endFound[i] = true;
                                        }
                                    }
                                    break;

                                default:
                                    break;
                                }

                                if (reader.NodeType == XmlNodeType.EndElement ||
                                    reader.NodeType == XmlNodeType.Comment)
                                {
                                    int tokenOffset = reader.NodeType == XmlNodeType.Element ? 3 : 5;
                                    for (int i = 0; i < positions.Count; i++)
                                    {
                                        if (endFound[i] && !XPathPositionsMatch(currPos, positions[i].Path))
                                        {
                                            if (results[i] != null)
                                            {
                                                results[i].EndPosition = GetAbsoluteCharPosition(lineInfo.LineNumber - 1, lineInfo.LinePosition - tokenOffset, text, lineLengths, true) + 1;
                                            }
                                            endFound[i] = false;
                                        }
                                    }
                                }

                                if (reader.NodeType == XmlNodeType.Element)
                                {
                                    for (int i = 0; i < positions.Count; i++)
                                    {
                                        if (endFound[i])
                                        {
                                            if (results[i] != null)
                                            {
                                                results[i].EndPosition = GetAbsoluteCharPosition(lineInfo.LineNumber - 1, lineInfo.LinePosition - 3, text, lineLengths, true) + 1;
                                            }
                                            endFound[i] = false;
                                        }

                                        if (XPathPositionsMatch(currPos, positions[i].Path))
                                        {
                                            results[i] = new GrepMatch(string.Empty, lineInfo.LineNumber, GetAbsoluteCharPosition(lineInfo.LineNumber - 1, lineInfo.LinePosition - 2, text, lineLengths, false), 0);
                                        }

                                        // If empty element (e.g.<element/>)
                                        if (reader.IsEmptyElement)
                                        {
                                            if (XPathPositionsMatch(currPos, positions[i].Path))
                                            {
                                                endFound[i] = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    finally
                    {
                        for (int i = 0; i < positions.Count; i++)
                        {
                            if (results[i] != null && results[i].Length == 0)
                            {
                                results[i].EndPosition = text.Length - 1;
                            }
                        }

                        reader.Close();
                    }
                    // Close the reader.
                }
            return(results);
        }
示例#11
0
        private IEnumerable <GrepMatch> RegexSearchIterator(int lineNumber, int filePosition, string text,
                                                            string searchPattern, bool isWholeWord, RegexOptions regexOptions)
        {
            if (isWholeWord)
            {
                if (!searchPattern.Trim().StartsWith("\\b"))
                {
                    searchPattern = "\\b" + searchPattern.Trim();
                }
                if (!searchPattern.Trim().EndsWith("\\b"))
                {
                    searchPattern = searchPattern.Trim() + "\\b";
                }
            }

            // Issue #210 .net regex will only match the $ end of line token with a \n, not \r\n or \r
            // see https://msdn.microsoft.com/en-us/library/yd1hzczs.aspx#Multiline
            // http://stackoverflow.com/questions/8618557/why-doesnt-in-net-multiline-regular-expressions-match-crlf
            // https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference

            // Note: in Singleline mode, need to capture the new line chars

            bool searchPatternEndsWithDot = searchPattern.EndsWith(".") || searchPattern.EndsWith(".*") ||
                                            searchPattern.EndsWith(".?") || searchPattern.EndsWith(".+");

            int extraChars = 0;

            if (text.Contains("\r\n"))
            {
                if (searchPattern.Contains("$"))
                {
                    if (regexOptions.HasFlag(RegexOptions.Singleline))
                    {
                        searchPattern = searchPattern.Replace("$", "\r?$");
                    }
                    else
                    {
                        searchPattern = searchPattern.Replace("$", "(?=\r?$)");

                        // can't make this pattern work if the multi line text does not end in a newline
                        if (regexOptions.HasFlag(RegexOptions.Multiline) && !text.EndsWith("\r\n"))
                        {
                            text      += "\r\n";
                            extraChars = 2;
                        }
                    }
                }

                // if the patten ends with a dot in some form, it will match the \r path of \r\n
                // modify the search pattern to capture or exclude the \r
                if (searchPatternEndsWithDot)
                {
                    if (regexOptions.HasFlag(RegexOptions.Singleline))
                    {
                        searchPattern += "\r?$";
                    }
                    else
                    {
                        searchPattern += "(?=\r?$)";

                        // can't make this pattern work if the multi line text does not end in a newline
                        if (regexOptions.HasFlag(RegexOptions.Multiline) && !text.EndsWith("\r\n"))
                        {
                            text      += "\r\n";
                            extraChars = 2;
                        }
                    }
                }
            }
            else if (text.Contains("\r") && (searchPattern.Contains("$") || searchPatternEndsWithDot))
            {
                // for this case, it's easiest to change the newline char while searching
                searchPattern = searchPattern.Replace('\r', '\n');
                text          = text.Replace('\r', '\n');
            }

            var lineEndIndexes = GetLineEndIndexes((initParams.VerboseMatchCount && lineNumber == -1) ? text : null);

            List <GrepMatch> globalMatches = new List <GrepMatch>();

            var regex   = new Regex(searchPattern, regexOptions, MatchTimeout);
            var matches = regex.Matches(text);

            foreach (Match match in matches)
            {
                if (initParams.VerboseMatchCount && lineEndIndexes.Count > 0)
                {
                    lineNumber = lineEndIndexes.FindIndex(i => i > match.Index) + 1;
                }

                int length = match.Length;
                if (match.Index + filePosition + match.Length > text.Length)
                {
                    length -= extraChars;
                }

                // The pattern (?=\r?$) fixes most problems trying to make \r\n process like \n
                // but it does capture the leading \r in the match. When that happens, set the
                // match length back one to exclude it
                if (!regexOptions.HasFlag(RegexOptions.Singleline) && match.Value.EndsWith("\r"))
                {
                    length -= 1;
                }

                var grepMatch = new GrepMatch(searchPattern, lineNumber, match.Index + filePosition, length);

                if (match.Groups.Count > 1)
                {
                    // Note that group 0 is always the whole match
                    for (int idx = 1; idx < match.Groups.Count; idx++)
                    {
                        var group = match.Groups[idx];
                        if (group.Success)
                        {
                            length = group.Length;
                            if (!regexOptions.HasFlag(RegexOptions.Singleline) && group.Value.EndsWith("\r"))
                            {
                                length -= 1;
                            }

                            grepMatch.Groups.Add(
                                new GrepCaptureGroup(regex.GroupNameFromNumber(idx), group.Index, length, group.Value));
                        }
                    }
                }

                yield return(grepMatch);
            }
        }
示例#12
0
        private IEnumerable <GrepMatch> RegexSearchIterator(int lineNumber, int filePosition, string text,
                                                            string searchPattern, bool isWholeWord, RegexOptions regexOptions)
        {
            if (isWholeWord)
            {
                if (!searchPattern.Trim().StartsWith("\\b"))
                {
                    searchPattern = "\\b" + searchPattern.Trim();
                }
                if (!searchPattern.Trim().EndsWith("\\b"))
                {
                    searchPattern = searchPattern.Trim() + "\\b";
                }
            }

            // Issue #210 .net regex will only match the $ end of line token with a \n, not \r\n or \r
            // see https://msdn.microsoft.com/en-us/library/yd1hzczs.aspx#Multiline
            // http://stackoverflow.com/questions/8618557/why-doesnt-in-net-multiline-regular-expressions-match-crlf
            // https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference

            // Note: in Singleline mode, need to capture the new line chars

            bool searchPatternEndsWithDot =
                (searchPattern.EndsWith(".") && !searchPattern.EndsWith(@"\.")) ||
                (searchPattern.EndsWith(".*") && !searchPattern.EndsWith(@"\.*")) ||
                (searchPattern.EndsWith(".?") && !searchPattern.EndsWith(@"\.?")) ||
                (searchPattern.EndsWith(".+") && !searchPattern.EndsWith(@"\.+"));

            string     textToSearch = text;
            bool       convertedFromWindowsNewline = false;
            List <int> newlineIndexes = null;

            if (searchPattern.ConstainsNotEscaped("$") || searchPatternEndsWithDot)
            {
                if (text.Contains("\r\n"))
                {
                    // the match index will be off by one for each line where the \r was dropped
                    searchPattern = searchPattern.Replace("\r\n", "\n").Replace('\r', '\n');
                    textToSearch  = ConvertNewLines(text, out newlineIndexes);
                    convertedFromWindowsNewline = true;
                }
                else if (text.Contains("\r"))
                {
                    // this will be the same length, just change the newline char while searching
                    searchPattern = searchPattern.Replace("\r\n", "\n").Replace('\r', '\n');
                    textToSearch  = text.Replace('\r', '\n');
                }
            }

            var lineEndIndexes = GetLineEndIndexes((initParams.VerboseMatchCount && lineNumber == -1) ? textToSearch : null);

            List <GrepMatch> globalMatches = new List <GrepMatch>();

            var regex   = new Regex(searchPattern, regexOptions, MatchTimeout);
            var matches = regex.Matches(textToSearch);

            foreach (Match match in matches)
            {
                if (match.Length < 1)
                {
                    continue;
                }

                if (initParams.VerboseMatchCount && lineEndIndexes.Count > 0)
                {
                    lineNumber = lineEndIndexes.FindIndex(i => i > match.Index) + 1;
                }

                int matchStart = match.Index;
                int length     = match.Length;
                if (convertedFromWindowsNewline && newlineIndexes != null)
                {
                    // since the search text is shorter by one for each converted newline,
                    // move the match start by one for each converted Windows newline
                    matchStart += CountWindowsNewLines(0, match.Index, newlineIndexes);
                    length     += CountWindowsNewLines(match.Index, match.Index + length, newlineIndexes);
                }

                var grepMatch = new GrepMatch(searchPattern, lineNumber, matchStart + filePosition, length);

                if (match.Groups.Count > 1)
                {
                    // Note that group 0 is always the whole match
                    for (int idx = 1; idx < match.Groups.Count; idx++)
                    {
                        var group = match.Groups[idx];
                        if (group.Success)
                        {
                            length = group.Length;
                            if (!regexOptions.HasFlag(RegexOptions.Singleline) && group.Value.EndsWith("\r"))
                            {
                                length -= 1;
                            }

                            grepMatch.Groups.Add(
                                new GrepCaptureGroup(regex.GroupNameFromNumber(idx), group.Index, length, group.Value));
                        }
                    }
                }

                yield return(grepMatch);
            }
        }
示例#13
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FormattedMatch"/> class.
 /// </summary>
 /// <param name="match">The source <see cref="GrepMatch"/>.</param>
 /// <param name="spans">The resulting <see cref="FormattedSpan"/>s.</param>
 public FormattedMatch(GrepMatch match, IList <FormattedSpan> spans)
 {
     this.Match = match;
     this.Spans = spans;
 }
        protected override void ColorizeLine(DocumentLine line)
        {
            if (result.Matches == null || result.Matches.Count == 0)
            {
                return;
            }

            int lineStartOffset = line.Offset;
            int lineNumber      = line.LineNumber;

            var lineResult = result.SearchResults.FirstOrDefault(sr => sr.ClippedFileLineNumber == lineNumber && sr.IsContext == false);

            if (lineResult != null)
            {
                Brush skipBackground = Application.Current.Resources["Match.Skip.Background"] as Brush;
                Brush skipForeground = Application.Current.Resources["Match.Skip.Foreground"] as Brush;
                Brush replBackground = Application.Current.Resources["Match.Replace.Background"] as Brush;
                Brush replForeground = Application.Current.Resources["Match.Replace.Foreground"] as Brush;

                foreach (var grepMatch in lineResult.Matches)
                {
                    try
                    {
                        // get the global file match corresponding to this line match
                        // only the file match has a valid ReplaceMatch flag
                        GrepMatch fileMatch  = result.Matches.FirstOrDefault(m => m.FileMatchId == grepMatch.FileMatchId);
                        Brush     foreground = fileMatch == null ? Brushes.Black : fileMatch.ReplaceMatch ? replForeground : skipForeground;
                        Brush     background = fileMatch == null ? Brushes.LightGray : fileMatch.ReplaceMatch ? replBackground : skipBackground;

                        bool isSelected = grepMatch.FileMatchId.Equals(SelectedGrepMatch.FileMatchId);

                        base.ChangeLinePart(
                            lineStartOffset + grepMatch.StartLocation,                                              // startOffset
                            // match may include the non-printing newline chars at the end of the line, don't overflow the length
                            Math.Min(line.EndOffset, lineStartOffset + grepMatch.StartLocation + grepMatch.Length), // endOffset
                            (VisualLineElement element) =>
                        {
                            // This lambda gets called once for every VisualLineElement
                            // between the specified offsets.
                            element.TextRunProperties.SetBackgroundBrush(background);
                            element.TextRunProperties.SetForegroundBrush(foreground);

                            if (isSelected)
                            {
                                TextDecorationCollection coll = new TextDecorationCollection
                                {
                                    new TextDecoration(
                                        TextDecorationLocation.Underline,
                                        new Pen(foreground, 2), 0,
                                        TextDecorationUnit.Pixel,
                                        TextDecorationUnit.Pixel)
                                };
                                element.TextRunProperties.SetTextDecorations(coll);
                            }
                        });
                    }
                    catch
                    {
                        // Do nothing
                    }
                }
            }
        }
示例#15
0
        private InlineCollection FormatLine(GrepLine line)
        {
            Paragraph paragraph = new Paragraph();

            const int MAX_LINE_LENGTH = 500;

            string fullLine = line.LineText;

            if (line.LineText.Length > MAX_LINE_LENGTH)
            {
                fullLine = line.LineText.Substring(0, MAX_LINE_LENGTH);
            }

            if (line.Matches.Count == 0)
            {
                Run mainRun = new Run(fullLine);
                paragraph.Inlines.Add(mainRun);
            }
            else
            {
                int         counter     = 0;
                GrepMatch[] lineMatches = new GrepMatch[line.Matches.Count];
                line.Matches.CopyTo(lineMatches);
                foreach (GrepMatch m in lineMatches)
                {
                    try
                    {
                        string regLine = null;
                        string fmtLine = null;
                        if (fullLine.Length < m.StartLocation + m.Length)
                        {
                            regLine = fullLine.Substring(counter, fullLine.Length - counter);
                        }
                        else
                        {
                            regLine = fullLine.Substring(counter, m.StartLocation - counter);
                            fmtLine = fullLine.Substring(m.StartLocation, m.Length);
                        }

                        Run regularRun = new Run(regLine);
                        paragraph.Inlines.Add(regularRun);

                        if (fmtLine != null)
                        {
                            paragraph.Inlines.Add(new Run(fmtLine)
                            {
                                Background = Brushes.Yellow
                            });
                        }
                        else
                        {
                            break;
                        }
                    }
                    catch
                    {
                        Run regularRun = new Run(fullLine);
                        paragraph.Inlines.Add(regularRun);
                    }
                    finally
                    {
                        counter = m.StartLocation + m.Length;
                    }
                }
                if (counter < fullLine.Length)
                {
                    try
                    {
                        string regLine    = fullLine.Substring(counter);
                        Run    regularRun = new Run(regLine);
                        paragraph.Inlines.Add(regularRun);
                    }
                    catch
                    {
                        Run regularRun = new Run(fullLine);
                        paragraph.Inlines.Add(regularRun);
                    }
                }
                if (line.LineText.Length > MAX_LINE_LENGTH)
                {
                    string msg = string.Format("...(+{0:n0} characters)", line.LineText.Length - MAX_LINE_LENGTH);
                    paragraph.Inlines.Add(new Run(msg)
                    {
                        Background = Brushes.AliceBlue
                    });

                    var hiddenMatches = line.Matches.Where(m => m.StartLocation > MAX_LINE_LENGTH).Select(m => m);
                    int count         = hiddenMatches.Count();
                    if (count > 0)
                    {
                        paragraph.Inlines.Add(new Run(" additional matches:"));
                    }

                    // if close to getting them all, then take them all,
                    // otherwise, stop at 20 and just show the remaining count
                    int takeCount = count > 25 ? 20 : count;

                    foreach (GrepMatch m in hiddenMatches.Take(takeCount))
                    {
                        if (m.StartLocation + m.Length <= line.LineText.Length)
                        {
                            paragraph.Inlines.Add(new Run("  "));
                            string fmtLine = line.LineText.Substring(m.StartLocation, m.Length);
                            paragraph.Inlines.Add(new Run(fmtLine)
                            {
                                Background = Brushes.Yellow
                            });

                            if (m.StartLocation + m.Length == line.LineText.Length)
                            {
                                paragraph.Inlines.Add(new Run(" (at end of line)"));
                            }
                            else
                            {
                                paragraph.Inlines.Add(new Run($" at position {m.StartLocation}"));
                            }
                        }
                    }

                    if (count > takeCount)
                    {
                        paragraph.Inlines.Add(new Run($", +{count - takeCount} more matches"));
                    }
                }
            }
            return(paragraph.Inlines);
        }
        private InlineCollection FormatLine(GrepLine line)
        {
            Paragraph paragraph = new Paragraph();

            const int MAX_LINE_LENGTH = 500;

            string fullLine = line.LineText;

            if (line.LineText.Length > MAX_LINE_LENGTH)
            {
                fullLine = line.LineText.Substring(0, MAX_LINE_LENGTH);
            }

            if (line.Matches.Count == 0)
            {
                Run mainRun = new Run(fullLine);
                paragraph.Inlines.Add(mainRun);
            }
            else
            {
                int         counter     = 0;
                GrepMatch[] lineMatches = new GrepMatch[line.Matches.Count];
                line.Matches.CopyTo(lineMatches);
                foreach (GrepMatch m in lineMatches)
                {
                    Parent.MatchIdx++;
                    try
                    {
                        string regLine = null;
                        string fmtLine = null;
                        if (m.StartLocation < fullLine.Length)
                        {
                            regLine = fullLine.Substring(counter, m.StartLocation - counter);
                        }

                        if (m.StartLocation + m.Length <= fullLine.Length)
                        {
                            fmtLine = fullLine.Substring(m.StartLocation, m.Length);
                        }
                        else
                        {
                            // match may include the non-printing newline chars at the end of the line: don't overflow the length
                            fmtLine = fullLine.Substring(m.StartLocation, fullLine.Length - m.StartLocation);
                        }

                        if (regLine != null)
                        {
                            Run regularRun = new Run(regLine);
                            paragraph.Inlines.Add(regularRun);
                        }
                        if (fmtLine != null)
                        {
                            if (HighlightCaptureGroups && m.Groups.Count > 0)
                            {
                                FormatCaptureGroups(paragraph, m, fmtLine);
                            }
                            else
                            {
                                var run = new Run(fmtLine);
                                run.SetResourceReference(Run.ForegroundProperty, "Match.Highlight.Foreground");
                                run.SetResourceReference(Run.BackgroundProperty, "Match.Highlight.Background");
                                paragraph.Inlines.Add(run);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    catch
                    {
                        Run regularRun = new Run(fullLine);
                        paragraph.Inlines.Add(regularRun);
                    }
                    finally
                    {
                        counter = m.StartLocation + m.Length;
                    }
                }
                if (counter < fullLine.Length)
                {
                    try
                    {
                        string regLine    = fullLine.Substring(counter);
                        Run    regularRun = new Run(regLine);
                        paragraph.Inlines.Add(regularRun);
                    }
                    catch
                    {
                        Run regularRun = new Run(fullLine);
                        paragraph.Inlines.Add(regularRun);
                    }
                }
                if (line.LineText.Length > MAX_LINE_LENGTH)
                {
                    string msg = string.Format("...(+{0:n0} characters)", line.LineText.Length - MAX_LINE_LENGTH);

                    var msgRun = new Run(msg);
                    msgRun.SetResourceReference(Run.ForegroundProperty, "TreeView.Message.Highlight.Foreground");
                    msgRun.SetResourceReference(Run.BackgroundProperty, "TreeView.Message.Highlight.Background");
                    paragraph.Inlines.Add(msgRun);

                    var hiddenMatches = line.Matches.Where(m => m.StartLocation > MAX_LINE_LENGTH).Select(m => m);
                    int count         = hiddenMatches.Count();
                    if (count > 0)
                    {
                        paragraph.Inlines.Add(new Run(" additional matches:"));
                    }

                    // if close to getting them all, then take them all,
                    // otherwise, stop at 20 and just show the remaining count
                    int takeCount = count > 25 ? 20 : count;

                    foreach (GrepMatch m in hiddenMatches.Take(takeCount))
                    {
                        if (m.StartLocation + m.Length <= line.LineText.Length)
                        {
                            paragraph.Inlines.Add(new Run("  "));
                            string fmtLine = line.LineText.Substring(m.StartLocation, m.Length);
                            var    run     = new Run(fmtLine);
                            run.SetResourceReference(Run.ForegroundProperty, "Match.Highlight.Foreground");
                            run.SetResourceReference(Run.BackgroundProperty, "Match.Highlight.Background");
                            paragraph.Inlines.Add(run);

                            if (m.StartLocation + m.Length == line.LineText.Length)
                            {
                                paragraph.Inlines.Add(new Run(" (at end of line)"));
                            }
                            else
                            {
                                paragraph.Inlines.Add(new Run($" at position {m.StartLocation}"));
                            }
                        }
                    }

                    if (count > takeCount)
                    {
                        paragraph.Inlines.Add(new Run($", +{count - takeCount} more matches"));
                    }
                }
            }
            return(paragraph.Inlines);
        }