ElyMark: untitled copies pair by the tab made for them (M-07)
restore_shown takes its entry through Keeping::take; the test runs a crashed session through start, untitled, made and take, the second tab first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ad97f25ea4
commit
2c19d027a6
4 files changed
+48
-24
No files matched your search
@@ -148,6 +148,16 @@ impl Keeping {
|
||||
self.waiting[at].tab = Some(tab);
|
||||
}
|
||||
|
||||
/// What tab `id` takes: its file or its copy.
|
||||
fn take(&mut self, real: Option<&PathBuf>, id: u64) -> Option<Waiting> {
|
||||
let at = self.waiting.iter().position(|waiting| match (&waiting.real, real) {
|
||||
(Some(kept), Some(open)) => kept == open,
|
||||
(None, None) => waiting.tab == Some(id),
|
||||
_ => false,
|
||||
})?;
|
||||
Some(self.waiting.remove(at))
|
||||
}
|
||||
|
||||
/// An end that never asked: the lock and points stay.
|
||||
pub fn hold(&mut self) {
|
||||
if self.crash.take().is_some() {
|
||||
@@ -192,13 +202,6 @@ fn clear(dir: &Path) -> io::Result<()> {
|
||||
}
|
||||
|
||||
/// What tab `id` restores: by file, or untitled by number.
|
||||
fn waiting_for(waiting: &[Waiting], real: Option<&PathBuf>, id: u64) -> Option<usize> {
|
||||
waiting.iter().position(|waiting| match (&waiting.real, real) {
|
||||
(Some(kept), Some(open)) => kept == open,
|
||||
(None, None) => waiting.tab == Some(id),
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
impl Desk {
|
||||
/// A tab just shown takes its kept mode, place, text.
|
||||
@@ -213,13 +216,12 @@ impl Desk {
|
||||
.session
|
||||
.path()
|
||||
.and_then(|path| std::fs::canonicalize(path).ok());
|
||||
let waiting = &mut self.keeping.waiting;
|
||||
let Some(at) = waiting_for(waiting, real.as_ref(), id) else {
|
||||
let Some(Waiting {
|
||||
kept, text: back, ..
|
||||
}) = self.keeping.take(real.as_ref(), id)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Waiting {
|
||||
kept, text: back, ..
|
||||
} = waiting.remove(at);
|
||||
let mode = Mode::parse(&kept.mode).unwrap_or(Mode::Visual);
|
||||
log::info!("mark: restores tab {id} as {}", mode.name());
|
||||
let tab = self.tab_mut(id).expect("open");
|
||||
@@ -409,18 +411,36 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_untitled_copy_goes_to_the_tab_made_for_it() {
|
||||
let untitled = |name: &str, tab: u64| super::Waiting {
|
||||
kept: super::Kept { path: None, name: name.into(), mode: "visual".into(), place: None, slot: String::new() },
|
||||
real: None,
|
||||
text: None,
|
||||
tab: Some(tab),
|
||||
fn each_untitled_copy_goes_to_the_tab_made_for_it() {
|
||||
let dir = tempfile::tempdir().expect("a temp dir");
|
||||
let kept = |name: &str, mode: &str, slot: &str| super::Kept {
|
||||
path: None,
|
||||
name: name.into(),
|
||||
mode: mode.into(),
|
||||
place: Some(super::Place { line: slot.len() as u64, column: 1, scroll: 0.0 }),
|
||||
slot: slot.into(),
|
||||
};
|
||||
let waiting = [untitled("Untitled1", 4), untitled("Untitled2", 5)];
|
||||
// The second tab shows first: it still takes its own.
|
||||
assert_eq!(super::waiting_for(&waiting, None, 5), Some(1));
|
||||
assert_eq!(super::waiting_for(&waiting, None, 4), Some(0));
|
||||
assert_eq!(super::waiting_for(&waiting, None, 9), None, "a new tab takes nothing");
|
||||
let tabs = vec![kept("Untitled1", "visual", "a"), kept("Untitled2", "source", "bb")];
|
||||
for (slot, text) in [("a", "first"), ("bb", "second")] {
|
||||
let mut points = super::Recovery::new(super::recovery(dir.path(), slot));
|
||||
points.write_once(text.as_bytes(), None, std::time::SystemTime::now()).expect("a point");
|
||||
}
|
||||
let saved = serde_json::to_vec(&super::Saved { tabs: tabs.clone() }).expect("a list");
|
||||
std::fs::write(dir.path().join("session.json"), saved).expect("the list");
|
||||
// A pid no process has: the last run crashed.
|
||||
std::fs::write(dir.path().join("session.lock"), "open 4294967295").expect("a lock");
|
||||
let (mut keeping, ..) = super::Keeping::start(dir.path()).expect("a session");
|
||||
let made: Vec<_> = keeping.untitled();
|
||||
assert_eq!(made, [(0, "Untitled1".to_string()), (1, "Untitled2".to_string())]);
|
||||
for (at, _) in made {
|
||||
keeping.made(at, 10 + at as u64);
|
||||
}
|
||||
assert!(keeping.take(None, 12).is_none(), "a new tab takes nothing");
|
||||
// The second tab shows first: each still takes its own.
|
||||
for (id, want, text) in [(11, &tabs[1], "second"), (10, &tabs[0], "first")] {
|
||||
let got = keeping.take(None, id).expect("its copy");
|
||||
assert_eq!((&got.kept, got.text.map(|(text, _)| text)), (want, Some(text.to_string())));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user