mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-23 01:46:18 +04:00
When calculating a new selection, we need to take newly inserted text into account.
This commit is contained in:
parent
4a9d1163e0
commit
0e5b421646
@ -65,14 +65,20 @@ fn handle_open(
|
||||
) -> Transaction {
|
||||
let mut ranges = SmallVec::with_capacity(selection.len());
|
||||
|
||||
let mut offs = 0;
|
||||
|
||||
let mut transaction = Transaction::change_by_selection(doc, selection, |range| {
|
||||
let pos = range.head;
|
||||
let next = next_char(doc, pos);
|
||||
|
||||
let head = pos + open.len_utf8();
|
||||
let head = pos + offs + open.len_utf8();
|
||||
// if selection, retain anchor, if cursor, move over
|
||||
ranges.push(Range::new(
|
||||
if range.is_empty() { head } else { range.anchor },
|
||||
if range.is_empty() {
|
||||
head
|
||||
} else {
|
||||
range.anchor + offs
|
||||
},
|
||||
head,
|
||||
));
|
||||
|
||||
@ -88,6 +94,8 @@ fn handle_open(
|
||||
pair.push_char(open);
|
||||
pair.push_char(close);
|
||||
|
||||
offs += 2;
|
||||
|
||||
(pos, pos, Some(pair))
|
||||
}
|
||||
}
|
||||
@ -99,14 +107,20 @@ fn handle_open(
|
||||
fn handle_close(doc: &Rope, selection: &Selection, _open: char, close: char) -> Transaction {
|
||||
let mut ranges = SmallVec::with_capacity(selection.len());
|
||||
|
||||
let mut offs = 0;
|
||||
|
||||
let mut transaction = Transaction::change_by_selection(doc, selection, |range| {
|
||||
let pos = range.head;
|
||||
let next = next_char(doc, pos);
|
||||
|
||||
let head = pos + close.len_utf8();
|
||||
let head = pos + offs + close.len_utf8();
|
||||
// if selection, retain anchor, if cursor, move over
|
||||
ranges.push(Range::new(
|
||||
if range.is_empty() { head } else { range.anchor },
|
||||
if range.is_empty() {
|
||||
head
|
||||
} else {
|
||||
range.anchor + offs
|
||||
},
|
||||
head,
|
||||
));
|
||||
|
||||
@ -114,6 +128,8 @@ fn handle_close(doc: &Rope, selection: &Selection, _open: char, close: char) ->
|
||||
// return transaction that moves past close
|
||||
(pos, pos, None) // no-op
|
||||
} else {
|
||||
offs += close.len_utf8();
|
||||
|
||||
// TODO: else return (use default handler that inserts close)
|
||||
(pos, pos, Some(Tendril::from_char(close)))
|
||||
}
|
||||
|
@ -1644,6 +1644,9 @@ pub fn insert_newline(cx: &mut Context) {
|
||||
let selection = doc.selection(view.id);
|
||||
let mut ranges = SmallVec::with_capacity(selection.len());
|
||||
|
||||
// TODO: this is annoying, but we need to do it to properly calculate pos after edits
|
||||
let mut offs = 0;
|
||||
|
||||
let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
|
||||
let pos = range.head;
|
||||
|
||||
@ -1667,10 +1670,14 @@ pub fn insert_newline(cx: &mut Context) {
|
||||
text.push('\n');
|
||||
text.push_str(&indent);
|
||||
|
||||
let head = pos + text.len();
|
||||
let head = pos + offs + text.len();
|
||||
|
||||
ranges.push(Range::new(
|
||||
if range.is_empty() { head } else { range.anchor },
|
||||
if range.is_empty() {
|
||||
head
|
||||
} else {
|
||||
range.anchor + offs
|
||||
},
|
||||
head,
|
||||
));
|
||||
|
||||
@ -1680,11 +1687,11 @@ pub fn insert_newline(cx: &mut Context) {
|
||||
let indent = doc.indent_unit().repeat(indent_level.saturating_sub(1));
|
||||
text.push('\n');
|
||||
text.push_str(&indent);
|
||||
}
|
||||
|
||||
offs += text.len();
|
||||
|
||||
(pos, pos, Some(text.into()))
|
||||
} else {
|
||||
(pos, pos, Some(text.into()))
|
||||
}
|
||||
});
|
||||
|
||||
transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));
|
||||
|
Loading…
Reference in New Issue
Block a user