on master help sign in
Introduce doc.selection()/set_selection()
commit55fa86248c77a01900379ec5bca668978fd5c0d3 authorBlaž Hrastnik <blaz@mxxn.io> dateFri 23 Oct 2020, 12:06 (6 years ago) parente4070d4
2 files changed+78−75
helix-view/src/commands.rs+67−75 helix-view/src/document.rs+11
helix-view/src/commands.rs+67−75
@@ -19,40 +19,38 @@ use crate::{
1919pub type Command = fn(view: &mut View, count: usize);
2020
2121pub fn move_char_left(view: &mut View, count: usize) {
22− // TODO: use a transaction
2322 let selection =
2423 view.doc
2524 .state
2625 .move_selection(Direction::Backward, Granularity::Character, count);
27− view.doc.state.selection = selection;
26+ view.doc.set_selection(selection);
2827}
2928
3029pub fn move_char_right(view: &mut View, count: usize) {
31− // TODO: use a transaction
32− view.doc.state.selection =
30+ let selection =
3331 view.doc
3432 .state
3533 .move_selection(Direction::Forward, Granularity::Character, count);
34+ view.doc.set_selection(selection);
3635}
3736
3837pub fn move_line_up(view: &mut View, count: usize) {
39− // TODO: use a transaction
40− view.doc.state.selection =
41− view.doc
42− .state
43− .move_selection(Direction::Backward, Granularity::Line, count);
38+ let selection = view
39+ .doc
40+ .state
41+ .move_selection(Direction::Backward, Granularity::Line, count);
42+ view.doc.set_selection(selection);
4443}
4544
4645pub fn move_line_down(view: &mut View, count: usize) {
47− // TODO: use a transaction
48− view.doc.state.selection =
49− view.doc
50− .state
51− .move_selection(Direction::Forward, Granularity::Line, count);
46+ let selection = view
47+ .doc
48+ .state
49+ .move_selection(Direction::Forward, Granularity::Line, count);
50+ view.doc.set_selection(selection);
5251}
5352
5453pub fn move_line_end(view: &mut View, _count: usize) {
55− // TODO: use a transaction
5654 let lines = selection_lines(&view.doc.state);
5755
5856 let positions = lines
@@ -68,9 +66,7 @@ pub fn move_line_end(view: &mut View, _count: usize) {
6866
6967 let selection = Selection::new(positions.collect(), 0);
7068
71− let transaction = Transaction::new(&mut view.doc.state).with_selection(selection);
72−
73− view.doc.apply(&transaction);
69+ view.doc.set_selection(selection);
7470}
7571
7672pub fn move_line_start(view: &mut View, _count: usize) {
@@ -86,64 +82,58 @@ pub fn move_line_start(view: &mut View, _count: usize) {
8682
8783 let selection = Selection::new(positions.collect(), 0);
8884
89− let transaction = Transaction::new(&mut view.doc.state).with_selection(selection);
90−
91− view.doc.apply(&transaction);
85+ view.doc.set_selection(selection);
9286}
9387
9488pub fn move_next_word_start(view: &mut View, count: usize) {
9589 let pos = view.doc.state.move_pos(
96− view.doc.state.selection.cursor(),
90+ view.doc.selection().cursor(),
9791 Direction::Forward,
9892 Granularity::Word,
9993 count,
10094 );
10195
102− // TODO: use a transaction
103− view.doc.state.selection = Selection::single(pos, pos);
96+ view.doc.set_selection(Selection::single(pos, pos));
10497}
10598
10699pub fn move_prev_word_start(view: &mut View, count: usize) {
107100 let pos = view.doc.state.move_pos(
108− view.doc.state.selection.cursor(),
101+ view.doc.selection().cursor(),
109102 Direction::Backward,
110103 Granularity::Word,
111104 count,
112105 );
113106
114− // TODO: use a transaction
115− view.doc.state.selection = Selection::single(pos, pos);
107+ view.doc.set_selection(Selection::single(pos, pos));
116108}
117109
118110pub fn move_next_word_end(view: &mut View, count: usize) {
119111 let pos = State::move_next_word_end(
120112 &view.doc.text().slice(..),
121− view.doc.state.selection.cursor(),
113+ view.doc.selection().cursor(),
122114 count,
123115 );
124116
125− // TODO: use a transaction
126− view.doc.state.selection = Selection::single(pos, pos);
117+ view.doc.set_selection(Selection::single(pos, pos));
127118}
128119
129120pub fn move_file_start(view: &mut View, _count: usize) {
130− // TODO: use a transaction
131− view.doc.state.selection = Selection::single(0, 0);
121+ view.doc.set_selection(Selection::single(0, 0));
132122
133123 view.doc.mode = Mode::Normal;
134124}
135125
136126pub fn move_file_end(view: &mut View, _count: usize) {
137− // TODO: use a transaction
138127 let text = &view.doc.text();
139128 let last_line = text.line_to_char(text.len_lines().saturating_sub(2));
140− view.doc.state.selection = Selection::single(last_line, last_line);
129+ view.doc
130+ .set_selection(Selection::single(last_line, last_line));
141131
142132 view.doc.mode = Mode::Normal;
143133}
144134
145135pub fn check_cursor_in_view(view: &mut View) -> bool {
146− let cursor = view.doc.state.selection().cursor();
136+ let cursor = view.doc.selection().cursor();
147137 let line = view.doc.text().char_to_line(cursor);
148138 let document_end = view.first_line + view.size.1.saturating_sub(1) as usize;
149139
@@ -163,7 +153,7 @@ pub fn page_up(view: &mut View, _count: usize) {
163153 if !check_cursor_in_view(view) {
164154 let text = view.doc.text();
165155 let pos = text.line_to_char(view.last_line().saturating_sub(PADDING));
166− view.doc.state.selection = Selection::single(pos, pos);
156+ view.doc.set_selection(Selection::single(pos, pos));
167157 }
168158}
169159
@@ -173,7 +163,7 @@ pub fn page_down(view: &mut View, _count: usize) {
173163 if view.first_line < view.doc.text().len_lines() {
174164 let text = view.doc.text();
175165 let pos = text.line_to_char(view.first_line as usize);
176− view.doc.state.selection = Selection::single(pos, pos);
166+ view.doc.set_selection(Selection::single(pos, pos));
177167 }
178168}
179169
@@ -187,7 +177,7 @@ pub fn half_page_up(view: &mut View, _count: usize) {
187177 if !check_cursor_in_view(view) {
188178 let text = &view.doc.text();
189179 let pos = text.line_to_char(view.last_line() - PADDING);
190− view.doc.state.selection = Selection::single(pos, pos);
180+ view.doc.set_selection(Selection::single(pos, pos));
191181 }
192182}
193183
@@ -199,42 +189,41 @@ pub fn half_page_down(view: &mut View, _count: usize) {
199189 if !check_cursor_in_view(view) {
200190 let text = view.doc.text();
201191 let pos = text.line_to_char(view.first_line as usize);
202− view.doc.state.selection = Selection::single(pos, pos);
192+ view.doc.set_selection(Selection::single(pos, pos));
203193 }
204194}
205195// avoid select by default by having a visual mode switch that makes movements into selects
206196
207197pub fn extend_char_left(view: &mut View, count: usize) {
208− // TODO: use a transaction
209198 let selection =
210199 view.doc
211200 .state
212201 .extend_selection(Direction::Backward, Granularity::Character, count);
213− view.doc.state.selection = selection;
202+ view.doc.set_selection(selection);
214203}
215204
216205pub fn extend_char_right(view: &mut View, count: usize) {
217− // TODO: use a transaction
218− view.doc.state.selection =
206+ let selection =
219207 view.doc
220208 .state
221209 .extend_selection(Direction::Forward, Granularity::Character, count);
210+ view.doc.set_selection(selection);
222211}
223212
224213pub fn extend_line_up(view: &mut View, count: usize) {
225− // TODO: use a transaction
226− view.doc.state.selection =
227− view.doc
228− .state
229− .extend_selection(Direction::Backward, Granularity::Line, count);
214+ let selection = view
215+ .doc
216+ .state
217+ .extend_selection(Direction::Backward, Granularity::Line, count);
218+ view.doc.set_selection(selection);
230219}
231220
232221pub fn extend_line_down(view: &mut View, count: usize) {
233− // TODO: use a transaction
234− view.doc.state.selection =
235− view.doc
236− .state
237− .extend_selection(Direction::Forward, Granularity::Line, count);
222+ let selection = view
223+ .doc
224+ .state
225+ .extend_selection(Direction::Forward, Granularity::Line, count);
226+ view.doc.set_selection(selection);
238227}
239228
240229pub fn split_selection_on_newline(view: &mut View, _count: usize) {
@@ -242,20 +231,19 @@ pub fn split_selection_on_newline(view: &mut View, _count: usize) {
242231 // only compile the regex once
243232 #[allow(clippy::trivial_regex)]
244233 static REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"\n").unwrap());
245− // TODO: use a transaction
246− view.doc.state.selection = selection::split_on_matches(text, view.doc.state.selection(), &REGEX)
234+ let selection = selection::split_on_matches(text, view.doc.selection(), &REGEX);
235+ view.doc.set_selection(selection);
247236}
248237
249238pub fn select_line(view: &mut View, _count: usize) {
250239 // TODO: count
251− let pos = view.doc.state.selection().primary();
240+ let pos = view.doc.selection().primary();
252241 let text = view.doc.text();
253242 let line = text.char_to_line(pos.head);
254243 let start = text.line_to_char(line);
255244 let end = text.line_to_char(line + 1).saturating_sub(1);
256245
257− // TODO: use a transaction
258− view.doc.state.selection = Selection::single(start, end);
246+ view.doc.set_selection(Selection::single(start, end));
259247}
260248
261249pub fn delete_selection(view: &mut View, _count: usize) {
@@ -273,19 +261,21 @@ pub fn change_selection(view: &mut View, count: usize) {
273261}
274262
275263pub fn collapse_selection(view: &mut View, _count: usize) {
276− view.doc.state.selection = view
264+ let selection = view
277265 .doc
278− .state
279− .selection
280− .transform(|range| Range::new(range.head, range.head))
266+ .selection()
267+ .transform(|range| Range::new(range.head, range.head));
268+
269+ view.doc.set_selection(selection);
281270}
282271
283272pub fn flip_selections(view: &mut View, _count: usize) {
284− view.doc.state.selection = view
273+ let selection = view
285274 .doc
286− .state
287− .selection
288− .transform(|range| Range::new(range.head, range.anchor))
275+ .selection()
276+ .transform(|range| Range::new(range.head, range.anchor));
277+
278+ view.doc.set_selection(selection);
289279}
290280
291281fn enter_insert_mode(view: &mut View) {
@@ -297,11 +287,11 @@ fn enter_insert_mode(view: &mut View) {
297287pub fn insert_mode(view: &mut View, _count: usize) {
298288 enter_insert_mode(view);
299289
300− view.doc.state.selection = view
290+ let selection = view
301291 .doc
302− .state
303− .selection
304− .transform(|range| Range::new(range.to(), range.from()))
292+ .selection()
293+ .transform(|range| Range::new(range.to(), range.from()));
294+ view.doc.set_selection(selection);
305295}
306296
307297// inserts at the end of each selection
@@ -311,13 +301,14 @@ pub fn append_mode(view: &mut View, _count: usize) {
311301
312302 // TODO: as transaction
313303 let text = &view.doc.text().slice(..);
314− view.doc.state.selection = view.doc.state.selection.transform(|range| {
304+ let selection = view.doc.selection().transform(|range| {
315305 // TODO: to() + next char
316306 Range::new(
317307 range.from(),
318308 graphemes::next_grapheme_boundary(text, range.to()),
319309 )
320− })
310+ });
311+ view.doc.set_selection(selection);
321312}
322313
323314// TODO: I, A, o and O can share a lot of the primitives.
@@ -402,7 +393,7 @@ fn append_changes_to_history(view: &mut View) {
402393 let changes = std::mem::replace(&mut view.doc.changes, new_changeset);
403394 // Instead of doing this messy merge we could always commit, and based on transaction
404395 // annotations either add a new layer or compose into the previous one.
405− let transaction = Transaction::from(changes).with_selection(view.doc.state.selection().clone());
396+ let transaction = Transaction::from(changes).with_selection(view.doc.selection().clone());
406397
407398 // increment document version
408399 // TODO: needs to happen on undo/redo too
@@ -424,12 +415,13 @@ pub fn normal_mode(view: &mut View, _count: usize) {
424415 // if leaving append mode, move cursor back by 1
425416 if view.doc.restore_cursor {
426417 let text = &view.doc.text().slice(..);
427− view.doc.state.selection = view.doc.state.selection.transform(|range| {
418+ let selection = view.doc.selection().transform(|range| {
428419 Range::new(
429420 range.from(),
430421 graphemes::prev_grapheme_boundary(text, range.to()),
431422 )
432423 });
424+ view.doc.set_selection(selection);
433425
434426 view.doc.restore_cursor = false;
435427 }
@@ -587,7 +579,7 @@ fn get_lines(view: &View) -> Vec<usize> {
587579 let mut lines = Vec::new();
588580
589581 // Get all line numbers
590− for range in view.doc.state.selection.ranges() {
582+ for range in view.doc.selection().ranges() {
591583 let start = view.doc.text().char_to_line(range.from());
592584 let end = view.doc.text().char_to_line(range.to());
593585
helix-view/src/document.rs+11
@@ -108,6 +108,11 @@ impl Document {
108108 };
109109 }
110110
111+ pub fn set_selection(&mut self, selection: Selection) {
112+ // TODO: use a transaction?
113+ self.state.selection = selection;
114+ }
115+
111116 pub fn apply(&mut self, transaction: &Transaction) -> bool {
112117 let old_doc = self.text().clone();
113118
@@ -119,6 +124,8 @@ impl Document {
119124 changes.compose(transaction.changes().clone()).unwrap()
120125 });
121126
127+ // TODO: when composing, replace transaction.selection too
128+
122129 // update tree-sitter syntax tree
123130 if let Some(syntax) = &mut self.syntax {
124131 // TODO: no unwrap
@@ -150,6 +157,10 @@ impl Document {
150157 &self.state.doc
151158 }
152159
160+ pub fn selection(&self) -> &Selection {
161+ &self.state.selection
162+ }
163+
153164 // pub fn slice<R>(&self, range: R) -> RopeSlice where R: RangeBounds {
154165 // self.state.doc.slice
155166 // }