PavelTorgashov / FastColoredTextBox

Fast Colored TextBox for Syntax Highlighting. The text editor component for .NET.
Other
1.22k stars 465 forks source link

Backward search capability in Find #141

Open KaustubhPatange opened 5 years ago

KaustubhPatange commented 5 years ago

Hi, In your Find form there is a function "FindNext" which searches for next words (also given below). How to modify it for previous search like Find Previous word, something like that.

  public virtual void FindNext(string pattern)
        {
            try
            {
                ShowText("");
                RegexOptions opt = cbMatchCase.Checked ? RegexOptions.None : RegexOptions.IgnoreCase;
                if (!cbRegex.Checked)
                    pattern = Regex.Escape(pattern);
                if (cbWholeWord.Checked)
                    pattern = "\\b" + pattern + "\\b";
                //
                Range range = tb.Selection.Clone();
                range.Normalize();
                //
                if (firstSearch)
                {
                    startPlace = range.Start;
                    firstSearch = false;
                }
                //
                range.Start = range.End;
                if (range.Start >= startPlace)
                    range.End = new Place(tb.GetLineLength(tb.LinesCount - 1), tb.LinesCount - 1);
                else
                    range.End = startPlace;
                //
                foreach (var r in range.GetRangesByLines(pattern, opt))
                {
                    tb.Selection = r;
                    tb.DoSelectionVisible();
                    tb.Invalidate();
                    return;
                }
                //
                if (range.Start >= startPlace && startPlace > Place.Empty)
                {
                    tb.Selection.Start = new Place(0, 0);
                    FindNext(pattern);
                    return;
                }
                ShowText($"Can't find the \"{tbFind.Text}\"", true);
            }
            catch (Exception ex)
            {
                ShowText(ex.Message, true);
            }
        }
sebhad commented 5 years ago

I would like to share what I did:

        public virtual void FindPrev(string pattern)
        {
            try
            {
                RegexOptions opt = cbMatchCase.Checked ? RegexOptions.None : RegexOptions.IgnoreCase;
                if (!cbRegex.Checked)
                    pattern = Regex.Escape(pattern);
                if (cbWholeWord.Checked)
                    pattern = "\\b" + pattern + "\\b";

                Range selectedRange = tb.Selection.Clone();
                selectedRange.Normalize();
                Range searchRange = new Range(tb);

                // Search range before selection
                searchRange.Start = new Place(0, 0);
                searchRange.End = selectedRange.Start;
                foreach (var r in searchRange.GetRangesByLinesReversed(pattern, opt))
                {
                    tb.Selection = r;
                    tb.DoSelectionVisible();
                    tb.Invalidate();
                    return;
                }

                // Search range after selection
                searchRange.Start = selectedRange.End;
                searchRange.End = new Place(tb.GetLineLength(tb.LinesCount - 1), tb.LinesCount - 1);
                foreach (var r in searchRange.GetRangesByLinesReversed(pattern, opt))
                {
                    tb.Selection = r;
                    tb.DoSelectionVisible();
                    tb.Invalidate();
                    return;
                }

                MessageBox.Show("Not found");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

I also changed the method FindNext in the same was to make the search start again when the end of the search was reached. For me the original code was very hard to understand and impossible to adapt for the backward search.