agent_ui: Fix send failure for pasted file#line mention links (#49786)

Xiaobo Liu created

Release Notes:

- Fixed send failure for pasted file#line mention links


Handle `MentionUri::Selection` with a file path in
`confirm_mention_for_uri`
by resolving it to text content via existing line-range loading logic,
instead
of returning "Unsupported mention URI type for paste".

Keep untitled-buffer selections (`abs_path: None`) as an explicit
unsupported
error for now.

Add a regression test for pasting selection mentions to ensure they
resolve to
`Mention::Text` with the expected line range.

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>

Change summary

crates/agent_ui/src/mention_set.rs | 47 +++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+), 1 deletion(-)

Detailed changes

crates/agent_ui/src/mention_set.rs 🔗

@@ -150,8 +150,14 @@ impl MentionSet {
             MentionUri::GitDiff { base_ref } => {
                 self.confirm_mention_for_git_diff(base_ref.into(), cx)
             }
+            MentionUri::Selection {
+                abs_path: Some(abs_path),
+                line_range,
+            } => self.confirm_mention_for_symbol(abs_path, line_range, cx),
+            MentionUri::Selection { abs_path: None, .. } => Task::ready(Err(anyhow!(
+                "Untitled buffer selection mentions are not supported for paste"
+            ))),
             MentionUri::PastedImage
-            | MentionUri::Selection { .. }
             | MentionUri::TerminalSelection { .. }
             | MentionUri::MergeConflict { .. } => {
                 Task::ready(Err(anyhow!("Unsupported mention URI type for paste")))
@@ -689,6 +695,45 @@ mod tests {
             "Unexpected error: {error:#}"
         );
     }
+
+    #[gpui::test]
+    async fn test_selection_mentions_supported_for_paste(cx: &mut TestAppContext) {
+        init_test(cx);
+
+        let fs = FakeFs::new(cx.executor());
+        fs.insert_tree(
+            "/project",
+            json!({"file.rs": "line 1\nline 2\nline 3\nline 4\n"}),
+        )
+        .await;
+        let project = Project::test(fs, [Path::new(path!("/project"))], cx).await;
+        let mention_set = cx.new(|_cx| MentionSet::new(project.downgrade(), None, None));
+
+        let mention_task = mention_set.update(cx, |mention_set, cx| {
+            let http_client = project.read(cx).client().http_client();
+            mention_set.confirm_mention_for_uri(
+                MentionUri::Selection {
+                    abs_path: Some(path!("/project/file.rs").into()),
+                    line_range: 1..=2,
+                },
+                false,
+                http_client,
+                cx,
+            )
+        });
+
+        let mention = mention_task.await.unwrap();
+        match mention {
+            Mention::Text {
+                content,
+                tracked_buffers,
+            } => {
+                assert_eq!(content, "line 2\nline 3\n");
+                assert_eq!(tracked_buffers.len(), 1);
+            }
+            other => panic!("Expected selection mention to resolve as text, got {other:?}"),
+        }
+    }
 }
 
 /// Inserts a list of images into the editor as context mentions.