Skip to content
54 changes: 51 additions & 3 deletions crates/acp_thread/src/mention.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,18 @@ impl MentionUri {
let path = url.path();
match url.scheme() {
"file" => {
let normalized = if path_style.is_windows() {
let trimmed = 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();
let decoded = decode(trimmed).unwrap_or(Cow::Borrowed(trimmed));
let normalized: Cow<str> = if path_style.is_windows() {
Cow::Owned(decoded.replace('/', "\\"))
} else {
decoded
};
let path = normalized.as_ref();

if let Some(fragment) = url.fragment() {
let line_range = parse_line_range(fragment).log_err().unwrap_or(1..=1);
Expand Down Expand Up @@ -493,6 +498,49 @@ mod tests {
assert_eq!(parsed.to_uri().to_string(), file_uri);
}

#[test]
fn test_parse_file_uris_use_native_separators_on_windows() {
let parsed = MentionUri::parse("file:///C:/path/to/file.rs", PathStyle::Windows).unwrap();
match parsed {
MentionUri::File { abs_path } => {
assert_eq!(abs_path, PathBuf::from("C:\\path\\to\\file.rs"));
}
other => panic!("Expected File variant, got {other:?}"),
}

let parsed = MentionUri::parse("file:///C:/path/to/dir/", PathStyle::Windows).unwrap();
match parsed {
MentionUri::Directory { abs_path } => {
assert_eq!(abs_path, PathBuf::from("C:\\path\\to\\dir\\"));
}
other => panic!("Expected Directory variant, got {other:?}"),
}

let parsed = MentionUri::parse(
"file:///C:/path/to/file.rs?symbol=MySymbol#L10:20",
PathStyle::Windows,
)
.unwrap();
match parsed {
MentionUri::Symbol { abs_path, .. } => {
assert_eq!(abs_path, PathBuf::from("C:\\path\\to\\file.rs"));
}
other => panic!("Expected Symbol variant, got {other:?}"),
}

let parsed =
MentionUri::parse("file:///C:/path/to/file.rs#L5:15", PathStyle::Windows).unwrap();
match parsed {
MentionUri::Selection {
abs_path: Some(abs_path),
..
} => {
assert_eq!(abs_path, PathBuf::from("C:\\path\\to\\file.rs"));
}
other => panic!("Expected Selection variant, got {other:?}"),
}
}

#[test]
fn test_to_directory_uri_without_slash() {
let uri = MentionUri::Directory {
Expand Down
4 changes: 4 additions & 0 deletions crates/agent_ui/src/mention_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ impl MentionSet {
self.mentions.values().map(|(uri, _)| uri.clone()).collect()
}

pub fn mention_uri_for_crease(&self, crease_id: &CreaseId) -> Option<MentionUri> {
self.mentions.get(crease_id).map(|(uri, _)| uri.clone())
}

pub fn set_mentions(&mut self, mentions: HashMap<CreaseId, (MentionUri, MentionTask)>) {
self.mentions = mentions;
}
Expand Down
Loading
Loading