mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-23 01:46:18 +04:00
Fully drop State references.
This commit is contained in:
parent
dfc17becd5
commit
9eaef6e333
@ -96,13 +96,15 @@ fn test_find_line_comment() {
|
||||
|
||||
// comment
|
||||
let transaction = toggle_line_comments(&state.doc, &state.selection);
|
||||
transaction.apply(&mut state);
|
||||
transaction.apply(&mut state.doc);
|
||||
state.selection = state.selection.clone().map(transaction.changes());
|
||||
|
||||
assert_eq!(state.doc, " // 1\n\n // 2\n // 3");
|
||||
|
||||
// uncomment
|
||||
let transaction = toggle_line_comments(&state.doc, &state.selection);
|
||||
transaction.apply(&mut state);
|
||||
transaction.apply(&mut state.doc);
|
||||
state.selection = state.selection.clone().map(transaction.changes());
|
||||
assert_eq!(state.doc, " 1\n\n 2\n 3");
|
||||
|
||||
// TODO: account for no margin after comment
|
||||
|
@ -33,7 +33,10 @@ fn default() -> Self {
|
||||
impl History {
|
||||
pub fn commit_revision(&mut self, transaction: &Transaction, original: &State) {
|
||||
// TODO: could store a single transaction, if deletes also stored the text they delete
|
||||
let revert = transaction.invert(original);
|
||||
let revert = transaction
|
||||
.invert(&original.doc)
|
||||
// Store the current cursor position
|
||||
.with_selection(original.selection.clone());
|
||||
|
||||
let new_cursor = self.revisions.len();
|
||||
self.revisions.push(Revision {
|
||||
@ -100,7 +103,7 @@ fn test_undo_redo() {
|
||||
|
||||
// Need to commit before applying!
|
||||
history.commit_revision(&transaction1, &state);
|
||||
transaction1.apply(&mut state);
|
||||
transaction1.apply(&mut state.doc);
|
||||
assert_eq!("hello world!", state.doc);
|
||||
|
||||
// ---
|
||||
@ -110,18 +113,18 @@ fn test_undo_redo() {
|
||||
|
||||
// Need to commit before applying!
|
||||
history.commit_revision(&transaction2, &state);
|
||||
transaction2.apply(&mut state);
|
||||
transaction2.apply(&mut state.doc);
|
||||
assert_eq!("hello 世界!", state.doc);
|
||||
|
||||
// ---
|
||||
fn undo(history: &mut History, state: &mut State) {
|
||||
if let Some(transaction) = history.undo() {
|
||||
transaction.apply(state);
|
||||
transaction.apply(&mut state.doc);
|
||||
}
|
||||
}
|
||||
fn redo(history: &mut History, state: &mut State) {
|
||||
if let Some(transaction) = history.redo() {
|
||||
transaction.apply(state);
|
||||
transaction.apply(&mut state.doc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1593,7 +1593,7 @@ fn test_input_edits() {
|
||||
&state.doc,
|
||||
vec![(6, 11, Some("test".into())), (12, 17, None)].into_iter(),
|
||||
);
|
||||
let edits = LanguageLayer::generate_edits(state.doc.slice(..), &transaction.changes);
|
||||
let edits = LanguageLayer::generate_edits(state.doc.slice(..), transaction.changes());
|
||||
// transaction.apply(&mut state);
|
||||
|
||||
assert_eq!(
|
||||
@ -1622,8 +1622,8 @@ fn test_input_edits() {
|
||||
let mut state = State::new("fn test() {}".into());
|
||||
let transaction =
|
||||
Transaction::change(&state.doc, vec![(8, 8, Some("a: u32".into()))].into_iter());
|
||||
let edits = LanguageLayer::generate_edits(state.doc.slice(..), &transaction.changes);
|
||||
transaction.apply(&mut state);
|
||||
let edits = LanguageLayer::generate_edits(state.doc.slice(..), transaction.changes());
|
||||
transaction.apply(&mut state.doc);
|
||||
|
||||
assert_eq!(state.doc, "fn test(a: u32) {}");
|
||||
assert_eq!(
|
||||
|
@ -400,9 +400,7 @@ pub fn changes_iter(&self) -> ChangeIterator {
|
||||
/// a single transaction.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Transaction {
|
||||
/// Changes made to the buffer.
|
||||
pub(crate) changes: ChangeSet,
|
||||
/// When set, explicitly updates the selection.
|
||||
changes: ChangeSet,
|
||||
selection: Option<Selection>,
|
||||
// effects, annotations
|
||||
// scroll_into_view
|
||||
@ -417,40 +415,35 @@ pub fn new(doc: &Rope) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
/// Changes made to the buffer.
|
||||
pub fn changes(&self) -> &ChangeSet {
|
||||
&self.changes
|
||||
}
|
||||
|
||||
/// When set, explicitly updates the selection.
|
||||
pub fn selection(&self) -> Option<&Selection> {
|
||||
self.selection.as_ref()
|
||||
}
|
||||
|
||||
/// Returns true if applied successfully.
|
||||
pub fn apply(&self, state: &mut State) -> bool {
|
||||
pub fn apply(&self, doc: &mut Rope) -> bool {
|
||||
if !self.changes.is_empty() {
|
||||
// apply changes to the document
|
||||
if !self.changes.apply(&mut state.doc) {
|
||||
if !self.changes.apply(doc) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: also avoid mapping the selection if not necessary
|
||||
|
||||
// update the selection: either take the selection specified in the transaction, or map the
|
||||
// current selection through changes.
|
||||
state.selection = self
|
||||
.selection
|
||||
.clone()
|
||||
.unwrap_or_else(|| state.selection.clone().map(&self.changes));
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Generate a transaction that reverts this one.
|
||||
pub fn invert(&self, original: &State) -> Self {
|
||||
let changes = self.changes.invert(&original.doc);
|
||||
// Store the current cursor position
|
||||
let selection = original.selection.clone();
|
||||
pub fn invert(&self, original: &Rope) -> Self {
|
||||
let changes = self.changes.invert(original);
|
||||
|
||||
Self {
|
||||
changes,
|
||||
selection: Some(selection),
|
||||
selection: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,7 +668,7 @@ fn transaction_change() {
|
||||
// (1, 1, None) is a useless 0-width delete
|
||||
vec![(1, 1, None), (6, 11, Some("void".into())), (12, 17, None)].into_iter(),
|
||||
);
|
||||
transaction.apply(&mut state);
|
||||
transaction.apply(&mut state.doc);
|
||||
assert_eq!(state.doc, Rope::from_str("hello void! 123"));
|
||||
}
|
||||
|
||||
@ -691,15 +684,20 @@ fn changes_iter() {
|
||||
fn optimized_composition() {
|
||||
let mut state = State::new("".into());
|
||||
let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('h'));
|
||||
t1.apply(&mut state);
|
||||
t1.apply(&mut state.doc);
|
||||
state.selection = state.selection.clone().map(t1.changes());
|
||||
let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('e'));
|
||||
t2.apply(&mut state);
|
||||
t2.apply(&mut state.doc);
|
||||
state.selection = state.selection.clone().map(t2.changes());
|
||||
let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
|
||||
t3.apply(&mut state);
|
||||
t3.apply(&mut state.doc);
|
||||
state.selection = state.selection.clone().map(t3.changes());
|
||||
let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
|
||||
t4.apply(&mut state);
|
||||
t4.apply(&mut state.doc);
|
||||
state.selection = state.selection.clone().map(t4.changes());
|
||||
let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('o'));
|
||||
t5.apply(&mut state);
|
||||
t5.apply(&mut state.doc);
|
||||
state.selection = state.selection.clone().map(t5.changes());
|
||||
|
||||
assert_eq!(state.doc, Rope::from_str("hello"));
|
||||
|
||||
|
@ -21,6 +21,7 @@ pub struct Document {
|
||||
// rope + selection
|
||||
pub(crate) id: DocumentId,
|
||||
state: State,
|
||||
|
||||
path: Option<PathBuf>,
|
||||
|
||||
/// Current editing mode.
|
||||
@ -185,9 +186,16 @@ pub fn set_selection(&mut self, selection: Selection) {
|
||||
fn _apply(&mut self, transaction: &Transaction) -> bool {
|
||||
let old_doc = self.text().clone();
|
||||
|
||||
let success = transaction.apply(&mut self.state);
|
||||
let success = transaction.changes().apply(&mut self.state.doc);
|
||||
|
||||
if !transaction.changes().is_empty() {
|
||||
// update the selection: either take the selection specified in the transaction, or map the
|
||||
// current selection through changes.
|
||||
self.state.selection = transaction
|
||||
.selection()
|
||||
.cloned()
|
||||
.unwrap_or_else(|| self.selection().clone().map(transaction.changes()));
|
||||
|
||||
self.version += 1;
|
||||
|
||||
// update tree-sitter syntax tree
|
||||
@ -415,7 +423,7 @@ fn changeset_to_changes() {
|
||||
|
||||
// delete
|
||||
|
||||
let transaction = transaction.invert(&old_doc);
|
||||
let transaction = transaction.invert(&old_doc.doc);
|
||||
let old_doc = doc.state.clone();
|
||||
doc.apply(&transaction);
|
||||
let changes = Client::changeset_to_changes(&old_doc.doc, doc.text(), transaction.changes());
|
||||
|
Loading…
Reference in New Issue
Block a user