Posted 4 years ago by Erwin Liong
Version: 15.1.0624
Platform: .NET 4.5
Environment: Windows 10 (64-bit)
Avatar

Hi Actipro,

I am not sure if this is the same problem as this. I am seeing the problem with Build 2015.1.624.

If I have the following sample text:

string sampleText =
@"The quick brown fox jumped over the lazy dog.
This is another line.
The quick brown dog jumped over the lazy fox.
This is some other lines.
This is also another line.
This is yet another line.
";

 

Problem #1:

If I place my cursor at "This is yet anothe~r line." where ~ is the caret position, When I perform a search up, I am getting the text "another" from that line itself.

My expected behavior is to be same with how Visual Studio has it. Visual Studio would return the "another" from the line before that "This is also another line." 

With the word selected, the search up works okay. That is, if I have "This is yet [another] line." where [] is my selection. The search up can find me the correct text from one line before last.

 

Problem #2:

I am observing different result in searching up when using FindNext with and without TextRange defined.

// Problematic Search up.
ISearchResultSet searchResultSet = snapshot.FindNext(searchOptions, startOffset, false, txtRange);

// OK Search Up.
ISearchResultSet searchResultSet = snapshot.FindNext(searchOptions, startOffset, false);

 

 Here is my complete code (modified from SvenG's unit test):

using ActiproSoftware.Text;
using ActiproSoftware.Text.Implementation;
using ActiproSoftware.Text.Searching;
using ActiproSoftware.Windows.Controls.SyntaxEditor;
using ActiproSoftware.Windows.Controls.SyntaxEditor.Implementation;
using System.Linq;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            #region Arrange
            const string searchString = "another";
            const bool searchUp = true;

            ITextSnapshot snapshot = GetSampleTextSnapshot();

            // With no text range:  5,12 gets the 6th Line "This is yet [another] line. 
            //                      5,11 gets the 5th Line "This is also [another] line."
            // With text range:     5,12 gets no result. 
            //                      5,11 gets the Line 5th "This is also [another] line."
            // Expected: 5,18 i.e. "This is yet anothe~r line" should get the result of "This is also [another] line."
            TextPosition startPos = new TextPosition(5,12); 
            TextPosition endPos = new TextPosition(0,0);
            int startOffset = snapshot.PositionToOffset(startPos);
            int endOffset = snapshot.PositionToOffset(endPos);
            TextRange txtRange = new TextRange(startOffset, endOffset);

            int line = snapshot.OffsetToPosition(startOffset).Line;
            string snapString = snapshot.Lines[line].Text;

            ISearchOptions searchOptions = GetSearchOptionsFromSearchSettings(searchString, searchUp);
            #endregion

            #region Act
            ISearchResultSet searchResultSet = snapshot.FindNext(searchOptions, startOffset, false, txtRange);
            #endregion

            #region Assert
            ISearchCapture firstCapture = searchResultSet.Results.First().Captures.First();
            TextPosition resultLine = snapshot.OffsetToPosition(firstCapture.TextRange.StartOffset);
            #endregion
        }

        private static ITextSnapshot GetSampleTextSnapshot()
        {
            string sampleText =
@"The quick brown fox jumped over the lazy dog.
This is another line.
The quick brown dog jumped over the lazy fox.
This is some other lines.
This is also another line.
This is yet another line.
";
            CodeDocument document = new CodeDocument();
            document.SetText(sampleText);

            return document.CurrentSnapshot;
        }

        private static ISearchOptions GetSearchOptionsFromSearchSettings(string text, bool searchUp, int maximumResultCount = 1)
        {
            return new EditorSearchOptions
            {
                FindText = text,
                MatchCase = false,
                MatchWholeWord = false,
                SearchUp = searchUp,
                PatternProvider = SearchPatternProviders.Normal,
                Scope = EditorSearchScope.Document,
                MaximumResultCount = maximumResultCount
            };
        }
    }
}

 

Question: 

It may take a while before I can switch over to an updated ActiPro, is there a way I can workaround these problems?

Comments (3)

Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Erwin,

For problem #1, some editors (Sublime Text, etc.) do find the text on the same line like we do and some editors (VS) don't.  VS seems to have extra code to ensure that the match it finds before the start offset doesn't extend past the search start offset.

For problem #2, when we tested it here it seemed to work ok.  Calling snapshot.FindNext will begin searching at the specified offset, even when in search up mode.  The editor view search model, which ends up calling into the core snapshot search model, will subtract 1 from the start offset when doing search up.  You could do the same in your code.

When specifying a text range, it's similar to search in selection where the text range is the selection.  It will require that any match is fully enclosed within the text range that is specified.  That seems to be working ok in our tests.


Actipro Software Support

