on master help sign in
Apply transactions to Views

This change adds View::apply calls for all Document::apply call-sites, ensuring that changes to a document do not leave invalid entries in the View's jumplist.

commit0aedef03334dfc0cb2a723cce23abc5b4ca55a22 authorMichael Davis <mcarsondavis@gmail.com> dateMon 10 Oct 2022, 14:56 (4 years ago) parentd418f07
6 files changed+58−20
helix-term/src/commands.rs+36−7 helix-term/src/commands/lsp.rs+2−3 helix-term/src/commands/typed.rs+5−1 helix-term/src/ui/completion.rs+5−2 helix-term/src/ui/editor.rs+2−1 helix-view/src/document.rs+8−6
helix-term/src/commands.rs+36−7
@@ -860,6 +860,7 @@ fn align_selections(cx: &mut Context) {
860860
861861 let transaction = Transaction::change(doc.text(), changes.into_iter());
862862 doc.apply(&transaction, view.id);
863+ view.apply(&transaction, doc);
863864}
864865
865866fn goto_window(cx: &mut Context, align: Align) {
@@ -1290,6 +1291,7 @@ fn replace(cx: &mut Context) {
12901291 });
12911292
12921293 doc.apply(&transaction, view.id);
1294+ view.apply(&transaction, doc);
12931295 }
12941296 })
12951297}
@@ -1307,6 +1309,7 @@ where
13071309 });
13081310
13091311 doc.apply(&transaction, view.id);
1312+ view.apply(&transaction, doc);
13101313}
13111314
13121315fn switch_case(cx: &mut Context) {
@@ -2113,6 +2116,7 @@ fn delete_selection_impl(cx: &mut Context, op: Operation) {
21132116 (range.from(), range.to(), None)
21142117 });
21152118 doc.apply(&transaction, view.id);
2119+ view.apply(&transaction, doc);
21162120
21172121 match op {
21182122 Operation::Delete => {
@@ -2126,7 +2130,7 @@ fn delete_selection_impl(cx: &mut Context, op: Operation) {
21262130}
21272131
21282132#[inline]
2129−fn delete_selection_insert_mode(doc: &mut Document, view: &View, selection: &Selection) {
2133+fn delete_selection_insert_mode(doc: &mut Document, view: &mut View, selection: &Selection) {
21302134 let view_id = view.id;
21312135
21322136 // then delete
@@ -2134,6 +2138,7 @@ fn delete_selection_insert_mode(doc: &mut Document, view: &View, selection: &Sel
21342138 (range.from(), range.to(), None)
21352139 });
21362140 doc.apply(&transaction, view_id);
2141+ view.apply(&transaction, doc);
21372142}
21382143
21392144fn delete_selection(cx: &mut Context) {
@@ -2230,6 +2235,7 @@ fn append_mode(cx: &mut Context) {
22302235 [(end, end, Some(doc.line_ending.as_str().into()))].into_iter(),
22312236 );
22322237 doc.apply(&transaction, view.id);
2238+ view.apply(&transaction, doc);
22332239 }
22342240
22352241 let selection = doc.selection(view.id).clone().transform(|range| {
@@ -2530,6 +2536,7 @@ async fn make_format_callback(
25302536 let view = view_mut!(editor);
25312537 if doc.version() == doc_version {
25322538 doc.apply(&format, view.id);
2539+ view.apply(&format, doc);
25332540 doc.append_changes_to_history(view.id);
25342541 doc.detect_indent_and_line_ending();
25352542 view.ensure_cursor_in_view(doc, scrolloff);
@@ -2617,6 +2624,7 @@ fn open(cx: &mut Context, open: Open) {
26172624 transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));
26182625
26192626 doc.apply(&transaction, view.id);
2627+ view.apply(&transaction, doc);
26202628}
26212629
26222630// o inserts a new line after each line with a selection
@@ -2637,7 +2645,7 @@ fn normal_mode(cx: &mut Context) {
26372645 cx.editor.mode = Mode::Normal;
26382646 let (view, doc) = current!(cx.editor);
26392647
2640− try_restore_indent(doc, view.id);
2648+ try_restore_indent(doc, view);
26412649
26422650 // if leaving append mode, move cursor back by 1
26432651 if doc.restore_cursor {
@@ -2654,7 +2662,7 @@ fn normal_mode(cx: &mut Context) {
26542662 }
26552663}
26562664
2657−fn try_restore_indent(doc: &mut Document, view_id: ViewId) {
2665+fn try_restore_indent(doc: &mut Document, view: &mut View) {
26582666 use helix_core::chars::char_is_whitespace;
26592667 use helix_core::Operation;
26602668
@@ -2673,18 +2681,19 @@ fn try_restore_indent(doc: &mut Document, view_id: ViewId) {
26732681
26742682 let doc_changes = doc.changes().changes();
26752683 let text = doc.text().slice(..);
2676− let range = doc.selection(view_id).primary();
2684+ let range = doc.selection(view.id).primary();
26772685 let pos = range.cursor(text);
26782686 let line_end_pos = line_end_char_index(&text, range.cursor_line(text));
26792687
26802688 if inserted_a_new_blank_line(doc_changes, pos, line_end_pos) {
26812689 // Removes tailing whitespaces.
26822690 let transaction =
2683− Transaction::change_by_selection(doc.text(), doc.selection(view_id), |range| {
2691+ Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
26842692 let line_start_pos = text.line_to_char(range.cursor_line(text));
26852693 (line_start_pos, pos, None)
26862694 });
2687− doc.apply(&transaction, view_id);
2695+ doc.apply(&transaction, view.id);
2696+ view.apply(&transaction, doc);
26882697 }
26892698}
26902699
@@ -2999,6 +3008,7 @@ pub mod insert {
29993008 let (view, doc) = current!(cx.editor);
30003009 if let Some(t) = transaction {
30013010 doc.apply(&t, view.id);
3011+ view.apply(&t, doc);
30023012 }
30033013
30043014 // TODO: need a post insert hook too for certain triggers (autocomplete, signature help, etc)
@@ -3021,6 +3031,7 @@ pub mod insert {
30213031 indent,
30223032 );
30233033 doc.apply(&transaction, view.id);
3034+ view.apply(&transaction, doc);
30243035 }
30253036
30263037 pub fn insert_newline(cx: &mut Context) {
@@ -3108,6 +3119,7 @@ pub mod insert {
31083119
31093120 let (view, doc) = current!(cx.editor);
31103121 doc.apply(&transaction, view.id);
3122+ view.apply(&transaction, doc);
31113123 }
31123124
31133125 pub fn delete_char_backward(cx: &mut Context) {
@@ -3202,6 +3214,7 @@ pub mod insert {
32023214 });
32033215 let (view, doc) = current!(cx.editor);
32043216 doc.apply(&transaction, view.id);
3217+ view.apply(&transaction, doc);
32053218
32063219 lsp::signature_help_impl(cx, SignatureHelpInvoked::Automatic);
32073220 }
@@ -3220,6 +3233,7 @@ pub mod insert {
32203233 )
32213234 });
32223235 doc.apply(&transaction, view.id);
3236+ view.apply(&transaction, doc);
32233237
32243238 lsp::signature_help_impl(cx, SignatureHelpInvoked::Automatic);
32253239 }
@@ -3413,7 +3427,7 @@ enum Paste {
34133427 Cursor,
34143428}
34153429
3416−fn paste_impl(values: &[String], doc: &mut Document, view: &View, action: Paste, count: usize) {
3430+fn paste_impl(values: &[String], doc: &mut Document, view: &mut View, action: Paste, count: usize) {
34173431 let repeat = std::iter::repeat(
34183432 values
34193433 .last()
@@ -3457,6 +3471,7 @@ fn paste_impl(values: &[String], doc: &mut Document, view: &View, action: Paste,
34573471 (pos, pos, values.next())
34583472 });
34593473 doc.apply(&transaction, view.id);
3474+ view.apply(&transaction, doc);
34603475}
34613476
34623477pub(crate) fn paste_bracketed_value(cx: &mut Context, contents: String) {
@@ -3549,6 +3564,7 @@ fn replace_with_yanked(cx: &mut Context) {
35493564 });
35503565
35513566 doc.apply(&transaction, view.id);
3567+ view.apply(&transaction, doc);
35523568 }
35533569 }
35543570}
@@ -3572,6 +3588,7 @@ fn replace_selections_with_clipboard_impl(
35723588 });
35733589
35743590 doc.apply(&transaction, view.id);
3591+ view.apply(&transaction, doc);
35753592 doc.append_changes_to_history(view.id);
35763593 Ok(())
35773594 }
@@ -3642,6 +3659,7 @@ fn indent(cx: &mut Context) {
36423659 }),
36433660 );
36443661 doc.apply(&transaction, view.id);
3662+ view.apply(&transaction, doc);
36453663}
36463664
36473665fn unindent(cx: &mut Context) {
@@ -3681,6 +3699,7 @@ fn unindent(cx: &mut Context) {
36813699 let transaction = Transaction::change(doc.text(), changes.into_iter());
36823700
36833701 doc.apply(&transaction, view.id);
3702+ view.apply(&transaction, doc);
36843703}
36853704
36863705fn format_selections(cx: &mut Context) {
@@ -3728,6 +3747,7 @@ fn format_selections(cx: &mut Context) {
37283747 // );
37293748
37303749 // doc.apply(&transaction, view.id);
3750+ // view.apply(&transaction, doc);
37313751 }
37323752}
37333753
@@ -3783,6 +3803,7 @@ fn join_selections_inner(cx: &mut Context, select_space: bool) {
37833803 };
37843804
37853805 doc.apply(&transaction, view.id);
3806+ view.apply(&transaction, doc);
37863807}
37873808
37883809fn keep_or_remove_selections_impl(cx: &mut Context, remove: bool) {
@@ -3936,6 +3957,7 @@ fn toggle_comments(cx: &mut Context) {
39363957 let transaction = comment::toggle_line_comments(doc.text(), doc.selection(view.id), token);
39373958
39383959 doc.apply(&transaction, view.id);
3960+ view.apply(&transaction, doc);
39393961 exit_select_mode(cx);
39403962}
39413963
@@ -3992,6 +4014,7 @@ fn rotate_selection_contents(cx: &mut Context, direction: Direction) {
39924014 );
39934015
39944016 doc.apply(&transaction, view.id);
4017+ view.apply(&transaction, doc);
39954018}
39964019
39974020fn rotate_selection_contents_forward(cx: &mut Context) {
@@ -4488,6 +4511,7 @@ fn surround_add(cx: &mut Context) {
44884511
44894512 let transaction = Transaction::change(doc.text(), changes.into_iter());
44904513 doc.apply(&transaction, view.id);
4514+ view.apply(&transaction, doc);
44914515 })
44924516}
44934517
@@ -4527,6 +4551,7 @@ fn surround_replace(cx: &mut Context) {
45274551 }),
45284552 );
45294553 doc.apply(&transaction, view.id);
4554+ view.apply(&transaction, doc);
45304555 });
45314556 })
45324557}
@@ -4554,6 +4579,7 @@ fn surround_delete(cx: &mut Context) {
45544579 let transaction =
45554580 Transaction::change(doc.text(), change_pos.into_iter().map(|p| (p, p + 1, None)));
45564581 doc.apply(&transaction, view.id);
4582+ view.apply(&transaction, doc);
45574583 })
45584584}
45594585
@@ -4729,6 +4755,7 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
47294755 if behavior != &ShellBehavior::Ignore {
47304756 let transaction = Transaction::change(doc.text(), changes.into_iter());
47314757 doc.apply(&transaction, view.id);
4758+ view.apply(&transaction, doc);
47324759 doc.append_changes_to_history(view.id);
47334760 }
47344761
@@ -4792,6 +4819,7 @@ fn add_newline_impl(cx: &mut Context, open: Open) {
47924819
47934820 let transaction = Transaction::change(text, changes);
47944821 doc.apply(&transaction, view.id);
4822+ view.apply(&transaction, doc);
47954823}
47964824
47974825/// Increment object under cursor by count.
@@ -4885,6 +4913,7 @@ fn increment_impl(cx: &mut Context, amount: i64) {
48854913 let transaction = transaction.with_selection(selection.clone());
48864914
48874915 doc.apply(&transaction, view.id);
4916+ view.apply(&transaction, doc);
48884917 }
48894918}
48904919
helix-term/src/commands/lsp.rs+2−3
@@ -596,9 +596,7 @@ pub fn apply_workspace_edit(
596596 }
597597 };
598598
599− let doc = editor
600− .document_mut(doc_id)
601− .expect("Document for document_changes not found");
599+ let doc = doc_mut!(editor, &doc_id);
602600
603601 // Need to determine a view for apply/append_changes_to_history
604602 let selections = doc.selections();
@@ -620,6 +618,7 @@ pub fn apply_workspace_edit(
620618 offset_encoding,
621619 );
622620 doc.apply(&transaction, view_id);
621+ view_mut!(editor, view_id).apply(&transaction, doc);
623622 doc.append_changes_to_history(view_id);
624623 };
625624
helix-term/src/commands/typed.rs+5−1
@@ -463,6 +463,7 @@ fn set_line_ending(
463463 }),
464464 );
465465 doc.apply(&transaction, view.id);
466+ view.apply(&transaction, doc);
466467 doc.append_changes_to_history(view.id);
467468
468469 Ok(())
@@ -884,6 +885,7 @@ fn replace_selections_with_clipboard_impl(
884885 });
885886
886887 doc.apply(&transaction, view.id);
888+ view.apply(&transaction, doc);
887889 doc.append_changes_to_history(view.id);
888890 Ok(())
889891 }
@@ -1004,7 +1006,7 @@ fn reload(
10041006
10051007 let scrolloff = cx.editor.config().scrolloff;
10061008 let (view, doc) = current!(cx.editor);
1007− doc.reload(view.id).map(|_| {
1009+ doc.reload(view).map(|_| {
10081010 view.ensure_cursor_in_view(doc, scrolloff);
10091011 })
10101012}
@@ -1399,6 +1401,7 @@ fn sort_impl(
13991401 );
14001402
14011403 doc.apply(&transaction, view.id);
1404+ view.apply(&transaction, doc);
14021405 doc.append_changes_to_history(view.id);
14031406
14041407 Ok(())
@@ -1443,6 +1446,7 @@ fn reflow(
14431446 });
14441447
14451448 doc.apply(&transaction, view.id);
1449+ view.apply(&transaction, doc);
14461450 doc.append_changes_to_history(view.id);
14471451 view.ensure_cursor_in_view(doc, scrolloff);
14481452
helix-term/src/ui/completion.rs+5−2
@@ -143,11 +143,11 @@ impl Completion {
143143 let (view, doc) = current!(editor);
144144
145145 // if more text was entered, remove it
146− doc.restore(view.id);
146+ doc.restore(view);
147147
148148 match event {
149149 PromptEvent::Abort => {
150− doc.restore(view.id);
150+ doc.restore(view);
151151 editor.last_completion = None;
152152 }
153153 PromptEvent::Update => {
@@ -165,6 +165,7 @@ impl Completion {
165165 // initialize a savepoint
166166 doc.savepoint();
167167 doc.apply(&transaction, view.id);
168+ view.apply(&transaction, doc);
168169
169170 editor.last_completion = Some(CompleteAction {
170171 trigger_offset,
@@ -184,6 +185,7 @@ impl Completion {
184185 );
185186
186187 doc.apply(&transaction, view.id);
188+ view.apply(&transaction, doc);
187189
188190 editor.last_completion = Some(CompleteAction {
189191 trigger_offset,
@@ -214,6 +216,7 @@ impl Completion {
214216 offset_encoding, // TODO: should probably transcode in Client
215217 );
216218 doc.apply(&transaction, view.id);
219+ view.apply(&transaction, doc);
217220 }
218221 }
219222 }
helix-term/src/ui/editor.rs+2−1
@@ -988,7 +988,7 @@ impl EditorView {
988988 InsertEvent::CompletionApply(compl) => {
989989 let (view, doc) = current!(cxt.editor);
990990
991− doc.restore(view.id);
991+ doc.restore(view);
992992
993993 let text = doc.text().slice(..);
994994 let cursor = doc.selection(view.id).primary().cursor(text);
@@ -1003,6 +1003,7 @@ impl EditorView {
10031003 }),
10041004 );
10051005 doc.apply(&tx, view.id);
1006+ view.apply(&tx, doc);
10061007 }
10071008 InsertEvent::TriggerCompletion => {
10081009 let (_, doc) = current!(cxt.editor);
helix-view/src/document.rs+8−6
@@ -24,7 +24,7 @@ use helix_core::{
2424 DEFAULT_LINE_ENDING,
2525};
2626
27−use crate::{DocumentId, Editor, ViewId};
27+use crate::{DocumentId, Editor, View, ViewId};
2828
2929/// 8kB of buffer space for encoding and decoding `Rope`s.
3030const BUF_SIZE: usize = 8192;
@@ -601,7 +601,7 @@ impl Document {
601601 }
602602
603603 /// Reload the document from its path.
604− pub fn reload(&mut self, view_id: ViewId) -> Result<(), Error> {
604+ pub fn reload(&mut self, view: &mut View) -> Result<(), Error> {
605605 let encoding = &self.encoding;
606606 let path = self.path().filter(|path| path.exists());
607607
@@ -617,8 +617,9 @@ impl Document {
617617 // This is not considered a modification of the contents of the file regardless
618618 // of the encoding.
619619 let transaction = helix_core::diff::compare_ropes(self.text(), &rope);
620− self.apply(&transaction, view_id);
621− self.append_changes_to_history(view_id);
620+ self.apply(&transaction, view.id);
621+ view.apply(&transaction, self);
622+ self.append_changes_to_history(view.id);
622623 self.reset_modified();
623624
624625 self.detect_indent_and_line_ending();
@@ -862,9 +863,10 @@ impl Document {
862863 self.savepoint = Some(Transaction::new(self.text()));
863864 }
864865
865− pub fn restore(&mut self, view_id: ViewId) {
866+ pub fn restore(&mut self, view: &mut View) {
866867 if let Some(revert) = self.savepoint.take() {
867− self.apply(&revert, view_id);
868+ self.apply(&revert, view.id);
869+ view.apply(&revert, self);
868870 }
869871 }
870872