@@ -2777,14 +2777,14 @@ pub mod insert {
27772777 let text = doc.text().slice(..);
27782778
27792779 let contents = doc.text();
2780− let selection = doc.selection(view.id).clone().cursors(text);
2780+ let selection = doc.selection(view.id).clone();
27812781 let mut ranges = SmallVec::with_capacity(selection.len());
27822782
27832783 // TODO: this is annoying, but we need to do it to properly calculate pos after edits
2784− let mut offs = 0;
2784+ let mut global_offs = 0;
27852785
27862786 let mut transaction = Transaction::change_by_selection(contents, &selection, |range| {
2787− let pos = range.head;
2787+ let pos = range.cursor(text);
27882788
27892789 let prev = if pos == 0 {
27902790 ' '
@@ -2814,27 +2814,41 @@ pub mod insert {
28142814 .and_then(|pair| if pair.close == curr { Some(pair) } else { None })
28152815 .is_some();
28162816
2817− let new_head_pos = if on_auto_pair {
2817+ let local_offs = if on_auto_pair {
28182818 let inner_indent = indent.clone() + doc.indent_style.as_str();
28192819 text.reserve_exact(2 + indent.len() + inner_indent.len());
28202820 text.push_str(doc.line_ending.as_str());
28212821 text.push_str(&inner_indent);
2822− let new_head_pos = pos + offs + text.chars().count();
2822+ let local_offs = text.chars().count();
28232823 text.push_str(doc.line_ending.as_str());
28242824 text.push_str(&indent);
2825− new_head_pos
2825+ local_offs
28262826 } else {
28272827 text.reserve_exact(1 + indent.len());
28282828 text.push_str(doc.line_ending.as_str());
28292829 text.push_str(&indent);
2830− pos + offs + text.chars().count()
2830+ text.chars().count()
2831+ };
2832+
2833+ let new_range = if doc.restore_cursor {
2834+ // when appending, extend the range by local_offs
2835+ Range::new(
2836+ range.anchor + global_offs,
2837+ range.head + local_offs + global_offs,
2838+ )
2839+ } else {
2840+ // when inserting, slide the range by local_offs
2841+ Range::new(
2842+ range.anchor + local_offs + global_offs,
2843+ range.head + local_offs + global_offs,
2844+ )
28312845 };
28322846
28332847 // TODO: range replace or extend
28342848 // range.replace(|range| range.is_empty(), head); -> fn extend if cond true, new head pos
28352849 // can be used with cx.mode to do replace or extend on most changes
2836− ranges.push(Range::new(new_head_pos, new_head_pos));
2837− offs += text.chars().count();
2850+ ranges.push(new_range);
2851+ global_offs += text.chars().count();
28382852
28392853 (pos, pos, Some(text.into()))
28402854 });