@@ -1,5 +1,5 @@
1use crate::graphemes;
1use crate::graphemes;
2−use crate::selection::Range;
2+use crate::selection::{Range, Selection};
3use crate::state::{Direction, Granularity, Mode, State};
3use crate::state::{Direction, Granularity, Mode, State};
4use crate::transaction::{ChangeSet, Transaction};
4use crate::transaction::{ChangeSet, Transaction};
5use crate::Tendril;
5use crate::Tendril;
@@ -62,8 +62,55 @@ pub fn append_mode(state: &mut State, _count: usize) {
63// I inserts at the start of each line with a selection
63// I inserts at the start of each line with a selection
64// A inserts at the end of each line with a selection
64// A inserts at the end of each line with a selection
65−// o inserts a new line before each line with a selection
66+// o inserts a new line after each line with a selection
67+pub fn open_below(state: &mut State, _count: usize) {
68+ state.mode = Mode::Insert;
70+ // calculate line numbers for each selection range
71+ let mut lines = state
75+ .map(|range| state.doc.char_to_line(range.head))
76+ .collect::<Vec<_>>();
81+ let positions: Vec<_> = lines
84+ // adjust all positions to the end of the line.
85+ let line = state.doc.line(index);
86+ let line_start = state.doc.line_to_char(index);
87+ line_start + line.len_chars()
91+ let changes = positions.iter().copied().map(|index|
93+ (index, index, Some(Tendril::from_char('\n'))));
95+ // TODO: count actually inserts "n" new lines and starts editing on all of them.
96+ // TODO: append "count" newlines and modify cursors to those lines
98+ let selection = Selection::new(
102+ .map(|pos| Range::new(pos, pos))
107+ let transaction = Transaction::change(state, changes.collect()).with_selection(selection);
109+ transaction.apply(state);
110+ // TODO: need to store into history if successful
66−// O inserts a new line after each line with a selection
113+// O inserts a new line before each line with a selection
68pub fn normal_mode(state: &mut State, _count: usize) {
115pub fn normal_mode(state: &mut State, _count: usize) {
69 // TODO: if leaving append mode, move cursor back by 1
116 // TODO: if leaving append mode, move cursor back by 1