49
50
SearchResult GetMatchAt (int offset);
50
51
SearchResult GetMatchAt (int offset, int length);
52
SearchResult SearchForward (System.ComponentModel.BackgroundWorker worker, int fromOffset);
53
SearchResult SearchBackward (System.ComponentModel.BackgroundWorker worker, int fromOffset);
53
SearchResult SearchForward (System.ComponentModel.BackgroundWorker worker, TextViewMargin.SearchWorkerArguments args, int fromOffset);
54
SearchResult SearchBackward (System.ComponentModel.BackgroundWorker worker, TextViewMargin.SearchWorkerArguments args, int fromOffset);
55
56
SearchResult SearchForward (int fromOffset);
56
57
SearchResult SearchBackward (int fromOffset);
58
59
void Replace (SearchResult result, string pattern);
61
int ReplaceAll (string withPattern);
60
63
ISearchEngine Clone ();
111
114
public abstract SearchResult GetMatchAt (int offset);
112
115
public abstract SearchResult GetMatchAt (int offset, int length);
114
public abstract SearchResult SearchForward (System.ComponentModel.BackgroundWorker worker, int fromOffset);
115
public abstract SearchResult SearchBackward (System.ComponentModel.BackgroundWorker worker, int fromOffset);
117
public abstract SearchResult SearchForward (System.ComponentModel.BackgroundWorker worker, TextViewMargin.SearchWorkerArguments args, int fromOffset);
118
public abstract SearchResult SearchBackward (System.ComponentModel.BackgroundWorker worker, TextViewMargin.SearchWorkerArguments args, int fromOffset);
117
120
public SearchResult SearchForward (int fromOffset)
119
return SearchForward (null, fromOffset);
122
return SearchForward (null, new TextViewMargin.SearchWorkerArguments () { Text = textEditorData.Text }, fromOffset);
121
125
public SearchResult SearchBackward (int fromOffset)
123
return SearchBackward (null, fromOffset);
127
return SearchBackward (null, new TextViewMargin.SearchWorkerArguments () { Text = textEditorData.Text }, fromOffset);
125
129
public abstract void Replace (SearchResult result, string pattern);
131
public virtual int ReplaceAll (string withPattern)
134
using (var undo = textEditorData.OpenUndoGroup ()) {
136
if (!SearchRequest.SearchRegion.IsInvalid)
137
offset = SearchRequest.SearchRegion.Offset;
138
SearchResult searchResult;
139
var text = textEditorData.Text;
140
var args = new TextViewMargin.SearchWorkerArguments () { Text = text };
142
searchResult = SearchForward (null, args, offset);
143
if (searchResult == null || searchResult.SearchWrapped)
145
Replace (searchResult, withPattern);
146
offset = searchResult.EndOffset;
150
textEditorData.ClearSelection ();
126
155
public virtual ISearchEngine Clone ()
128
157
ISearchEngine result = (ISearchEngine)MemberwiseClone ();
186
public override SearchResult SearchForward (System.ComponentModel.BackgroundWorker worker, int fromOffset)
215
public override SearchResult SearchForward (System.ComponentModel.BackgroundWorker worker, TextViewMargin.SearchWorkerArguments args, int fromOffset)
188
217
if (!string.IsNullOrEmpty (SearchRequest.SearchPattern)) {
189
218
// TODO: Optimize
190
for (int i = 0; i < this.textEditorData.Document.TextLength; i++) {
191
int offset = (fromOffset + i) % this.textEditorData.Document.TextLength;
219
for (int i = 0; i < args.Text.Length; i++) {
220
int offset = (fromOffset + i) % args.Text.Length;
192
221
if (worker != null && worker.CancellationPending)
194
223
if (IsMatchAt (offset) && (searchRequest.SearchRegion.IsInvalid || searchRequest.SearchRegion.Contains (offset)))
201
public override SearchResult SearchBackward (System.ComponentModel.BackgroundWorker worker, int fromOffset)
230
public override SearchResult SearchBackward (System.ComponentModel.BackgroundWorker worker, TextViewMargin.SearchWorkerArguments args, int fromOffset)
203
232
if (!string.IsNullOrEmpty (SearchRequest.SearchPattern)) {
204
233
// TODO: Optimize
205
for (int i = 0; i < this.textEditorData.Document.TextLength; i++) {
206
int offset = (fromOffset + this.textEditorData.Document.TextLength * 2 - 1 - i) % this.textEditorData.Document.TextLength;
234
for (int i = 0; i < args.Text.Length; i++) {
235
int offset = (fromOffset + args.Text.Length * 2 - 1 - i) % args.Text.Length;
207
236
if (worker != null && worker.CancellationPending)
209
238
if (IsMatchAt (offset) && (searchRequest.SearchRegion.IsInvalid || searchRequest.SearchRegion.Contains (offset)))
216
245
public override void Replace (SearchResult result, string pattern)
218
247
textEditorData.Replace (result.Offset, result.Length, pattern);
250
public override int ReplaceAll (string withPattern)
252
var searchResults = new List<SearchResult> ();
255
if (!SearchRequest.SearchRegion.IsInvalid)
256
offset = SearchRequest.SearchRegion.Offset;
257
SearchResult searchResult;
258
var text = textEditorData.Text;
259
var args = new TextViewMargin.SearchWorkerArguments () { Text = text };
261
searchResult = SearchForward (null, args, offset);
262
if (searchResult == null || searchResult.SearchWrapped)
264
searchResults.Add (searchResult);
265
offset = searchResult.EndOffset;
267
if (searchResults.Count < 100) {
268
using (var undo = textEditorData.OpenUndoGroup ()) {
269
for (int i = searchResults.Count - 1; i >= 0; i--) {
270
Replace (searchResults [i], withPattern);
272
if (searchResults.Count > 0)
273
textEditorData.ClearSelection ();
276
char[] oldText = text.ToCharArray ();
277
char[] newText = new char[oldText.Length + searchResults.Count * (withPattern.Length - compiledPattern.Length)];
278
char[] pattern = withPattern.ToCharArray ();
279
int curOffset = 0, destOffset = 0;
280
foreach (var sr in searchResults) {
281
var length = sr.Offset - curOffset;
282
Array.Copy (oldText, curOffset, newText, destOffset, length);
283
destOffset += length;
284
Array.Copy (pattern, 0, newText, destOffset, pattern.Length);
285
destOffset += withPattern.Length;
286
curOffset = sr.EndOffset;
288
var l = textEditorData.Length - curOffset;
289
Array.Copy (oldText, curOffset, newText, destOffset, l);
291
textEditorData.Replace (0, textEditorData.Length, new string (newText));
292
textEditorData.ClearSelection ();
294
return searchResults.Count;
222
298
public class RegexSearchEngine : AbstractSearchEngine
275
public override SearchResult SearchForward (System.ComponentModel.BackgroundWorker worker, int fromOffset)
351
public override SearchResult SearchForward (System.ComponentModel.BackgroundWorker worker, TextViewMargin.SearchWorkerArguments args, int fromOffset)
277
353
if (regex == null || String.IsNullOrEmpty (searchRequest.SearchPattern))
279
System.Text.RegularExpressions.Match match = regex.Match (this.textEditorData.Document.Text, fromOffset);
355
System.Text.RegularExpressions.Match match = regex.Match (args.Text, fromOffset);
280
356
if (match.Success) {
281
357
return new SearchResult (match.Index,
282
358
match.Length, false);
284
match = regex.Match (this.textEditorData.Document.Text, 0, fromOffset);
360
match = regex.Match (args.Text, 0, fromOffset);
285
361
if (match.Success) {
286
362
return new SearchResult (match.Index,
287
363
match.Length, true);
292
public override SearchResult SearchBackward (System.ComponentModel.BackgroundWorker worker, int fromOffset)
368
public override SearchResult SearchBackward (System.ComponentModel.BackgroundWorker worker, TextViewMargin.SearchWorkerArguments args, int fromOffset)
294
370
if (regex == null || String.IsNullOrEmpty (searchRequest.SearchPattern))
296
372
System.Text.RegularExpressions.Match found = null;
297
373
System.Text.RegularExpressions.Match last = null;
298
foreach (System.Text.RegularExpressions.Match match in regex.Matches (this.textEditorData.Document.Text)) {
374
foreach (System.Text.RegularExpressions.Match match in regex.Matches (args.Text)) {
299
375
if (match.Index < fromOffset) {