zed/crates/workspace/Cargo.toml
MartinYe1234 f78f6da255
Make file paths in backticks clickable in agent panel (#57303)
When the agent mentions a file path inside `backticks` (e.g. ``
`src/main.rs` `` or `` `src/main.rs:42` ``), the rendered code span now
becomes a clickable link in the agent panel. Clicking opens the
referenced file in the workspace, jumping to the right line and column
when present.

## How it works

- **Shared path resolution.** Extracted `OpenTarget` and the
workspace/worktree resolution logic out of
`terminal_view::terminal_path_like_target` into a new
`workspace::path_link` module so both the terminal and the agent panel
can use the same code. Includes a `sanitize_path_text` helper ported
from the terminal's URL/punctuation handling. Pure refactor — terminal
behavior is unchanged.
- **`markdown` crate hook.** Added
`MarkdownElement::on_code_span_link(callback)`. When the callback
returns `Some(url)` for a given code span's contents, the existing
`push_link` machinery wires up cmd-hover, hit testing, and the existing
`on_url_click` callback. When it returns `None`, the code span renders
as before. The hook is opt-in, so `markdown` stays workspace-agnostic.
- **Agent panel wiring.** `render_agent_markdown` constructs an
`AgentCodeSpanResolver` that snapshots the project's visible worktree
entries plus their file extensions. `try_resolve` does a cheap
synchronous heuristic check (path must contain `/`/`\` or end in an
extension present in the workspace, can't be a URL, can't be all digits,
etc.) and then looks the candidate up in the per-worktree
`HashSet<Arc<RelPath>>`. On a hit it returns a `MentionUri::File` or
`MentionUri::Selection` URI, which the existing `thread_view::open_link`
already knows how to open at the right line.

## Edge cases handled

- Code spans inside fenced code blocks stay plain (gated on
`builder.code_block_stack.is_empty()`, matching how regular markdown
links behave).
- Trailing prose punctuation (`` `src/main.rs.` ``) is stripped before
lookup.
- Identifiers like `` `String` ``, `` `await` ``, `` `npm run dev` ``
stay plain — they don't pass the path-like heuristic.
- Cross-platform path separators handled via the per-worktree
`PathStyle`.

## Tests

- `crates/markdown` — unit test asserting code spans become links when
the callback returns `Some`, and stay plain when it doesn't.
- `crates/agent_ui` — unit test for `AgentCodeSpanResolver::try_resolve`
covering hits with and without a `:line` suffix, misses, identifiers,
and trailing punctuation.
- Existing `terminal_view` tests cover the moved resolution code
(unchanged behavior).

## Notes

- There's currently a temporary `log::info!` in
`AgentCodeSpanResolver::try_resolve` that reports per-call worktree-walk
timing and a cumulative total. Kept in for now to verify the feature
isn't being called excessively during streaming renders. Can be removed
before merge.
- Resolution is sync-only against worktree entries; absolute paths
outside the workspace are not resolved (would require an async re-render
path).

Closes AI-277

Release Notes:

- Made file paths in `backticks` clickable in the agent panel; clicking
opens the referenced file at the given line when present.
2026-05-21 22:04:32 +00:00

90 lines
2.3 KiB
TOML

[package]
name = "workspace"
version = "0.1.0"
edition.workspace = true
publish.workspace = true
license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/workspace.rs"
doctest = false
[features]
test-support = [
"client/test-support",
"http_client/test-support",
"db/test-support",
"project/test-support",
"remote/test-support",
"session/test-support",
"settings/test-support",
"gpui/test-support",
"fs/test-support",
]
[dependencies]
any_vec.workspace = true
agent_settings.workspace = true
anyhow.workspace = true
async-recursion.workspace = true
client.workspace = true
chrono.workspace = true
clock.workspace = true
collections.workspace = true
component.workspace = true
db.workspace = true
dirs.workspace = true
futures-lite.workspace = true
fs.workspace = true
futures.workspace = true
git.workspace = true
gpui.workspace = true
http_client.workspace = true
itertools.workspace = true
language.workspace = true
log.workspace = true
menu.workspace = true
markdown.workspace = true
node_runtime.workspace = true
parking_lot.workspace = true
postage.workspace = true
project.workspace = true
remote.workspace = true
schemars.workspace = true
serde.workspace = true
serde_json.workspace = true
session.workspace = true
settings.workspace = true
smallvec.workspace = true
sqlez.workspace = true
strum.workspace = true
task.workspace = true
telemetry.workspace = true
theme.workspace = true
theme_settings.workspace = true
ui.workspace = true
util.workspace = true
uuid.workspace = true
zed_actions.workspace = true
[target.'cfg(target_os = "windows")'.dependencies]
windows.workspace = true
[dev-dependencies]
client = { workspace = true, features = ["test-support"] }
db = { workspace = true, features = ["test-support"] }
fs = { workspace = true, features = ["test-support"] }
gpui = { workspace = true, features = ["test-support"] }
project = { workspace = true, features = ["test-support"] }
remote = { workspace = true, features = ["test-support"] }
session = { workspace = true, features = ["test-support"] }
settings = { workspace = true, features = ["test-support"] }
http_client = { workspace = true, features = ["test-support"] }
pretty_assertions.workspace = true
proptest.workspace = true
proptest-derive.workspace = true
tempfile.workspace = true
zlog.workspace = true