Fix cursor position bugs related to o and O

- `O` at the beginning of file didn't move cursor
- `o` and `O` messed up cursor position with multiple cursors

Fixes #127
pull/268/head^2
Gokul Soumya 3 years ago committed by Blaž Hrastnik
parent a364d6c383
commit 20d6b202d5

@ -1495,53 +1495,55 @@ fn open(cx: &mut Context, open: Open) {
enter_insert_mode(doc);
let text = doc.text().slice(..);
let contents = doc.text();
let selection = doc.selection(view.id);
let mut ranges = SmallVec::with_capacity(selection.len());
let mut offs = 0;
let changes: Vec<Change> = selection
.iter()
.map(|range| {
let line = text.char_to_line(range.head);
let line = match open {
// adjust position to the end of the line (next line - 1)
Open::Below => line + 1,
// adjust position to the end of the previous line (current line - 1)
Open::Above => line,
};
let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
let line = text.char_to_line(range.head);
let index = doc.text().line_to_char(line).saturating_sub(1);
let line = match open {
// adjust position to the end of the line (next line - 1)
Open::Below => line + 1,
// adjust position to the end of the previous line (current line - 1)
Open::Above => line,
};
// TODO: share logic with insert_newline for indentation
let indent_level = indent::suggested_indent_for_pos(
doc.language_config(),
doc.syntax(),
text,
index,
true,
);
let indent = doc.indent_unit().repeat(indent_level);
let mut text = String::with_capacity(1 + indent.len());
text.push('\n');
text.push_str(&indent);
let text = text.repeat(count);
let index = doc.text().line_to_char(line).saturating_sub(1);
// calculate new selection range
let pos = index + text.chars().count();
ranges.push(Range::new(pos, pos));
// TODO: share logic with insert_newline for indentation
let indent_level = indent::suggested_indent_for_pos(
doc.language_config(),
doc.syntax(),
text,
index,
true,
);
let indent = doc.indent_unit().repeat(indent_level);
let mut text = String::with_capacity(1 + indent.len());
text.push('\n');
text.push_str(&indent);
let text = text.repeat(count);
// calculate new selection range
let pos = if line == 0 {
0 // Required since text will have a min len of 1 (\n)
} else {
index + offs + text.chars().count()
};
ranges.push(Range::new(pos, pos));
(index, index, Some(text.into()))
})
.collect();
offs += text.chars().count();
(index, index, Some(text.into()))
});
// TODO: count actually inserts "n" new lines and starts editing on all of them.
// TODO: append "count" newlines and modify cursors to those lines
let selection = Selection::new(ranges, 0);
let transaction =
Transaction::change(doc.text(), changes.into_iter()).with_selection(selection);
transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));
doc.apply(&transaction, view.id);
}

Loading…
Cancel
Save