1 | // Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team |
---|
2 | // |
---|
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this |
---|
4 | // software and associated documentation files (the "Software"), to deal in the Software |
---|
5 | // without restriction, including without limitation the rights to use, copy, modify, merge, |
---|
6 | // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons |
---|
7 | // to whom the Software is furnished to do so, subject to the following conditions: |
---|
8 | // |
---|
9 | // The above copyright notice and this permission notice shall be included in all copies or |
---|
10 | // substantial portions of the Software. |
---|
11 | // |
---|
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
---|
13 | // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
---|
14 | // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE |
---|
15 | // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
---|
16 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
---|
17 | // DEALINGS IN THE SOFTWARE. |
---|
18 | |
---|
19 | using System; |
---|
20 | using System.Collections.Generic; |
---|
21 | using System.Linq; |
---|
22 | using System.Text; |
---|
23 | using System.Text.RegularExpressions; |
---|
24 | using System.Windows.Documents; |
---|
25 | using ICSharpCode.AvalonEdit.Document; |
---|
26 | using ICSharpCode.NRefactory.Editor; |
---|
27 | |
---|
28 | namespace ICSharpCode.AvalonEdit.Search |
---|
29 | { |
---|
30 | class RegexSearchStrategy : ISearchStrategy |
---|
31 | { |
---|
32 | readonly Regex searchPattern; |
---|
33 | readonly bool matchWholeWords; |
---|
34 | |
---|
35 | public RegexSearchStrategy(Regex searchPattern, bool matchWholeWords) |
---|
36 | { |
---|
37 | if (searchPattern == null) |
---|
38 | throw new ArgumentNullException("searchPattern"); |
---|
39 | this.searchPattern = searchPattern; |
---|
40 | this.matchWholeWords = matchWholeWords; |
---|
41 | } |
---|
42 | |
---|
43 | public IEnumerable<ISearchResult> FindAll(ITextSource document, int offset, int length) |
---|
44 | { |
---|
45 | int endOffset = offset + length; |
---|
46 | foreach (Match result in searchPattern.Matches(document.Text)) { |
---|
47 | int resultEndOffset = result.Length + result.Index; |
---|
48 | if (offset > result.Index || endOffset < resultEndOffset) |
---|
49 | continue; |
---|
50 | if (matchWholeWords && (!IsWordBorder(document, result.Index) || !IsWordBorder(document, resultEndOffset))) |
---|
51 | continue; |
---|
52 | yield return new SearchResult { StartOffset = result.Index, Length = result.Length, Data = result }; |
---|
53 | } |
---|
54 | } |
---|
55 | |
---|
56 | static bool IsWordBorder(ITextSource document, int offset) |
---|
57 | { |
---|
58 | return TextUtilities.GetNextCaretPosition(document, offset - 1, LogicalDirection.Forward, CaretPositioningMode.WordBorder) == offset; |
---|
59 | } |
---|
60 | |
---|
61 | public ISearchResult FindNext(ITextSource document, int offset, int length) |
---|
62 | { |
---|
63 | return FindAll(document, offset, length).FirstOrDefault(); |
---|
64 | } |
---|
65 | |
---|
66 | public bool Equals(ISearchStrategy other) |
---|
67 | { |
---|
68 | var strategy = other as RegexSearchStrategy; |
---|
69 | return strategy != null && |
---|
70 | strategy.searchPattern.ToString() == searchPattern.ToString() && |
---|
71 | strategy.searchPattern.Options == searchPattern.Options && |
---|
72 | strategy.searchPattern.RightToLeft == searchPattern.RightToLeft; |
---|
73 | } |
---|
74 | } |
---|
75 | |
---|
76 | class SearchResult : TextSegment, ISearchResult |
---|
77 | { |
---|
78 | public Match Data { get; set; } |
---|
79 | |
---|
80 | public string ReplaceWith(string replacement) |
---|
81 | { |
---|
82 | return Data.Result(replacement); |
---|
83 | } |
---|
84 | } |
---|
85 | } |
---|