@@ -3,7 +3,7 @@ use helix_core::{
33 regex::Regex,
44 selection,
55 state::{Direction, Granularity, Mode, State},
6− Range, Selection, Tendril, Transaction,
6+ ChangeSet, Range, Selection, Tendril, Transaction,
77};
88use once_cell::sync::Lazy;
99
@@ -253,14 +253,16 @@ pub fn collapse_selection(view: &mut View, _count: usize) {
253253 .transform(|range| Range::new(range.head, range.head))
254254}
255255
256−// insert mode:
257−// first we calculate the correct cursors/selections
258−// then we just append at each cursor
259−// lastly, if it was append mode we shift cursor by 1?
256+fn enter_insert_mode(view: &mut View) {
257+ view.state.mode = Mode::Insert;
260258
259+ // HAXX
260+ view.state.changes = Some(ChangeSet::new(view.state.doc()));
261+ view.state.old_state = Some((view.state.doc().clone(), view.state.selection.clone()));
262+}
261263// inserts at the start of each selection
262264pub fn insert_mode(view: &mut View, _count: usize) {
263− view.state.mode = Mode::Insert;
265+ enter_insert_mode(view);
264266
265267 view.state.selection = view
266268 .state
@@ -270,7 +272,7 @@ pub fn insert_mode(view: &mut View, _count: usize) {
270272
271273// inserts at the end of each selection
272274pub fn append_mode(view: &mut View, _count: usize) {
273− view.state.mode = Mode::Insert;
275+ enter_insert_mode(view);
274276 view.state.restore_cursor = true;
275277
276278 // TODO: as transaction
@@ -303,21 +305,21 @@ fn selection_lines(state: &State) -> Vec<usize> {
303305
304306// I inserts at the start of each line with a selection
305307pub fn prepend_to_line(view: &mut View, count: usize) {
306− view.state.mode = Mode::Insert;
308+ enter_insert_mode(view);
307309
308310 move_line_start(view, count);
309311}
310312
311313// A inserts at the end of each line with a selection
312314pub fn append_to_line(view: &mut View, count: usize) {
313− view.state.mode = Mode::Insert;
315+ enter_insert_mode(view);
314316
315317 move_line_end(view, count);
316318}
317319
318320// o inserts a new line after each line with a selection
319321pub fn open_below(view: &mut View, _count: usize) {
320− view.state.mode = Mode::Insert;
322+ enter_insert_mode(view);
321323
322324 let lines = selection_lines(&view.state);
323325
@@ -356,6 +358,18 @@ pub fn open_below(view: &mut View, _count: usize) {
356358pub fn normal_mode(view: &mut View, _count: usize) {
357359 view.state.mode = Mode::Normal;
358360
361+ if let Some(changes) = view.state.changes.take() {
362+ // Instead of doing this messy merge we could always commit, and based on transaction
363+ // annotations either add a new layer or compose into the previous one.
364+ let transaction = Transaction::from(changes).with_selection(view.state.selection().clone());
365+ let (doc, selection) = view.state.old_state.take().unwrap();
366+ let mut old_state = State::new(doc);
367+ old_state.selection = selection;
368+
369+ // TODO: take transaction by value?
370+ view.history.commit_revision(&transaction, &old_state);
371+ }
372+
359373 // if leaving append mode, move cursor back by 1
360374 if view.state.restore_cursor {
361375 let text = &view.state.doc.slice(..);