@@ -1,10 +1,10 @@
1use helix_core::{
1use helix_core::{
2− comment, coords_at_pos, graphemes, match_brackets,
2+ comment, coords_at_pos, graphemes, indent, match_brackets,
3 movement::{self, Direction},
3 movement::{self, Direction},
4 object, pos_at_coords,
4 object, pos_at_coords,
5 regex::{self, Regex},
5 regex::{self, Regex},
6 register, search, selection, Change, ChangeSet, Position, Range, Rope, RopeSlice, Selection,
6 register, search, selection, Change, ChangeSet, Position, Range, Rope, RopeSlice, Selection,
7− Tendril, Transaction,
7+ SmallVec, Tendril, Transaction,
10use once_cell::sync::Lazy;
10use once_cell::sync::Lazy;
@@ -951,26 +951,29 @@ pub fn open_below(cx: &mut Context) {
951 let (view, doc) = cx.current();
951 let (view, doc) = cx.current();
952 enter_insert_mode(doc);
952 enter_insert_mode(doc);
954+ let text = doc.text().slice(..);
954 let lines = selection_lines(doc.text(), doc.selection(view.id));
955 let lines = selection_lines(doc.text(), doc.selection(view.id));
956− let positions = lines.into_iter().map(|index| {
957+ let mut ranges = SmallVec::with_capacity(lines.len());
957− // adjust all positions to the end of the line (next line minus one)
958− doc.text().line_to_char(index + 1).saturating_sub(1)
961− let text = doc.text().slice(..);
959+ let changes: Vec<Change> = lines
962+ // adjust all positions to the end of the line (next line minus one)
963+ let index = doc.text().line_to_char(line + 1).saturating_sub(1);
963− let changes: Vec<Change> = positions
965 // TODO: share logic with insert_newline for indentation
965 // TODO: share logic with insert_newline for indentation
967− helix_core::indent::suggested_indent_for_pos(doc.syntax(), text, index, true);
966+ let indent_level = indent::suggested_indent_for_pos(doc.syntax(), text, index, true);
968 let indent = doc.indent_unit().repeat(indent_level);
967 let indent = doc.indent_unit().repeat(indent_level);
969 let mut text = String::with_capacity(1 + indent.len());
968 let mut text = String::with_capacity(1 + indent.len());
970 text.push('\n');
969 text.push('\n');
971 text.push_str(&indent);
970 text.push_str(&indent);
972 let text = text.repeat(count);
971 let text = text.repeat(count);
973+ // calculate new selection range
974+ let pos = index + text.len();
975+ ranges.push(Range::new(pos, pos));
974 (index, index, Some(text.into()))
977 (index, index, Some(text.into()))
976 .collect();
979 .collect();
@@ -978,17 +981,7 @@ pub fn open_below(cx: &mut Context) {
978 // TODO: count actually inserts "n" new lines and starts editing on all of them.
981 // TODO: count actually inserts "n" new lines and starts editing on all of them.
979 // TODO: append "count" newlines and modify cursors to those lines
982 // TODO: append "count" newlines and modify cursors to those lines
981− let selection = Selection::new(
984+ let selection = Selection::new(ranges, 0);
984− .map(|(start, _end, text): &Change| {
985− let len = text.as_ref().map(|text| text.len()).unwrap(); // minus newline
986− let pos = start + len;
987− Range::new(pos, pos)
993 let transaction =
986 let transaction =
994 Transaction::change(doc.text(), changes.into_iter()).with_selection(selection);
987 Transaction::change(doc.text(), changes.into_iter()).with_selection(selection);
@@ -1002,26 +995,29 @@ pub fn open_above(cx: &mut Context) {
1002 let (view, doc) = cx.current();
995 let (view, doc) = cx.current();
1003 enter_insert_mode(doc);
996 enter_insert_mode(doc);
998+ let text = doc.text().slice(..);
1005 let lines = selection_lines(doc.text(), doc.selection(view.id));
999 let lines = selection_lines(doc.text(), doc.selection(view.id));
1007− let positions = lines.into_iter().map(|index| {
1001+ let mut ranges = SmallVec::with_capacity(lines.len());
1008− // adjust all positions to the end of the previous line
1009− doc.text().line_to_char(index).saturating_sub(1)
1012− let text = doc.text().slice(..);
1003+ let changes: Vec<Change> = lines
1006+ // adjust all positions to the end of the previous line
1007+ let index = doc.text().line_to_char(line).saturating_sub(1);
1014− let changes: Vec<Change> = positions
1016 // TODO: share logic with insert_newline for indentation
1009 // TODO: share logic with insert_newline for indentation
1018− helix_core::indent::suggested_indent_for_pos(doc.syntax(), text, index, true);
1010+ let indent_level = indent::suggested_indent_for_pos(doc.syntax(), text, index, true);
1019 let indent = doc.indent_unit().repeat(indent_level);
1011 let indent = doc.indent_unit().repeat(indent_level);
1020 let mut text = String::with_capacity(1 + indent.len());
1012 let mut text = String::with_capacity(1 + indent.len());
1021 text.push('\n');
1013 text.push('\n');
1022 text.push_str(&indent);
1014 text.push_str(&indent);
1023 let text = text.repeat(count);
1015 let text = text.repeat(count);
1017+ // calculate new selection range
1018+ let pos = index + text.len();
1019+ ranges.push(Range::new(pos, pos));
1025 // generate changes
1021 // generate changes
1026 (index, index, Some(text.into()))
1022 (index, index, Some(text.into()))
@@ -1030,17 +1026,7 @@ pub fn open_above(cx: &mut Context) {
1030 // TODO: count actually inserts "n" new lines and starts editing on all of them.
1026 // TODO: count actually inserts "n" new lines and starts editing on all of them.
1031 // TODO: append "count" newlines and modify cursors to those lines
1027 // TODO: append "count" newlines and modify cursors to those lines
1033− let selection = Selection::new(
1029+ let selection = Selection::new(ranges, 0);
1036− .map(|(start, _end, text): &Change| {
1037− let len = text.as_ref().map(|text| text.len()).unwrap(); // minus newline
1038− let pos = start + len;
1039− Range::new(pos, pos)
1045 let transaction =
1031 let transaction =
1046 Transaction::change(doc.text(), changes.into_iter()).with_selection(selection);
1032 Transaction::change(doc.text(), changes.into_iter()).with_selection(selection);
@@ -1359,12 +1345,8 @@ pub mod insert {
1359 let transaction =
1345 let transaction =
1360 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
1346 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
1361 // TODO: offset range.head by 1? when calculating?
1347 // TODO: offset range.head by 1? when calculating?
1362− let indent_level = helix_core::indent::suggested_indent_for_pos(
1349+ indent::suggested_indent_for_pos(doc.syntax(), text, range.head, true);
1368 let indent = doc.indent_unit().repeat(indent_level);
1350 let indent = doc.indent_unit().repeat(indent_level);
1369 let mut text = String::with_capacity(1 + indent.len());
1351 let mut text = String::with_capacity(1 + indent.len());
1370 text.push('\n');
1352 text.push('\n');