Skip to content

text_view: Add TextViewState::reveal_range - #3216

Merged
huacnlee merged 4 commits into
longbridge:mainfrom
white07S:text-view-reveal-range
Sep 25, 2026
Merged

huacnlee merged 4 commits into
longbridge:mainfrom
white07S:text-view-reveal-range

Conversation

@white07S

@white07S white07S commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Closes #3214

Follows #3215, which added the range highlights this builds on.

Description

Adds reveal_range, which scrolls the line where a range starts into view, for example the current search result, or a line deep inside a long paragraph.

It works in a scrollable TextView and inside an app's gpui::list, such as a chat. Other scroll containers, like a div with overflow_y_scroll, can use the new TextView::on_reveal callback. It gets the line's position, so the app can scroll its own container.

It doesn't scroll when the line is already visible, and it follows the content the same way highlights do. It also gives up after a second if the line can't be shown, so it never jumps late.

The markdown example gets previous and next buttons. Enter and Shift+Enter in the find field do the same.

Not covered: text scrolled sideways inside a table, and a scrollable TextView inside an app list, which only scrolls itself.

Also fixes a RangeHighlight doc comment that was cut off mid-sentence in #3215.

Public API

gpui-base

Also available on the gpui_component::text::TextView wrapper.

  • TextViewState::reveal_range(&mut self, range: Range<usize>, cx: &mut Context<Self>) -> Result<(), RangeHighlightError>: scrolls the line where range starts into view. Like set_range_highlights, range points into the current rendered_text(). It's best effort: Ok(()) means the request was taken, not that the view has scrolled.
  • TextView::on_reveal(self, handler: impl Fn(Bounds<Pixels>, &mut Window, &mut App) + 'static) -> Self: lets a container that ignores scroll requests follow a reveal, using the line's bounds in window coordinates.

How to Test

  • cargo test -p gpui-base --lib text::
  • cargo run -p example-markdown, search in the "Find in preview" field, then step through the matches with the arrows or Enter / Shift+Enter.

Checklist

  • I have read the CONTRIBUTING document and followed the guidelines.
  • Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate.
  • Passed cargo run for story tests related to the changes.
  • Tested macOS, Windows and Linux platforms performance (if the change is platform-specific)

@suxiaoshao

suxiaoshao commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Thank you for implementing this and the companion highlight PR! Together they look very close to what we hoped for in #3214. The separation between application-owned search and the component's highlighting/reveal capabilities fits the request well.

One small question about the API contract: if reveal_range() accepts a request but it later times out, is there a way for the caller to tell that the reveal did not complete, or is this intentionally a best-effort operation with no completion feedback? Clarifying that in the docs would help callers understand what a successful return means.

Thanks again for the work and the test coverage!

@white07S

Copy link
Copy Markdown
Contributor Author

@suxiaoshao Thanks! It's intentionally best effort. Ok(()) means the range is valid for the current text and the request was taken, not that the view has scrolled. A request is dropped without notice if its text changes, the view clamps its lines with max_lines, or the line can't be shown within about a second.

I've made that explicit in the reveal_range docs and the TextView page (110f3f1). If callers turn out to need the outcome, a completion callback could be added later, but I'd rather keep the API small until there's a concrete need.

@white07S white07S mentioned this pull request Sep 24, 2026
4 tasks
@white07S
white07S force-pushed the text-view-reveal-range branch from 110f3f1 to f0a9881 Compare September 24, 2026 12:16
Scroll the line a range of the rendered text starts on into view, in the
view itself, an enclosing list, or through `TextView::on_reveal`.

Refs longbridge#3214
@white07S
white07S force-pushed the text-view-reveal-range branch from f0a9881 to f5fccfd Compare September 25, 2026 12:06
@white07S
white07S marked this pull request as ready for review September 25, 2026 12:25
A reveal starting on a line break or an empty line in an inline flow
paragraph fell between fragments, so no fragment carried it out and it
was dropped after its timeout. It now goes to the next fragment of its
text, or the last when none follows.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@huacnlee huacnlee left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I pushed 19a13f6 to fix a reveal that starts on a line break (or an empty line) inside an inline flow paragraph: no fragment contained that offset, so the reveal was never carried out and was dropped after its timeout. It now goes to the next fragment of its text, with a test covering the case.

@huacnlee
huacnlee enabled auto-merge (squash) September 25, 2026 14:48
@huacnlee
huacnlee merged commit 80230b6 into longbridge:main Sep 25, 2026
12 checks passed
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 this pull request may close these issues.

text_view: Expose range highlighting and scroll-to-range APIs

3 participants