Implement rudimentary undo/redo support
This commit is contained in:
parent
ae45c3392f
commit
9ab272823d
|
@ -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) {
|
||||
|
|
39
src/state.rs
39
src/state.rs
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue