From 561857fdf232c466b0035ce6bca47725a3816db6 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 11 Oct 2021 17:22:18 -0600 Subject: [PATCH] Restore all active selections when undoing/redoing autoindent In the unlikely event that we're handling autoindent requests from multiple editors, we undo/redo selections from both editors. This is somewhat imperfect but probably good enough and easier than performing auto-indents on a per-editor basis. --- crates/buffer/src/lib.rs | 104 ++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 45 deletions(-) diff --git a/crates/buffer/src/lib.rs b/crates/buffer/src/lib.rs index 51f8a04603..19c74da9f1 100644 --- a/crates/buffer/src/lib.rs +++ b/crates/buffer/src/lib.rs @@ -201,7 +201,7 @@ struct SyntaxTree { #[derive(Clone)] struct AutoindentRequest { - selection_set_id: Option, + selection_set_ids: HashSet, before_edit: Snapshot, edited: AnchorSet, inserted: Option, @@ -214,8 +214,8 @@ struct Transaction { buffer_was_dirty: bool, edits: Vec, ranges: Vec>, - selections_before: Option<(SelectionSetId, Arc<[Selection]>)>, - selections_after: Option<(SelectionSetId, Arc<[Selection]>)>, + selections_before: HashMap>, + selections_after: HashMap>, first_edit_at: Instant, last_edit_at: Instant, } @@ -299,7 +299,7 @@ impl History { &mut self, start: clock::Global, buffer_was_dirty: bool, - selections: Option<(SelectionSetId, Arc<[Selection]>)>, + selections_before: HashMap>, now: Instant, ) { self.transaction_depth += 1; @@ -310,8 +310,8 @@ impl History { buffer_was_dirty, edits: Vec::new(), ranges: Vec::new(), - selections_before: selections, - selections_after: None, + selections_before, + selections_after: Default::default(), first_edit_at: now, last_edit_at: now, }); @@ -320,7 +320,7 @@ impl History { fn end_transaction( &mut self, - selections: Option<(SelectionSetId, Arc<[Selection]>)>, + selections_after: HashMap>, now: Instant, ) -> Option<&Transaction> { assert_ne!(self.transaction_depth, 0); @@ -331,7 +331,7 @@ impl History { None } else { let transaction = self.undo_stack.last_mut().unwrap(); - transaction.selections_after = selections; + transaction.selections_after = selections_after; transaction.last_edit_at = now; Some(transaction) } @@ -367,7 +367,9 @@ impl History { if let Some(transaction) = transactions_to_merge.last_mut() { last_transaction.last_edit_at = transaction.last_edit_at; - last_transaction.selections_after = transaction.selections_after.take(); + last_transaction + .selections_after + .extend(transaction.selections_after.drain()); last_transaction.end = transaction.end.clone(); } } @@ -1114,16 +1116,17 @@ impl Buffer { let selection_set_ids = self .autoindent_requests .drain(..) - .filter_map(|req| req.selection_set_id) + .flat_map(|req| req.selection_set_ids.clone()) .collect::>(); - self.start_transaction(None).unwrap(); + self.start_transaction(selection_set_ids.iter().copied()) + .unwrap(); for (row, indent_column) in &indent_columns { self.set_indent_column_for_line(*row, *indent_column, cx); } - for selection_set_id in selection_set_ids { - if let Some(set) = self.selections.get(&selection_set_id) { + for selection_set_id in &selection_set_ids { + if let Some(set) = self.selections.get(selection_set_id) { let new_selections = set .selections .iter() @@ -1149,12 +1152,13 @@ impl Buffer { selection.clone() }) .collect::>(); - self.update_selection_set(selection_set_id, new_selections, cx) + self.update_selection_set(*selection_set_id, new_selections, cx) .unwrap(); } } - self.end_transaction(None, cx).unwrap(); + self.end_transaction(selection_set_ids.iter().copied(), cx) + .unwrap(); } pub fn indent_column_for_line(&self, row: u32) -> u32 { @@ -1382,20 +1386,28 @@ impl Buffer { self.deferred_ops.len() } - pub fn start_transaction(&mut self, set_id: Option) -> Result<()> { - self.start_transaction_at(set_id, Instant::now()) + pub fn start_transaction( + &mut self, + selection_set_ids: impl IntoIterator, + ) -> Result<()> { + self.start_transaction_at(selection_set_ids, Instant::now()) } - fn start_transaction_at(&mut self, set_id: Option, now: Instant) -> Result<()> { - let selections = if let Some(set_id) = set_id { - let set = self - .selections - .get(&set_id) - .ok_or_else(|| anyhow!("invalid selection set {:?}", set_id))?; - Some((set_id, set.selections.clone())) - } else { - None - }; + fn start_transaction_at( + &mut self, + selection_set_ids: impl IntoIterator, + now: Instant, + ) -> Result<()> { + let selections = selection_set_ids + .into_iter() + .map(|set_id| { + let set = self + .selections + .get(&set_id) + .expect("invalid selection set id"); + (set_id, set.selections.clone()) + }) + .collect(); self.history .start_transaction(self.version.clone(), self.is_dirty(), selections, now); Ok(()) @@ -1403,27 +1415,28 @@ impl Buffer { pub fn end_transaction( &mut self, - set_id: Option, + selection_set_ids: impl IntoIterator, cx: &mut ModelContext, ) -> Result<()> { - self.end_transaction_at(set_id, Instant::now(), cx) + self.end_transaction_at(selection_set_ids, Instant::now(), cx) } fn end_transaction_at( &mut self, - set_id: Option, + selection_set_ids: impl IntoIterator, now: Instant, cx: &mut ModelContext, ) -> Result<()> { - let selections = if let Some(set_id) = set_id { - let set = self - .selections - .get(&set_id) - .ok_or_else(|| anyhow!("invalid selection set {:?}", set_id))?; - Some((set_id, set.selections.clone())) - } else { - None - }; + let selections = selection_set_ids + .into_iter() + .map(|set_id| { + let set = self + .selections + .get(&set_id) + .expect("invalid selection set id"); + (set_id, set.selections.clone()) + }) + .collect(); if let Some(transaction) = self.history.end_transaction(selections, now) { let since = transaction.start.clone(); @@ -1544,16 +1557,17 @@ impl Buffer { }))); } - let selection_set_id = self + let selection_set_ids = self .history .undo_stack .last() .unwrap() .selections_before - .as_ref() - .map(|(set_id, _)| *set_id); + .keys() + .copied() + .collect(); self.autoindent_requests.push(Arc::new(AutoindentRequest { - selection_set_id, + selection_set_ids, before_edit, edited, inserted, @@ -1953,7 +1967,7 @@ impl Buffer { if let Some(transaction) = self.history.pop_undo().cloned() { let selections = transaction.selections_before.clone(); self.undo_or_redo(transaction, cx).unwrap(); - if let Some((set_id, selections)) = selections { + for (set_id, selections) in selections { let _ = self.update_selection_set(set_id, selections, cx); } } @@ -1972,7 +1986,7 @@ impl Buffer { if let Some(transaction) = self.history.pop_redo().cloned() { let selections = transaction.selections_after.clone(); self.undo_or_redo(transaction, cx).unwrap(); - if let Some((set_id, selections)) = selections { + for (set_id, selections) in selections { let _ = self.update_selection_set(set_id, selections, cx); } }