aboutsummaryrefslogtreecommitdiff
path: root/helix-view
diff options
context:
space:
mode:
authorMichael Davis2022-11-27 16:45:17 +0000
committerBlaž Hrastnik2022-11-29 16:15:20 +0000
commit056a19a003a290b7914c7b442ebd640b93eaba0c (patch)
treef46181a25c6a4982d6c17df20cd9ec370151a1af /helix-view
parent4d1f5389f99013be99b9498fd3fee78eec6217f3 (diff)
Sync changes between doc and view on switch
Diffstat (limited to 'helix-view')
-rw-r--r--helix-view/src/editor.rs7
-rw-r--r--helix-view/src/view.rs40
2 files changed, 42 insertions, 5 deletions
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 6eaa89aa..e54c7497 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -959,7 +959,8 @@ impl Editor {
fn _refresh(&mut self) {
let config = self.config();
for (view, _) in self.tree.views_mut() {
- let doc = &self.documents[&view.doc];
+ let doc = doc_mut!(self, &view.doc);
+ view.sync_changes(doc);
view.ensure_cursor_in_view(doc, config.scrolloff)
}
}
@@ -971,6 +972,7 @@ impl Editor {
let doc = doc_mut!(self, &doc_id);
doc.ensure_view_init(view.id);
+ view.sync_changes(doc);
align_view(doc, view, Align::Center);
}
@@ -1239,6 +1241,9 @@ impl Editor {
// within view
if prev_id != view_id {
self.mode = Mode::Normal;
+ let view = view_mut!(self, view_id);
+ let doc = doc_mut!(self, &view.doc);
+ view.sync_changes(doc);
self.ensure_cursor_in_view(view_id);
}
}
diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs
index c917a1ab..845a5458 100644
--- a/helix-view/src/view.rs
+++ b/helix-view/src/view.rs
@@ -3,7 +3,10 @@ use helix_core::{
pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection, Transaction,
};
-use std::{collections::VecDeque, fmt};
+use std::{
+ collections::{HashMap, VecDeque},
+ fmt,
+};
const JUMP_LIST_CAPACITY: usize = 30;
@@ -102,6 +105,11 @@ pub struct View {
pub object_selections: Vec<Selection>,
/// GutterTypes used to fetch Gutter (constructor) and width for rendering
gutters: Vec<GutterType>,
+ /// A mapping between documents and the last history revision the view was updated at.
+ /// Changes between documents and views are synced lazily when switching windows. This
+ /// mapping keeps track of the last applied history revision so that only new changes
+ /// are applied.
+ doc_revisions: HashMap<DocumentId, usize>,
}
impl fmt::Debug for View {
@@ -126,6 +134,7 @@ impl View {
last_modified_docs: [None, None],
object_selections: Vec::new(),
gutters: gutter_types,
+ doc_revisions: HashMap::new(),
}
}
@@ -349,10 +358,33 @@ impl View {
/// 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 {
+ pub fn apply(&mut self, transaction: &Transaction, doc: &mut Document) {
self.jumps.apply(transaction, doc);
- // TODO: remove the boolean return. This is unused.
- true
+ self.doc_revisions
+ .insert(doc.id(), doc.get_current_revision());
+ }
+
+ pub fn sync_changes(&mut self, doc: &mut Document) {
+ let latest_revision = doc.get_current_revision();
+ let current_revision = *self
+ .doc_revisions
+ .entry(doc.id())
+ .or_insert(latest_revision);
+
+ if current_revision == latest_revision {
+ return;
+ }
+
+ log::debug!(
+ "Syncing view {:?} between {} and {}",
+ self.id,
+ current_revision,
+ latest_revision
+ );
+
+ if let Some(transaction) = doc.history.get_mut().changes_since(current_revision) {
+ self.apply(&transaction, doc);
+ }
}
}