Conversation
tidely
marked this pull request as draft
September 27, 2026 22:34
tidely
force-pushed
the
text-view-source-range-highlights
branch
from
September 27, 2026 22:34
1ba5468 to
7221242
Compare
tidely
marked this pull request as ready for review
September 27, 2026 22:37
huacnlee
requested changes
Sep 29, 2026
huacnlee
left a comment
Member
There was a problem hiding this comment.
One issue with code blocks now that they join the source map; everything else (escape splitting, the linear flag, range rejection, custom blocks, table cell offsets) checks out.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
#3215 added range highlights, which are addressed by offsets into
rendered_text(). But an application often knows what was selected in terms of the Markdown source:TextViewState::selected_source_range()reports source ranges, and apps store those ranges alongside their own data (comments, annotations, citations). Until now there was no way to turn a source range back into a rendered range, so a stored source selection could not be highlighted again.This PR adds
RenderedText::range_for_source, which converts a UTF-8 byte range of the Markdown source into the matching range of the rendered text, so it can be passed toRangeHighlight. It also addsRenderedText::source, the source of the same parse, so callers can check that their ranges index the source the view actually rendered (while streaming it is a prefix; afterset_textit may still be the previous text until the new parse lands).How it works:
RenderedIndexnow also builds a source map from theSourceSegments the parser already records for paragraphs, headings, table cells and code blocks. Custom blocks and inline plugin objects map as a whole to theirsource_range().SourceSegmentgets alinearflag: whether each rendered character came from a source character of the same length, so part of the segment can map to part of its source. Before, this was inferred fromrendered.len() == source.len(), which is wrong for entities whose decoded text happens to be as long as the entity (∾̳→∾̳, 5 bytes each). Entities, escapes and soft breaks now always map as a whole.**bold**andboldconvert to the same range.None.The
linearflag also changes existing behavior: text after an escaped character now maps character for character. Previously the escape made the whole text run map only as a block, so selectingbin\*abcreported more source than was selected.Public API
gpui-base (re-exported as
gpui_component::text::RenderedText)gpui_base::text::RenderedText::source(&self) -> &str: the Markdown source this rendered text was parsed from, whose byte rangesrange_for_sourcetakes.gpui_base::text::RenderedText::range_for_source(&self, source: Range<usize>) -> Option<Range<usize>>: converts a source byte range (e.g. fromselected_source_range()) into the rendered-text range aRangeHighlighttakes;Nonefor empty, reversed, out-of-bounds or non-char-boundary ranges, ranges that render nothing, and HTML views.How to Test
cargo test -p gpui-base --lib text::range_highlight.rscover emphasis, entities, escapes, code blocks, tables, custom blocks, inline objects and HTML.TestAppContexttests instate.rscover Select All and dragged-selection round trips, streaming appends, background parses landing, snapshots converting against their own source, and HTML views.markdown.rscover entities as long as their decoded characters (∾̳) and text after an escape.website/component/text-view.md(en and zh-CN) for ahighlight_commentsexample that re-highlights stored source ranges.Checklist
cargo runfor story tests related to the changes.