use super::*;
pub fn undo(
state: &mut Ed<'_>,
ui: &mut dyn UI,
selection: Option<Sel<'_>>,
arguments: &str,
) -> Result<()> {
if selection.is_some() {return Err(EdError::SelectionForbidden); }
let mut arg_iter = arguments.chars();
match arg_iter.next() {
Some('-') => {
let steps = if arg_iter.next().is_some() {
arguments[1..]
.parse::<usize>()
.map_err(|_| EdError::UndoStepsNotInt(arguments[1..].to_owned()))
?
} else { 1 };
if steps == 0 { return Err(EdError::NoOp); }
let new_pos = state.history.set_viewed_i(state.history.viewed_i() + steps)?;
ui.print_message(&format!(
"Redid {} operation(s) to right after {}.",
steps,
new_pos,
))?;
},
x => {
let steps = if x.is_some() {
arguments
.parse::<usize>()
.map_err(|_| EdError::UndoStepsNotInt(arguments.to_owned()))
?
} else { 1 };
if steps == 0 { return Err(EdError::NoOp); }
if state.history.viewed_i() < steps {
return Err(EdError::UndoIndexNegative{relative_undo_limit: state.history.viewed_i()});
}
let new_pos = state.history.set_viewed_i(state.history.viewed_i() - steps)?;
ui.print_message(&format!(
"Undid {} operation(s) to right after {}.",
steps,
new_pos
))?;
},
}
Ok(())
}
pub fn manage_history(
state: &mut Ed<'_>,
ui: &mut dyn UI,
selection: Option<Sel<'_>>,
tail: &str,
) -> Result<()> {
if selection.is_some() {return Err(EdError::SelectionForbidden); }
let mut _flags = parse_flags(tail, "")?;
let i = state.history.viewed_i();
let view = state.history.snapshots();
let history_indices = if i < 10 {
0 .. 10.min(view.len())
}
else if view.len().saturating_sub(10) <= i {
view.len().saturating_sub(10) .. view.len()
}
else {
i - 5 .. i + 4
};
let saved = state.history.saved_i();
let mut tmp = String::new();
for hi in history_indices {
tmp.push_str(&format!(
"{} {} {}",
if hi == i { '>' } else { ' ' },
view[hi].0,
if Some(hi) == saved { "(saved)" } else { "" },
));
}
ui.print_message(&tmp)?;
Ok(())
}