Posted 4 years ago by Erwin Liong
Avatar

Hi Actipro,

Problem #1 (Continued):

Scenario: ~ is the position of caret/search start offset.

The quick brown fox jumped over the lazy dog.
This is another line.
The quick brown dog jumped over the lazy fox.
This is some other lines.
This is also another line.
This is yet ~another line.

 When searching up with Sublime, I get "This is also [another] line.". However, with Actipro, I am getting "This is yet [another] line.". 

The root problem here is because you have added the subtract 1 from start offset in Editor View Search Model class instead of Snapshot class. I am using ITextSnapshot.FindNext. I believe the logic to subtract 1 should reside in Snapshot instead of Editor View because I need to perform the search without having any editor view.

 

Problem #2 (Continued):

I am surprised you do not see the problem I am seeing on my end. Are you using v15.1.0624?

Here is another attempt to better illustrate my problem:

using ActiproSoftware.Text;
using ActiproSoftware.Text.Implementation;
using ActiproSoftware.Text.Searching;
using ActiproSoftware.Windows.Controls.SyntaxEditor;
using ActiproSoftware.Windows.Controls.SyntaxEditor.Implementation;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            #region Arrange
            const string searchString = "another";
            const bool searchUp = true;

            ITextSnapshot snapshot = GetSampleTextSnapshot();

            TextRange searchBounds = new TextRange(snapshot.TextRange.EndOffset, snapshot.TextRange.StartOffset);
            int searchOffset = searchBounds.StartOffset;

            ISearchOptions searchOptions = GetSearchOptionsFromSearchSettings(searchString, searchUp);
            #endregion

            #region Act
            do
            {
                ISearchResultSet searchResultSet = snapshot.FindNext(searchOptions, searchOffset, false/*, searchBounds*/); // Always return offset [179-186].
                //ISearchResultSet searchResultSet = snapshot.FindNext(searchOptions, searchOffset, false, searchBounds); // Only return offset [179-186] on the first loop. Second round returns zero search result count.
                if (searchResultSet.Results.Count > 0)
                {
                    TextRange foundRange = searchResultSet.Results[0].FindSnapshotRange.TranslateTo(snapshot, TextRangeTrackingModes.Default);

                    TextPosition foundPosition = snapshot.OffsetToPosition(foundRange.StartOffset);

                    searchBounds = new TextRange(foundRange.StartOffset, searchBounds.EndOffset);
                    searchOffset = searchBounds.StartOffset;// - 1 here to accomodate for Editor View Search Model Subtraction of 1;
                }
                else
                    break;
            }
            while (true);

            #endregion
        }

        private static ITextSnapshot GetSampleTextSnapshot()
        {
            string sampleText =
@"The quick brown fox jumped over the lazy dog.
This is another line.
The quick brown dog jumped over the lazy fox.
This is some other lines.
This is also another line.
This is yet another line.
";

            CodeDocument document = new CodeDocument();
            document.SetText(sampleText);

            return document.CurrentSnapshot;
        }

        private static ISearchOptions GetSearchOptionsFromSearchSettings(string text, bool searchUp, int maximumResultCount = 1)
        {
            return new EditorSearchOptions
            {
                FindText = text,
                MatchCase = false,
                MatchWholeWord = false,
                SearchUp = searchUp,
                PatternProvider = SearchPatternProviders.Normal,
                Scope = EditorSearchScope.Document,
                MaximumResultCount = maximumResultCount
            };
        }
    }
}

 Note the code at line 28 and 29; and also line 37.

Without the -1 on line 37, when I am running code with line 28, I am always getting "This is yet [another] line.".

Without the -1 on line 37, when I am running code with line 29, I am always only getting one search result. "This is yet [another] line."

Question: Why would the search on snapshot be any difference with and without a search boundary defined?

 

With the -1 on line 37, both scenario on line 28 or line 29 will work fine to iterate and find all the search result. This is a a naive subtraction. I believe the logic in Editor View should be implemented in Snapshot instead. This avoids the Snapshot client having to manipulate the input data.

Question: Would Actipro change the Snapshot to be able to handle its own Search Offset Adjustment for Search Up, instead of relying on the client to do it (in your case, the Editor View Searcher)?

Please advise. Thank you.

Answer - Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

For the second issue, when I run your exact code above in our latest 2016.1 code with the -1 on line 37, I get the proper 3 results. It looks like we recently made an update to searching within text ranges that fixed that issue. Note that this updated was made in the codebase for the upcoming 2016.1 build 631 maintenance release, which should be out in a week or two.

As for the offset issue, we will update snapshot.FindNext to also start an offset earlier when searching up so that everything is consistent. We'll get that in for build 631 as well.


Actipro Software Support

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.