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.
This commit is contained in:
Nathan Sobo 2021-10-11 17:22:18 -06:00
parent 47372e7342
commit 561857fdf2

View file

@ -201,7 +201,7 @@ struct SyntaxTree {
#[derive(Clone)] #[derive(Clone)]
struct AutoindentRequest { struct AutoindentRequest {
selection_set_id: Option<SelectionSetId>, selection_set_ids: HashSet<SelectionSetId>,
before_edit: Snapshot, before_edit: Snapshot,
edited: AnchorSet, edited: AnchorSet,
inserted: Option<AnchorRangeSet>, inserted: Option<AnchorRangeSet>,
@ -214,8 +214,8 @@ struct Transaction {
buffer_was_dirty: bool, buffer_was_dirty: bool,
edits: Vec<clock::Local>, edits: Vec<clock::Local>,
ranges: Vec<Range<usize>>, ranges: Vec<Range<usize>>,
selections_before: Option<(SelectionSetId, Arc<[Selection]>)>, selections_before: HashMap<SelectionSetId, Arc<[Selection]>>,
selections_after: Option<(SelectionSetId, Arc<[Selection]>)>, selections_after: HashMap<SelectionSetId, Arc<[Selection]>>,
first_edit_at: Instant, first_edit_at: Instant,
last_edit_at: Instant, last_edit_at: Instant,
} }
@ -299,7 +299,7 @@ impl History {
&mut self, &mut self,
start: clock::Global, start: clock::Global,
buffer_was_dirty: bool, buffer_was_dirty: bool,
selections: Option<(SelectionSetId, Arc<[Selection]>)>, selections_before: HashMap<SelectionSetId, Arc<[Selection]>>,
now: Instant, now: Instant,
) { ) {
self.transaction_depth += 1; self.transaction_depth += 1;
@ -310,8 +310,8 @@ impl History {
buffer_was_dirty, buffer_was_dirty,
edits: Vec::new(), edits: Vec::new(),
ranges: Vec::new(), ranges: Vec::new(),
selections_before: selections, selections_before,
selections_after: None, selections_after: Default::default(),
first_edit_at: now, first_edit_at: now,
last_edit_at: now, last_edit_at: now,
}); });
@ -320,7 +320,7 @@ impl History {
fn end_transaction( fn end_transaction(
&mut self, &mut self,
selections: Option<(SelectionSetId, Arc<[Selection]>)>, selections_after: HashMap<SelectionSetId, Arc<[Selection]>>,
now: Instant, now: Instant,
) -> Option<&Transaction> { ) -> Option<&Transaction> {
assert_ne!(self.transaction_depth, 0); assert_ne!(self.transaction_depth, 0);
@ -331,7 +331,7 @@ impl History {
None None
} else { } else {
let transaction = self.undo_stack.last_mut().unwrap(); let transaction = self.undo_stack.last_mut().unwrap();
transaction.selections_after = selections; transaction.selections_after = selections_after;
transaction.last_edit_at = now; transaction.last_edit_at = now;
Some(transaction) Some(transaction)
} }
@ -367,7 +367,9 @@ impl History {
if let Some(transaction) = transactions_to_merge.last_mut() { if let Some(transaction) = transactions_to_merge.last_mut() {
last_transaction.last_edit_at = transaction.last_edit_at; 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(); last_transaction.end = transaction.end.clone();
} }
} }
@ -1114,16 +1116,17 @@ impl Buffer {
let selection_set_ids = self let selection_set_ids = self
.autoindent_requests .autoindent_requests
.drain(..) .drain(..)
.filter_map(|req| req.selection_set_id) .flat_map(|req| req.selection_set_ids.clone())
.collect::<HashSet<_>>(); .collect::<HashSet<_>>();
self.start_transaction(None).unwrap(); self.start_transaction(selection_set_ids.iter().copied())
.unwrap();
for (row, indent_column) in &indent_columns { for (row, indent_column) in &indent_columns {
self.set_indent_column_for_line(*row, *indent_column, cx); self.set_indent_column_for_line(*row, *indent_column, cx);
} }
for selection_set_id in selection_set_ids { for selection_set_id in &selection_set_ids {
if let Some(set) = self.selections.get(&selection_set_id) { if let Some(set) = self.selections.get(selection_set_id) {
let new_selections = set let new_selections = set
.selections .selections
.iter() .iter()
@ -1149,12 +1152,13 @@ impl Buffer {
selection.clone() selection.clone()
}) })
.collect::<Arc<[_]>>(); .collect::<Arc<[_]>>();
self.update_selection_set(selection_set_id, new_selections, cx) self.update_selection_set(*selection_set_id, new_selections, cx)
.unwrap(); .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 { pub fn indent_column_for_line(&self, row: u32) -> u32 {
@ -1382,20 +1386,28 @@ impl Buffer {
self.deferred_ops.len() self.deferred_ops.len()
} }
pub fn start_transaction(&mut self, set_id: Option<SelectionSetId>) -> Result<()> { pub fn start_transaction(
self.start_transaction_at(set_id, Instant::now()) &mut self,
selection_set_ids: impl IntoIterator<Item = SelectionSetId>,
) -> Result<()> {
self.start_transaction_at(selection_set_ids, Instant::now())
} }
fn start_transaction_at(&mut self, set_id: Option<SelectionSetId>, now: Instant) -> Result<()> { fn start_transaction_at(
let selections = if let Some(set_id) = set_id { &mut self,
let set = self selection_set_ids: impl IntoIterator<Item = SelectionSetId>,
.selections now: Instant,
.get(&set_id) ) -> Result<()> {
.ok_or_else(|| anyhow!("invalid selection set {:?}", set_id))?; let selections = selection_set_ids
Some((set_id, set.selections.clone())) .into_iter()
} else { .map(|set_id| {
None let set = self
}; .selections
.get(&set_id)
.expect("invalid selection set id");
(set_id, set.selections.clone())
})
.collect();
self.history self.history
.start_transaction(self.version.clone(), self.is_dirty(), selections, now); .start_transaction(self.version.clone(), self.is_dirty(), selections, now);
Ok(()) Ok(())
@ -1403,27 +1415,28 @@ impl Buffer {
pub fn end_transaction( pub fn end_transaction(
&mut self, &mut self,
set_id: Option<SelectionSetId>, selection_set_ids: impl IntoIterator<Item = SelectionSetId>,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Result<()> { ) -> Result<()> {
self.end_transaction_at(set_id, Instant::now(), cx) self.end_transaction_at(selection_set_ids, Instant::now(), cx)
} }
fn end_transaction_at( fn end_transaction_at(
&mut self, &mut self,
set_id: Option<SelectionSetId>, selection_set_ids: impl IntoIterator<Item = SelectionSetId>,
now: Instant, now: Instant,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Result<()> { ) -> Result<()> {
let selections = if let Some(set_id) = set_id { let selections = selection_set_ids
let set = self .into_iter()
.selections .map(|set_id| {
.get(&set_id) let set = self
.ok_or_else(|| anyhow!("invalid selection set {:?}", set_id))?; .selections
Some((set_id, set.selections.clone())) .get(&set_id)
} else { .expect("invalid selection set id");
None (set_id, set.selections.clone())
}; })
.collect();
if let Some(transaction) = self.history.end_transaction(selections, now) { if let Some(transaction) = self.history.end_transaction(selections, now) {
let since = transaction.start.clone(); let since = transaction.start.clone();
@ -1544,16 +1557,17 @@ impl Buffer {
}))); })));
} }
let selection_set_id = self let selection_set_ids = self
.history .history
.undo_stack .undo_stack
.last() .last()
.unwrap() .unwrap()
.selections_before .selections_before
.as_ref() .keys()
.map(|(set_id, _)| *set_id); .copied()
.collect();
self.autoindent_requests.push(Arc::new(AutoindentRequest { self.autoindent_requests.push(Arc::new(AutoindentRequest {
selection_set_id, selection_set_ids,
before_edit, before_edit,
edited, edited,
inserted, inserted,
@ -1953,7 +1967,7 @@ impl Buffer {
if let Some(transaction) = self.history.pop_undo().cloned() { if let Some(transaction) = self.history.pop_undo().cloned() {
let selections = transaction.selections_before.clone(); let selections = transaction.selections_before.clone();
self.undo_or_redo(transaction, cx).unwrap(); 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); let _ = self.update_selection_set(set_id, selections, cx);
} }
} }
@ -1972,7 +1986,7 @@ impl Buffer {
if let Some(transaction) = self.history.pop_redo().cloned() { if let Some(transaction) = self.history.pop_redo().cloned() {
let selections = transaction.selections_after.clone(); let selections = transaction.selections_after.clone();
self.undo_or_redo(transaction, cx).unwrap(); 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); let _ = self.update_selection_set(set_id, selections, cx);
} }
} }