@@ -1691,17 +1691,34 @@ impl MentionCompletion {
offset_to_line: usize,
supported_modes: &[PromptContextType],
) -> Option<Self> {
- let last_mention_start = line.rfind('@')?;
+ // Find the rightmost '@' that has a word boundary before it and no whitespace immediately after
+ let mut last_mention_start = None;
+ for (idx, _) in line.rmatch_indices('@') {
+ // No whitespace immediately after '@'
+ if line[idx + 1..]
+ .chars()
+ .next()
+ .is_some_and(|c| c.is_whitespace())
+ {
+ continue;
+ }
- // No whitespace immediately after '@'
- if line[last_mention_start + 1..]
- .chars()
- .next()
- .is_some_and(|c| c.is_whitespace())
- {
- return None;
+ // Must be a word boundary before '@'
+ if idx > 0
+ && line[..idx]
+ .chars()
+ .last()
+ .is_some_and(|c| !c.is_whitespace())
+ {
+ continue;
+ }
+
+ last_mention_start = Some(idx);
+ break;
}
+ let last_mention_start = last_mention_start?;
+
// Must be a word boundary before '@'
if last_mention_start > 0
&& line[..last_mention_start]
@@ -2488,6 +2505,48 @@ mod tests {
None,
"Should not parse with a space after @ at the start of the line"
);
+
+ assert_eq!(
+ MentionCompletion::try_parse(
+ "@fetch https://www.npmjs.com/package/@matterport/sdk",
+ 0,
+ &[PromptContextType::Fetch]
+ ),
+ Some(MentionCompletion {
+ source_range: 0..52,
+ mode: Some(PromptContextType::Fetch),
+ argument: Some("https://www.npmjs.com/package/@matterport/sdk".to_string()),
+ }),
+ "Should handle URLs with @ in the path"
+ );
+
+ assert_eq!(
+ MentionCompletion::try_parse(
+ "@fetch https://example.com/@org/@repo/file",
+ 0,
+ &[PromptContextType::Fetch]
+ ),
+ Some(MentionCompletion {
+ source_range: 0..42,
+ mode: Some(PromptContextType::Fetch),
+ argument: Some("https://example.com/@org/@repo/file".to_string()),
+ }),
+ "Should handle URLs with multiple @ characters"
+ );
+
+ assert_eq!(
+ MentionCompletion::try_parse(
+ "@fetch https://example.com/@",
+ 0,
+ &[PromptContextType::Fetch]
+ ),
+ Some(MentionCompletion {
+ source_range: 0..28,
+ mode: Some(PromptContextType::Fetch),
+ argument: Some("https://example.com/@".to_string()),
+ }),
+ "Should parse URL ending with @ (even if URL is incomplete)"
+ );
}
#[gpui::test]