mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-28 18:47:18 +00:00
clarify filename
This commit is contained in:
1 parent
11709316d2
commit
adbf89e318
16 files changed
+573
-61
No files matched your search
@@ -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)]
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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, ¤t))).then(|| Diff {
|
||||
modified: vec![id],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
fn can_redo(&self, files: &[FileId]) -> bool {
|
||||
self.any(files, FileHistory::can_redo)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user