editor: Fix code completions menu flashing due variable width (#30598)

Smit Barmase created

Closes #27631

We use `widest_completion_ix` to figure out completion menu width. This
results in flickering between frames as more information about
completion items, such as signatures, is populated asynchronously. There
is no way to know this width or which item will be widest beforehand.
While using a hardcoded value feels like a backward approach, it results
in a far smoother experience. VSCode also uses fixed width for
completion menu.

Before:


https://github.com/user-attachments/assets/0f044bae-fae9-43dc-8d4a-d8e7be8be6c4

After:


https://github.com/user-attachments/assets/21ab475c-7331-4de3-bb01-3986182fc9e4

Release Notes:

- Fixed issue where code completion menu would flicker while typing.

Change summary

crates/editor/src/code_context_menus.rs | 26 ++------------------------
1 file changed, 2 insertions(+), 24 deletions(-)

Detailed changes

crates/editor/src/code_context_menus.rs 🔗

@@ -450,29 +450,7 @@ impl CompletionsMenu {
         window: &mut Window,
         cx: &mut Context<Editor>,
     ) -> AnyElement {
-        let completions = self.completions.borrow_mut();
         let show_completion_documentation = self.show_completion_documentation;
-        let widest_completion_ix = self
-            .entries
-            .borrow()
-            .iter()
-            .enumerate()
-            .max_by_key(|(_, mat)| {
-                let completion = &completions[mat.candidate_id];
-                let documentation = &completion.documentation;
-
-                let mut len = completion.label.text.chars().count();
-                if let Some(CompletionDocumentation::SingleLine(text)) = documentation {
-                    if show_completion_documentation {
-                        len += text.chars().count();
-                    }
-                }
-
-                len
-            })
-            .map(|(ix, _)| ix);
-        drop(completions);
-
         let selected_item = self.selected_item;
         let completions = self.completions.clone();
         let entries = self.entries.clone();
@@ -596,8 +574,8 @@ impl CompletionsMenu {
         .occlude()
         .max_h(max_height_in_lines as f32 * window.line_height())
         .track_scroll(self.scroll_handle.clone())
-        .with_width_from_item(widest_completion_ix)
-        .with_sizing_behavior(ListSizingBehavior::Infer);
+        .with_sizing_behavior(ListSizingBehavior::Infer)
+        .w(rems(34.));
 
         Popover::new().child(list).into_any_element()
     }