Prefix read_file tool output with line numbers#56779
Merged
Merged
Conversation
Format read_file tool output in cat -n style: each line is prefixed with its line number right-aligned in a 6-character field, followed by a tab, followed by the line's original content. The outline path for large files is left untouched. Documents the prefix format on the edit_file tool so the model knows to strip it before constructing old_text/new_text.
Contributor
Author
|
Need to fix: |
Contributor
Author
Contributor
Author
Follow-up to the cat -n style line-number prefixing in read_file:
- Stop prefixing line numbers on synthetic content returned by get_buffer_content_or_outline. Previously the 1KB-fallback path (used when a file is larger than AUTO_OUTLINE_SIZE and has no parseable symbol outline) would emit a synthetic '# First 1KB of …' header and then have line numbers attached as if it were real file content, misleading the model about where each line actually lives. The fallback is now reported as is_synthetic: true, matching the symbol-outline case.
- Rename BufferContent::is_outline to is_synthetic to reflect its new meaning ('callers must skip real-file line numbers'), since the 1KB fallback is not actually an outline.
- Extract a shared resolve_line_range helper used by both the skill-file and buffer-backed paths, eliminating duplicated default-and-clamp arithmetic that had already drifted between the two.
- Warn (once) when format_with_line_numbers crosses u32::MAX lines, so the silent 'offset as u32' wraparound has a breadcrumb if it ever fires.
- Restore write!(output, …) over push_str(&format!(…)) inside the line-number loop to avoid a per-line allocation.
Pairs with the read_file tool's cat -n style line-number prefixing: when the conversation view encounters a fenced code block whose lines are prefixed with a right-aligned line number and a tab, it parses the prefix out, renders the file content with its detected language's syntax highlighting, and shows the line numbers in a dedicated gutter rather than letting them appear inline as if they were part of the source. - markdown: add Markdown::first_code_block_language so the renderer can pick syntax highlighting based on the fence language or path. - conversation_view: thread the additional gpui (StyledText, TextRun) and language (Language, Rope) imports needed by the new renderer. - thread_view: add a CatNumberedCodeBlock parser/renderer that detects the line-number prefix on each line of a single fenced code block and lays the content out with a gutter.
The ReadFileTool now prefixes its output with cat -n-style line numbers, but this remote-editing integration test was missed when the unit tests were updated.
…226/line-numbers-in-read-file
benbrandt
approved these changes
May 22, 2026
benbrandt
left a comment
Member
There was a problem hiding this comment.
I know i said to feature flag it... but given that the models are all passing -n to every tool already, and evals looked good, I'm actually fine just rolling with it since it effects multiple parts of the system. We'll have time to test it out.
Thanks 💪🏻
fb8695b to
32fab86
Compare
Contributor
|
@MartinYe1234 related? #57230 |
Contributor
Author
TomPlanche
pushed a commit
to TomPlanche/zed
that referenced
this pull request
Jun 2, 2026
Format `read_file` tool output in `cat -n` style: each line is prefixed with its line number right-aligned in a 6-character field, followed by a single tab, followed by the line's original content (newlines preserved, including CRLF). Numbering reflects the actual file lines, so a ranged read starting at line 42 emits `42` for its first line, not `1`. For large files, content returned by `get_buffer_content_or_outline` is **not** prefixed: - The symbol outline path already conveys structure via its `[L100-150]` annotations. - The truncated first-1KB fallback (used when a file exceeds `AUTO_OUTLINE_SIZE` and has no parseable outline) is wrapped in a synthetic `# First 1KB of …` header, so its lines don't correspond to real file line numbers. Both cases are reported via `BufferContent::is_synthetic` (renamed from `is_outline`). Also updates the `edit_file` tool's input doc to describe the prefix format and tell the model to strip it before constructing `old_text` / `new_text`, preserving the original indentation that appears after the tab. Updates how we render `read_file` tool call outputs in the UI (screenshots included in comments below). Also fixes an existing bug where `read_file` tool call outputs would not re-render their content code block when an older thread was restored (the tool's `replay` hook was missing). Closes AI-226 Release Notes: - Improved how `read_file` tool output renders in the agent panel, with a line-number gutter, and fixed it not re-rendering on restored threads --------- Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
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.



Format
read_filetool output incat -nstyle: each line is prefixed with its line number right-aligned in a 6-character field, followed by a single tab, followed by the line's original content (newlines preserved, including CRLF). Numbering reflects the actual file lines, so a ranged read starting at line 42 emits42for its first line, not1.For large files, content returned by
get_buffer_content_or_outlineis not prefixed:[L100-150]annotations.AUTO_OUTLINE_SIZEand has no parseable outline) is wrapped in a synthetic# First 1KB of …header, so its lines don't correspond to real file line numbers.Both cases are reported via
BufferContent::is_synthetic(renamed fromis_outline).Also updates the
edit_filetool's input doc to describe the prefix format and tell the model to strip it before constructingold_text/new_text, preserving the original indentation that appears after the tab.Updates how we render
read_filetool call outputs in the UI (screenshots included in comments below).Also fixes an existing bug where
read_filetool call outputs would not re-render their content code block when an older thread was restored (the tool'sreplayhook was missing).Closes AI-226
Release Notes:
read_filetool output renders in the agent panel, with a line-number gutter, and fixed it not re-rendering on restored threads