agent: Fix inline assistant focusing behavior for cursor placement (#29998)

Umesh Yadav and Bennet Bo Fenner created

Ref: https://github.com/zed-industries/zed/pull/29919

This PR improves how inline assistants are detected and focused based on
cursor position.

### Problem
The current implementation has inconsistent behavior:
- When selecting text within an inline assistant's range, the assistant
properly focuses
- When placing a cursor on a line containing an assistant (without
selection), a new assistant is created instead of focusing the existing
one

### Solution
Enhanced the assistant detection logic to:
- Check if the cursor is anywhere within the line range of an existing
assistant
- Maintain the same behavior for both cursor placement and text
selection
- Convert both cursor position and assistant ranges to points for better
line-based comparison

This creates a more intuitive editing experience when working with
inline assistants, reducing the creation of duplicate assistants when
the user intends to interact with existing ones.


https://github.com/user-attachments/assets/55eb80d1-76a7-4d42-aac4-2702e85f13c4

Release Notes:

- agent: Improved inline assistant behavior to focus existing assistants
when cursor is placed on their line, matching selection behavior

---------

Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>

Change summary

crates/agent/src/inline_assistant.rs | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)

Detailed changes

crates/agent/src/inline_assistant.rs 🔗

@@ -338,13 +338,27 @@ impl InlineAssistant {
         window: &mut Window,
         cx: &mut App,
     ) {
-        let (snapshot, initial_selections) = editor.update(cx, |editor, cx| {
-            (
-                editor.snapshot(window, cx),
-                editor.selections.all::<Point>(cx),
-            )
+        let (snapshot, initial_selections, newest_selection) = editor.update(cx, |editor, cx| {
+            let selections = editor.selections.all::<Point>(cx);
+            let newest_selection = editor.selections.newest::<Point>(cx);
+            (editor.snapshot(window, cx), selections, newest_selection)
         });
 
+        // Check if there is already an inline assistant that contains the
+        // newest selection, if there is, focus it
+        if let Some(editor_assists) = self.assists_by_editor.get(&editor.downgrade()) {
+            for assist_id in &editor_assists.assist_ids {
+                let assist = &self.assists[assist_id];
+                let range = assist.range.to_point(&snapshot.buffer_snapshot);
+                if range.start.row <= newest_selection.start.row
+                    && newest_selection.end.row <= range.end.row
+                {
+                    self.focus_assist(*assist_id, window, cx);
+                    return;
+                }
+            }
+        }
+
         let mut selections = Vec::<Selection<Point>>::new();
         let mut newest_selection = None;
         for mut selection in initial_selections {