clarify filename

This commit is contained in:
vcoppe committed 2026-10-17 22:17:17 +02:00
1 parent 11709316d2
commit adbf89e318
16 files changed
+573 -61

No files matched your search

+17 -1
View File
@@ -1,6 +1,6 @@
use std::rc::Rc;
use super::{Diff, Files, History, diff_between};
use super::{Diff, Files, History, Renamer, diff_between};
use crate::{CommandError, FileId};
/// One history for the whole workspace: each entry is a state of all the files.
@@ -123,6 +123,22 @@ impl History for GlobalHistory {
None => !self.entries.is_empty(),
}
}
fn rename(&mut self, id: FileId, name: &str) -> Option<Diff> {
let before = self.current()?.get(&id)?.clone();
let mut renamer = Renamer::new(name);
for entry in self.entries.iter_mut() {
if let Some(file) = entry.get(&id) {
let renamed = renamer.rename(file);
entry.insert(id, renamed);
}
}
let after = self.current()?.get(&id)?;
(!Rc::ptr_eq(&before, after)).then(|| Diff {
modified: vec![id],
..Default::default()
})
}
}
#[cfg(test)]
+35
View File
@@ -57,6 +57,41 @@ pub trait History: Default + Debug {
/// Whether [`History::redo`] would do something for these `files`.
fn can_redo(&self, files: &[FileId]) -> bool;
/// Names a file `name` in all its states, as if it had always been called so: there is nothing
/// to undo. Says that the file changed, `None` if there is no such file or it is called so.
fn rename(&mut self, id: FileId, name: &str) -> Option<Diff>;
}
/// Names the states of a file: the ones that were shared stay shared (a state that several
/// entries have is renamed once), and the ones that are called so already are kept.
pub(super) struct Renamer<'a> {
name: &'a str,
renamed: HashMap<*const File, Rc<File>>,
}
impl<'a> Renamer<'a> {
pub(super) fn new(name: &'a str) -> Self {
Self {
name,
renamed: HashMap::new(),
}
}
pub(super) fn rename(&mut self, file: &Rc<File>) -> Rc<File> {
if file.info.name == self.name {
return file.clone();
}
let name = self.name;
self.renamed
.entry(Rc::as_ptr(file))
.or_insert_with(|| {
let mut renamed = (**file).clone();
renamed.info.name = name.to_owned();
Rc::new(renamed)
})
.clone()
}
}
/// Which files were added, removed or modified by a change of the current files.
+15 -1
View File
@@ -1,6 +1,6 @@
use std::rc::Rc;
use super::{Diff, Files, History, diff_between};
use super::{Diff, Files, History, Renamer, diff_between};
use crate::{CommandError, File, FileId};
use std::collections::HashMap;
@@ -139,6 +139,20 @@ impl History for PerFileHistory {
self.any(files, FileHistory::can_undo)
}
fn rename(&mut self, id: FileId, name: &str) -> Option<Diff> {
let history = self.stacks.get_mut(&id)?;
let mut renamer = Renamer::new(name);
for entry in history.entries.iter_mut() {
*entry = renamer.rename(entry);
}
let current = history.current().clone();
let before = self.current.insert(id, current.clone());
(!before.is_some_and(|before| Rc::ptr_eq(&before, &current))).then(|| Diff {
modified: vec![id],
..Default::default()
})
}
fn can_redo(&self, files: &[FileId]) -> bool {
self.any(files, FileHistory::can_redo)
}