agent: Add a whitespace after inserting @-mention to allow for continuous typing (#30381)

Release Notes:

- agent: Added a space after @-mentioning something in the message
editor to allow for continuous typing.

---------

Co-authored-by: Peter Tripp <peter@zed.dev>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This commit is contained in:
Patrick Leibersperger 2025-05-26 14:55:19 +02:00 committed by GitHub
parent e78b726ed8
commit 7497deff7a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 25 additions and 21 deletions

View file

@ -766,6 +766,7 @@ pub(crate) fn insert_crease_for_mention(
let ids = editor.insert_creases(vec![crease.clone()], cx);
editor.fold_creases(vec![crease], false, window, cx);
Some(ids[0])
})
}

View file

@ -322,7 +322,10 @@ impl ContextPickerCompletionProvider {
})
.collect::<Vec<_>>();
let new_text = selection_infos.iter().map(|(_, link, _)| link).join(" ");
let new_text = format!(
"{} ",
selection_infos.iter().map(|(_, link, _)| link).join(" ")
);
let callback = Arc::new({
let context_store = context_store.clone();
@ -420,7 +423,7 @@ impl ContextPickerCompletionProvider {
} else {
IconName::MessageBubbles
};
let new_text = MentionLink::for_thread(&thread_entry);
let new_text = format!("{} ", MentionLink::for_thread(&thread_entry));
let new_text_len = new_text.len();
Completion {
replace_range: source_range.clone(),
@ -435,7 +438,7 @@ impl ContextPickerCompletionProvider {
thread_entry.title().clone(),
excerpt_id,
source_range.start,
new_text_len,
new_text_len - 1,
editor.clone(),
context_store.clone(),
move |window, cx| match &thread_entry {
@ -489,7 +492,7 @@ impl ContextPickerCompletionProvider {
editor: Entity<Editor>,
context_store: Entity<ContextStore>,
) -> Completion {
let new_text = MentionLink::for_rule(&rules);
let new_text = format!("{} ", MentionLink::for_rule(&rules));
let new_text_len = new_text.len();
Completion {
replace_range: source_range.clone(),
@ -504,7 +507,7 @@ impl ContextPickerCompletionProvider {
rules.title.clone(),
excerpt_id,
source_range.start,
new_text_len,
new_text_len - 1,
editor.clone(),
context_store.clone(),
move |_, cx| {
@ -526,7 +529,7 @@ impl ContextPickerCompletionProvider {
context_store: Entity<ContextStore>,
http_client: Arc<HttpClientWithUrl>,
) -> Completion {
let new_text = MentionLink::for_fetch(&url_to_fetch);
let new_text = format!("{} ", MentionLink::for_fetch(&url_to_fetch));
let new_text_len = new_text.len();
Completion {
replace_range: source_range.clone(),
@ -541,7 +544,7 @@ impl ContextPickerCompletionProvider {
url_to_fetch.clone(),
excerpt_id,
source_range.start,
new_text_len,
new_text_len - 1,
editor.clone(),
context_store.clone(),
move |_, cx| {
@ -611,7 +614,7 @@ impl ContextPickerCompletionProvider {
crease_icon_path.clone()
};
let new_text = MentionLink::for_file(&file_name, &full_path);
let new_text = format!("{} ", MentionLink::for_file(&file_name, &full_path));
let new_text_len = new_text.len();
Completion {
replace_range: source_range.clone(),
@ -626,7 +629,7 @@ impl ContextPickerCompletionProvider {
file_name,
excerpt_id,
source_range.start,
new_text_len,
new_text_len - 1,
editor,
context_store.clone(),
move |_, cx| {
@ -682,7 +685,7 @@ impl ContextPickerCompletionProvider {
label.push_str(" ", None);
label.push_str(&file_name, comment_id);
let new_text = MentionLink::for_symbol(&symbol.name, &full_path);
let new_text = format!("{} ", MentionLink::for_symbol(&symbol.name, &full_path));
let new_text_len = new_text.len();
Some(Completion {
replace_range: source_range.clone(),
@ -697,7 +700,7 @@ impl ContextPickerCompletionProvider {
symbol.name.clone().into(),
excerpt_id,
source_range.start,
new_text_len,
new_text_len - 1,
editor.clone(),
context_store.clone(),
move |_, cx| {
@ -1353,7 +1356,7 @@ mod tests {
});
editor.update(&mut cx, |editor, cx| {
assert_eq!(editor.text(cx), "Lorem [@one.txt](@file:dir/a/one.txt)",);
assert_eq!(editor.text(cx), "Lorem [@one.txt](@file:dir/a/one.txt) ");
assert!(!editor.has_visible_completions_menu());
assert_eq!(
fold_ranges(editor, cx),
@ -1364,7 +1367,7 @@ mod tests {
cx.simulate_input(" ");
editor.update(&mut cx, |editor, cx| {
assert_eq!(editor.text(cx), "Lorem [@one.txt](@file:dir/a/one.txt) ",);
assert_eq!(editor.text(cx), "Lorem [@one.txt](@file:dir/a/one.txt) ");
assert!(!editor.has_visible_completions_menu());
assert_eq!(
fold_ranges(editor, cx),
@ -1377,7 +1380,7 @@ mod tests {
editor.update(&mut cx, |editor, cx| {
assert_eq!(
editor.text(cx),
"Lorem [@one.txt](@file:dir/a/one.txt) Ipsum ",
"Lorem [@one.txt](@file:dir/a/one.txt) Ipsum ",
);
assert!(!editor.has_visible_completions_menu());
assert_eq!(
@ -1391,7 +1394,7 @@ mod tests {
editor.update(&mut cx, |editor, cx| {
assert_eq!(
editor.text(cx),
"Lorem [@one.txt](@file:dir/a/one.txt) Ipsum @file ",
"Lorem [@one.txt](@file:dir/a/one.txt) Ipsum @file ",
);
assert!(editor.has_visible_completions_menu());
assert_eq!(
@ -1409,14 +1412,14 @@ mod tests {
editor.update(&mut cx, |editor, cx| {
assert_eq!(
editor.text(cx),
"Lorem [@one.txt](@file:dir/a/one.txt) Ipsum [@seven.txt](@file:dir/b/seven.txt)"
"Lorem [@one.txt](@file:dir/a/one.txt) Ipsum [@seven.txt](@file:dir/b/seven.txt) "
);
assert!(!editor.has_visible_completions_menu());
assert_eq!(
fold_ranges(editor, cx),
vec![
Point::new(0, 6)..Point::new(0, 37),
Point::new(0, 44)..Point::new(0, 79)
Point::new(0, 45)..Point::new(0, 80)
]
);
});
@ -1426,14 +1429,14 @@ mod tests {
editor.update(&mut cx, |editor, cx| {
assert_eq!(
editor.text(cx),
"Lorem [@one.txt](@file:dir/a/one.txt) Ipsum [@seven.txt](@file:dir/b/seven.txt)\n@"
"Lorem [@one.txt](@file:dir/a/one.txt) Ipsum [@seven.txt](@file:dir/b/seven.txt) \n@"
);
assert!(editor.has_visible_completions_menu());
assert_eq!(
fold_ranges(editor, cx),
vec![
Point::new(0, 6)..Point::new(0, 37),
Point::new(0, 44)..Point::new(0, 79)
Point::new(0, 45)..Point::new(0, 80)
]
);
});
@ -1447,14 +1450,14 @@ mod tests {
editor.update(&mut cx, |editor, cx| {
assert_eq!(
editor.text(cx),
"Lorem [@one.txt](@file:dir/a/one.txt) Ipsum [@seven.txt](@file:dir/b/seven.txt)\n[@six.txt](@file:dir/b/six.txt)"
"Lorem [@one.txt](@file:dir/a/one.txt) Ipsum [@seven.txt](@file:dir/b/seven.txt) \n[@six.txt](@file:dir/b/six.txt) "
);
assert!(!editor.has_visible_completions_menu());
assert_eq!(
fold_ranges(editor, cx),
vec![
Point::new(0, 6)..Point::new(0, 37),
Point::new(0, 44)..Point::new(0, 79),
Point::new(0, 45)..Point::new(0, 80),
Point::new(1, 0)..Point::new(1, 31)
]
);