Skip syntax highlighting for read_file outline responses#57287
Merged
Conversation
|
Thank you for your pull request and welcome to our community. We could not parse the GitHub identity of the following contributors: Martin Ye.
|
|
Thank you for your pull request and welcome to our community. We could not parse the GitHub identity of the following contributors: Martin Ye.
|
When read_file returns a file outline instead of full contents, wrap the result in a plain fenced code block rather than tagging it with the file's path. The outline is structural (e.g. `fn foo [L10-20]`) and is not valid source for the file's language, so running the language's tree-sitter parser against it on every paint is both expensive and produces incorrect highlighting. This noticeably improves scrolling smoothness in the agent panel when a read_file tool call with a large outline output is expanded.
30487d3 to
d128b23
Compare
Asserts that the outline response wraps its markdown in an *untagged* fenced code block (so the markdown renderer doesn't run tree-sitter against pseudo-code outline text on every paint), and that the non-outline path still tags the code block with the file path for syntax highlighting.
`MarkdownElementBuilder::push_text` was computing the base text style (which clones `base_text_style` and walks the style stack) twice per highlighted token: once for the run preceding the highlight and once for the run itself. For a code block with hundreds of highlight tokens, that's hundreds of redundant `TextStyle` clones per paint. The style stack does not change while runs are being attributed, so compute the style once outside the loop and reuse it. The clone is now only paid when a highlight is actually applied (because `TextStyle::highlight` takes `self` by value).
smitbarmase
approved these changes
May 21, 2026
TomPlanche
pushed a commit
to TomPlanche/zed
that referenced
this pull request
Jun 2, 2026
…ies#57287) When `read_file` returns a file outline instead of full contents, the result is now wrapped in a plain fenced code block rather than tagging it with the file's path. Previously, the outline was wrapped in a fenced block tagged with the file path (e.g. `` ```crates/agent/src/tools/read_file_tool.rs ``). Because the tag contains a slash, the markdown parser routed it through `CodeBlockKind::FencedSrc`, resolved the file's language by path, and ran the language's tree-sitter parser against the outline on every paint. The outline is structural (e.g. `fn foo [L10-20]`), not actual source for the file's language, so the parse was both expensive and produced incorrect highlighting. Because GPUI rebuilds the visible element tree on every window paint, anything that triggers a repaint (cursor blink in the focused message editor, animations, the turn timer, etc.) would re-run the tree-sitter parse on the entire outline, throttling the frame rate while the tool call was expanded. This change adds an `is_outline_response` flag in `ReadFileTool::run` and, when set, passes an empty tag to `MarkdownCodeBlock` so the renderer sees `CodeBlockKind::Fenced` (no language). Plain monospace formatting is preserved; the path tag is still used for the non-outline (full file) case. Adds two regression tests: one asserting the outline path uses an untagged fenced block, and one asserting the full-file path keeps the path tag (so the next person fixing this doesn't accidentally strip the tag everywhere). Also includes a small markdown-rendering follow-up: `MarkdownElementBuilder::push_text` was recomputing the base text style (cloning `base_text_style` and walking the style stack) twice per highlighted token. For a code block with hundreds of highlight tokens, that's hundreds of redundant `TextStyle` clones per paint. The style stack does not change while runs are being attributed, so the style is now computed once outside the loop and reused. Closes AI-234 Release Notes: - Improved scrolling smoothness in the agent panel when a `read_file` tool call with a large file outline is expanded.
This was referenced Jun 3, 2026
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.
When
read_filereturns a file outline instead of full contents, the result is now wrapped in a plain fenced code block rather than tagging it with the file's path.Previously, the outline was wrapped in a fenced block tagged with the file path (e.g.
```crates/agent/src/tools/read_file_tool.rs). Because the tag contains a slash, the markdown parser routed it throughCodeBlockKind::FencedSrc, resolved the file's language by path, and ran the language's tree-sitter parser against the outline on every paint. The outline is structural (e.g.fn foo [L10-20]), not actual source for the file's language, so the parse was both expensive and produced incorrect highlighting.Because GPUI rebuilds the visible element tree on every window paint, anything that triggers a repaint (cursor blink in the focused message editor, animations, the turn timer, etc.) would re-run the tree-sitter parse on the entire outline, throttling the frame rate while the tool call was expanded.
This change adds an
is_outline_responseflag inReadFileTool::runand, when set, passes an empty tag toMarkdownCodeBlockso the renderer seesCodeBlockKind::Fenced(no language). Plain monospace formatting is preserved; the path tag is still used for the non-outline (full file) case.Adds two regression tests: one asserting the outline path uses an untagged fenced block, and one asserting the full-file path keeps the path tag (so the next person fixing this doesn't accidentally strip the tag everywhere).
Also includes a small markdown-rendering follow-up:
MarkdownElementBuilder::push_textwas recomputing the base text style (cloningbase_text_styleand walking the style stack) twice per highlighted token. For a code block with hundreds of highlight tokens, that's hundreds of redundantTextStyleclones per paint. The style stack does not change while runs are being attributed, so the style is now computed once outside the loop and reused.Closes AI-234
Release Notes:
read_filetool call with a large file outline is expanded.