Exemple #1
0
		void UpdateTextMarkerSearch() {
			if (!IsSearchControlVisible)
				return;

			if (SearchString.Length == 0) {
				var oldColl = findResultCollection;
				findResultCollection = NormalizedSnapshotSpanCollection.Empty;
				if (oldColl != null && oldColl.Count != 0)
					RefreshAllTags();
				SetFoundResult(true);
				return;
			}

			var snapshot = wpfTextView.TextSnapshot;
			var searchRange = new SnapshotSpan(snapshot, 0, snapshot.Length);
			var options = GetFindOptions(searchKind, true);
			int count = 0;
			try {
				var list = new List<SnapshotSpan>();
				foreach (var res in textSearchService2.FindAll(searchRange, SearchString, options)) {
					if (res.Length != 0)
						list.Add(res);
					count++;
					if (count == MAX_SEARCH_RESULTS)
						break;
				}
				findResultCollection = new NormalizedSnapshotSpanCollection(list);
			}
			catch (ArgumentException) when ((options & FindOptions.UseRegularExpressions) != 0) {
				// Invalid regex string
				findResultCollection = NormalizedSnapshotSpanCollection.Empty;
				count = 0;
			}
			RefreshAllTags();
			SetFoundResult(count != 0);
		}
Exemple #2
0
        public bool Find()
        {
            if (SearchTerm == null)
            {
                throw new InvalidOperationException();
            }
            if (SearchTerm.Length == 0)
            {
                throw new InvalidOperationException();
            }

            SnapshotPoint startingPosition;

            if (CurrentResult != null)
            {
                if ((SearchOptions & FindOptions.SearchReverse) != 0)
                {
                    if (CurrentResult.Value.End.Position > 0)
                    {
                        startingPosition = CurrentResult.Value.End - 1;
                    }
                    else if ((SearchOptions & FindOptions.Wrap) != 0)
                    {
                        startingPosition = new SnapshotPoint(CurrentResult.Value.Snapshot, CurrentResult.Value.Snapshot.Length);
                    }
                    else
                    {
                        return(FindFailed());
                    }
                }
                else
                {
                    if (CurrentResult.Value.Start.Position != CurrentResult.Value.Snapshot.Length)
                    {
                        startingPosition = CurrentResult.Value.Start + 1;
                    }
                    else if ((SearchOptions & FindOptions.Wrap) != 0)
                    {
                        startingPosition = new SnapshotPoint(CurrentResult.Value.Snapshot, 0);
                    }
                    else
                    {
                        return(FindFailed());
                    }
                }
            }
            else if (StartPoint != null)
            {
                startingPosition = StartPoint.Value;
            }
            else
            {
                startingPosition = new SnapshotPoint(buffer.CurrentSnapshot, 0);
            }
            startingPosition = startingPosition.TranslateTo(buffer.CurrentSnapshot, (SearchOptions & FindOptions.SearchReverse) != 0 ? PointTrackingMode.Negative : PointTrackingMode.Positive);

            var spanToUse = searchSpan?.GetSpan(buffer.CurrentSnapshot) ?? new SnapshotSpan(buffer.CurrentSnapshot, 0, buffer.CurrentSnapshot.Length);

            if (!IsValidStartingPosition(spanToUse, startingPosition))
            {
                return(FindFailed());
            }
            foreach (var result in textSearchService2.FindAll(spanToUse, startingPosition, SearchTerm, SearchOptions))
            {
                currentResult = result;
                return(true);
            }

            return(FindFailed());
        }
Exemple #3
0
        public bool Find()
        {
            if (string.IsNullOrEmpty(this.SearchTerm))
            {
                throw new InvalidOperationException("You must set a non-empty search term before searching.");
            }

            bool forward = (this.SearchOptions & FindOptions.SearchReverse) != FindOptions.SearchReverse;
            bool wrap    = (this.SearchOptions & FindOptions.Wrap) == FindOptions.Wrap;
            bool regEx   = (this.SearchOptions & FindOptions.UseRegularExpressions) == FindOptions.UseRegularExpressions;

            ITextSnapshot searchSnapshot = _buffer.CurrentSnapshot;

            //There could be a version skew here if someone calls find from inside a text changed callback on the buffer. That probably wouldn't be a good
            //idea but we need to handle it gracefully.
            this.AdvanceToSnapshot(searchSnapshot);

            SnapshotPoint?searchStart = this.CalculateStartPoint(searchSnapshot, wrap, forward);

            if (searchStart.HasValue)
            {
                int index = 0;
                NormalizedSnapshotSpanCollection searchSpans = this.SearchSpans;

                if (searchSpans != null)
                {
                    Debug.Assert(searchSpans.Count > 0);

                    //Index is potentially outside the range of [0...searchSpans.Count-1] but we handle that below.
                    if (!(TextSearchNavigator.TryGetIndexOfContainingSpan(searchSpans, searchStart.Value, out index) || forward))
                    {
                        //For reversed searches, we want the index of the span before the point if we can't get a span that contains the point.
                        --index;
                    }
                }
                else
                {
                    searchSpans = new NormalizedSnapshotSpanCollection(new SnapshotSpan(searchSnapshot, Span.FromBounds(0, searchSnapshot.Length)));
                }

                int searchIterations = searchSpans.Count;
                for (int i = 0; (i < searchIterations); ++i)
                {
                    //index needs to be normalized to [0 ... searchSpans.Count - 1] but could be negative.
                    index = (index + searchSpans.Count) % searchSpans.Count;

                    SnapshotSpan searchSpan = searchSpans[index];
                    if ((i != 0) || (searchStart.Value < searchSpan.Start) || (searchStart.Value > searchSpan.End))
                    {
                        searchStart = forward ? searchSpan.Start : searchSpan.End;
                    }
                    else if (wrap && (i == 0))
                    {
                        //We will need to repeat the search to account for wrap being on and we are not searching everything in searchSpans[0].
                        //This is the same as simply doing a search for i == searchSpans.Count we we can make happen by bumping the number of iterations.
                        ++searchIterations;
                    }

                    foreach (var result in _textSearchService.FindAll(searchSpan, searchStart.Value, this.SearchTerm, this.SearchOptions & ~FindOptions.Wrap))
                    {
                        // As a safety measure, we don't include results of length zero in the navigator unless regular expressions are being used.
                        // Zero width matches could be useful in RegEx when for example somebody is trying to replace the start of the line using the "^"
                        // pattern.
                        if (result.Length == 0 && !regEx)
                        {
                            continue;
                        }
                        else
                        {
                            // We accept the first match
                            this.CurrentResult = result;
                            return(true);
                        }
                    }

                    if (forward)
                    {
                        ++index;
                    }
                    else
                    {
                        --index;
                    }
                }
            }

            // If nothing was found, then clear the current result
            this.ClearCurrentResult();

            return(false);
        }