fix(preview): refresh markdown and SVG after reload

This commit is contained in:
jiechen 2026-05-17 18:02:18 +08:00
parent f7ca86e6ee
commit 35c75600c4
4 changed files with 110 additions and 4 deletions

View file

@ -9378,9 +9378,11 @@ impl Editor {
cx.emit(EditorEvent::TitleChanged);
cx.emit(EditorEvent::FileHandleChanged);
}
multi_buffer::Event::Reloaded | multi_buffer::Event::BufferDiffChanged => {
cx.emit(EditorEvent::TitleChanged)
multi_buffer::Event::Reloaded => {
cx.emit(EditorEvent::TitleChanged);
cx.emit(EditorEvent::BufferReloaded);
}
multi_buffer::Event::BufferDiffChanged => cx.emit(EditorEvent::TitleChanged),
multi_buffer::Event::DiagnosticsUpdated => {
self.update_diagnostics_state(window, cx);
}
@ -11466,6 +11468,7 @@ pub enum EditorEvent {
hunks: Vec<MultiBufferDiffHunk>,
},
BufferEdited,
BufferReloaded,
Edited {
transaction_id: clock::Lamport,
},

View file

@ -107,6 +107,9 @@ fn test_edit_events(cx: &mut TestAppContext) {
EditorEvent::BufferEdited => {
events.borrow_mut().push(("editor1", "buffer edited"))
}
EditorEvent::BufferReloaded => {
events.borrow_mut().push(("editor1", "buffer reloaded"))
}
_ => {}
},
)
@ -126,6 +129,9 @@ fn test_edit_events(cx: &mut TestAppContext) {
EditorEvent::BufferEdited => {
events.borrow_mut().push(("editor2", "buffer edited"))
}
EditorEvent::BufferReloaded => {
events.borrow_mut().push(("editor2", "buffer reloaded"))
}
_ => {}
},
)
@ -211,6 +217,20 @@ fn test_edit_events(cx: &mut TestAppContext) {
editor.backspace(&Backspace, window, cx);
});
assert_eq!(mem::take(&mut *events.borrow_mut()), []);
buffer.update(cx, |buffer, cx| {
let version = buffer.saved_version().clone();
let line_ending = buffer.snapshot().line_ending();
let saved_mtime = buffer.saved_mtime();
buffer.did_reload(version, line_ending, saved_mtime, cx);
});
assert_eq!(
mem::take(&mut *events.borrow_mut()),
[
("editor1", "buffer reloaded"),
("editor2", "buffer reloaded"),
]
);
}
#[gpui::test]

View file

@ -308,6 +308,9 @@ impl MarkdownPreviewView {
| EditorEvent::BuffersEdited { .. } => {
this.update_markdown_from_active_editor(true, false, window, cx);
}
EditorEvent::BufferReloaded => {
this.update_markdown_from_active_editor(false, false, window, cx);
}
EditorEvent::SelectionsChanged { .. } => {
let (selection_start, editor_is_focused) =
editor.update(cx, |editor, cx| {
@ -1201,7 +1204,7 @@ mod tests {
use crate::markdown_preview_view::ImageSource;
use crate::markdown_preview_view::Resource;
use crate::markdown_preview_view::resolve_preview_image;
use editor::Editor;
use editor::{Editor, EditorEvent};
use gpui::{Entity, TestAppContext};
use serde_json::json;
use std::path::PathBuf;
@ -1452,6 +1455,86 @@ mod tests {
);
}
#[gpui::test]
async fn refreshes_preview_when_source_editor_buffer_reloads(cx: &mut TestAppContext) {
let app_state = init_test(cx);
app_state
.fs
.as_fake()
.insert_tree(
path!("/dir"),
json!({
"notes.md": "# Fresh\n"
}),
)
.await;
cx.update(|cx| {
open_paths(
&[PathBuf::from(path!("/dir/notes.md"))],
app_state.clone(),
workspace::OpenOptions::default(),
cx,
)
})
.await
.unwrap();
let multi_workspace = cx.update(|cx| cx.windows()[0].downcast::<MultiWorkspace>().unwrap());
let (preview, editor) = multi_workspace
.update(cx, |multi_workspace, window, cx| {
let workspace = multi_workspace.workspace().clone();
let editor: Entity<Editor> = workspace
.read(cx)
.active_item(cx)
.and_then(|item| item.act_as::<Editor>(cx))
.unwrap();
let preview = workspace.update(cx, |workspace, cx| {
let preview = MarkdownPreviewView::create_markdown_view(
workspace,
editor.clone(),
window,
cx,
);
workspace.active_pane().update(cx, |pane, cx| {
pane.add_item(Box::new(preview.clone()), true, true, None, window, cx)
});
preview
});
(preview, editor)
})
.unwrap();
cx.run_until_parked();
preview.update(cx, |preview, cx| {
preview.markdown.update(cx, |markdown, cx| {
markdown.reset("# Stale\n".into(), cx);
});
});
assert_eq!(
preview.read_with(cx, |preview, cx| preview
.markdown
.read(cx)
.source()
.to_string()),
"# Stale\n"
);
editor.update(cx, |_, cx| cx.emit(EditorEvent::BufferReloaded));
cx.run_until_parked();
assert_eq!(
preview.read_with(cx, |preview, cx| preview
.markdown
.read(cx)
.source()
.to_string()),
"# Fresh\n"
);
}
fn init_test(cx: &mut TestAppContext) -> Arc<AppState> {
cx.update(|cx| {
let state = AppState::test(cx);

View file

@ -182,7 +182,7 @@ impl SvgPreviewView {
buffer,
window,
move |this, _buffer, event: &BufferEvent, window, cx| match event {
BufferEvent::Edited { .. } | BufferEvent::Saved => {
BufferEvent::Edited { .. } | BufferEvent::Saved | BufferEvent::Reloaded => {
this.render_image(window, cx);
}
_ => {}