Skip to content

"Replace next" incorrect behavior #355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gusmanb opened this issue Jul 15, 2023 · 16 comments · Fixed by #393
Closed

"Replace next" incorrect behavior #355

gusmanb opened this issue Jul 15, 2023 · 16 comments · Fixed by #393
Assignees

Comments

@gusmanb
Copy link

gusmanb commented Jul 15, 2023

The "replace next" function of the search panel implements an incorrect behavior when used more than once.

  • Version:

AvaloniaEdit 11.0.0

  • Simptoms:

If you have a text that contains multiple matches and replace one by one using the "Replace next" button it skips one of the matches each time.

  • Cause:

Internally the "Replace next" function calls "FindNext", which searches one char ahead of the caret position, this behavior makes sense for the "FindNext" functionality but not for the replace as once you replace a match it moves the caret to the next one so the next time you press the "Replace next" button that match is skipped and the next one is replaced.

  • Solution:

"Replace next" should use its own search criteria that searches from the caret position, not from the next position.

  • Considerations:

"FindNext" also may present an erratic behavior because of the search-ahead, for example, if an user places the caret at the beginning of a file and the searched text is present starting at the first char the function will skip it and go to the next. The search-ahead behavior should be used only after the first "FindNext" is issued and if the user has not moved manually the caret.

@KrzysztofDusko
Copy link
Contributor

KrzysztofDusko commented Jan 5, 2024

@danipen will PR with "fast and dirty" fix will be accepted ?
Idea is simple, at this time we have

        public void ReplaceNext()
        {
            if (!IsReplaceMode) return;

            FindNext();
            if (!_textArea.Selection.IsEmpty)
            {
                _textArea.Selection.ReplaceSelectionWithText(ReplacePattern ?? string.Empty);
            }

            UpdateSearch();
        }
(...)
        public void FindNext()
        {
            var result = _renderer.CurrentResults.FindFirstSegmentWithStartAfter(_textArea.Caret.Offset + 1) ??
                         _renderer.CurrentResults.FirstSegment;
            if (result != null)
            {
                _currentSearchResultIndex = GetSearchResultIndex(_renderer.CurrentResults, result);
                SelectResult(result);
                UpdateSearchLabel();
            }
        }

we can fix this issue with allowing to add additional offset (negative) in FindNext like this:

        public void FindNext(int additionallOffset = 0)
        {
            var result = _renderer.CurrentResults.FindFirstSegmentWithStartAfter(_textArea.Caret.Offset + 1 + additionallOffset) ??
                         _renderer.CurrentResults.FirstSegment;
            if (result != null)
            {
                _currentSearchResultIndex = GetSearchResultIndex(_renderer.CurrentResults, result);
                SelectResult(result);
                UpdateSearchLabel();
            }
        }

and ReplaceNext :

        public void ReplaceNext()
        {
            if (!IsReplaceMode) return;

            FindNext(-1);
            if (!_textArea.Selection.IsEmpty)
            {
                _textArea.Selection.ReplaceSelectionWithText(ReplacePattern ?? string.Empty);
            }

            UpdateSearch();
        }

to be 100% precise
image
image

@danipen
Copy link
Collaborator

danipen commented Jan 5, 2024

Haha It's a quite dirty hack... A better solution would be desired...

@KrzysztofDusko
Copy link
Contributor

FindNextOrAcual method will be OK ? and this method will be really very simillar to Find next .. only difference will be no this "+1"
image
this approach leads to code duplication..

if this is bad idea too can you guide me a little ?

@KrzysztofDusko
Copy link
Contributor

KrzysztofDusko commented Jan 5, 2024

or insead off
public void FindNext(int additionallOffset = 0)
this ?
public void FindNext(bool startWithNoOffset = false)
and false = no +1 :)

@danipen
Copy link
Collaborator

danipen commented Jan 5, 2024

IMO first step is taking a look to the upstream repo to see if the bug is there. If not we should review the port. If the bug is there too we can think a fix for it.

@KrzysztofDusko
Copy link
Contributor

KrzysztofDusko commented Jan 5, 2024

orginal implemenation do not have replace option.. or i cant find it..
image
and
but findnext have similar implementation witch is wrong for ReplaceNext purpose (but ok for finding and only this usage exists in AvalonEdit)
image

@KrzysztofDusko
Copy link
Contributor

i maked PR for this issue
#392

@danipen
Copy link
Collaborator

danipen commented Jan 9, 2024

@gusmanb please could you elaborate a little bit more on this, showing a video or an example?

"FindNext" also may present an erratic behavior because of the search-ahead, for example, if an user places the caret at the beginning of a file and the searched text is present starting at the first char the function will skip it and go to the next. The search-ahead behavior should be used only after the first "FindNext" is issued and if the user has not moved manually the caret.

@danipen
Copy link
Collaborator

danipen commented Jan 9, 2024

Started PR #393.

@danipen danipen self-assigned this Jan 9, 2024
@gusmanb
Copy link
Author

gusmanb commented Jan 9, 2024

Here is an example of what I meant. As you can see the first occurence of the word is skipped and it selects the next one.

search2.online-video-cutter.com.mp4

@danipen
Copy link
Collaborator

danipen commented Jan 9, 2024

@gusmanb got it. Other editors place the caret at the end of the search result, so they then FindNext just from the caret position. I will mimic that behavior in AvaloniaEdit.

@danipen
Copy link
Collaborator

danipen commented Jan 9, 2024

@gusmanb it should be fixed now. Could you please give it a try to #393. Thanks!

@gusmanb
Copy link
Author

gusmanb commented Jan 9, 2024

@danipen Search works as expected, selects the first occurence of the word, but replace next still skips one occurence each time (should it also be fixed in that pr?)

Desktop.2024.01.09.-.17.52.08.02.online-video-cutter.com.mp4

@danipen
Copy link
Collaborator

danipen commented Jan 9, 2024

Yes, it should work in this PR. Taking a look again...

@danipen
Copy link
Collaborator

danipen commented Jan 9, 2024

@gusmanb ok, it was broken with latest changes, it should work as expected now. Please can you give it a try? Thanks!

@gusmanb
Copy link
Author

gusmanb commented Jan 9, 2024

@danipen Excellent! Now everything works as expected, find next and replace next 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants