Skip to content

Conversation

@personalizedrefrigerator
Copy link
Collaborator

@personalizedrefrigerator personalizedrefrigerator commented Sep 17, 2025

Summary

This pull request adds logic to auto-scroll to the next (or first, should no match be found after the cursor) search match when the search query changes.

Resolves #12343.

Notes

Testing plan

Web and desktop (Fedora 42):

  1. Create a new note that contains, in a ```ts code block, the content of searchExtension.ts.
  2. Search for EditorView.
  3. Scroll to the end of the document and dismiss the search bar.
  4. Tap the editor to move the selection.
  5. Re-open the search bar.
  6. Verify that the end of the document is still visible.
  7. Backspace the w in EditorView.
  8. Verify that the editor scrolls to the first EditorView match.
  9. Search for ```.
  10. Verify that the end of the code block is matched.
  11. Search for ```ts and verify that the start of the code block is matched.
  12. Search for ```$ and enable regular expression search.
  13. Verify that this scrolls the last line of the code block into view.

Screen recording (web):

Screencast.from.2025-09-17.15-21-53.webm

Screen recording (desktop):

Screencast.from.2025-09-17.15-30-08.webm

Needs accessibility testing. Currently, this change should announce each new
search match using an aria-live=polite region (in a similar way to
CodeMirror's findNext).
@personalizedrefrigerator personalizedrefrigerator changed the title Mobile,Desktop: Resolves #12343: Auto-scroll to the next match Mobile,Desktop: Resolves #12343: Markdown editor search: Auto-scroll to the next match Sep 17, 2025
@personalizedrefrigerator personalizedrefrigerator changed the title Mobile,Desktop: Resolves #12343: Markdown editor search: Auto-scroll to the next match Mobile,Desktop: Resolves #12343: Markdown editor search: Auto-scroll to the next match when the search changes Sep 17, 2025
@personalizedrefrigerator personalizedrefrigerator added the markdown-editor About the Markdown editor label Sep 17, 2025
@mrjo118
Copy link
Contributor

mrjo118 commented Sep 17, 2025

auto-scroll to the next (or first, should no match be found after the cursor) search match when the search query changes

I'm slightly concerned by this logic. Lets say I have the following note content spread across 3 lines (I couldn't work out how to do a multi line code block):
1. I want a hat to wear to work 2. I love hatty 3. I really want to buy a hat that is expensive

I want to search for the word 'hat', but I initially type 'hatt' by mistake. As I type this out, it will first match line 1, then it will match line 2. I then notice my mistake and remove the 't'. This will stay on line 2 and then when I press find next it will match line 3, rather than the first match on line 1. This is obviously a very simple example, but if these 3 lines were spread across 1000 lines, it would not be obvious that I missed the first match

EDIT: If the search actually told you up front how many matches there are, and how many matches in the search is, then this would not be an issue. I'm not sure how hard this would be to implement though. See example from a desktop web browser:
matches

@mrjo118
Copy link
Contributor

mrjo118 commented Sep 17, 2025

Also if the note is very large, the search as you type should not cause input lag while the user is typing the search term, particularly on mobile where it may be slower

@laurent22
Copy link
Owner

I want to search for the word 'hat', but I initially type 'hatt' by mistake. As I type this out, it will first match line 1, then it will match line 2. I then notice my mistake and remove the 't'. This will stay on line 2 and then when I press find next it will match line 3, rather than the first match on line 1. This is obviously a very simple example, but if these 3 lines were spread across 1000 lines, it would not be obvious that I missed the first match

Indeed I see that for example on VSCode if I type "hatt", then delete the last "t", it goes back to the first result. That being said, the current change is still a big improvement over what we have now. Maybe we could tweak the logic but that doesn't seem essential unless I'm missing something.

Also if the note is very large, the search as you type should not cause input lag while the user is typing the search term, particularly on mobile where it may be slower

Hmm, yes I don't know if it would, I'd expect it's not that slow. @personalizedrefrigerator what do you think? Could it have the same issue as global search, where you type the first character and it freezes because it processes all the note?

@mrjo118
Copy link
Contributor

mrjo118 commented Sep 18, 2025

Indeed I see that for example on VSCode if I type "hatt", then delete the last "t", it goes back to the first result.

VS Code actually doesn't go back to the first result in this scenario, it goes back 1 match if there are more matches preceding the current match since the search term changed. You can verify this by duplicating my 3 example lines and initially matching the second instance of 'hatt'.

EDIT: Actually you're right. It does go to the first match when the search term changes, but it goes to the first match after the cursor position.

I think if the logic could be implemented that way, it would be good. Web browsers presumably don't do this because a web page doesn't have a cursor position except within inputs, but the search within a Joplin note is search within a text editor, so it would work well to do it this way.

@personalizedrefrigerator
Copy link
Collaborator Author

I think if the logic could be implemented that way, it would be good. Web browsers presumably don't do this because a web page doesn't have a cursor position except within inputs

Note: Enabling caret browsing (by pressing F7 on Linux) in Firefox and Chromium seems to result in similar behavior.

@personalizedrefrigerator
Copy link
Collaborator Author

To allow for additional testing, I've deployed a version of this pull request to https://personalizedrefrigerator.github.io/joplin/web-client/.

Needs further testing.

At present, this works by:
- Adding a new cancellable async scanForFirstMatch that searches the document in
  chunks, pausing after each chunk has been processed.
- Updating the "scroll to next match on search change" extension to 1) use
  the new scanForFirstMatch function and 2) cancel the previous
  scanForFirstMatch when starting a new one.
- Updating the note editor's search field to better handle search
  updates coming back from the editor with a delay. Previously, when
  changing the input's content, the search state would be sent to the
  editor. The editor would then apply the change and send an event back
  to React. If different from the current search, the current search is
  updated and a re-render is triggered. If the WebView is running
  slowly, however, old, outdated searches will be received by React in
  the search change listener. This would cause the search input to
  sometimes revert to previous values, particularly when searching in a
  long document with the new "scroll to first match" logic.
@personalizedrefrigerator personalizedrefrigerator marked this pull request as draft September 19, 2025 00:17
@personalizedrefrigerator
Copy link
Collaborator Author

Also if the note is very large, the search as you type should not cause input lag while the user is typing the search term, particularly on mobile where it may be slower

The "auto-scroll to the next match" logic did cause significant input issues when testing on a 154,841-line (8,776,740 character) document. This may be fixed by 88ade38, but I will need to do further testing to confirm. For now, I'm converting this pull request to a draft.

@mrjo118
Copy link
Contributor

mrjo118 commented Sep 19, 2025

  • this pull request instead scrolls to the first match after the user's selection. The behavior in this pull request is intended to more closely match the behavior of browsers and other editors (e.g. VSCode, Firefox with caret browsing enabled, Chromium with caret browsing enabled).

@personalizedrefrigerator I hadn't read this part initially as I'd just read the part in the summary which I had issue with. I tested this on your deployed web app and it seems that the reason why removing a 't' in my example does not go back to 'hat' with your code change is because the cursor moves to the position of the match (in the case of VS Code, the cursor does not move when text is matched). Is it possible to leave the position of the cursor where it is when scrolling to the first match, or is that essentially what you are using to make it scroll?

@personalizedrefrigerator
Copy link
Collaborator Author

Context for why the selection change is done:

  • CodeMirror marks a particular match as the current match by selecting it. The selection change is intended to align with CodeMirror's native findNext behavior. This should allow the "scroll the first match into view" behavior to work better with the "find next"/"replace next" actions.
  • Selecting the current match prevents Joplin from scrolling away when dismissing the search. When the editor resizes, the selection is scrolled into view (to fix Beta editor on mobile (Android) not scrolling screen when keyboard opened #5949). Dismissing search resizes the editor.

@personalizedrefrigerator
Copy link
Collaborator Author

This may be fixed by 88ade38, but I will need to do further testing to confirm. For now, I'm converting this pull request to a draft.

I've moved some of the search performance improvements to a separate pull request: #13259.

@personalizedrefrigerator
Copy link
Collaborator Author

I'm marking this pull request as ready for review. The performance issues should be resolved by 88ade38 and #13259. The search position issue raised by @mrjo118 should be fixed by 32bea2c.

@laurent22
Copy link
Owner

That looks good, thank you! Just one conflict to be fixed and then we can merge

@laurent22 laurent22 merged commit b06ffe3 into laurent22:dev Oct 9, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

markdown-editor About the Markdown editor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When searching, the editor should scroll to the first match automatically

3 participants