From d418f0795d8a33c83ad87c5530c4819d83da09ef Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Mon, 10 Oct 2022 14:54:57 -0500 Subject: [PATCH] Add View::apply for adjusting jumplist ranges Applying a transaction to a View adjusts the ranges in the jumplist to ensure that they remain within the text of the document and follow regular selection invariants (for example, must be have a width of at least one). --- helix-view/src/view.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index 3df533dfc..62984b889 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -3,7 +3,9 @@ use crate::{ gutter::{self, Gutter}, Document, DocumentId, ViewId, }; -use helix_core::{pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection}; +use helix_core::{ + pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection, Transaction, +}; use std::fmt; @@ -62,6 +64,22 @@ impl JumpList { pub fn get(&self) -> &[Jump] { &self.jumps } + + /// Applies a [`Transaction`] of changes to the jumplist. + /// This is necessary to ensure that changes to documents do not leave jump-list + /// selections pointing to parts of the text which no longer exist. + fn apply(&mut self, transaction: &Transaction, doc: &Document) { + let text = doc.text().slice(..); + + for (doc_id, selection) in &mut self.jumps { + if doc.id() == *doc_id { + *selection = selection + .clone() + .map(transaction.changes()) + .ensure_invariants(text); + } + } + } } #[derive(Clone)] @@ -334,6 +352,14 @@ impl View { // (None, None) => return, // } // } + + /// Applies a [`Transaction`] to the view. + /// Instead of calling this function directly, use [crate::apply_transaction] + /// which applies a transaction to the [`Document`] and view together. + pub fn apply(&mut self, transaction: &Transaction, doc: &Document) -> bool { + self.jumps.apply(transaction, doc); + true + } } #[cfg(test)]