@@ -60,8 +60,86 @@ pub fn append_mode(state: &mut State, _count: usize) {
6060 })
6161}
6262
63+// TODO: I, A, o and O can share a lot of the primitives.
64+
6365// I inserts at the start of each line with a selection
66+pub fn prepend_to_line(state: &mut State, _count: usize) {
67+ state.mode = Mode::Insert;
68+
69+ // calculate line numbers for each selection range
70+ let mut lines = state
71+ .selection
72+ .ranges()
73+ .iter()
74+ .map(|range| state.doc.char_to_line(range.head))
75+ .collect::<Vec<_>>();
76+
77+ lines.sort();
78+ lines.dedup();
79+
80+ let positions: Vec<_> = lines
81+ .into_iter()
82+ .map(|index| {
83+ // adjust all positions to the end of the line.
84+ let line_start = state.doc.line_to_char(index);
85+ line_start
86+ })
87+ .collect();
88+
89+ let selection = Selection::new(
90+ positions
91+ .iter()
92+ .copied()
93+ .map(|pos| Range::new(pos, pos))
94+ .collect(),
95+ 0,
96+ );
97+
98+ let transaction = Transaction::new(state).with_selection(selection);
99+
100+ transaction.apply(state);
101+ // TODO: need to store into history if successful
102+}
103+
64104// A inserts at the end of each line with a selection
105+pub fn append_to_line(state: &mut State, _count: usize) {
106+ state.mode = Mode::Insert;
107+
108+ // calculate line numbers for each selection range
109+ let mut lines = state
110+ .selection
111+ .ranges()
112+ .iter()
113+ .map(|range| state.doc.char_to_line(range.head))
114+ .collect::<Vec<_>>();
115+
116+ lines.sort();
117+ lines.dedup();
118+
119+ let positions: Vec<_> = lines
120+ .into_iter()
121+ .map(|index| {
122+ // adjust all positions to the end of the line.
123+ let line = state.doc.line(index);
124+ let line_start = state.doc.line_to_char(index);
125+ line_start + line.len_chars() - 1
126+ })
127+ .collect();
128+
129+ let selection = Selection::new(
130+ positions
131+ .iter()
132+ .copied()
133+ .map(|pos| Range::new(pos, pos))
134+ .collect(),
135+ 0,
136+ );
137+
138+ let transaction = Transaction::new(state).with_selection(selection);
139+
140+ transaction.apply(state);
141+ // TODO: need to store into history if successful
142+}
65143
66144// o inserts a new line after each line with a selection
67145pub fn open_below(state: &mut State, _count: usize) {