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) {
|
pub fn insert_mode(state: &mut State) {
|
||||||
|
state.save_buffer();
|
||||||
state.mode = Mode::Insert(InsertState { append: false });
|
state.mode = Mode::Insert(InsertState { append: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append_mode(state: &mut State) {
|
pub fn append_mode(state: &mut State) {
|
||||||
|
state.save_buffer();
|
||||||
state.move_cursor(Direction::Right);
|
state.move_cursor(Direction::Right);
|
||||||
state.mode = Mode::Insert(InsertState { append: true });
|
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) {
|
pub fn open_below(state: &mut State) {
|
||||||
|
insert_mode(state);
|
||||||
state.cursor.line += 1;
|
state.cursor.line += 1;
|
||||||
state.cursor.column = 0;
|
state.cursor.column = 0;
|
||||||
state.buffer.insert_char(state.cursor, '\n');
|
state.buffer.insert_char(state.cursor, '\n');
|
||||||
state.mode = Mode::Insert(InsertState { append: false });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_above(state: &mut State) {
|
pub fn open_above(state: &mut State) {
|
||||||
|
insert_mode(state);
|
||||||
state.cursor.column = 0;
|
state.cursor.column = 0;
|
||||||
state.buffer.insert_char(state.cursor, '\n');
|
state.buffer.insert_char(state.cursor, '\n');
|
||||||
state.mode = Mode::Insert(InsertState { append: false });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn undo(state: &mut State) {
|
pub fn undo(state: &mut State) {
|
||||||
state.set_error("undo is unimplemented");
|
state.undo();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redo(state: &mut State) {
|
pub fn redo(state: &mut State) {
|
||||||
state.set_error("redo is unimplemented");
|
state.redo();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_char_backward(state: &mut State) {
|
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 styles: Arc<Mutex<StyleStore>>,
|
||||||
pub config: Config,
|
pub config: Config,
|
||||||
pub buffer: Buffer,
|
pub buffer: Buffer,
|
||||||
|
pub undo_buffers: Vec<Buffer>,
|
||||||
|
pub redo_buffers: Vec<Buffer>,
|
||||||
pub cursor: Cursor,
|
pub cursor: Cursor,
|
||||||
pub file: Option<OsString>,
|
pub file: Option<OsString>,
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
|
@ -95,6 +97,8 @@ impl State {
|
||||||
styles,
|
styles,
|
||||||
config: Default::default(),
|
config: Default::default(),
|
||||||
buffer,
|
buffer,
|
||||||
|
undo_buffers: Vec::new(),
|
||||||
|
redo_buffers: Vec::new(),
|
||||||
cursor: Cursor::default(),
|
cursor: Cursor::default(),
|
||||||
file: file_name,
|
file: file_name,
|
||||||
mode: Mode::default(),
|
mode: Mode::default(),
|
||||||
|
@ -375,4 +379,39 @@ impl State {
|
||||||
self.scroll.line = self.cursor.line + 3 - self.size.1;
|
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