agent_panel: Fix mention pasting crash (#58375)
This crash occurred because metion crease were using raw text ranges that were precomputed before calling editor.edit(), and didn't take into account that editor normalizes text inserted The fix is normalizing the text first, then using the normalize text range for the crease Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fix a crash that could occur when adding a crease to the agent panel
This commit is contained in:
1 parent
ab913c96c6
commit
bc5e58ecc0
1 file changed
+36
-4
@@ -37,6 +37,7 @@ use project::{
|
||||
use rope::Point;
|
||||
use settings::Settings;
|
||||
use std::{cmp::min, fmt::Write, ops::Range, rc::Rc, sync::Arc};
|
||||
use text::LineEnding;
|
||||
use theme_settings::ThemeSettings;
|
||||
use ui::{ContextMenu, prelude::*};
|
||||
use util::paths::PathStyle;
|
||||
@@ -1719,11 +1720,15 @@ impl MessageEditor {
|
||||
let path_style = workspace.read(cx).project().read(cx).path_style(cx);
|
||||
let mut text = String::new();
|
||||
let mut mentions = Vec::new();
|
||||
let append_normalized = |text: &mut String, mut segment: String| {
|
||||
LineEnding::normalize(&mut segment);
|
||||
text.push_str(&segment);
|
||||
};
|
||||
|
||||
for chunk in message {
|
||||
match chunk {
|
||||
acp::ContentBlock::Text(text_content) => {
|
||||
text.push_str(&text_content.text);
|
||||
append_normalized(&mut text, text_content.text);
|
||||
}
|
||||
acp::ContentBlock::Resource(acp::EmbeddedResource {
|
||||
resource: acp::EmbeddedResourceResource::TextResourceContents(resource),
|
||||
@@ -1734,7 +1739,7 @@ impl MessageEditor {
|
||||
continue;
|
||||
};
|
||||
let start = text.len();
|
||||
write!(&mut text, "{}", mention_uri.as_link()).ok();
|
||||
append_normalized(&mut text, mention_uri.as_link().to_string());
|
||||
let end = text.len();
|
||||
mentions.push((
|
||||
start..end,
|
||||
@@ -1750,7 +1755,7 @@ impl MessageEditor {
|
||||
MentionUri::parse(&resource.uri, path_style).log_err()
|
||||
{
|
||||
let start = text.len();
|
||||
write!(&mut text, "{}", mention_uri.as_link()).ok();
|
||||
append_normalized(&mut text, mention_uri.as_link().to_string());
|
||||
let end = text.len();
|
||||
mentions.push((start..end, mention_uri, Mention::Link));
|
||||
}
|
||||
@@ -1776,7 +1781,7 @@ impl MessageEditor {
|
||||
continue;
|
||||
};
|
||||
let start = text.len();
|
||||
write!(&mut text, "{}", mention_uri.as_link()).ok();
|
||||
append_normalized(&mut text, mention_uri.as_link().to_string());
|
||||
let end = text.len();
|
||||
mentions.push((
|
||||
start..end,
|
||||
@@ -5296,6 +5301,33 @@ mod tests {
|
||||
assert!(!message_editor.update(cx, |editor, cx| editor.is_empty(cx)));
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_set_message_normalizes_crlf_before_mention(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
let (message_editor, cx) = setup_message_editor(cx).await;
|
||||
|
||||
message_editor.update_in(cx, |editor, window, cx| {
|
||||
editor.set_message(
|
||||
vec![
|
||||
acp::ContentBlock::Text(acp::TextContent::new("before\r\n".to_string())),
|
||||
acp::ContentBlock::ResourceLink(acp::ResourceLink::new(
|
||||
"file.txt",
|
||||
"file:///project/file.txt",
|
||||
)),
|
||||
],
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
|
||||
let text = message_editor.update(cx, |editor, cx| editor.text(cx));
|
||||
assert_eq!(text, "before\n[@file.txt](file:///project/file.txt)");
|
||||
|
||||
let mention_uris =
|
||||
message_editor.update(cx, |editor, cx| editor.mention_set.read(cx).mentions());
|
||||
assert_eq!(mention_uris.len(), 1);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_set_message_replaces_existing_content(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
Reference in new issue
Block a user