acp_thread: Decode file:// mention paths so non-ASCII names render correctly (#44983)

## Summary

This fixes a minor bug I found #44981 

- Fix percent-encoded filenames appearing in agent mentions after
message submission.
- Decode file:// paths in MentionUri::parse using the existing
urlencoding crate (already used elsewhere in the codebase).
- Add tests for non-ASCII file URIs.

## Screenshots

<img width="409" height="116" alt="image"
src="https://github.com/user-attachments/assets/32ef033b-6232-47c5-80c7-d5247d5dae88"
/>
This commit is contained in:
Daiki Takagi authored and GitHub committed 2025-12-16 13:43:23 +00:00
1 parent 37bd27b2a8
commit 0362e301f7
3 files changed
+20 -1

No files matched your search

Generated
+1
View File
@@ -37,6 +37,7 @@ dependencies = [
"terminal",
"ui",
"url",
"urlencoding",
"util",
"uuid",
"watch",
+1
View File
@@ -46,6 +46,7 @@ url.workspace = true
util.workspace = true
uuid.workspace = true
watch.workspace = true
urlencoding.workspace = true
[dev-dependencies]
env_logger.workspace = true
+18 -1
View File
@@ -4,12 +4,14 @@ use file_icons::FileIcons;
use prompt_store::{PromptId, UserPromptId};
use serde::{Deserialize, Serialize};
use std::{
borrow::Cow,
fmt,
ops::RangeInclusive,
path::{Path, PathBuf},
};
use ui::{App, IconName, SharedString};
use url::Url;
use urlencoding::decode;
use util::paths::PathStyle;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
@@ -74,11 +76,13 @@ impl MentionUri {
let path = url.path();
match url.scheme() {
"file" => {
let path = if path_style.is_windows() {
let normalized = if path_style.is_windows() {
path.trim_start_matches("/")
} else {
path
};
let decoded = decode(normalized).unwrap_or(Cow::Borrowed(normalized));
let path = decoded.as_ref();
if let Some(fragment) = url.fragment() {
let line_range = parse_line_range(fragment)?;
@@ -406,6 +410,19 @@ mod tests {
assert_eq!(parsed.to_uri().to_string(), selection_uri);
}
#[test]
fn test_parse_file_uri_with_non_ascii() {
let file_uri = uri!("file:///path/to/%E6%97%A5%E6%9C%AC%E8%AA%9E.txt");
let parsed = MentionUri::parse(file_uri, PathStyle::local()).unwrap();
match &parsed {
MentionUri::File { abs_path } => {
assert_eq!(abs_path, Path::new(path!("/path/to/日本語.txt")));
}
_ => panic!("Expected File variant"),
}
assert_eq!(parsed.to_uri().to_string(), file_uri);
}
#[test]
fn test_parse_untitled_selection_uri() {
let selection_uri = uri!("zed:///agent/untitled-buffer#L1:10");