mirror of https://github.com/helix-editor/helix
Sync changes between doc and view on switch
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…
Reference in New Issue