on master help sign in
When calculating a new selection, we need to take newly inserted text into account.
commit0e5b42164628e5d25044cb5fd9592f7222701d6f authorBlaž Hrastnik <blaz@mxxn.io> dateSat 15 May 2021, 10:26 (5 years ago) parent4a9d116
2 files changed+33−10
helix-core/src/auto_pairs.rs+20−4 helix-term/src/commands.rs+13−6
helix-core/src/auto_pairs.rs+20−4
@@ -65,14 +65,20 @@ fn handle_open(
6565) -> Transaction {
6666 let mut ranges = SmallVec::with_capacity(selection.len());
6767
68+ let mut offs = 0;
69+
6870 let mut transaction = Transaction::change_by_selection(doc, selection, |range| {
6971 let pos = range.head;
7072 let next = next_char(doc, pos);
7173
72− let head = pos + open.len_utf8();
74+ let head = pos + offs + open.len_utf8();
7375 // if selection, retain anchor, if cursor, move over
7476 ranges.push(Range::new(
75− if range.is_empty() { head } else { range.anchor },
77+ if range.is_empty() {
78+ head
79+ } else {
80+ range.anchor + offs
81+ },
7682 head,
7783 ));
7884
@@ -88,6 +94,8 @@ fn handle_open(
8894 pair.push_char(open);
8995 pair.push_char(close);
9096
97+ offs += 2;
98+
9199 (pos, pos, Some(pair))
92100 }
93101 }
@@ -99,14 +107,20 @@ fn handle_open(
99107fn handle_close(doc: &Rope, selection: &Selection, _open: char, close: char) -> Transaction {
100108 let mut ranges = SmallVec::with_capacity(selection.len());
101109
110+ let mut offs = 0;
111+
102112 let mut transaction = Transaction::change_by_selection(doc, selection, |range| {
103113 let pos = range.head;
104114 let next = next_char(doc, pos);
105115
106− let head = pos + close.len_utf8();
116+ let head = pos + offs + close.len_utf8();
107117 // if selection, retain anchor, if cursor, move over
108118 ranges.push(Range::new(
109− if range.is_empty() { head } else { range.anchor },
119+ if range.is_empty() {
120+ head
121+ } else {
122+ range.anchor + offs
123+ },
110124 head,
111125 ));
112126
@@ -114,6 +128,8 @@ fn handle_close(doc: &Rope, selection: &Selection, _open: char, close: char) ->
114128 // return transaction that moves past close
115129 (pos, pos, None) // no-op
116130 } else {
131+ offs += close.len_utf8();
132+
117133 // TODO: else return (use default handler that inserts close)
118134 (pos, pos, Some(Tendril::from_char(close)))
119135 }
helix-term/src/commands.rs+13−6
@@ -1644,6 +1644,9 @@ pub mod insert {
16441644 let selection = doc.selection(view.id);
16451645 let mut ranges = SmallVec::with_capacity(selection.len());
16461646
1647+ // TODO: this is annoying, but we need to do it to properly calculate pos after edits
1648+ let mut offs = 0;
1649+
16471650 let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
16481651 let pos = range.head;
16491652
@@ -1667,10 +1670,14 @@ pub mod insert {
16671670 text.push('\n');
16681671 text.push_str(&indent);
16691672
1670− let head = pos + text.len();
1673+ let head = pos + offs + text.len();
16711674
16721675 ranges.push(Range::new(
1673− if range.is_empty() { head } else { range.anchor },
1676+ if range.is_empty() {
1677+ head
1678+ } else {
1679+ range.anchor + offs
1680+ },
16741681 head,
16751682 ));
16761683
@@ -1680,11 +1687,11 @@ pub mod insert {
16801687 let indent = doc.indent_unit().repeat(indent_level.saturating_sub(1));
16811688 text.push('\n');
16821689 text.push_str(&indent);
1683−
1684− (pos, pos, Some(text.into()))
1685− } else {
1686− (pos, pos, Some(text.into()))
16871690 }
1691+
1692+ offs += text.len();
1693+
1694+ (pos, pos, Some(text.into()))
16881695 });
16891696
16901697 transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));