diff --git a/crates/engine/src/lib.rs b/crates/engine/src/lib.rs index 412b3afdf..71b7c736a 100644 --- a/crates/engine/src/lib.rs +++ b/crates/engine/src/lib.rs @@ -627,6 +627,12 @@ impl Session { } None => run.machine.begin(self), }; + // Redraw what the command has added so far (LINE adds a segment per point), not only when it ends. + if let Ok(st) = self.state_mut() + && !Arc::ptr_eq(&run.before, &st.doc) + { + st.revision += 1; + } match step { Ok(Step::Continue) => { self.running = Some(run); diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index 98b21bbf6..446639b8f 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -25,6 +25,26 @@ fn line_via_command_line() { assert_eq!(s.doc().unwrap().model.len(), 3); } +#[test] +fn edits_while_a_command_runs_redraw() { + // The canvas rebuilds when (revision, doc pointer) changes; each new segment must change it (issue #4). + fn key(s: &Session) -> (u64, usize) { + let st = s.state().unwrap(); + (st.revision, Arc::as_ptr(&st.doc) as usize) + } + let mut s = Session::new(); + for (cmd, pts) in [("line", ["0,0", "10,0", "10,5", "0,5"]), ("pline", ["20,0", "30,0", "30,5", "20,5"])] { + s.cmdline(cmd).unwrap(); + s.cmdline(pts[0]).unwrap(); + for p in &pts[1..] { + let before = key(&s); + s.cmdline(p).unwrap(); + assert_ne!(key(&s), before, "{cmd}: segment to {p} not redrawn"); + } + s.cmdline("").unwrap(); + } +} + #[test] fn line_undo_option_and_aliases() { let mut s = Session::new();