on master help sign in
Replace `Editor::current` by a macro
8664d70Benoît CORTIER
helix-term/src/commands.rs+122−134
@@ -52,27 +52,6 @@ pub struct Context<'a> {
52}
52}
53
53
54impl<'a> Context<'a> {
54impl<'a> Context<'a> {
55− #[inline]
56− pub fn view(&mut self) -> &mut View {
57− self.editor.view_mut()
58− }
59−
60− #[inline]
61− pub fn doc(&mut self) -> &mut Document {
62− let id = self.editor.view().doc;
63− &mut self.editor.documents[id]
64− }
65−
66− #[inline]
67− pub fn current(&mut self) -> (&mut View, &mut Document) {
68− self.editor.current()
69− }
70−
71− #[inline]
72− pub fn current_with_registers(&mut self) -> (&mut View, &mut Document, &mut Registers) {
73− self.editor.current_with_registers()
74− }
75−
76 /// Push a new component onto the compositor.
55 /// Push a new component onto the compositor.
77 pub fn push_layer(&mut self, mut component: Box<dyn Component>) {
56 pub fn push_layer(&mut self, mut component: Box<dyn Component>) {
78 self.callback = Some(Box::new(|compositor: &mut Compositor| {
57 self.callback = Some(Box::new(|compositor: &mut Compositor| {
@@ -275,7 +254,7 @@ impl Command {
275
254
276fn move_char_left(cx: &mut Context) {
255fn move_char_left(cx: &mut Context) {
277 let count = cx.count();
256 let count = cx.count();
278− let (view, doc) = cx.current();
257+ let (view, doc) = current!(cx.editor);
279 let text = doc.text().slice(..);
258 let text = doc.text().slice(..);
280 let selection = doc.selection(view.id).transform(|range| {
259 let selection = doc.selection(view.id).transform(|range| {
281 movement::move_horizontally(text, range, Direction::Backward, count, Movement::Move)
260 movement::move_horizontally(text, range, Direction::Backward, count, Movement::Move)
@@ -285,7 +264,7 @@ fn move_char_left(cx: &mut Context) {
285
264
286fn move_char_right(cx: &mut Context) {
265fn move_char_right(cx: &mut Context) {
287 let count = cx.count();
266 let count = cx.count();
288− let (view, doc) = cx.current();
267+ let (view, doc) = current!(cx.editor);
289 let text = doc.text().slice(..);
268 let text = doc.text().slice(..);
290 let selection = doc.selection(view.id).transform(|range| {
269 let selection = doc.selection(view.id).transform(|range| {
291 movement::move_horizontally(text, range, Direction::Forward, count, Movement::Move)
270 movement::move_horizontally(text, range, Direction::Forward, count, Movement::Move)
@@ -295,7 +274,7 @@ fn move_char_right(cx: &mut Context) {
295
274
296fn move_line_up(cx: &mut Context) {
275fn move_line_up(cx: &mut Context) {
297 let count = cx.count();
276 let count = cx.count();
298− let (view, doc) = cx.current();
277+ let (view, doc) = current!(cx.editor);
299 let text = doc.text().slice(..);
278 let text = doc.text().slice(..);
300 let selection = doc.selection(view.id).transform(|range| {
279 let selection = doc.selection(view.id).transform(|range| {
301 movement::move_vertically(text, range, Direction::Backward, count, Movement::Move)
280 movement::move_vertically(text, range, Direction::Backward, count, Movement::Move)
@@ -305,7 +284,7 @@ fn move_line_up(cx: &mut Context) {
305
284
306fn move_line_down(cx: &mut Context) {
285fn move_line_down(cx: &mut Context) {
307 let count = cx.count();
286 let count = cx.count();
308− let (view, doc) = cx.current();
287+ let (view, doc) = current!(cx.editor);
309 let text = doc.text().slice(..);
288 let text = doc.text().slice(..);
310 let selection = doc.selection(view.id).transform(|range| {
289 let selection = doc.selection(view.id).transform(|range| {
311 movement::move_vertically(text, range, Direction::Forward, count, Movement::Move)
290 movement::move_vertically(text, range, Direction::Forward, count, Movement::Move)
@@ -314,7 +293,7 @@ fn move_line_down(cx: &mut Context) {
314}
293}
315
294
316fn move_line_end(cx: &mut Context) {
295fn move_line_end(cx: &mut Context) {
317− let (view, doc) = cx.current();
296+ let (view, doc) = current!(cx.editor);
318
297
319 let selection = doc.selection(view.id).transform(|range| {
298 let selection = doc.selection(view.id).transform(|range| {
320 let text = doc.text();
299 let text = doc.text();
@@ -330,7 +309,7 @@ fn move_line_end(cx: &mut Context) {
330}
309}
331
310
332fn move_line_start(cx: &mut Context) {
311fn move_line_start(cx: &mut Context) {
333− let (view, doc) = cx.current();
312+ let (view, doc) = current!(cx.editor);
334
313
335 let selection = doc.selection(view.id).transform(|range| {
314 let selection = doc.selection(view.id).transform(|range| {
336 let text = doc.text();
315 let text = doc.text();
@@ -345,7 +324,7 @@ fn move_line_start(cx: &mut Context) {
345}
324}
346
325
347fn move_first_nonwhitespace(cx: &mut Context) {
326fn move_first_nonwhitespace(cx: &mut Context) {
348− let (view, doc) = cx.current();
327+ let (view, doc) = current!(cx.editor);
349
328
350 let selection = doc.selection(view.id).transform(|range| {
329 let selection = doc.selection(view.id).transform(|range| {
351 let text = doc.text();
330 let text = doc.text();
@@ -368,7 +347,7 @@ fn move_first_nonwhitespace(cx: &mut Context) {
368
347
369fn move_next_word_start(cx: &mut Context) {
348fn move_next_word_start(cx: &mut Context) {
370 let count = cx.count();
349 let count = cx.count();
371− let (view, doc) = cx.current();
350+ let (view, doc) = current!(cx.editor);
372 let text = doc.text().slice(..);
351 let text = doc.text().slice(..);
373
352
374 let selection = doc
353 let selection = doc
@@ -380,7 +359,7 @@ fn move_next_word_start(cx: &mut Context) {
380
359
381fn move_prev_word_start(cx: &mut Context) {
360fn move_prev_word_start(cx: &mut Context) {
382 let count = cx.count();
361 let count = cx.count();
383− let (view, doc) = cx.current();
362+ let (view, doc) = current!(cx.editor);
384 let text = doc.text().slice(..);
363 let text = doc.text().slice(..);
385
364
386 let selection = doc
365 let selection = doc
@@ -392,7 +371,7 @@ fn move_prev_word_start(cx: &mut Context) {
392
371
393fn move_next_word_end(cx: &mut Context) {
372fn move_next_word_end(cx: &mut Context) {
394 let count = cx.count();
373 let count = cx.count();
395− let (view, doc) = cx.current();
374+ let (view, doc) = current!(cx.editor);
396 let text = doc.text().slice(..);
375 let text = doc.text().slice(..);
397
376
398 let selection = doc
377 let selection = doc
@@ -404,13 +383,13 @@ fn move_next_word_end(cx: &mut Context) {
404
383
405fn move_file_start(cx: &mut Context) {
384fn move_file_start(cx: &mut Context) {
406 push_jump(cx.editor);
385 push_jump(cx.editor);
407− let (view, doc) = cx.current();
386+ let (view, doc) = current!(cx.editor);
408 doc.set_selection(view.id, Selection::point(0));
387 doc.set_selection(view.id, Selection::point(0));
409}
388}
410
389
411fn move_file_end(cx: &mut Context) {
390fn move_file_end(cx: &mut Context) {
412 push_jump(cx.editor);
391 push_jump(cx.editor);
413− let (view, doc) = cx.current();
392+ let (view, doc) = current!(cx.editor);
414 let text = doc.text();
393 let text = doc.text();
415 let last_line = text.line_to_char(text.len_lines().saturating_sub(2));
394 let last_line = text.line_to_char(text.len_lines().saturating_sub(2));
416 doc.set_selection(view.id, Selection::point(last_line));
395 doc.set_selection(view.id, Selection::point(last_line));
@@ -418,7 +397,7 @@ fn move_file_end(cx: &mut Context) {
418
397
419fn extend_next_word_start(cx: &mut Context) {
398fn extend_next_word_start(cx: &mut Context) {
420 let count = cx.count();
399 let count = cx.count();
421− let (view, doc) = cx.current();
400+ let (view, doc) = current!(cx.editor);
422 let text = doc.text().slice(..);
401 let text = doc.text().slice(..);
423
402
424 let selection = doc.selection(view.id).transform(|mut range| {
403 let selection = doc.selection(view.id).transform(|mut range| {
@@ -432,7 +411,7 @@ fn extend_next_word_start(cx: &mut Context) {
432
411
433fn extend_prev_word_start(cx: &mut Context) {
412fn extend_prev_word_start(cx: &mut Context) {
434 let count = cx.count();
413 let count = cx.count();
435− let (view, doc) = cx.current();
414+ let (view, doc) = current!(cx.editor);
436 let text = doc.text().slice(..);
415 let text = doc.text().slice(..);
437
416
438 let selection = doc.selection(view.id).transform(|mut range| {
417 let selection = doc.selection(view.id).transform(|mut range| {
@@ -445,7 +424,7 @@ fn extend_prev_word_start(cx: &mut Context) {
445
424
446fn extend_next_word_end(cx: &mut Context) {
425fn extend_next_word_end(cx: &mut Context) {
447 let count = cx.count();
426 let count = cx.count();
448− let (view, doc) = cx.current();
427+ let (view, doc) = current!(cx.editor);
449 let text = doc.text().slice(..);
428 let text = doc.text().slice(..);
450
429
451 let selection = doc.selection(view.id).transform(|mut range| {
430 let selection = doc.selection(view.id).transform(|mut range| {
@@ -482,7 +461,7 @@ where
482 _ => return,
461 _ => return,
483 };
462 };
484
463
485− let (view, doc) = cx.current();
464+ let (view, doc) = current!(cx.editor);
486 let text = doc.text().slice(..);
465 let text = doc.text().slice(..);
487
466
488 let selection = doc.selection(view.id).transform(|mut range| {
467 let selection = doc.selection(view.id).transform(|mut range| {
@@ -574,7 +553,7 @@ fn extend_prev_char(cx: &mut Context) {
574}
553}
575
554
576fn extend_first_nonwhitespace(cx: &mut Context) {
555fn extend_first_nonwhitespace(cx: &mut Context) {
577− let (view, doc) = cx.current();
556+ let (view, doc) = current!(cx.editor);
578
557
579 let selection = doc.selection(view.id).transform(|range| {
558 let selection = doc.selection(view.id).transform(|range| {
580 let text = doc.text();
559 let text = doc.text();
@@ -607,7 +586,7 @@ fn replace(cx: &mut Context) {
607 };
586 };
608
587
609 if let Some(ch) = ch {
588 if let Some(ch) = ch {
610− let (view, doc) = cx.current();
589+ let (view, doc) = current!(cx.editor);
611
590
612 let transaction =
591 let transaction =
613 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
592 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
@@ -631,7 +610,7 @@ fn replace(cx: &mut Context) {
631
610
632fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
611fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
633 use Direction::*;
612 use Direction::*;
634− let (view, doc) = cx.current();
613+ let (view, doc) = current!(cx.editor);
635 let cursor = coords_at_pos(doc.text().slice(..), doc.selection(view.id).cursor());
614 let cursor = coords_at_pos(doc.text().slice(..), doc.selection(view.id).cursor());
636 let doc_last_line = doc.text().len_lines() - 1;
615 let doc_last_line = doc.text().len_lines() - 1;
637
616
@@ -672,32 +651,32 @@ fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
672}
651}
673
652
674fn page_up(cx: &mut Context) {
653fn page_up(cx: &mut Context) {
675− let view = cx.view();
654+ let view = view!(cx.editor);
676 let offset = view.area.height as usize;
655 let offset = view.area.height as usize;
677 scroll(cx, offset, Direction::Backward);
656 scroll(cx, offset, Direction::Backward);
678}
657}
679
658
680fn page_down(cx: &mut Context) {
659fn page_down(cx: &mut Context) {
681− let view = cx.view();
660+ let view = view!(cx.editor);
682 let offset = view.area.height as usize;
661 let offset = view.area.height as usize;
683 scroll(cx, offset, Direction::Forward);
662 scroll(cx, offset, Direction::Forward);
684}
663}
685
664
686fn half_page_up(cx: &mut Context) {
665fn half_page_up(cx: &mut Context) {
687− let view = cx.view();
666+ let view = view!(cx.editor);
688 let offset = view.area.height as usize / 2;
667 let offset = view.area.height as usize / 2;
689 scroll(cx, offset, Direction::Backward);
668 scroll(cx, offset, Direction::Backward);
690}
669}
691
670
692fn half_page_down(cx: &mut Context) {
671fn half_page_down(cx: &mut Context) {
693− let view = cx.view();
672+ let view = view!(cx.editor);
694 let offset = view.area.height as usize / 2;
673 let offset = view.area.height as usize / 2;
695 scroll(cx, offset, Direction::Forward);
674 scroll(cx, offset, Direction::Forward);
696}
675}
697
676
698fn extend_char_left(cx: &mut Context) {
677fn extend_char_left(cx: &mut Context) {
699 let count = cx.count();
678 let count = cx.count();
700− let (view, doc) = cx.current();
679+ let (view, doc) = current!(cx.editor);
701 let text = doc.text().slice(..);
680 let text = doc.text().slice(..);
702 let selection = doc.selection(view.id).transform(|range| {
681 let selection = doc.selection(view.id).transform(|range| {
703 movement::move_horizontally(text, range, Direction::Backward, count, Movement::Extend)
682 movement::move_horizontally(text, range, Direction::Backward, count, Movement::Extend)
@@ -707,7 +686,7 @@ fn extend_char_left(cx: &mut Context) {
707
686
708fn extend_char_right(cx: &mut Context) {
687fn extend_char_right(cx: &mut Context) {
709 let count = cx.count();
688 let count = cx.count();
710− let (view, doc) = cx.current();
689+ let (view, doc) = current!(cx.editor);
711 let text = doc.text().slice(..);
690 let text = doc.text().slice(..);
712 let selection = doc.selection(view.id).transform(|range| {
691 let selection = doc.selection(view.id).transform(|range| {
713 movement::move_horizontally(text, range, Direction::Forward, count, Movement::Extend)
692 movement::move_horizontally(text, range, Direction::Forward, count, Movement::Extend)
@@ -717,7 +696,7 @@ fn extend_char_right(cx: &mut Context) {
717
696
718fn extend_line_up(cx: &mut Context) {
697fn extend_line_up(cx: &mut Context) {
719 let count = cx.count();
698 let count = cx.count();
720− let (view, doc) = cx.current();
699+ let (view, doc) = current!(cx.editor);
721 let text = doc.text().slice(..);
700 let text = doc.text().slice(..);
722 let selection = doc.selection(view.id).transform(|range| {
701 let selection = doc.selection(view.id).transform(|range| {
723 movement::move_vertically(text, range, Direction::Backward, count, Movement::Extend)
702 movement::move_vertically(text, range, Direction::Backward, count, Movement::Extend)
@@ -727,7 +706,7 @@ fn extend_line_up(cx: &mut Context) {
727
706
728fn extend_line_down(cx: &mut Context) {
707fn extend_line_down(cx: &mut Context) {
729 let count = cx.count();
708 let count = cx.count();
730− let (view, doc) = cx.current();
709+ let (view, doc) = current!(cx.editor);
731 let text = doc.text().slice(..);
710 let text = doc.text().slice(..);
732 let selection = doc.selection(view.id).transform(|range| {
711 let selection = doc.selection(view.id).transform(|range| {
733 movement::move_vertically(text, range, Direction::Forward, count, Movement::Extend)
712 movement::move_vertically(text, range, Direction::Forward, count, Movement::Extend)
@@ -736,7 +715,7 @@ fn extend_line_down(cx: &mut Context) {
736}
715}
737
716
738fn extend_line_end(cx: &mut Context) {
717fn extend_line_end(cx: &mut Context) {
739− let (view, doc) = cx.current();
718+ let (view, doc) = current!(cx.editor);
740
719
741 let selection = doc.selection(view.id).transform(|range| {
720 let selection = doc.selection(view.id).transform(|range| {
742 let text = doc.text();
721 let text = doc.text();
@@ -752,7 +731,7 @@ fn extend_line_end(cx: &mut Context) {
752}
731}
753
732
754fn extend_line_start(cx: &mut Context) {
733fn extend_line_start(cx: &mut Context) {
755− let (view, doc) = cx.current();
734+ let (view, doc) = current!(cx.editor);
756
735
757 let selection = doc.selection(view.id).transform(|range| {
736 let selection = doc.selection(view.id).transform(|range| {
758 let text = doc.text();
737 let text = doc.text();
@@ -767,7 +746,7 @@ fn extend_line_start(cx: &mut Context) {
767}
746}
768
747
769fn select_all(cx: &mut Context) {
748fn select_all(cx: &mut Context) {
770− let (view, doc) = cx.current();
749+ let (view, doc) = current!(cx.editor);
771
750
772 let end = doc.text().len_chars().saturating_sub(1);
751 let end = doc.text().len_chars().saturating_sub(1);
773 doc.set_selection(view.id, Selection::single(0, end))
752 doc.set_selection(view.id, Selection::single(0, end))
@@ -796,7 +775,7 @@ fn split_selection(cx: &mut Context) {
796}
775}
797
776
798fn split_selection_on_newline(cx: &mut Context) {
777fn split_selection_on_newline(cx: &mut Context) {
799− let (view, doc) = cx.current();
778+ let (view, doc) = current!(cx.editor);
800 let text = doc.text().slice(..);
779 let text = doc.text().slice(..);
801 // only compile the regex once
780 // only compile the regex once
802 #[allow(clippy::trivial_regex)]
781 #[allow(clippy::trivial_regex)]
@@ -848,7 +827,7 @@ fn search_impl(doc: &mut Document, view: &mut View, contents: &str, regex: &Rege
848
827
849// TODO: use one function for search vs extend
828// TODO: use one function for search vs extend
850fn search(cx: &mut Context) {
829fn search(cx: &mut Context) {
851− let (view, doc) = cx.current();
830+ let (view, doc) = current!(cx.editor);
852
831
853 // TODO: could probably share with select_on_matches?
832 // TODO: could probably share with select_on_matches?
854
833
@@ -871,7 +850,8 @@ fn search(cx: &mut Context) {
871}
850}
872
851
873fn search_next_impl(cx: &mut Context, extend: bool) {
852fn search_next_impl(cx: &mut Context, extend: bool) {
874− let (view, doc, registers) = cx.current_with_registers();
853+ let (view, doc) = current!(cx.editor);
854+ let registers = &mut cx.editor.registers;
875 if let Some(query) = registers.read('\\') {
855 if let Some(query) = registers.read('\\') {
876 let query = query.first().unwrap();
856 let query = query.first().unwrap();
877 let contents = doc.text().slice(..).to_string();
857 let contents = doc.text().slice(..).to_string();
@@ -889,7 +869,7 @@ fn extend_search_next(cx: &mut Context) {
889}
869}
890
870
891fn search_selection(cx: &mut Context) {
871fn search_selection(cx: &mut Context) {
892− let (view, doc) = cx.current();
872+ let (view, doc) = current!(cx.editor);
893 let contents = doc.text().slice(..);
873 let contents = doc.text().slice(..);
894 let query = doc.selection(view.id).primary().fragment(contents);
874 let query = doc.selection(view.id).primary().fragment(contents);
895 let regex = regex::escape(&query);
875 let regex = regex::escape(&query);
@@ -905,7 +885,7 @@ fn search_selection(cx: &mut Context) {
905
885
906fn select_line(cx: &mut Context) {
886fn select_line(cx: &mut Context) {
907 let count = cx.count();
887 let count = cx.count();
908− let (view, doc) = cx.current();
888+ let (view, doc) = current!(cx.editor);
909
889
910 let pos = doc.selection(view.id).primary();
890 let pos = doc.selection(view.id).primary();
911 let text = doc.text();
891 let text = doc.text();
@@ -920,7 +900,7 @@ fn select_line(cx: &mut Context) {
920}
900}
921fn extend_line(cx: &mut Context) {
901fn extend_line(cx: &mut Context) {
922 let count = cx.count();
902 let count = cx.count();
923− let (view, doc) = cx.current();
903+ let (view, doc) = current!(cx.editor);
924
904
925 let pos = doc.selection(view.id).primary();
905 let pos = doc.selection(view.id).primary();
926 let text = doc.text();
906 let text = doc.text();
@@ -962,7 +942,8 @@ fn delete_selection_impl(reg: &mut Register, doc: &mut Document, view_id: ViewId
962
942
963fn delete_selection(cx: &mut Context) {
943fn delete_selection(cx: &mut Context) {
964 let reg_name = cx.selected_register.name();
944 let reg_name = cx.selected_register.name();
965− let (view, doc, registers) = cx.current_with_registers();
945+ let (view, doc) = current!(cx.editor);
946+ let registers = &mut cx.editor.registers;
966 let reg = registers.get_or_insert(reg_name);
947 let reg = registers.get_or_insert(reg_name);
967 delete_selection_impl(reg, doc, view.id);
948 delete_selection_impl(reg, doc, view.id);
968
949
@@ -974,14 +955,15 @@ fn delete_selection(cx: &mut Context) {
974
955
975fn change_selection(cx: &mut Context) {
956fn change_selection(cx: &mut Context) {
976 let reg_name = cx.selected_register.name();
957 let reg_name = cx.selected_register.name();
977− let (view, doc, registers) = cx.current_with_registers();
958+ let (view, doc) = current!(cx.editor);
959+ let registers = &mut cx.editor.registers;
978 let reg = registers.get_or_insert(reg_name);
960 let reg = registers.get_or_insert(reg_name);
979 delete_selection_impl(reg, doc, view.id);
961 delete_selection_impl(reg, doc, view.id);
980 enter_insert_mode(doc);
962 enter_insert_mode(doc);
981}
963}
982
964
983fn collapse_selection(cx: &mut Context) {
965fn collapse_selection(cx: &mut Context) {
984− let (view, doc) = cx.current();
966+ let (view, doc) = current!(cx.editor);
985 let selection = doc
967 let selection = doc
986 .selection(view.id)
968 .selection(view.id)
987 .transform(|range| Range::new(range.head, range.head));
969 .transform(|range| Range::new(range.head, range.head));
@@ -990,7 +972,7 @@ fn collapse_selection(cx: &mut Context) {
990}
972}
991
973
992fn flip_selections(cx: &mut Context) {
974fn flip_selections(cx: &mut Context) {
993− let (view, doc) = cx.current();
975+ let (view, doc) = current!(cx.editor);
994 let selection = doc
976 let selection = doc
995 .selection(view.id)
977 .selection(view.id)
996 .transform(|range| Range::new(range.head, range.anchor));
978 .transform(|range| Range::new(range.head, range.anchor));
@@ -1004,7 +986,7 @@ fn enter_insert_mode(doc: &mut Document) {
1004
986
1005// inserts at the start of each selection
987// inserts at the start of each selection
1006fn insert_mode(cx: &mut Context) {
988fn insert_mode(cx: &mut Context) {
1007− let (view, doc) = cx.current();
989+ let (view, doc) = current!(cx.editor);
1008 enter_insert_mode(doc);
990 enter_insert_mode(doc);
1009
991
1010 let selection = doc
992 let selection = doc
@@ -1015,7 +997,7 @@ fn insert_mode(cx: &mut Context) {
1015
997
1016// inserts at the end of each selection
998// inserts at the end of each selection
1017fn append_mode(cx: &mut Context) {
999fn append_mode(cx: &mut Context) {
1018− let (view, doc) = cx.current();
1000+ let (view, doc) = current!(cx.editor);
1019 enter_insert_mode(doc);
1001 enter_insert_mode(doc);
1020 doc.restore_cursor = true;
1002 doc.restore_cursor = true;
1021
1003
@@ -1062,11 +1044,11 @@ mod cmd {
1062 if editor.tree.views().count() == 1 && buffers_remaining_impl(editor) {
1044 if editor.tree.views().count() == 1 && buffers_remaining_impl(editor) {
1063 return;
1045 return;
1064 }
1046 }
1065− editor.close(editor.view().id, /* close_buffer */ false);
1047+ editor.close(view!(editor).id, /* close_buffer */ false);
1066 }
1048 }
1067
1049
1068 fn force_quit(editor: &mut Editor, args: &[&str], event: PromptEvent) {
1050 fn force_quit(editor: &mut Editor, args: &[&str], event: PromptEvent) {
1069− editor.close(editor.view().id, /* close_buffer */ false);
1051+ editor.close(view!(editor).id, /* close_buffer */ false);
1070 }
1052 }
1071
1053
1072 fn open(editor: &mut Editor, args: &[&str], event: PromptEvent) {
1054 fn open(editor: &mut Editor, args: &[&str], event: PromptEvent) {
@@ -1108,7 +1090,7 @@ mod cmd {
1108 }
1090 }
1109
1091
1110 fn write(editor: &mut Editor, args: &[&str], event: PromptEvent) {
1092 fn write(editor: &mut Editor, args: &[&str], event: PromptEvent) {
1111− let (view, doc) = editor.current();
1093+ let (view, doc) = current!(editor);
1112 if let Err(e) = write_impl(view, doc, args.first()) {
1094 if let Err(e) = write_impl(view, doc, args.first()) {
1113 editor.set_error(e.to_string());
1095 editor.set_error(e.to_string());
1114 };
1096 };
@@ -1119,7 +1101,7 @@ mod cmd {
1119 }
1101 }
1120
1102
1121 fn format(editor: &mut Editor, args: &[&str], event: PromptEvent) {
1103 fn format(editor: &mut Editor, args: &[&str], event: PromptEvent) {
1122− let (view, doc) = editor.current();
1104+ let (view, doc) = current!(editor);
1123
1105
1124 doc.format(view.id)
1106 doc.format(view.id)
1125 }
1107 }
@@ -1129,7 +1111,7 @@ mod cmd {
1129
1111
1130 // If no argument, report current indent style.
1112 // If no argument, report current indent style.
1131 if args.is_empty() {
1113 if args.is_empty() {
1132− let style = editor.current().1.indent_style;
1114+ let style = current!(editor).1.indent_style;
1133 editor.set_status(match style {
1115 editor.set_status(match style {
1134 Tabs => "tabs".into(),
1116 Tabs => "tabs".into(),
1135 Spaces(1) => "1 space".into(),
1117 Spaces(1) => "1 space".into(),
@@ -1152,7 +1134,7 @@ mod cmd {
1152 };
1134 };
1153
1135
1154 if let Some(s) = style {
1136 if let Some(s) = style {
1155− let (_, doc) = editor.current();
1137+ let doc = doc_mut!(editor);
1156 doc.indent_style = s;
1138 doc.indent_style = s;
1157 } else {
1139 } else {
1158 // Invalid argument.
1140 // Invalid argument.
@@ -1168,7 +1150,7 @@ mod cmd {
1168 return;
1150 return;
1169 }
1151 }
1170 };
1152 };
1171− let (view, doc) = editor.current();
1153+ let (view, doc) = current!(editor);
1172 doc.earlier(view.id, uk)
1154 doc.earlier(view.id, uk)
1173 }
1155 }
1174
1156
@@ -1180,12 +1162,12 @@ mod cmd {
1180 return;
1162 return;
1181 }
1163 }
1182 };
1164 };
1183− let (view, doc) = editor.current();
1165+ let (view, doc) = current!(editor);
1184 doc.later(view.id, uk)
1166 doc.later(view.id, uk)
1185 }
1167 }
1186
1168
1187 fn write_quit(editor: &mut Editor, args: &[&str], event: PromptEvent) {
1169 fn write_quit(editor: &mut Editor, args: &[&str], event: PromptEvent) {
1188− let (view, doc) = editor.current();
1170+ let (view, doc) = current!(editor);
1189 if let Err(e) = write_impl(view, doc, args.first()) {
1171 if let Err(e) = write_impl(view, doc, args.first()) {
1190 editor.set_error(e.to_string());
1172 editor.set_error(e.to_string());
1191 return;
1173 return;
@@ -1499,7 +1481,7 @@ fn file_picker(cx: &mut Context) {
1499
1481
1500fn buffer_picker(cx: &mut Context) {
1482fn buffer_picker(cx: &mut Context) {
1501 use std::path::{Path, PathBuf};
1483 use std::path::{Path, PathBuf};
1502− let current = cx.editor.view().doc;
1484+ let current = view!(cx.editor).doc;
1503
1485
1504 let picker = Picker::new(
1486 let picker = Picker::new(
1505 cx.editor
1487 cx.editor
@@ -1547,7 +1529,7 @@ fn symbol_picker(cx: &mut Context) {
1547 nested_to_flat(list, file, child);
1529 nested_to_flat(list, file, child);
1548 }
1530 }
1549 }
1531 }
1550− let (view, doc) = cx.current();
1532+ let (view, doc) = current!(cx.editor);
1551
1533
1552 let language_server = match doc.language_server() {
1534 let language_server = match doc.language_server() {
1553 Some(language_server) => language_server,
1535 Some(language_server) => language_server,
@@ -1568,7 +1550,7 @@ fn symbol_picker(cx: &mut Context) {
1568 let symbols = match symbols {
1550 let symbols = match symbols {
1569 lsp::DocumentSymbolResponse::Flat(symbols) => symbols,
1551 lsp::DocumentSymbolResponse::Flat(symbols) => symbols,
1570 lsp::DocumentSymbolResponse::Nested(symbols) => {
1552 lsp::DocumentSymbolResponse::Nested(symbols) => {
1571− let (_view, doc) = editor.current();
1553+ let (_view, doc) = current!(editor);
1572 let mut flat_symbols = Vec::new();
1554 let mut flat_symbols = Vec::new();
1573 for symbol in symbols {
1555 for symbol in symbols {
1574 nested_to_flat(&mut flat_symbols, &doc.identifier(), symbol)
1556 nested_to_flat(&mut flat_symbols, &doc.identifier(), symbol)
@@ -1582,7 +1564,7 @@ fn symbol_picker(cx: &mut Context) {
1582 |symbol| (&symbol.name).into(),
1564 |symbol| (&symbol.name).into(),
1583 move |editor: &mut Editor, symbol, _action| {
1565 move |editor: &mut Editor, symbol, _action| {
1584 push_jump(editor);
1566 push_jump(editor);
1585− let (view, doc) = editor.current();
1567+ let (view, doc) = current!(editor);
1586
1568
1587 if let Some(range) =
1569 if let Some(range) =
1588 lsp_range_to_range(doc.text(), symbol.location.range, offset_encoding)
1570 lsp_range_to_range(doc.text(), symbol.location.range, offset_encoding)
@@ -1601,13 +1583,13 @@ fn symbol_picker(cx: &mut Context) {
1601// I inserts at the first nonwhitespace character of each line with a selection
1583// I inserts at the first nonwhitespace character of each line with a selection
1602fn prepend_to_line(cx: &mut Context) {
1584fn prepend_to_line(cx: &mut Context) {
1603 move_first_nonwhitespace(cx);
1585 move_first_nonwhitespace(cx);
1604− let doc = cx.doc();
1586+ let doc = doc_mut!(cx.editor);
1605 enter_insert_mode(doc);
1587 enter_insert_mode(doc);
1606}
1588}
1607
1589
1608// A inserts at the end of each line with a selection
1590// A inserts at the end of each line with a selection
1609fn append_to_line(cx: &mut Context) {
1591fn append_to_line(cx: &mut Context) {
1610− let (view, doc) = cx.current();
1592+ let (view, doc) = current!(cx.editor);
1611 enter_insert_mode(doc);
1593 enter_insert_mode(doc);
1612
1594
1613 let selection = doc.selection(view.id).transform(|range| {
1595 let selection = doc.selection(view.id).transform(|range| {
@@ -1627,7 +1609,7 @@ enum Open {
1627
1609
1628fn open(cx: &mut Context, open: Open) {
1610fn open(cx: &mut Context, open: Open) {
1629 let count = cx.count();
1611 let count = cx.count();
1630− let (view, doc) = cx.current();
1612+ let (view, doc) = current!(cx.editor);
1631 enter_insert_mode(doc);
1613 enter_insert_mode(doc);
1632
1614
1633 let text = doc.text().slice(..);
1615 let text = doc.text().slice(..);
@@ -1695,7 +1677,7 @@ fn open_above(cx: &mut Context) {
1695}
1677}
1696
1678
1697fn normal_mode(cx: &mut Context) {
1679fn normal_mode(cx: &mut Context) {
1698− let (view, doc) = cx.current();
1680+ let (view, doc) = current!(cx.editor);
1699
1681
1700 doc.mode = Mode::Normal;
1682 doc.mode = Mode::Normal;
1701
1683
@@ -1718,13 +1700,13 @@ fn normal_mode(cx: &mut Context) {
1718
1700
1719// Store a jump on the jumplist.
1701// Store a jump on the jumplist.
1720fn push_jump(editor: &mut Editor) {
1702fn push_jump(editor: &mut Editor) {
1721− let (view, doc) = editor.current();
1703+ let (view, doc) = current!(editor);
1722 let jump = (doc.id(), doc.selection(view.id).clone());
1704 let jump = (doc.id(), doc.selection(view.id).clone());
1723 view.jumps.push(jump);
1705 view.jumps.push(jump);
1724}
1706}
1725
1707
1726fn switch_to_last_accessed_file(cx: &mut Context) {
1708fn switch_to_last_accessed_file(cx: &mut Context) {
1727− let alternate_file = cx.view().last_accessed_doc;
1709+ let alternate_file = view!(cx.editor).last_accessed_doc;
1728 if let Some(alt) = alternate_file {
1710 if let Some(alt) = alternate_file {
1729 cx.editor.switch(alt, Action::Replace);
1711 cx.editor.switch(alt, Action::Replace);
1730 } else {
1712 } else {
@@ -1736,7 +1718,7 @@ fn goto_mode(cx: &mut Context) {
1736 if let Some(count) = cx.count {
1718 if let Some(count) = cx.count {
1737 push_jump(cx.editor);
1719 push_jump(cx.editor);
1738
1720
1739− let (view, doc) = cx.current();
1721+ let (view, doc) = current!(cx.editor);
1740 let line_idx = std::cmp::min(count.get() - 1, doc.text().len_lines().saturating_sub(2));
1722 let line_idx = std::cmp::min(count.get() - 1, doc.text().len_lines().saturating_sub(2));
1741 let pos = doc.text().line_to_char(line_idx);
1723 let pos = doc.text().line_to_char(line_idx);
1742 doc.set_selection(view.id, Selection::point(pos));
1724 doc.set_selection(view.id, Selection::point(pos));
@@ -1750,7 +1732,8 @@ fn goto_mode(cx: &mut Context) {
1750 } = event
1732 } = event
1751 {
1733 {
1752 // TODO: temporarily show GOTO in the mode list
1734 // TODO: temporarily show GOTO in the mode list
1735+ let doc = doc_mut!(cx.editor);
1753− match (cx.doc().mode, ch) {
1736+ match (doc.mode, ch) {
1754 (_, 'g') => move_file_start(cx),
1737 (_, 'g') => move_file_start(cx),
1755 (_, 'e') => move_file_end(cx),
1738 (_, 'e') => move_file_end(cx),
1756 (_, 'a') => switch_to_last_accessed_file(cx),
1739 (_, 'a') => switch_to_last_accessed_file(cx),
@@ -1766,7 +1749,7 @@ fn goto_mode(cx: &mut Context) {
1766 (Mode::Select, 's') => extend_first_nonwhitespace(cx),
1749 (Mode::Select, 's') => extend_first_nonwhitespace(cx),
1767
1750
1768 (_, 't') | (_, 'm') | (_, 'b') => {
1751 (_, 't') | (_, 'm') | (_, 'b') => {
1769− let (view, doc) = cx.current();
1752+ let (view, doc) = current!(cx.editor);
1770
1753
1771 let pos = doc.selection(view.id).cursor();
1754 let pos = doc.selection(view.id).cursor();
1772 let line = doc.text().char_to_line(pos);
1755 let line = doc.text().char_to_line(pos);
@@ -1794,11 +1777,11 @@ fn goto_mode(cx: &mut Context) {
1794}
1777}
1795
1778
1796fn select_mode(cx: &mut Context) {
1779fn select_mode(cx: &mut Context) {
1797− cx.doc().mode = Mode::Select;
1780+ doc_mut!(cx.editor).mode = Mode::Select;
1798}
1781}
1799
1782
1800fn exit_select_mode(cx: &mut Context) {
1783fn exit_select_mode(cx: &mut Context) {
1801− cx.doc().mode = Mode::Normal;
1784+ doc_mut!(cx.editor).mode = Mode::Normal;
1802}
1785}
1803
1786
1804fn goto_impl(
1787fn goto_impl(
@@ -1820,7 +1803,7 @@ fn goto_impl(
1820 let id = editor
1803 let id = editor
1821 .open(PathBuf::from(location.uri.path()), action)
1804 .open(PathBuf::from(location.uri.path()), action)
1822 .expect("editor.open failed");
1805 .expect("editor.open failed");
1823− let (view, doc) = editor.current();
1806+ let (view, doc) = current!(editor);
1824 let definition_pos = location.range.start;
1807 let definition_pos = location.range.start;
1825 // TODO: convert inside server
1808 // TODO: convert inside server
1826 let new_pos =
1809 let new_pos =
@@ -1858,7 +1841,7 @@ fn goto_impl(
1858}
1841}
1859
1842
1860fn goto_definition(cx: &mut Context) {
1843fn goto_definition(cx: &mut Context) {
1861− let (view, doc) = cx.current();
1844+ let (view, doc) = current!(cx.editor);
1862 let language_server = match doc.language_server() {
1845 let language_server = match doc.language_server() {
1863 Some(language_server) => language_server,
1846 Some(language_server) => language_server,
1864 None => return,
1847 None => return,
@@ -1895,7 +1878,7 @@ fn goto_definition(cx: &mut Context) {
1895}
1878}
1896
1879
1897fn goto_type_definition(cx: &mut Context) {
1880fn goto_type_definition(cx: &mut Context) {
1898− let (view, doc) = cx.current();
1881+ let (view, doc) = current!(cx.editor);
1899 let language_server = match doc.language_server() {
1882 let language_server = match doc.language_server() {
1900 Some(language_server) => language_server,
1883 Some(language_server) => language_server,
1901 None => return,
1884 None => return,
@@ -1932,7 +1915,7 @@ fn goto_type_definition(cx: &mut Context) {
1932}
1915}
1933
1916
1934fn goto_implementation(cx: &mut Context) {
1917fn goto_implementation(cx: &mut Context) {
1935− let (view, doc) = cx.current();
1918+ let (view, doc) = current!(cx.editor);
1936 let language_server = match doc.language_server() {
1919 let language_server = match doc.language_server() {
1937 Some(language_server) => language_server,
1920 Some(language_server) => language_server,
1938 None => return,
1921 None => return,
@@ -1969,7 +1952,7 @@ fn goto_implementation(cx: &mut Context) {
1969}
1952}
1970
1953
1971fn goto_reference(cx: &mut Context) {
1954fn goto_reference(cx: &mut Context) {
1972− let (view, doc) = cx.current();
1955+ let (view, doc) = current!(cx.editor);
1973 let language_server = match doc.language_server() {
1956 let language_server = match doc.language_server() {
1974 Some(language_server) => language_server,
1957 Some(language_server) => language_server,
1975 None => return,
1958 None => return,
@@ -2000,7 +1983,7 @@ fn goto_reference(cx: &mut Context) {
2000fn goto_pos(editor: &mut Editor, pos: usize) {
1983fn goto_pos(editor: &mut Editor, pos: usize) {
2001 push_jump(editor);
1984 push_jump(editor);
2002
1985
2003− let (view, doc) = editor.current();
1986+ let (view, doc) = current!(editor);
2004
1987
2005 doc.set_selection(view.id, Selection::point(pos));
1988 doc.set_selection(view.id, Selection::point(pos));
2006 align_view(doc, view, Align::Center);
1989 align_view(doc, view, Align::Center);
@@ -2008,7 +1991,7 @@ fn goto_pos(editor: &mut Editor, pos: usize) {
2008
1991
2009fn goto_first_diag(cx: &mut Context) {
1992fn goto_first_diag(cx: &mut Context) {
2010 let editor = &mut cx.editor;
1993 let editor = &mut cx.editor;
2011− let (view, doc) = editor.current();
1994+ let (view, doc) = current!(editor);
2012
1995
2013 let cursor_pos = doc.selection(view.id).cursor();
1996 let cursor_pos = doc.selection(view.id).cursor();
2014 let diag = if let Some(diag) = doc.diagnostics().first() {
1997 let diag = if let Some(diag) = doc.diagnostics().first() {
@@ -2022,7 +2005,7 @@ fn goto_first_diag(cx: &mut Context) {
2022
2005
2023fn goto_last_diag(cx: &mut Context) {
2006fn goto_last_diag(cx: &mut Context) {
2024 let editor = &mut cx.editor;
2007 let editor = &mut cx.editor;
2025− let (view, doc) = editor.current();
2008+ let (view, doc) = current!(editor);
2026
2009
2027 let cursor_pos = doc.selection(view.id).cursor();
2010 let cursor_pos = doc.selection(view.id).cursor();
2028 let diag = if let Some(diag) = doc.diagnostics().last() {
2011 let diag = if let Some(diag) = doc.diagnostics().last() {
@@ -2036,7 +2019,7 @@ fn goto_last_diag(cx: &mut Context) {
2036
2019
2037fn goto_next_diag(cx: &mut Context) {
2020fn goto_next_diag(cx: &mut Context) {
2038 let editor = &mut cx.editor;
2021 let editor = &mut cx.editor;
2039− let (view, doc) = editor.current();
2022+ let (view, doc) = current!(editor);
2040
2023
2041 let cursor_pos = doc.selection(view.id).cursor();
2024 let cursor_pos = doc.selection(view.id).cursor();
2042 let diag = if let Some(diag) = doc
2025 let diag = if let Some(diag) = doc
@@ -2057,7 +2040,7 @@ fn goto_next_diag(cx: &mut Context) {
2057
2040
2058fn goto_prev_diag(cx: &mut Context) {
2041fn goto_prev_diag(cx: &mut Context) {
2059 let editor = &mut cx.editor;
2042 let editor = &mut cx.editor;
2060− let (view, doc) = editor.current();
2043+ let (view, doc) = current!(editor);
2061
2044
2062 let cursor_pos = doc.selection(view.id).cursor();
2045 let cursor_pos = doc.selection(view.id).cursor();
2063 let diag = if let Some(diag) = doc
2046 let diag = if let Some(diag) = doc
@@ -2078,7 +2061,7 @@ fn goto_prev_diag(cx: &mut Context) {
2078}
2061}
2079
2062
2080fn signature_help(cx: &mut Context) {
2063fn signature_help(cx: &mut Context) {
2081− let (view, doc) = cx.current();
2064+ let (view, doc) = current!(cx.editor);
2082
2065
2083 let language_server = match doc.language_server() {
2066 let language_server = match doc.language_server() {
2084 Some(language_server) => language_server,
2067 Some(language_server) => language_server,
@@ -2124,7 +2107,7 @@ pub mod insert {
2124
2107
2125 fn completion(cx: &mut Context, ch: char) {
2108 fn completion(cx: &mut Context, ch: char) {
2126 // if ch matches completion char, trigger completion
2109 // if ch matches completion char, trigger completion
2127− let doc = cx.doc();
2110+ let doc = doc_mut!(cx.editor);
2128 let language_server = match doc.language_server() {
2111 let language_server = match doc.language_server() {
2129 Some(language_server) => language_server,
2112 Some(language_server) => language_server,
2130 None => return,
2113 None => return,
@@ -2152,7 +2135,7 @@ pub mod insert {
2152
2135
2153 fn signature_help(cx: &mut Context, ch: char) {
2136 fn signature_help(cx: &mut Context, ch: char) {
2154 // if ch matches signature_help char, trigger
2137 // if ch matches signature_help char, trigger
2155− let doc = cx.doc();
2138+ let doc = doc_mut!(cx.editor);
2156 let language_server = match doc.language_server() {
2139 let language_server = match doc.language_server() {
2157 Some(language_server) => language_server,
2140 Some(language_server) => language_server,
2158 None => return,
2141 None => return,
@@ -2207,7 +2190,7 @@ pub mod insert {
2207 const POST_HOOKS: &[PostHook] = &[completion, signature_help];
2190 const POST_HOOKS: &[PostHook] = &[completion, signature_help];
2208
2191
2209 pub fn insert_char(cx: &mut Context, c: char) {
2192 pub fn insert_char(cx: &mut Context, c: char) {
2210− let (view, doc) = cx.current();
2193+ let (view, doc) = current!(cx.editor);
2211
2194
2212 let text = doc.text();
2195 let text = doc.text();
2213 let selection = doc.selection(view.id);
2196 let selection = doc.selection(view.id);
@@ -2229,7 +2212,7 @@ pub mod insert {
2229 }
2212 }
2230
2213
2231 pub fn insert_tab(cx: &mut Context) {
2214 pub fn insert_tab(cx: &mut Context) {
2232− let (view, doc) = cx.current();
2215+ let (view, doc) = current!(cx.editor);
2233 // TODO: round out to nearest indentation level (for example a line with 3 spaces should
2216 // TODO: round out to nearest indentation level (for example a line with 3 spaces should
2234 // indent by one to reach 4 spaces).
2217 // indent by one to reach 4 spaces).
2235
2218
@@ -2239,7 +2222,7 @@ pub mod insert {
2239 }
2222 }
2240
2223
2241 pub fn insert_newline(cx: &mut Context) {
2224 pub fn insert_newline(cx: &mut Context) {
2242− let (view, doc) = cx.current();
2225+ let (view, doc) = current!(cx.editor);
2243 let text = doc.text().slice(..);
2226 let text = doc.text().slice(..);
2244
2227
2245 let contents = doc.text();
2228 let contents = doc.text();
@@ -2308,7 +2291,7 @@ pub mod insert {
2308 // TODO: handle indent-aware delete
2291 // TODO: handle indent-aware delete
2309 pub fn delete_char_backward(cx: &mut Context) {
2292 pub fn delete_char_backward(cx: &mut Context) {
2310 let count = cx.count();
2293 let count = cx.count();
2311− let (view, doc) = cx.current();
2294+ let (view, doc) = current!(cx.editor);
2312 let text = doc.text().slice(..);
2295 let text = doc.text().slice(..);
2313 let transaction =
2296 let transaction =
2314 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
2297 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
@@ -2323,7 +2306,7 @@ pub mod insert {
2323
2306
2324 pub fn delete_char_forward(cx: &mut Context) {
2307 pub fn delete_char_forward(cx: &mut Context) {
2325 let count = cx.count();
2308 let count = cx.count();
2326− let (view, doc) = cx.current();
2309+ let (view, doc) = current!(cx.editor);
2327 let text = doc.text().slice(..);
2310 let text = doc.text().slice(..);
2328 let transaction =
2311 let transaction =
2329 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
2312 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
@@ -2338,7 +2321,7 @@ pub mod insert {
2338
2321
2339 pub fn delete_word_backward(cx: &mut Context) {
2322 pub fn delete_word_backward(cx: &mut Context) {
2340 let count = cx.count();
2323 let count = cx.count();
2341− let (view, doc) = cx.current();
2324+ let (view, doc) = current!(cx.editor);
2342 let text = doc.text().slice(..);
2325 let text = doc.text().slice(..);
2343 let selection = doc
2326 let selection = doc
2344 .selection(view.id)
2327 .selection(view.id)
@@ -2354,20 +2337,22 @@ pub mod insert {
2354// storing it?
2337// storing it?
2355
2338
2356fn undo(cx: &mut Context) {
2339fn undo(cx: &mut Context) {
2357− let view_id = cx.view().id;
2340+ let (view, doc) = current!(cx.editor);
2341+ let view_id = view.id;
2358− cx.doc().undo(view_id);
2342+ doc.undo(view_id);
2359}
2343}
2360
2344
2361fn redo(cx: &mut Context) {
2345fn redo(cx: &mut Context) {
2362− let view_id = cx.view().id;
2346+ let (view, doc) = current!(cx.editor);
2347+ let view_id = view.id;
2363− cx.doc().redo(view_id);
2348+ doc.redo(view_id);
2364}
2349}
2365
2350
2366// Yank / Paste
2351// Yank / Paste
2367
2352
2368fn yank(cx: &mut Context) {
2353fn yank(cx: &mut Context) {
2369 // TODO: should selections be made end inclusive?
2354 // TODO: should selections be made end inclusive?
2370− let (view, doc) = cx.current();
2355+ let (view, doc) = current!(cx.editor);
2371 let values: Vec<String> = doc
2356 let values: Vec<String> = doc
2372 .selection(view.id)
2357 .selection(view.id)
2373 .fragments(doc.text().slice(..))
2358 .fragments(doc.text().slice(..))
@@ -2432,7 +2417,8 @@ fn paste_impl(
2432
2417
2433fn replace_with_yanked(cx: &mut Context) {
2418fn replace_with_yanked(cx: &mut Context) {
2434 let reg_name = cx.selected_register.name();
2419 let reg_name = cx.selected_register.name();
2435− let (view, doc, registers) = cx.current_with_registers();
2420+ let (view, doc) = current!(cx.editor);
2421+ let registers = &mut cx.editor.registers;
2436
2422
2437 if let Some(values) = registers.read(reg_name) {
2423 if let Some(values) = registers.read(reg_name) {
2438 if let Some(yank) = values.first() {
2424 if let Some(yank) = values.first() {
@@ -2461,7 +2447,8 @@ fn replace_with_yanked(cx: &mut Context) {
2461
2447
2462fn paste_after(cx: &mut Context) {
2448fn paste_after(cx: &mut Context) {
2463 let reg_name = cx.selected_register.name();
2449 let reg_name = cx.selected_register.name();
2464− let (view, doc, registers) = cx.current_with_registers();
2450+ let (view, doc) = current!(cx.editor);
2451+ let registers = &mut cx.editor.registers;
2465
2452
2466 if let Some(transaction) = registers
2453 if let Some(transaction) = registers
2467 .read(reg_name)
2454 .read(reg_name)
@@ -2474,7 +2461,8 @@ fn paste_after(cx: &mut Context) {
2474
2461
2475fn paste_before(cx: &mut Context) {
2462fn paste_before(cx: &mut Context) {
2476 let reg_name = cx.selected_register.name();
2463 let reg_name = cx.selected_register.name();
2477− let (view, doc, registers) = cx.current_with_registers();
2464+ let (view, doc) = current!(cx.editor);
2465+ let registers = &mut cx.editor.registers;
2478
2466
2479 if let Some(transaction) = registers
2467 if let Some(transaction) = registers
2480 .read(reg_name)
2468 .read(reg_name)
@@ -2504,7 +2492,7 @@ fn get_lines(doc: &Document, view_id: ViewId) -> Vec<usize> {
2504
2492
2505fn indent(cx: &mut Context) {
2493fn indent(cx: &mut Context) {
2506 let count = cx.count();
2494 let count = cx.count();
2507− let (view, doc) = cx.current();
2495+ let (view, doc) = current!(cx.editor);
2508 let lines = get_lines(doc, view.id);
2496 let lines = get_lines(doc, view.id);
2509
2497
2510 // Indent by one level
2498 // Indent by one level
@@ -2523,7 +2511,7 @@ fn indent(cx: &mut Context) {
2523
2511
2524fn unindent(cx: &mut Context) {
2512fn unindent(cx: &mut Context) {
2525 let count = cx.count();
2513 let count = cx.count();
2526− let (view, doc) = cx.current();
2514+ let (view, doc) = current!(cx.editor);
2527 let lines = get_lines(doc, view.id);
2515 let lines = get_lines(doc, view.id);
2528 let mut changes = Vec::with_capacity(lines.len());
2516 let mut changes = Vec::with_capacity(lines.len());
2529 let tab_width = doc.tab_width();
2517 let tab_width = doc.tab_width();
@@ -2562,7 +2550,7 @@ fn unindent(cx: &mut Context) {
2562}
2550}
2563
2551
2564fn format_selections(cx: &mut Context) {
2552fn format_selections(cx: &mut Context) {
2565− let (view, doc) = cx.current();
2553+ let (view, doc) = current!(cx.editor);
2566
2554
2567 // via lsp if available
2555 // via lsp if available
2568 // else via tree-sitter indentation calculations
2556 // else via tree-sitter indentation calculations
@@ -2609,7 +2597,7 @@ fn format_selections(cx: &mut Context) {
2609
2597
2610fn join_selections(cx: &mut Context) {
2598fn join_selections(cx: &mut Context) {
2611 use movement::skip_while;
2599 use movement::skip_while;
2612− let (view, doc) = cx.current();
2600+ let (view, doc) = current!(cx.editor);
2613 let text = doc.text();
2601 let text = doc.text();
2614 let slice = doc.text().slice(..);
2602 let slice = doc.text().slice(..);
2615
2603
@@ -2665,7 +2653,7 @@ fn keep_selections(cx: &mut Context) {
2665}
2653}
2666
2654
2667fn keep_primary_selection(cx: &mut Context) {
2655fn keep_primary_selection(cx: &mut Context) {
2668− let (view, doc) = cx.current();
2656+ let (view, doc) = current!(cx.editor);
2669
2657
2670 let range = doc.selection(view.id).primary();
2658 let range = doc.selection(view.id).primary();
2671 let selection = Selection::single(range.anchor, range.head);
2659 let selection = Selection::single(range.anchor, range.head);
@@ -2678,7 +2666,7 @@ fn save(cx: &mut Context) {
2678 // Spawns an async task to actually do the saving. This way we prevent blocking.
2666 // Spawns an async task to actually do the saving. This way we prevent blocking.
2679
2667
2680 // TODO: handle save errors somehow?
2668 // TODO: handle save errors somehow?
2681− tokio::spawn(cx.doc().save());
2669+ tokio::spawn(doc_mut!(cx.editor).save());
2682}
2670}
2683
2671
2684fn completion(cx: &mut Context) {
2672fn completion(cx: &mut Context) {
@@ -2718,7 +2706,7 @@ fn completion(cx: &mut Context) {
2718 // The prefix still has to satisfy `company-minimum-prefix-length' before that
2706 // The prefix still has to satisfy `company-minimum-prefix-length' before that
2719 // happens. The value of nil means no idle completion."
2707 // happens. The value of nil means no idle completion."
2720
2708
2721− let (view, doc) = cx.current();
2709+ let (view, doc) = current!(cx.editor);
2722
2710
2723 let language_server = match doc.language_server() {
2711 let language_server = match doc.language_server() {
2724 Some(language_server) => language_server,
2712 Some(language_server) => language_server,
@@ -2772,7 +2760,7 @@ fn completion(cx: &mut Context) {
2772}
2760}
2773
2761
2774fn hover(cx: &mut Context) {
2762fn hover(cx: &mut Context) {
2775− let (view, doc) = cx.current();
2763+ let (view, doc) = current!(cx.editor);
2776
2764
2777 let language_server = match doc.language_server() {
2765 let language_server = match doc.language_server() {
2778 Some(language_server) => language_server,
2766 Some(language_server) => language_server,
@@ -2822,7 +2810,7 @@ fn hover(cx: &mut Context) {
2822
2810
2823// comments
2811// comments
2824fn toggle_comments(cx: &mut Context) {
2812fn toggle_comments(cx: &mut Context) {
2825− let (view, doc) = cx.current();
2813+ let (view, doc) = current!(cx.editor);
2826 let transaction = comment::toggle_line_comments(doc.text(), doc.selection(view.id));
2814 let transaction = comment::toggle_line_comments(doc.text(), doc.selection(view.id));
2827
2815
2828 doc.apply(&transaction, view.id);
2816 doc.apply(&transaction, view.id);
@@ -2832,7 +2820,7 @@ fn toggle_comments(cx: &mut Context) {
2832// tree sitter node selection
2820// tree sitter node selection
2833
2821
2834fn expand_selection(cx: &mut Context) {
2822fn expand_selection(cx: &mut Context) {
2835− let (view, doc) = cx.current();
2823+ let (view, doc) = current!(cx.editor);
2836
2824
2837 if let Some(syntax) = doc.syntax() {
2825 if let Some(syntax) = doc.syntax() {
2838 let text = doc.text().slice(..);
2826 let text = doc.text().slice(..);
@@ -2842,7 +2830,7 @@ fn expand_selection(cx: &mut Context) {
2842}
2830}
2843
2831
2844fn match_brackets(cx: &mut Context) {
2832fn match_brackets(cx: &mut Context) {
2845− let (view, doc) = cx.current();
2833+ let (view, doc) = current!(cx.editor);
2846
2834
2847 if let Some(syntax) = doc.syntax() {
2835 if let Some(syntax) = doc.syntax() {
2848 let pos = doc.selection(view.id).cursor();
2836 let pos = doc.selection(view.id).cursor();
@@ -2857,12 +2845,12 @@ fn match_brackets(cx: &mut Context) {
2857
2845
2858fn jump_forward(cx: &mut Context) {
2846fn jump_forward(cx: &mut Context) {
2859 let count = cx.count();
2847 let count = cx.count();
2860− let (view, doc) = cx.current();
2848+ let (view, doc) = current!(cx.editor);
2861
2849
2862 if let Some((id, selection)) = view.jumps.forward(count) {
2850 if let Some((id, selection)) = view.jumps.forward(count) {
2863 view.doc = *id;
2851 view.doc = *id;
2864 let selection = selection.clone();
2852 let selection = selection.clone();
2865− let (view, doc) = cx.current(); // refetch doc
2853+ let (view, doc) = current!(cx.editor); // refetch doc
2866 doc.set_selection(view.id, selection);
2854 doc.set_selection(view.id, selection);
2867
2855
2868 align_view(doc, view, Align::Center);
2856 align_view(doc, view, Align::Center);
@@ -2871,7 +2859,7 @@ fn jump_forward(cx: &mut Context) {
2871
2859
2872fn jump_backward(cx: &mut Context) {
2860fn jump_backward(cx: &mut Context) {
2873 let count = cx.count();
2861 let count = cx.count();
2874− let (view, doc) = cx.current();
2862+ let (view, doc) = current!(cx.editor);
2875
2863
2876 if let Some((id, selection)) = view.jumps.backward(view.id, doc, count) {
2864 if let Some((id, selection)) = view.jumps.backward(view.id, doc, count) {
2877 // manually set the alternate_file as we cannot use the Editor::switch function here.
2865 // manually set the alternate_file as we cannot use the Editor::switch function here.
@@ -2880,7 +2868,7 @@ fn jump_backward(cx: &mut Context) {
2880 }
2868 }
2881 view.doc = *id;
2869 view.doc = *id;
2882 let selection = selection.clone();
2870 let selection = selection.clone();
2883− let (view, doc) = cx.current(); // refetch doc
2871+ let (view, doc) = current!(cx.editor); // refetch doc
2884 doc.set_selection(view.id, selection);
2872 doc.set_selection(view.id, selection);
2885
2873
2886 align_view(doc, view, Align::Center);
2874 align_view(doc, view, Align::Center);
@@ -2915,7 +2903,7 @@ use helix_view::editor::Action;
2915use self::cmd::TypableCommand;
2903use self::cmd::TypableCommand;
2916fn split(cx: &mut Context, action: Action) {
2904fn split(cx: &mut Context, action: Action) {
2917 use helix_view::editor::Action;
2905 use helix_view::editor::Action;
2918− let (view, doc) = cx.current();
2906+ let (view, doc) = current!(cx.editor);
2919 let id = doc.id();
2907 let id = doc.id();
2920 let selection = doc.selection(view.id).clone();
2908 let selection = doc.selection(view.id).clone();
2921 let first_line = view.first_line;
2909 let first_line = view.first_line;
@@ -2923,7 +2911,7 @@ fn split(cx: &mut Context, action: Action) {
2923 cx.editor.switch(id, action);
2911 cx.editor.switch(id, action);
2924
2912
2925 // match the selection in the previous view
2913 // match the selection in the previous view
2926− let (view, doc) = cx.current();
2914+ let (view, doc) = current!(cx.editor);
2927 view.first_line = first_line;
2915 view.first_line = first_line;
2928 doc.set_selection(view.id, selection);
2916 doc.set_selection(view.id, selection);
2929}
2917}
@@ -2937,7 +2925,7 @@ fn vsplit(cx: &mut Context) {
2937}
2925}
2938
2926
2939fn wclose(cx: &mut Context) {
2927fn wclose(cx: &mut Context) {
2940− let view_id = cx.view().id;
2928+ let view_id = view!(cx.editor).id;
2941 // close current split
2929 // close current split
2942 cx.editor.close(view_id, /* close_buffer */ false);
2930 cx.editor.close(view_id, /* close_buffer */ false);
2943}
2931}
@@ -2992,7 +2980,7 @@ fn view_mode(cx: &mut Context) {
2992 | 't'
2980 | 't'
2993 // bottom
2981 // bottom
2994 | 'b' => {
2982 | 'b' => {
2995− let (view, doc) = cx.current();
2983+ let (view, doc) = current!(cx.editor);
2996
2984
2997 align_view(doc, view, match ch {
2985 align_view(doc, view, match ch {
2998 'z' | 'c' => Align::Center,
2986 'z' | 'c' => Align::Center,
@@ -3002,7 +2990,7 @@ fn view_mode(cx: &mut Context) {
3002 });
2990 });
3003 }
2991 }
3004 'm' => {
2992 'm' => {
3005− let (view, doc) = cx.current();
2993+ let (view, doc) = current!(cx.editor);
3006 let pos = doc.selection(view.id).cursor();
2994 let pos = doc.selection(view.id).cursor();
3007 let pos = coords_at_pos(doc.text().slice(..), pos);
2995 let pos = coords_at_pos(doc.text().slice(..), pos);
3008
2996
helix-term/src/lib.rs+3
@@ -1,5 +1,8 @@
1#![allow(unused)]
1#![allow(unused)]
2
2
3+#[macro_use]
4+extern crate helix_view;
5+
3pub mod application;
6pub mod application;
4pub mod args;
7pub mod args;
5pub mod commands;
8pub mod commands;
helix-term/src/ui/completion.rs+3−3
@@ -89,7 +89,7 @@ impl Completion {
89 // doc.state = snapshot.clone();
89 // doc.state = snapshot.clone();
90 }
90 }
91 PromptEvent::Validate => {
91 PromptEvent::Validate => {
92− let (view, doc) = editor.current();
92+ let (view, doc) = current!(editor);
93
93
94 // revert state to what it was before the last update
94 // revert state to what it was before the last update
95 // doc.state = snapshot.clone();
95 // doc.state = snapshot.clone();
@@ -169,7 +169,7 @@ impl Completion {
169 pub fn update(&mut self, cx: &mut commands::Context) {
169 pub fn update(&mut self, cx: &mut commands::Context) {
170 // recompute menu based on matches
170 // recompute menu based on matches
171 let menu = self.popup.contents_mut();
171 let menu = self.popup.contents_mut();
172− let (view, doc) = cx.editor.current();
172+ let (view, doc) = current!(cx.editor);
173
173
174 // cx.hooks()
174 // cx.hooks()
175 // cx.add_hook(enum type, ||)
175 // cx.add_hook(enum type, ||)
@@ -233,7 +233,7 @@ impl Component for Completion {
233 // ---
233 // ---
234 // option.documentation
234 // option.documentation
235
235
236− let (view, doc) = cx.editor.current();
236+ let (view, doc) = current!(cx.editor);
237 let language = doc
237 let language = doc
238 .language()
238 .language()
239 .and_then(|scope| scope.strip_prefix("source."))
239 .and_then(|scope| scope.strip_prefix("source."))
helix-term/src/ui/editor.rs+2−2
@@ -615,7 +615,7 @@ impl Component for EditorView {
615 // clear status
615 // clear status
616 cx.editor.status_msg = None;
616 cx.editor.status_msg = None;
617
617
618− let (view, doc) = cx.editor.current();
618+ let (view, doc) = current!(cx.editor);
619 let mode = doc.mode();
619 let mode = doc.mode();
620
620
621 let mut cxt = commands::Context {
621 let mut cxt = commands::Context {
@@ -684,7 +684,7 @@ impl Component for EditorView {
684 return EventResult::Ignored;
684 return EventResult::Ignored;
685 }
685 }
686
686
687− let (view, doc) = cx.editor.current();
687+ let (view, doc) = current!(cx.editor);
688 view.ensure_cursor_in_view(doc);
688 view.ensure_cursor_in_view(doc);
689
689
690 // mode transitions
690 // mode transitions
helix-term/src/ui/mod.rs+6−4
@@ -30,8 +30,9 @@ pub fn regex_prompt(
30 prompt: String,
30 prompt: String,
31 fun: impl Fn(&mut View, &mut Document, &mut Registers, Regex) + 'static,
31 fun: impl Fn(&mut View, &mut Document, &mut Registers, Regex) + 'static,
32) -> Prompt {
32) -> Prompt {
33− let view_id = cx.view().id;
33+ let (view, doc) = current!(cx.editor);
34+ let view_id = view.id;
34− let snapshot = cx.doc().selection(view_id).clone();
35+ let snapshot = doc.selection(view_id).clone();
35
36
36 Prompt::new(
37 Prompt::new(
37 prompt,
38 prompt,
@@ -40,7 +41,7 @@ pub fn regex_prompt(
40 match event {
41 match event {
41 PromptEvent::Abort => {
42 PromptEvent::Abort => {
42 // TODO: also revert text
43 // TODO: also revert text
43− let (view, doc) = editor.current();
44+ let (view, doc) = current!(editor);
44 doc.set_selection(view.id, snapshot.clone());
45 doc.set_selection(view.id, snapshot.clone());
45 }
46 }
46 PromptEvent::Validate => {
47 PromptEvent::Validate => {
@@ -54,7 +55,8 @@ pub fn regex_prompt(
54
55
55 match Regex::new(input) {
56 match Regex::new(input) {
56 Ok(regex) => {
57 Ok(regex) => {
57− let (view, doc, registers) = editor.current_with_registers();
58+ let (view, doc) = current!(editor);
59+ let registers = &mut editor.registers;
58
60
59 // revert state to what it was before the last update
61 // revert state to what it was before the last update
60 // TODO: also revert text
62 // TODO: also revert text
helix-view/src/editor.rs+4−25
@@ -101,19 +101,19 @@ impl Editor {
101
101
102 match action {
102 match action {
103 Action::Replace => {
103 Action::Replace => {
104− let view = self.view();
104+ let view = view!(self);
105 let jump = (
105 let jump = (
106 view.doc,
106 view.doc,
107 self.documents[view.doc].selection(view.id).clone(),
107 self.documents[view.doc].selection(view.id).clone(),
108 );
108 );
109
109
110− let view = self.view_mut();
110+ let view = view_mut!(self);
111 view.jumps.push(jump);
111 view.jumps.push(jump);
112 view.last_accessed_doc = Some(view.doc);
112 view.last_accessed_doc = Some(view.doc);
113 view.doc = id;
113 view.doc = id;
114 view.first_line = 0;
114 view.first_line = 0;
115
115
116− let (view, doc) = self.current();
116+ let (view, doc) = current!(self);
117
117
118 // initialize selection for view
118 // initialize selection for view
119 let selection = doc
119 let selection = doc
@@ -238,27 +238,6 @@ impl Editor {
238 self.tree.is_empty()
238 self.tree.is_empty()
239 }
239 }
240
240
241− pub fn current(&mut self) -> (&mut View, &mut Document) {
242− let view = self.tree.get_mut(self.tree.focus);
243− let doc = &mut self.documents[view.doc];
244− (view, doc)
245− }
246−
247− pub fn current_with_registers(&mut self) -> (&mut View, &mut Document, &mut Registers) {
248− let view = self.tree.get_mut(self.tree.focus);
249− let doc = &mut self.documents[view.doc];
250− let registers = &mut self.registers;
251− (view, doc, registers)
252− }
253−
254− pub fn view(&self) -> &View {
255− self.tree.get(self.tree.focus)
256− }
257−
258− pub fn view_mut(&mut self) -> &mut View {
259− self.tree.get_mut(self.tree.focus)
260− }
261−
262 pub fn ensure_cursor_in_view(&mut self, id: ViewId) {
241 pub fn ensure_cursor_in_view(&mut self, id: ViewId) {
263 let view = self.tree.get_mut(id);
242 let view = self.tree.get_mut(id);
264 let doc = &self.documents[view.doc];
243 let doc = &self.documents[view.doc];
@@ -280,7 +259,7 @@ impl Editor {
280
259
281 pub fn cursor(&self) -> (Option<Position>, CursorKind) {
260 pub fn cursor(&self) -> (Option<Position>, CursorKind) {
282 const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
261 const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
283− let view = self.view();
262+ let view = view!(self);
284 let doc = &self.documents[view.doc];
263 let doc = &self.documents[view.doc];
285 let cursor = doc.selection(view.id).cursor();
264 let cursor = doc.selection(view.id).cursor();
286 if let Some(mut pos) = view.screen_coords_at_pos(doc, doc.text().slice(..), cursor) {
265 if let Some(mut pos) = view.screen_coords_at_pos(doc, doc.text().slice(..), cursor) {
helix-view/src/lib.rs+3
@@ -1,3 +1,6 @@
1+#[macro_use]
2+pub mod macros;
3+
1pub mod document;
4pub mod document;
2pub mod editor;
5pub mod editor;
3pub mod register_selection;
6pub mod register_selection;
helix-view/src/macros.rsnew file+29
@@ -0,0 +1,29 @@
1+#[macro_export]
2+macro_rules! current {
3+ ( $( $editor:ident ).+ ) => {{
4+ let view = $crate::view_mut!( $( $editor ).+ );
5+ let doc = &mut $( $editor ).+ .documents[view.doc];
6+ (view, doc)
7+ }};
8+}
9+
10+#[macro_export]
11+macro_rules! doc_mut {
12+ ( $( $editor:ident ).+ ) => {{
13+ $crate::current!( $( $editor ).+ ).1
14+ }};
15+}
16+
17+#[macro_export]
18+macro_rules! view_mut {
19+ ( $( $editor:ident ).+ ) => {{
20+ $( $editor ).+ .tree.get_mut($( $editor ).+ .tree.focus)
21+ }};
22+}
23+
24+#[macro_export]
25+macro_rules! view {
26+ ( $( $editor:ident ).+ ) => {{
27+ $( $editor ).+ .tree.get($( $editor ).+ .tree.focus)
28+ }};
29+}