ElyMark: a new file takes typing in visual; modes change no byte; PERF-07 timed (C14.6)
The component library opens an empty visual document's end on focus. The view logs once when its mode first takes input; 1 MB opens to visual in 341 ms P50 on Windows. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
b7bd95c3ab
commit
5f5a9bbf97
9 files changed
+113
-10
No files matched your search
@@ -2,9 +2,7 @@
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use ely_gpui_component::documents::{
|
||||
DocumentEvent, LARGEST_READ, MarkdownDocument, MarkdownMode,
|
||||
};
|
||||
use ely_gpui_component::documents::{DocumentEvent, LARGEST_READ, MarkdownDocument, MarkdownMode};
|
||||
use gpui::{
|
||||
AppContext as _, Context, Entity, EventEmitter, FocusHandle, Focusable as _,
|
||||
InteractiveElement as _, IntoElement, ParentElement as _, Render, Styled as _, Window, div,
|
||||
@@ -78,6 +76,8 @@ pub struct MarkView {
|
||||
pub mode: Mode,
|
||||
/// The file's folder: pictures resolve here.
|
||||
pub(crate) folder: PathBuf,
|
||||
/// The mode first took input (PERF-07).
|
||||
pub(crate) shown: bool,
|
||||
pub focus: FocusHandle,
|
||||
}
|
||||
|
||||
@@ -108,7 +108,10 @@ impl MarkView {
|
||||
});
|
||||
cx.subscribe_in(&document, window, Self::heard).detach();
|
||||
// The shell hears the load.
|
||||
cx.defer_in(window, |_, _, cx| cx.emit(Reported));
|
||||
cx.defer_in(window, |view, _, cx| {
|
||||
view.show_once(cx);
|
||||
cx.emit(Reported);
|
||||
});
|
||||
let focus = cx.focus_handle();
|
||||
// The view's focus is the document's.
|
||||
cx.on_focus(&focus, window, |view, window, cx| {
|
||||
@@ -123,6 +126,7 @@ impl MarkView {
|
||||
saved,
|
||||
mode,
|
||||
folder,
|
||||
shown: false,
|
||||
focus,
|
||||
}
|
||||
}
|
||||
@@ -269,9 +273,19 @@ impl MarkView {
|
||||
self.switch(Mode::Source, window, cx);
|
||||
}
|
||||
}
|
||||
self.show_once(cx);
|
||||
cx.emit(Reported);
|
||||
}
|
||||
|
||||
/// Logs the first moment the mode takes input.
|
||||
fn show_once(&mut self, cx: &gpui::App) {
|
||||
let ready = self.mode == Mode::Source || self.document.read(cx).read_now(cx);
|
||||
if ready && !self.shown {
|
||||
self.shown = true;
|
||||
log::info!("mark: shown as {:?}", self.mode.name());
|
||||
}
|
||||
}
|
||||
|
||||
/// A pressed link: web and mail open outside (M-05).
|
||||
fn follow(&mut self, url: &str, cx: &mut Context<Self>) {
|
||||
if ely_office::outward(url) {
|
||||
|
||||
@@ -54,6 +54,69 @@ fn current(view: &Entity<MarkView>, cx: &mut VisualTestContext) -> String {
|
||||
})
|
||||
}
|
||||
|
||||
fn focused(view: &Entity<MarkView>, cx: &mut VisualTestContext) {
|
||||
let focus = view.read_with(cx, |view, _| view.focus.clone());
|
||||
cx.update(|window, cx| window.focus(&focus, cx));
|
||||
cx.run_until_parked();
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn switching_modes_writes_no_byte(cx: &mut TestAppContext) {
|
||||
let (view, cx) = open("# A\r\n\r\n* b\r\n", cx);
|
||||
for mode in [Mode::Source, Mode::Preview, Mode::Visual, Mode::Source] {
|
||||
view.update_in(cx, |view, window, cx| view.switch(mode, window, cx));
|
||||
cx.run_until_parked();
|
||||
}
|
||||
let written = view.read_with(cx, |view, _| {
|
||||
let doc = view.doc.lock().expect("the text lock");
|
||||
doc.source.encode(&doc.current)
|
||||
});
|
||||
assert_eq!(written, b"# A\r\n\r\n* b\r\n");
|
||||
let (modified, changed) = view.read_with(cx, |view, _| (view.modified(), view.changed()));
|
||||
assert!(!modified && changed == 0);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn undo_reaches_across_modes(cx: &mut TestAppContext) {
|
||||
let (view, cx) = open("# A\n", cx);
|
||||
view.update_in(cx, |view, window, cx| view.switch(Mode::Source, window, cx));
|
||||
focused(&view, cx);
|
||||
cx.simulate_input("x");
|
||||
assert_eq!(current(&view, cx), "x# A\n");
|
||||
view.update_in(cx, |view, window, cx| view.switch(Mode::Visual, window, cx));
|
||||
focused(&view, cx);
|
||||
cx.simulate_keystrokes("secondary-z");
|
||||
cx.run_until_parked();
|
||||
assert_eq!(
|
||||
current(&view, cx),
|
||||
"# A\n",
|
||||
"the source edit undone in visual"
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn a_new_empty_file_takes_typing_in_visual(cx: &mut TestAppContext) {
|
||||
let (view, cx) = open("", cx);
|
||||
assert_eq!(view.read_with(cx, |view, _| view.mode), Mode::Visual);
|
||||
focused(&view, cx);
|
||||
cx.simulate_input("Hi");
|
||||
assert_eq!(current(&view, cx), "Hi");
|
||||
assert!(view.read_with(cx, |view, _| view.modified()));
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn a_long_file_shows_once_its_blocks_are_read(cx: &mut TestAppContext) {
|
||||
let long = "para\n\n".repeat(40_000);
|
||||
let (view, cx) = open(&long, cx);
|
||||
cx.executor()
|
||||
.advance_clock(std::time::Duration::from_secs(1));
|
||||
cx.run_until_parked();
|
||||
let (shown, read) = view.read_with(cx, |view, cx| {
|
||||
(view.shown, view.document.read(cx).read_now(cx))
|
||||
});
|
||||
assert!(shown && read, "shown with its blocks read");
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn a_refresh_is_saved_text_and_keeps_no_undo(cx: &mut TestAppContext) {
|
||||
let (view, cx) = open("one\n", cx);
|
||||
|
||||
Reference in new issue
Block a user