Sync changes between doc and view on switch

pull/1/head
Michael Davis 2 years ago committed by Blaž Hrastnik
parent 4d1f5389f9
commit 056a19a003

@ -959,7 +959,8 @@ impl Editor {
fn _refresh(&mut self) { fn _refresh(&mut self) {
let config = self.config(); let config = self.config();
for (view, _) in self.tree.views_mut() { 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) view.ensure_cursor_in_view(doc, config.scrolloff)
} }
} }
@ -971,6 +972,7 @@ impl Editor {
let doc = doc_mut!(self, &doc_id); let doc = doc_mut!(self, &doc_id);
doc.ensure_view_init(view.id); doc.ensure_view_init(view.id);
view.sync_changes(doc);
align_view(doc, view, Align::Center); align_view(doc, view, Align::Center);
} }
@ -1239,6 +1241,9 @@ impl Editor {
// within view // within view
if prev_id != view_id { if prev_id != view_id {
self.mode = Mode::Normal; 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); self.ensure_cursor_in_view(view_id);
} }
} }

@ -3,7 +3,10 @@ use helix_core::{
pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection, Transaction, 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; const JUMP_LIST_CAPACITY: usize = 30;
@ -102,6 +105,11 @@ pub struct View {
pub object_selections: Vec<Selection>, pub object_selections: Vec<Selection>,
/// GutterTypes used to fetch Gutter (constructor) and width for rendering /// GutterTypes used to fetch Gutter (constructor) and width for rendering
gutters: Vec<GutterType>, 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 { impl fmt::Debug for View {
@ -126,6 +134,7 @@ impl View {
last_modified_docs: [None, None], last_modified_docs: [None, None],
object_selections: Vec::new(), object_selections: Vec::new(),
gutters: gutter_types, gutters: gutter_types,
doc_revisions: HashMap::new(),
} }
} }
@ -349,10 +358,33 @@ impl View {
/// Applies a [`Transaction`] to the view. /// Applies a [`Transaction`] to the view.
/// Instead of calling this function directly, use [crate::apply_transaction] /// Instead of calling this function directly, use [crate::apply_transaction]
/// which applies a transaction to the [`Document`] and view together. /// 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); self.jumps.apply(transaction, doc);
// TODO: remove the boolean return. This is unused. self.doc_revisions
true .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);
}
} }
} }

Loading…
Cancel
Save