aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/commands.rs
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term/src/commands.rs')
-rw-r--r--helix-term/src/commands.rs78
1 files changed, 30 insertions, 48 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 235cb52d..98ffa3d1 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -1,10 +1,10 @@
use helix_core::{
- comment, coords_at_pos, graphemes, match_brackets,
+ comment, coords_at_pos, graphemes, indent, match_brackets,
movement::{self, Direction},
object, pos_at_coords,
regex::{self, Regex},
register, search, selection, Change, ChangeSet, Position, Range, Rope, RopeSlice, Selection,
- Tendril, Transaction,
+ SmallVec, Tendril, Transaction,
};
use once_cell::sync::Lazy;
@@ -951,26 +951,29 @@ pub fn open_below(cx: &mut Context) {
let (view, doc) = cx.current();
enter_insert_mode(doc);
+ let text = doc.text().slice(..);
let lines = selection_lines(doc.text(), doc.selection(view.id));
- let positions = lines.into_iter().map(|index| {
- // adjust all positions to the end of the line (next line minus one)
- doc.text().line_to_char(index + 1).saturating_sub(1)
- });
+ let mut ranges = SmallVec::with_capacity(lines.len());
- let text = doc.text().slice(..);
+ let changes: Vec<Change> = lines
+ .into_iter()
+ .map(|line| {
+ // adjust all positions to the end of the line (next line minus one)
+ let index = doc.text().line_to_char(line + 1).saturating_sub(1);
- let changes: Vec<Change> = positions
- .map(|index| {
// TODO: share logic with insert_newline for indentation
- let indent_level =
- helix_core::indent::suggested_indent_for_pos(doc.syntax(), text, index, true);
+ let indent_level = indent::suggested_indent_for_pos(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 = index + text.len();
+ ranges.push(Range::new(pos, pos));
+
(index, index, Some(text.into()))
})
.collect();
@@ -978,17 +981,7 @@ pub fn open_below(cx: &mut Context) {
// 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(
- changes
- .iter()
- .map(|(start, _end, text): &Change| {
- let len = text.as_ref().map(|text| text.len()).unwrap(); // minus newline
- let pos = start + len;
- Range::new(pos, pos)
- })
- .collect(),
- 0,
- );
+ let selection = Selection::new(ranges, 0);
let transaction =
Transaction::change(doc.text(), changes.into_iter()).with_selection(selection);
@@ -1002,26 +995,29 @@ pub fn open_above(cx: &mut Context) {
let (view, doc) = cx.current();
enter_insert_mode(doc);
+ let text = doc.text().slice(..);
let lines = selection_lines(doc.text(), doc.selection(view.id));
- let positions = lines.into_iter().map(|index| {
- // adjust all positions to the end of the previous line
- doc.text().line_to_char(index).saturating_sub(1)
- });
+ let mut ranges = SmallVec::with_capacity(lines.len());
- let text = doc.text().slice(..);
+ let changes: Vec<Change> = lines
+ .into_iter()
+ .map(|line| {
+ // adjust all positions to the end of the previous line
+ let index = doc.text().line_to_char(line).saturating_sub(1);
- let changes: Vec<Change> = positions
- .map(|index| {
// TODO: share logic with insert_newline for indentation
- let indent_level =
- helix_core::indent::suggested_indent_for_pos(doc.syntax(), text, index, true);
+ let indent_level = indent::suggested_indent_for_pos(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 = index + text.len();
+ ranges.push(Range::new(pos, pos));
+
// generate changes
(index, index, Some(text.into()))
})
@@ -1030,17 +1026,7 @@ pub fn open_above(cx: &mut Context) {
// 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(
- changes
- .iter()
- .map(|(start, _end, text): &Change| {
- let len = text.as_ref().map(|text| text.len()).unwrap(); // minus newline
- let pos = start + len;
- Range::new(pos, pos)
- })
- .collect(),
- 0,
- );
+ let selection = Selection::new(ranges, 0);
let transaction =
Transaction::change(doc.text(), changes.into_iter()).with_selection(selection);
@@ -1359,12 +1345,8 @@ pub mod insert {
let transaction =
Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
// TODO: offset range.head by 1? when calculating?
- let indent_level = helix_core::indent::suggested_indent_for_pos(
- doc.syntax(),
- text,
- range.head,
- true,
- );
+ let indent_level =
+ indent::suggested_indent_for_pos(doc.syntax(), text, range.head, true);
let indent = doc.indent_unit().repeat(indent_level);
let mut text = String::with_capacity(1 + indent.len());
text.push('\n');