@@ -3,7 +3,9 @@ use crate::{
3 gutter::{self, Gutter},
3 gutter::{self, Gutter},
4 Document, DocumentId, ViewId,
4 Document, DocumentId, ViewId,
6−use helix_core::{pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection};
7+ pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection, Transaction,
8use std::fmt;
10use std::fmt;
@@ -62,6 +64,22 @@ impl JumpList {
62 pub fn get(&self) -> &[Jump] {
64 pub fn get(&self) -> &[Jump] {
63 &self.jumps
65 &self.jumps
68+ /// Applies a [`Transaction`] of changes to the jumplist.
69+ /// This is necessary to ensure that changes to documents do not leave jump-list
70+ /// selections pointing to parts of the text which no longer exist.
71+ fn apply(&mut self, transaction: &Transaction, doc: &Document) {
72+ let text = doc.text().slice(..);
74+ for (doc_id, selection) in &mut self.jumps {
75+ if doc.id() == *doc_id {
76+ *selection = selection
78+ .map(transaction.changes())
79+ .ensure_invariants(text);
67#[derive(Clone)]
85#[derive(Clone)]
@@ -334,6 +352,14 @@ impl View {
334 // (None, None) => return,
352 // (None, None) => return,
356+ /// Applies a [`Transaction`] to the view.
357+ /// Instead of calling this function directly, use [crate::apply_transaction]
358+ /// which applies a transaction to the [`Document`] and view together.
359+ pub fn apply(&mut self, transaction: &Transaction, doc: &Document) -> bool {
360+ self.jumps.apply(transaction, doc);
339#[cfg(test)]
365#[cfg(test)]