Implement rudimentary undo/redo support

This commit is contained in:
mars 2023-04-18 20:05:28 -04:00
parent ae45c3392f
commit 9ab272823d
2 changed files with 45 additions and 4 deletions

View File

@ -130,10 +130,12 @@ pub fn visual_mode(state: &mut State) {
}
pub fn insert_mode(state: &mut State) {
state.save_buffer();
state.mode = Mode::Insert(InsertState { append: false });
}
pub fn append_mode(state: &mut State) {
state.save_buffer();
state.move_cursor(Direction::Right);
state.mode = Mode::Insert(InsertState { append: true });
}
@ -149,24 +151,24 @@ pub fn insert_at_line_end(state: &mut State) {
}
pub fn open_below(state: &mut State) {
insert_mode(state);
state.cursor.line += 1;
state.cursor.column = 0;
state.buffer.insert_char(state.cursor, '\n');
state.mode = Mode::Insert(InsertState { append: false });
}
pub fn open_above(state: &mut State) {
insert_mode(state);
state.cursor.column = 0;
state.buffer.insert_char(state.cursor, '\n');
state.mode = Mode::Insert(InsertState { append: false });
}
pub fn undo(state: &mut State) {
state.set_error("undo is unimplemented");
state.undo();
}
pub fn redo(state: &mut State) {
state.set_error("redo is unimplemented");
state.redo();
}
pub fn delete_char_backward(state: &mut State) {

View File

@ -71,6 +71,8 @@ pub struct State {
pub styles: Arc<Mutex<StyleStore>>,
pub config: Config,
pub buffer: Buffer,
pub undo_buffers: Vec<Buffer>,
pub redo_buffers: Vec<Buffer>,
pub cursor: Cursor,
pub file: Option<OsString>,
pub mode: Mode,
@ -95,6 +97,8 @@ impl State {
styles,
config: Default::default(),
buffer,
undo_buffers: Vec::new(),
redo_buffers: Vec::new(),
cursor: Cursor::default(),
file: file_name,
mode: Mode::default(),
@ -375,4 +379,39 @@ impl State {
self.scroll.line = self.cursor.line + 3 - self.size.1;
}
}
/// If modified, saves the current buffer in undo history and clears the redo history.
pub fn save_buffer(&mut self) {
/*if let Some(last) = self.undo_buffers.last() {
if *last.as_ref() == *self.buffer.as_ref() {
return;
}
}*/
let current = self.buffer.clone();
self.undo_buffers.push(current);
self.redo_buffers.clear();
}
/// Pops the last undo state from the history and pushes the current state to the redo buffers.
pub fn undo(&mut self) {
match self.undo_buffers.pop() {
None => self.set_error("Already at oldest change"),
Some(last) => {
let current = std::mem::replace(&mut self.buffer, last);
self.redo_buffers.push(current);
}
}
}
/// Pops the next redo state from the history and pushes the current state to the undo buffers.
pub fn redo(&mut self) {
match self.redo_buffers.pop() {
None => self.set_error("Already at newest change"),
Some(next) => {
let current = std::mem::replace(&mut self.buffer, next);
self.undo_buffers.push(current);
}
}
}
}