on master help sign in
Merge pull request #62 from pickfire/cell
7761c88Corey Powell
helix-core/src/history.rs+4−6
@@ -65,9 +65,7 @@ impl History {
65 self.cursor == 0
65 self.cursor == 0
66 }
66 }
67
67
68− // TODO: I'd like to pass Transaction by reference but it fights with the borrowck
69−
70− pub fn undo(&mut self) -> Option<Transaction> {
68+ pub fn undo(&mut self) -> Option<&Transaction> {
71 if self.at_root() {
69 if self.at_root() {
72 // We're at the root of undo, nothing to do.
70 // We're at the root of undo, nothing to do.
73 return None;
71 return None;
@@ -77,17 +75,17 @@ impl History {
77
75
78 self.cursor = current_revision.parent;
76 self.cursor = current_revision.parent;
79
77
80− Some(current_revision.revert.clone())
78+ Some(&current_revision.revert)
81 }
79 }
82
80
83− pub fn redo(&mut self) -> Option<Transaction> {
81+ pub fn redo(&mut self) -> Option<&Transaction> {
84 let current_revision = &self.revisions[self.cursor];
82 let current_revision = &self.revisions[self.cursor];
85
83
86 // for now, simply pick the latest child (linear undo / redo)
84 // for now, simply pick the latest child (linear undo / redo)
87 if let Some((index, transaction)) = current_revision.children.last() {
85 if let Some((index, transaction)) = current_revision.children.last() {
88 self.cursor = *index;
86 self.cursor = *index;
89
87
90− return Some(transaction.clone());
88+ return Some(&transaction);
91 }
89 }
92 None
90 None
93 }
91 }
helix-core/src/transaction.rs+1−1
@@ -415,7 +415,7 @@ impl ChangeSet {
415
415
416/// Transaction represents a single undoable unit of changes. Several changes can be grouped into
416/// Transaction represents a single undoable unit of changes. Several changes can be grouped into
417/// a single transaction.
417/// a single transaction.
418−#[derive(Debug, Clone)]
418+#[derive(Debug, Default, Clone)]
419pub struct Transaction {
419pub struct Transaction {
420 changes: ChangeSet,
420 changes: ChangeSet,
421 selection: Option<Selection>,
421 selection: Option<Selection>,
helix-view/src/document.rs+22−8
@@ -1,4 +1,5 @@
1use anyhow::{Context, Error};
1use anyhow::{Context, Error};
2+use std::cell::Cell;
2use std::future::Future;
3use std::future::Future;
3use std::path::{Component, Path, PathBuf};
4use std::path::{Component, Path, PathBuf};
4use std::sync::Arc;
5use std::sync::Arc;
@@ -40,7 +41,10 @@ pub struct Document {
40 /// State at last commit. Used for calculating reverts.
41 /// State at last commit. Used for calculating reverts.
41 old_state: Option<State>,
42 old_state: Option<State>,
42 /// Undo tree.
43 /// Undo tree.
44+ // It can be used as a cell where we will take it out to get some parts of the history and put
45+ // it back as it separated from the edits. We could split out the parts manually but that will
46+ // be more troublesome.
43− history: History,
47+ history: Cell<History>,
44 last_saved_revision: usize,
48 last_saved_revision: usize,
45 version: i32, // should be usize?
49 version: i32, // should be usize?
46
50
@@ -121,7 +125,7 @@ impl Document {
121 old_state,
125 old_state,
122 diagnostics: Vec::new(),
126 diagnostics: Vec::new(),
123 version: 0,
127 version: 0,
124− history: History::default(),
128+ history: Cell::new(History::default()),
125 last_saved_revision: 0,
129 last_saved_revision: 0,
126 language_server: None,
130 language_server: None,
127 }
131 }
@@ -190,7 +194,9 @@ impl Document {
190 let language_server = self.language_server.clone();
194 let language_server = self.language_server.clone();
191
195
192 // reset the modified flag
196 // reset the modified flag
197+ let history = self.history.take();
193− self.last_saved_revision = self.history.current_revision();
198+ self.last_saved_revision = history.current_revision();
199+ self.history.set(history);
194
200
195 async move {
201 async move {
196 use tokio::{fs::File, io::AsyncWriteExt};
202 use tokio::{fs::File, io::AsyncWriteExt};
@@ -335,7 +341,8 @@ impl Document {
335 }
341 }
336
342
337 pub fn undo(&mut self, view_id: ViewId) -> bool {
343 pub fn undo(&mut self, view_id: ViewId) -> bool {
344+ let mut history = self.history.take();
338− if let Some(transaction) = self.history.undo() {
345+ if let Some(transaction) = history.undo() {
339 let success = self._apply(&transaction, view_id);
346 let success = self._apply(&transaction, view_id);
340
347
341 // reset changeset to fix len
348 // reset changeset to fix len
@@ -343,11 +350,13 @@ impl Document {
343
350
344 return success;
351 return success;
345 }
352 }
353+ self.history.set(history);
346 false
354 false
347 }
355 }
348
356
349 pub fn redo(&mut self, view_id: ViewId) -> bool {
357 pub fn redo(&mut self, view_id: ViewId) -> bool {
358+ let mut history = self.history.take();
350− if let Some(transaction) = self.history.redo() {
359+ if let Some(transaction) = history.redo() {
351 let success = self._apply(&transaction, view_id);
360 let success = self._apply(&transaction, view_id);
352
361
353 // reset changeset to fix len
362 // reset changeset to fix len
@@ -355,6 +364,7 @@ impl Document {
355
364
356 return success;
365 return success;
357 }
366 }
367+ self.history.set(history);
358 false
368 false
359 }
369 }
360
370
@@ -373,7 +383,9 @@ impl Document {
373 // HAXX: we need to reconstruct the state as it was before the changes..
383 // HAXX: we need to reconstruct the state as it was before the changes..
374 let old_state = self.old_state.take().expect("no old_state available");
384 let old_state = self.old_state.take().expect("no old_state available");
375
385
386+ let mut history = self.history.take();
376− self.history.commit_revision(&transaction, &old_state);
387+ history.commit_revision(&transaction, &old_state);
388+ self.history.set(history);
377 }
389 }
378
390
379 #[inline]
391 #[inline]
@@ -383,9 +395,11 @@ impl Document {
383
395
384 #[inline]
396 #[inline]
385 pub fn is_modified(&self) -> bool {
397 pub fn is_modified(&self) -> bool {
398+ let history = self.history.take();
399+ let current_revision = history.current_revision();
400+ self.history.set(history);
386 self.path.is_some()
401 self.path.is_some()
387− && (self.history.current_revision() != self.last_saved_revision
402+ && (current_revision != self.last_saved_revision || !self.changes.is_empty())
388− || !self.changes.is_empty())
389 }
403 }
390
404
391 #[inline]
405 #[inline]