aboutsummaryrefslogtreecommitdiff
path: root/helix-view
diff options
context:
space:
mode:
authorBlaž Hrastnik2020-10-06 05:44:18 +0000
committerBlaž Hrastnik2020-10-13 14:13:56 +0000
commitb765c17896632e27857c7707a9d3d96bd49b8899 (patch)
tree8c9a95e1244c8839e2c21776bf73baee0a033d94 /helix-view
parent0926904d4c7f8851d53adfad337bac59ac8f8fb4 (diff)
Hacky undo/redo integration.
Diffstat (limited to 'helix-view')
-rw-r--r--helix-view/src/commands.rs34
1 files changed, 24 insertions, 10 deletions
diff --git a/helix-view/src/commands.rs b/helix-view/src/commands.rs
index c92b33f5..9a6d2e5d 100644
--- a/helix-view/src/commands.rs
+++ b/helix-view/src/commands.rs
@@ -3,7 +3,7 @@ use helix_core::{
regex::Regex,
selection,
state::{Direction, Granularity, Mode, State},
- Range, Selection, Tendril, Transaction,
+ ChangeSet, Range, Selection, Tendril, Transaction,
};
use once_cell::sync::Lazy;
@@ -253,14 +253,16 @@ pub fn collapse_selection(view: &mut View, _count: usize) {
.transform(|range| Range::new(range.head, range.head))
}
-// insert mode:
-// first we calculate the correct cursors/selections
-// then we just append at each cursor
-// lastly, if it was append mode we shift cursor by 1?
+fn enter_insert_mode(view: &mut View) {
+ view.state.mode = Mode::Insert;
+ // HAXX
+ view.state.changes = Some(ChangeSet::new(view.state.doc()));
+ view.state.old_state = Some((view.state.doc().clone(), view.state.selection.clone()));
+}
// inserts at the start of each selection
pub fn insert_mode(view: &mut View, _count: usize) {
- view.state.mode = Mode::Insert;
+ enter_insert_mode(view);
view.state.selection = view
.state
@@ -270,7 +272,7 @@ pub fn insert_mode(view: &mut View, _count: usize) {
// inserts at the end of each selection
pub fn append_mode(view: &mut View, _count: usize) {
- view.state.mode = Mode::Insert;
+ enter_insert_mode(view);
view.state.restore_cursor = true;
// TODO: as transaction
@@ -303,21 +305,21 @@ fn selection_lines(state: &State) -> Vec<usize> {
// I inserts at the start of each line with a selection
pub fn prepend_to_line(view: &mut View, count: usize) {
- view.state.mode = Mode::Insert;
+ enter_insert_mode(view);
move_line_start(view, count);
}
// A inserts at the end of each line with a selection
pub fn append_to_line(view: &mut View, count: usize) {
- view.state.mode = Mode::Insert;
+ enter_insert_mode(view);
move_line_end(view, count);
}
// o inserts a new line after each line with a selection
pub fn open_below(view: &mut View, _count: usize) {
- view.state.mode = Mode::Insert;
+ enter_insert_mode(view);
let lines = selection_lines(&view.state);
@@ -356,6 +358,18 @@ pub fn open_below(view: &mut View, _count: usize) {
pub fn normal_mode(view: &mut View, _count: usize) {
view.state.mode = Mode::Normal;
+ if let Some(changes) = view.state.changes.take() {
+ // Instead of doing this messy merge we could always commit, and based on transaction
+ // annotations either add a new layer or compose into the previous one.
+ let transaction = Transaction::from(changes).with_selection(view.state.selection().clone());
+ let (doc, selection) = view.state.old_state.take().unwrap();
+ let mut old_state = State::new(doc);
+ old_state.selection = selection;
+
+ // TODO: take transaction by value?
+ view.history.commit_revision(&transaction, &old_state);
+ }
+
// if leaving append mode, move cursor back by 1
if view.state.restore_cursor {
let text = &view.state.doc.slice(..);