on master help sign in
commands: refactor open_below to support count.
5fa1ba6Blaž Hrastnik
helix-term/src/commands.rs+34−29
@@ -5,7 +5,7 @@ use helix_core::{
5 regex::{self, Regex},
5 regex::{self, Regex},
6 register, selection,
6 register, selection,
7 state::{Direction, Granularity, State},
7 state::{Direction, Granularity, State},
8− ChangeSet, Range, Selection, Tendril, Transaction,
8+ Change, ChangeSet, Range, Selection, Tendril, Transaction,
9};
9};
10
10
11use once_cell::sync::Lazy;
11use once_cell::sync::Lazy;
@@ -588,47 +588,51 @@ pub fn append_to_line(cx: &mut Context) {
588
588
589// o inserts a new line after each line with a selection
589// o inserts a new line after each line with a selection
590pub fn open_below(cx: &mut Context) {
590pub fn open_below(cx: &mut Context) {
591+ let count = cx.count;
591 let doc = cx.doc();
592 let doc = cx.doc();
592 enter_insert_mode(doc);
593 enter_insert_mode(doc);
593
594
594 let lines = selection_lines(&doc.state);
595 let lines = selection_lines(&doc.state);
595
596
596 let positions = lines.into_iter().map(|index| {
597 let positions = lines.into_iter().map(|index| {
597− // adjust all positions to the end of the line/start of the next one.
598+ // adjust all positions to the end of the line (next line minus one)
598− doc.text().line_to_char(index + 1)
599+ doc.text().line_to_char(index + 1).saturating_sub(1)
599 });
600 });
600
601
601− let changes = positions.map(|index| {
602+ let changes: Vec<Change> = positions
603+ .map(|index| {
602− // TODO: share logic with insert_newline for indentation
604+ // TODO: share logic with insert_newline for indentation
603− let indent_level = helix_core::indent::suggested_indent_for_pos(
605+ let indent_level = helix_core::indent::suggested_indent_for_pos(
604− doc.syntax.as_ref(),
606+ doc.syntax.as_ref(),
605− &doc.state,
607+ &doc.state,
606− index - 1, // need to match the indentation to the prev line
608+ index,
607− true,
609+ true,
608− );
610+ );
609− let indent = " ".repeat(TAB_WIDTH).repeat(indent_level);
611+ let indent = " ".repeat(TAB_WIDTH).repeat(indent_level);
610− let mut text = String::with_capacity(1 + indent.len());
612+ let mut text = String::with_capacity(1 + indent.len());
611− text.push_str(&indent);
612− text.push('\n');
613+ text.push('\n');
613−
614+ text.push_str(&indent);
615+ let text = text.repeat(count);
616+
614− // TODO: ideally we want to run a hook over the transactions to figure out and reindent all
617+ // TODO: ideally we want to run a hook over the transactions to figure out and reindent all
615− // \n's as a post-processing step?
618+ // \n's as a post-processing step?
616− // behaviors:
619+ // behaviors:
617− // - on insert mode enter: we add newline + indent and position cursor at the end
620+ // - on insert mode enter: we add newline + indent and position cursor at the end
618− // - on 3o/3O: we insert 3 newlines + indents each and position cursors at ends
621+ // - on 3o/3O: we insert 3 newlines + indents each and position cursors at ends
619−
622+
620− // generate changes
623+ // generate changes
621− (index, index, Some(text.into()))
624+ (index, index, Some(text.into()))
622− });
625+ })
626+ .collect();
623
627
624 // TODO: count actually inserts "n" new lines and starts editing on all of them.
628 // TODO: count actually inserts "n" new lines and starts editing on all of them.
625 // TODO: append "count" newlines and modify cursors to those lines
629 // TODO: append "count" newlines and modify cursors to those lines
626
630
627 let selection = Selection::new(
631 let selection = Selection::new(
628 changes
632 changes
629− .clone()
633+ .iter()
630− .map(|(start, end, text): (usize, usize, Option<Tendril>)| {
634+ .map(|(start, _end, text): &Change| {
631− let len = text.map(|text| text.len()).unwrap() - 1; // minus newline
635+ let len = text.as_ref().map(|text| text.len()).unwrap(); // minus newline
632 let pos = start + len;
636 let pos = start + len;
633 Range::new(pos, pos)
637 Range::new(pos, pos)
634 })
638 })
@@ -636,7 +640,8 @@ pub fn open_below(cx: &mut Context) {
636 0,
640 0,
637 );
641 );
638
642
643+ let transaction =
639− let transaction = Transaction::change(&doc.state, changes).with_selection(selection);
644+ Transaction::change(&doc.state, changes.into_iter()).with_selection(selection);
640
645
641 doc.apply(&transaction);
646 doc.apply(&transaction);
642}
647}