Skip to content

Commit

Permalink
Improve undo of EditCommands
Browse files Browse the repository at this point in the history
Address #190

Formalize the undo role of different edit commands via exhaustive
matching

Open questions:

- [ ] Undo behavior of pure moves
    * Do we want to make them undoable
    * Do we have to register them for accurate undos of true edits
- [ ] Manual backspace and delete
    * Do we want to coalesce them if a whole word is manually deleted?
  • Loading branch information
sholderbach committed Dec 1, 2021
1 parent 82bc3ac commit 85dab62
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 23 deletions.
31 changes: 9 additions & 22 deletions src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use {
completion::{CircularCompletionHandler, CompletionActionHandler},
core_editor::Editor,
edit_mode::{EditMode, Emacs},
enums::ReedlineEvent,
enums::{ReedlineEvent, UndoBehavior},
hinter::{DefaultHinter, Hinter},
history::{FileBackedHistory, History, HistoryNavigationQuery},
painter::Painter,
Expand Down Expand Up @@ -820,8 +820,6 @@ impl Reedline {
self.wrap(position, prompt)?;
}

self.editor.remember_undo_state(false);

self.repaint(prompt)?;
}
EditCommand::Backspace => self.editor.backspace(),
Expand All @@ -843,25 +841,14 @@ impl Reedline {
EditCommand::Redo => self.editor.redo(),
}

if [
EditCommand::MoveToEnd,
EditCommand::MoveToStart,
EditCommand::MoveLeft,
EditCommand::MoveRight,
EditCommand::MoveWordLeft,
EditCommand::MoveWordRight,
EditCommand::Backspace,
EditCommand::Delete,
EditCommand::BackspaceWord,
EditCommand::DeleteWord,
EditCommand::CutFromStart,
EditCommand::CutToEnd,
EditCommand::CutWordLeft,
EditCommand::CutWordRight,
]
.contains(command)
{
self.editor.remember_undo_state(true);
match command.undo_behavior() {
UndoBehavior::Ignore => {}
UndoBehavior::Full => {
self.editor.remember_undo_state(true);
}
UndoBehavior::Coalesce => {
self.editor.remember_undo_state(false);
}
}
}

Expand Down
52 changes: 52 additions & 0 deletions src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,58 @@ pub enum EditCommand {
Redo,
}

impl EditCommand {
/// Determine if a certain operation should be undoable
/// or if the operations should be coalesced for undoing
pub fn undo_behavior(&self) -> UndoBehavior {
match self {
// Cursor moves
EditCommand::MoveToStart
| EditCommand::MoveToEnd
| EditCommand::MoveLeft
| EditCommand::MoveRight
| EditCommand::MoveWordLeft
| EditCommand::MoveWordRight => UndoBehavior::Ignore,

// Coalesceable insert
EditCommand::InsertChar(_) => UndoBehavior::Coalesce,

// Full edits
EditCommand::Backspace
| EditCommand::Delete
| EditCommand::BackspaceWord
| EditCommand::DeleteWord
| EditCommand::Clear
| EditCommand::CutFromStart
| EditCommand::CutToEnd
| EditCommand::CutWordLeft
| EditCommand::CutWordRight
| EditCommand::PasteCutBuffer
| EditCommand::UppercaseWord
| EditCommand::LowercaseWord
| EditCommand::CapitalizeChar
| EditCommand::SwapWords
| EditCommand::SwapGraphemes => UndoBehavior::Full,

EditCommand::Undo | EditCommand::Redo => UndoBehavior::Ignore,
}
}
}

/// Specifies how the (previously executed) operation should be treated in the Undo stack.
pub enum UndoBehavior {
/// Operation is not affecting the LineBuffers content and should be ignored
///
/// e.g. the undo commands themselves are not stored in the undo stack
Ignore,
/// The operation is one logical unit of work that should be stored in the undo stack
Full,
/// The operation is a single operation that should be best coalesced in logical units such as words
///
/// e.g. insertion of characters by typing
Coalesce,
}

/// Reedline supported actions.
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
pub enum ReedlineEvent {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ pub use core_editor::LineBuffer;
mod text_manipulation;

mod enums;
pub use enums::{EditCommand, ReedlineEvent, Signal};
pub use enums::{EditCommand, ReedlineEvent, Signal, UndoBehavior};

mod painter;

Expand Down

0 comments on commit 85dab62

Please sign in to comment.