1mod anchor;
2mod point;
3pub mod rope;
4mod selection;
5
6pub use anchor::*;
7use parking_lot::Mutex;
8pub use point::*;
9pub use rope::{Chunks, Rope, TextSummary};
10use seahash::SeaHasher;
11pub use selection::*;
12use similar::{ChangeTag, TextDiff};
13use tree_sitter::{InputEdit, Parser, QueryCursor};
14
15use crate::{
16 editor::Bias,
17 language::{Language, Tree},
18 operation_queue::{self, OperationQueue},
19 sum_tree::{self, FilterCursor, SeekBias, SumTree},
20 time::{self, ReplicaId},
21 worktree::FileHandle,
22};
23use anyhow::{anyhow, Result};
24use gpui::{AppContext, Entity, ModelContext, Task};
25use lazy_static::lazy_static;
26use std::{
27 cell::RefCell,
28 cmp,
29 hash::BuildHasher,
30 iter::{self, Iterator},
31 mem,
32 ops::Range,
33 str,
34 sync::Arc,
35 time::{Duration, Instant, SystemTime, UNIX_EPOCH},
36};
37
38const UNDO_GROUP_INTERVAL: Duration = Duration::from_millis(300);
39
40#[derive(Clone, Default)]
41struct DeterministicState;
42
43impl BuildHasher for DeterministicState {
44 type Hasher = SeaHasher;
45
46 fn build_hasher(&self) -> Self::Hasher {
47 SeaHasher::new()
48 }
49}
50
51#[cfg(test)]
52type HashMap<K, V> = std::collections::HashMap<K, V, DeterministicState>;
53
54#[cfg(test)]
55type HashSet<T> = std::collections::HashSet<T, DeterministicState>;
56
57#[cfg(not(test))]
58type HashMap<K, V> = std::collections::HashMap<K, V>;
59
60#[cfg(not(test))]
61type HashSet<T> = std::collections::HashSet<T>;
62
63thread_local! {
64 pub static PARSER: RefCell<Parser> = RefCell::new(Parser::new());
65}
66
67pub struct Buffer {
68 fragments: SumTree<Fragment>,
69 visible_text: Rope,
70 deleted_text: Rope,
71 insertion_splits: HashMap<time::Local, SumTree<InsertionSplit>>,
72 pub version: time::Global,
73 saved_version: time::Global,
74 saved_mtime: SystemTime,
75 last_edit: time::Local,
76 undo_map: UndoMap,
77 history: History,
78 file: Option<FileHandle>,
79 language: Option<Arc<Language>>,
80 tree: Option<(Tree, time::Global)>,
81 query_cursor: Mutex<Option<tree_sitter::QueryCursor>>,
82 is_parsing: bool,
83 selections: HashMap<SelectionSetId, Arc<[Selection]>>,
84 pub selections_last_update: SelectionsVersion,
85 deferred_ops: OperationQueue<Operation>,
86 deferred_replicas: HashSet<ReplicaId>,
87 replica_id: ReplicaId,
88 local_clock: time::Local,
89 lamport_clock: time::Lamport,
90}
91
92#[derive(Clone)]
93struct Transaction {
94 start: time::Global,
95 buffer_was_dirty: bool,
96 edits: Vec<time::Local>,
97 selections_before: Option<(SelectionSetId, Arc<[Selection]>)>,
98 selections_after: Option<(SelectionSetId, Arc<[Selection]>)>,
99 first_edit_at: Instant,
100 last_edit_at: Instant,
101}
102
103#[derive(Clone)]
104pub struct History {
105 // TODO: Turn this into a String or Rope, maybe.
106 pub base_text: Arc<str>,
107 ops: HashMap<time::Local, EditOperation>,
108 undo_stack: Vec<Transaction>,
109 redo_stack: Vec<Transaction>,
110 transaction_depth: usize,
111 group_interval: Duration,
112}
113
114impl History {
115 pub fn new(base_text: Arc<str>) -> Self {
116 Self {
117 base_text,
118 ops: Default::default(),
119 undo_stack: Vec::new(),
120 redo_stack: Vec::new(),
121 transaction_depth: 0,
122 group_interval: UNDO_GROUP_INTERVAL,
123 }
124 }
125
126 fn push(&mut self, op: EditOperation) {
127 self.ops.insert(op.id, op);
128 }
129
130 fn start_transaction(
131 &mut self,
132 start: time::Global,
133 buffer_was_dirty: bool,
134 selections: Option<(SelectionSetId, Arc<[Selection]>)>,
135 now: Instant,
136 ) {
137 self.transaction_depth += 1;
138 if self.transaction_depth == 1 {
139 self.undo_stack.push(Transaction {
140 start,
141 buffer_was_dirty,
142 edits: Vec::new(),
143 selections_before: selections,
144 selections_after: None,
145 first_edit_at: now,
146 last_edit_at: now,
147 });
148 }
149 }
150
151 fn end_transaction(
152 &mut self,
153 selections: Option<(SelectionSetId, Arc<[Selection]>)>,
154 now: Instant,
155 ) -> Option<&Transaction> {
156 assert_ne!(self.transaction_depth, 0);
157 self.transaction_depth -= 1;
158 if self.transaction_depth == 0 {
159 let transaction = self.undo_stack.last_mut().unwrap();
160 transaction.selections_after = selections;
161 transaction.last_edit_at = now;
162 Some(transaction)
163 } else {
164 None
165 }
166 }
167
168 fn group(&mut self) {
169 let mut new_len = self.undo_stack.len();
170 let mut transactions = self.undo_stack.iter_mut();
171
172 if let Some(mut transaction) = transactions.next_back() {
173 for prev_transaction in transactions.next_back() {
174 if transaction.first_edit_at - prev_transaction.last_edit_at <= self.group_interval
175 {
176 prev_transaction.edits.append(&mut transaction.edits);
177 prev_transaction.last_edit_at = transaction.last_edit_at;
178 prev_transaction.selections_after = transaction.selections_after.take();
179 transaction = prev_transaction;
180 new_len -= 1;
181 } else {
182 break;
183 }
184 }
185 }
186
187 self.undo_stack.truncate(new_len);
188 }
189
190 fn push_undo(&mut self, edit_id: time::Local) {
191 assert_ne!(self.transaction_depth, 0);
192 self.undo_stack.last_mut().unwrap().edits.push(edit_id);
193 }
194
195 fn pop_undo(&mut self) -> Option<&Transaction> {
196 assert_eq!(self.transaction_depth, 0);
197 if let Some(transaction) = self.undo_stack.pop() {
198 self.redo_stack.push(transaction);
199 self.redo_stack.last()
200 } else {
201 None
202 }
203 }
204
205 fn pop_redo(&mut self) -> Option<&Transaction> {
206 assert_eq!(self.transaction_depth, 0);
207 if let Some(transaction) = self.redo_stack.pop() {
208 self.undo_stack.push(transaction);
209 self.undo_stack.last()
210 } else {
211 None
212 }
213 }
214}
215
216#[derive(Clone, Default, Debug)]
217struct UndoMap(HashMap<time::Local, Vec<UndoOperation>>);
218
219impl UndoMap {
220 fn insert(&mut self, undo: UndoOperation) {
221 self.0.entry(undo.edit_id).or_default().push(undo);
222 }
223
224 fn is_undone(&self, edit_id: time::Local) -> bool {
225 self.undo_count(edit_id) % 2 == 1
226 }
227
228 fn was_undone(&self, edit_id: time::Local, version: &time::Global) -> bool {
229 let undo_count = self
230 .0
231 .get(&edit_id)
232 .unwrap_or(&Vec::new())
233 .iter()
234 .filter(|undo| version.observed(undo.id))
235 .map(|undo| undo.count)
236 .max()
237 .unwrap_or(0);
238 undo_count % 2 == 1
239 }
240
241 fn undo_count(&self, edit_id: time::Local) -> u32 {
242 self.0
243 .get(&edit_id)
244 .unwrap_or(&Vec::new())
245 .iter()
246 .map(|undo| undo.count)
247 .max()
248 .unwrap_or(0)
249 }
250}
251
252struct Edits<'a, F: Fn(&FragmentSummary) -> bool> {
253 deleted_text: &'a Rope,
254 cursor: FilterCursor<'a, F, Fragment, FragmentTextSummary>,
255 undos: &'a UndoMap,
256 since: time::Global,
257 delta: isize,
258}
259
260#[derive(Clone, Debug, Default, Eq, PartialEq)]
261pub struct Edit {
262 pub old_range: Range<usize>,
263 pub new_range: Range<usize>,
264 pub old_lines: Point,
265}
266
267impl Edit {
268 pub fn delta(&self) -> isize {
269 (self.new_range.end - self.new_range.start) as isize
270 - (self.old_range.end - self.old_range.start) as isize
271 }
272
273 pub fn old_extent(&self) -> usize {
274 self.old_range.end - self.old_range.start
275 }
276}
277
278struct Diff {
279 base_version: time::Global,
280 new_text: Arc<str>,
281 changes: Vec<(ChangeTag, usize)>,
282}
283
284#[derive(Clone, Eq, PartialEq, Debug)]
285pub struct Insertion {
286 id: time::Local,
287 parent_id: time::Local,
288 offset_in_parent: usize,
289 lamport_timestamp: time::Lamport,
290}
291
292#[derive(Eq, PartialEq, Clone, Debug)]
293struct Fragment {
294 id: FragmentId,
295 insertion: Arc<Insertion>,
296 range_in_insertion: Range<usize>,
297 deletions: HashSet<time::Local>,
298 max_undos: time::Global,
299 visible: bool,
300}
301
302#[derive(Eq, PartialEq, Clone, Debug)]
303pub struct FragmentSummary {
304 text: FragmentTextSummary,
305 max_fragment_id: FragmentId,
306 max_version: time::Global,
307}
308
309#[derive(Default, Clone, Debug, PartialEq, Eq)]
310struct FragmentTextSummary {
311 visible: usize,
312 deleted: usize,
313}
314
315impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary {
316 fn add_summary(&mut self, summary: &'a FragmentSummary) {
317 self.visible += summary.text.visible;
318 self.deleted += summary.text.deleted;
319 }
320}
321
322#[derive(Eq, PartialEq, Clone, Debug)]
323struct InsertionSplit {
324 extent: usize,
325 fragment_id: FragmentId,
326}
327
328#[derive(Eq, PartialEq, Clone, Debug)]
329struct InsertionSplitSummary {
330 extent: usize,
331}
332
333#[derive(Clone, Debug, Eq, PartialEq)]
334pub enum Operation {
335 Edit {
336 edit: EditOperation,
337 lamport_timestamp: time::Lamport,
338 },
339 Undo {
340 undo: UndoOperation,
341 lamport_timestamp: time::Lamport,
342 },
343 UpdateSelections {
344 set_id: SelectionSetId,
345 selections: Option<Arc<[Selection]>>,
346 lamport_timestamp: time::Lamport,
347 },
348}
349
350#[derive(Clone, Debug, Eq, PartialEq)]
351pub struct EditOperation {
352 id: time::Local,
353 start_id: time::Local,
354 start_offset: usize,
355 end_id: time::Local,
356 end_offset: usize,
357 version_in_range: time::Global,
358 new_text: Option<String>,
359}
360
361#[derive(Copy, Clone, Debug, Eq, PartialEq)]
362pub struct UndoOperation {
363 id: time::Local,
364 edit_id: time::Local,
365 count: u32,
366}
367
368impl Buffer {
369 pub fn new<T: Into<Arc<str>>>(
370 replica_id: ReplicaId,
371 base_text: T,
372 ctx: &mut ModelContext<Self>,
373 ) -> Self {
374 Self::build(replica_id, History::new(base_text.into()), None, None, ctx)
375 }
376
377 pub fn from_history(
378 replica_id: ReplicaId,
379 history: History,
380 file: Option<FileHandle>,
381 language: Option<Arc<Language>>,
382 ctx: &mut ModelContext<Self>,
383 ) -> Self {
384 Self::build(replica_id, history, file, language, ctx)
385 }
386
387 fn build(
388 replica_id: ReplicaId,
389 history: History,
390 file: Option<FileHandle>,
391 language: Option<Arc<Language>>,
392 ctx: &mut ModelContext<Self>,
393 ) -> Self {
394 let saved_mtime;
395 if let Some(file) = file.as_ref() {
396 saved_mtime = file.mtime();
397 file.observe_from_model(ctx, |this, file, ctx| {
398 let version = this.version.clone();
399 if this.version == this.saved_version {
400 if file.is_deleted() {
401 ctx.emit(Event::Dirtied);
402 } else {
403 ctx.spawn(|handle, mut ctx| async move {
404 let (current_version, history) = handle.read_with(&ctx, |this, ctx| {
405 (this.version.clone(), file.load_history(ctx.as_ref()))
406 });
407 if let (Ok(history), true) = (history.await, current_version == version)
408 {
409 let diff = handle
410 .read_with(&ctx, |this, ctx| this.diff(history.base_text, ctx))
411 .await;
412 handle.update(&mut ctx, |this, ctx| {
413 if let Some(_ops) = this.set_text_via_diff(diff, ctx) {
414 this.saved_version = this.version.clone();
415 this.saved_mtime = file.mtime();
416 ctx.emit(Event::Reloaded);
417 }
418 });
419 }
420 })
421 .detach();
422 }
423 }
424 ctx.emit(Event::FileHandleChanged);
425 });
426 } else {
427 saved_mtime = UNIX_EPOCH;
428 }
429
430 let mut visible_text = Rope::new();
431 let mut insertion_splits = HashMap::default();
432 let mut fragments = SumTree::new();
433
434 let base_text = Rope::from(history.base_text.as_ref());
435 let base_insertion = Arc::new(Insertion {
436 id: time::Local::default(),
437 parent_id: time::Local::default(),
438 offset_in_parent: 0,
439 lamport_timestamp: time::Lamport::default(),
440 });
441
442 insertion_splits.insert(
443 base_insertion.id,
444 SumTree::from_item(
445 InsertionSplit {
446 fragment_id: FragmentId::min_value().clone(),
447 extent: 0,
448 },
449 &(),
450 ),
451 );
452 fragments.push(
453 Fragment::new(
454 FragmentId::min_value().clone(),
455 base_insertion.clone(),
456 0..0,
457 ),
458 &(),
459 );
460
461 if base_text.len() > 0 {
462 let base_fragment_id =
463 FragmentId::between(&FragmentId::min_value(), &FragmentId::max_value());
464 let range_in_insertion = 0..base_text.len();
465
466 visible_text = base_text.clone();
467 insertion_splits.get_mut(&base_insertion.id).unwrap().push(
468 InsertionSplit {
469 fragment_id: base_fragment_id.clone(),
470 extent: range_in_insertion.end,
471 },
472 &(),
473 );
474 fragments.push(
475 Fragment::new(base_fragment_id, base_insertion, range_in_insertion.clone()),
476 &(),
477 );
478 }
479
480 let mut result = Self {
481 visible_text,
482 deleted_text: Rope::new(),
483 fragments,
484 insertion_splits,
485 version: time::Global::new(),
486 saved_version: time::Global::new(),
487 last_edit: time::Local::default(),
488 undo_map: Default::default(),
489 history,
490 file,
491 tree: None,
492 is_parsing: false,
493 language,
494 query_cursor: Mutex::new(Some(QueryCursor::new())),
495 saved_mtime,
496 selections: HashMap::default(),
497 selections_last_update: 0,
498 deferred_ops: OperationQueue::new(),
499 deferred_replicas: HashSet::default(),
500 replica_id,
501 local_clock: time::Local::new(replica_id),
502 lamport_clock: time::Lamport::new(replica_id),
503 };
504 result.reparse(ctx);
505 result
506 }
507
508 pub fn snapshot(&self) -> Rope {
509 self.visible_text.clone()
510 }
511
512 pub fn file(&self) -> Option<&FileHandle> {
513 self.file.as_ref()
514 }
515
516 pub fn save(
517 &mut self,
518 new_file: Option<FileHandle>,
519 ctx: &mut ModelContext<Self>,
520 ) -> Task<Result<()>> {
521 let snapshot = self.snapshot();
522 let version = self.version.clone();
523 let file = self.file.clone();
524
525 ctx.spawn(|handle, mut ctx| async move {
526 if let Some(file) = new_file.as_ref().or(file.as_ref()) {
527 let result = ctx.read(|ctx| file.save(snapshot, ctx.as_ref())).await;
528 if result.is_ok() {
529 handle.update(&mut ctx, |me, ctx| me.did_save(version, new_file, ctx));
530 }
531 result
532 } else {
533 Ok(())
534 }
535 })
536 }
537
538 fn did_save(
539 &mut self,
540 version: time::Global,
541 file: Option<FileHandle>,
542 ctx: &mut ModelContext<Buffer>,
543 ) {
544 if file.is_some() {
545 self.file = file;
546 }
547 if let Some(file) = &self.file {
548 self.saved_mtime = file.mtime();
549 }
550 self.saved_version = version;
551 ctx.emit(Event::Saved);
552 }
553
554 pub fn syntax_tree(&mut self) -> Option<Tree> {
555 if let Some((mut tree, tree_version)) = self.tree.take() {
556 let mut delta = 0_isize;
557 for Edit {
558 old_range,
559 new_range,
560 old_lines,
561 } in self.edits_since(tree_version.clone())
562 {
563 let start_offset = (old_range.start as isize + delta) as usize;
564 let start_point = self.visible_text.to_point(start_offset);
565 let old_bytes = old_range.end - old_range.start;
566 let new_bytes = new_range.end - new_range.start;
567 tree.edit(&InputEdit {
568 start_byte: start_offset,
569 old_end_byte: start_offset + old_bytes,
570 new_end_byte: start_offset + new_bytes,
571 start_position: start_point.into(),
572 old_end_position: (start_point + old_lines).into(),
573 new_end_position: self.visible_text.to_point(start_offset + new_bytes).into(),
574 });
575 delta += new_bytes as isize - old_bytes as isize;
576 }
577 let result = tree.clone();
578 self.tree = Some((tree, self.version()));
579 Some(result)
580 } else {
581 None
582 }
583 }
584
585 fn should_reparse(&self) -> bool {
586 self.tree
587 .as_ref()
588 .map_or(true, |(_, tree_version)| *tree_version != self.version)
589 }
590
591 fn reparse(&mut self, ctx: &mut ModelContext<Self>) {
592 // Avoid spawning a new parsing task if the buffer is already being reparsed
593 // due to an earlier edit.
594 if self.is_parsing {
595 return;
596 }
597
598 if let Some(language) = self.language.clone() {
599 self.is_parsing = true;
600 ctx.spawn(|handle, mut ctx| async move {
601 while handle.read_with(&ctx, |this, _| this.should_reparse()) {
602 // The parse tree is out of date, so grab the syntax tree to synchronously
603 // splice all the edits that have happened since the last parse.
604 let new_tree = handle.update(&mut ctx, |this, _| this.syntax_tree());
605 let (new_text, new_version) = handle
606 .read_with(&ctx, |this, _| (this.visible_text.clone(), this.version()));
607
608 // Parse the current text in a background thread.
609 let new_tree = ctx
610 .background_executor()
611 .spawn({
612 let language = language.clone();
613 async move { Self::parse_text(&new_text, new_tree, &language) }
614 })
615 .await;
616
617 handle.update(&mut ctx, |this, ctx| {
618 this.tree = Some((new_tree, new_version));
619 ctx.emit(Event::Reparsed);
620 });
621 }
622 handle.update(&mut ctx, |this, _| this.is_parsing = false);
623 })
624 .detach();
625 }
626 }
627
628 fn parse_text(text: &Rope, old_tree: Option<Tree>, language: &Language) -> Tree {
629 PARSER.with(|parser| {
630 let mut parser = parser.borrow_mut();
631 parser
632 .set_language(language.grammar)
633 .expect("incompatible grammar");
634 let mut chunks = text.chunks_in_range(0..text.len());
635 let tree = parser
636 .parse_with(
637 &mut move |offset, _| {
638 chunks.seek(offset);
639 chunks.next().unwrap_or("").as_bytes()
640 },
641 old_tree.as_ref(),
642 )
643 .unwrap();
644 tree
645 })
646 }
647
648 fn diff(&self, new_text: Arc<str>, ctx: &AppContext) -> Task<Diff> {
649 // TODO: it would be nice to not allocate here.
650 let old_text = self.text();
651 let base_version = self.version();
652 ctx.background_executor().spawn(async move {
653 let changes = TextDiff::from_lines(old_text.as_str(), new_text.as_ref())
654 .iter_all_changes()
655 .map(|c| (c.tag(), c.value().len()))
656 .collect::<Vec<_>>();
657 Diff {
658 base_version,
659 new_text,
660 changes,
661 }
662 })
663 }
664
665 fn set_text_via_diff(
666 &mut self,
667 diff: Diff,
668 ctx: &mut ModelContext<Self>,
669 ) -> Option<Vec<Operation>> {
670 if self.version == diff.base_version {
671 self.start_transaction(None).unwrap();
672 let mut operations = Vec::new();
673 let mut offset = 0;
674 for (tag, len) in diff.changes {
675 let range = offset..(offset + len);
676 match tag {
677 ChangeTag::Equal => offset += len,
678 ChangeTag::Delete => operations
679 .extend_from_slice(&self.edit(Some(range), "", Some(ctx)).unwrap()),
680 ChangeTag::Insert => {
681 operations.extend_from_slice(
682 &self
683 .edit(Some(offset..offset), &diff.new_text[range], Some(ctx))
684 .unwrap(),
685 );
686 offset += len;
687 }
688 }
689 }
690 self.end_transaction(None, Some(ctx)).unwrap();
691 Some(operations)
692 } else {
693 None
694 }
695 }
696
697 pub fn is_dirty(&self) -> bool {
698 self.version > self.saved_version || self.file.as_ref().map_or(false, |f| f.is_deleted())
699 }
700
701 pub fn has_conflict(&self) -> bool {
702 self.version > self.saved_version
703 && self
704 .file
705 .as_ref()
706 .map_or(false, |f| f.mtime() > self.saved_mtime)
707 }
708
709 pub fn version(&self) -> time::Global {
710 self.version.clone()
711 }
712
713 pub fn text_summary(&self) -> TextSummary {
714 self.visible_text.summary()
715 }
716
717 pub fn text_summary_for_range(&self, range: Range<usize>) -> TextSummary {
718 self.visible_text.cursor(range.start).summary(range.end)
719 }
720
721 pub fn len(&self) -> usize {
722 self.fragments.extent::<usize>()
723 }
724
725 pub fn line_len(&self, row: u32) -> u32 {
726 let row_start_offset = Point::new(row, 0).to_offset(self);
727 let row_end_offset = if row >= self.max_point().row {
728 self.len()
729 } else {
730 Point::new(row + 1, 0).to_offset(self) - 1
731 };
732 (row_end_offset - row_start_offset) as u32
733 }
734
735 pub fn max_point(&self) -> Point {
736 self.visible_text.max_point()
737 }
738
739 pub fn line(&self, row: u32) -> String {
740 self.chars_at(Point::new(row, 0))
741 .take_while(|c| *c != '\n')
742 .collect()
743 }
744
745 pub fn text(&self) -> String {
746 self.text_for_range(0..self.len()).collect()
747 }
748
749 pub fn text_for_range<'a, T: ToOffset>(&'a self, range: Range<T>) -> Chunks<'a> {
750 let start = range.start.to_offset(self);
751 let end = range.end.to_offset(self);
752 self.visible_text.chunks_in_range(start..end)
753 }
754
755 pub fn highlighted_text_for_range<'a, T: ToOffset>(
756 &'a self,
757 range: Range<T>,
758 ) -> impl Iterator<Item = (&'a str, Option<usize>)> {
759 if let (Some(language), Some((tree, _))) = (&self.language, self.tree.as_ref()) {
760 let visible_text = &self.visible_text;
761 let mut cursor = self
762 .query_cursor
763 .lock()
764 .take()
765 .unwrap_or_else(|| QueryCursor::new());
766 let start = range.start.to_offset(self);
767 let end = range.end.to_offset(self);
768 cursor.set_byte_range(start, end);
769 let chunks = self.visible_text.chunks_in_range(start..end);
770 let cursor_ref = unsafe { mem::transmute::<_, &'static mut QueryCursor>(&mut cursor) };
771 let captures = cursor_ref.captures(
772 &language.highlight_query,
773 tree.root_node(),
774 move |node: tree_sitter::Node| {
775 visible_text
776 .chunks_in_range(node.byte_range())
777 .map(str::as_bytes)
778 },
779 );
780
781 HighlightedChunksIter {
782 captures: captures.peekable(),
783 chunks,
784 stack: Default::default(),
785 offset: start,
786 query_cursor: Some(cursor),
787 buffer: self,
788 }
789 } else {
790 todo!()
791 }
792 }
793
794 pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
795 self.chars_at(0)
796 }
797
798 pub fn chars_at<T: ToOffset>(&self, position: T) -> impl Iterator<Item = char> + '_ {
799 let offset = position.to_offset(self);
800 self.visible_text.chars_at(offset)
801 }
802
803 pub fn selections_changed_since(&self, since: SelectionsVersion) -> bool {
804 self.selections_last_update != since
805 }
806
807 pub fn edits_since<'a>(&'a self, since: time::Global) -> impl 'a + Iterator<Item = Edit> {
808 let since_2 = since.clone();
809 let cursor = self
810 .fragments
811 .filter(move |summary| summary.max_version.changed_since(&since_2));
812
813 Edits {
814 deleted_text: &self.deleted_text,
815 cursor,
816 undos: &self.undo_map,
817 since,
818 delta: 0,
819 }
820 }
821
822 pub fn deferred_ops_len(&self) -> usize {
823 self.deferred_ops.len()
824 }
825
826 pub fn start_transaction(&mut self, set_id: Option<SelectionSetId>) -> Result<()> {
827 self.start_transaction_at(set_id, Instant::now())
828 }
829
830 fn start_transaction_at(&mut self, set_id: Option<SelectionSetId>, now: Instant) -> Result<()> {
831 let selections = if let Some(set_id) = set_id {
832 let selections = self
833 .selections
834 .get(&set_id)
835 .ok_or_else(|| anyhow!("invalid selection set {:?}", set_id))?;
836 Some((set_id, selections.clone()))
837 } else {
838 None
839 };
840 self.history
841 .start_transaction(self.version.clone(), self.is_dirty(), selections, now);
842 Ok(())
843 }
844
845 pub fn end_transaction(
846 &mut self,
847 set_id: Option<SelectionSetId>,
848 ctx: Option<&mut ModelContext<Self>>,
849 ) -> Result<()> {
850 self.end_transaction_at(set_id, Instant::now(), ctx)
851 }
852
853 fn end_transaction_at(
854 &mut self,
855 set_id: Option<SelectionSetId>,
856 now: Instant,
857 ctx: Option<&mut ModelContext<Self>>,
858 ) -> Result<()> {
859 let selections = if let Some(set_id) = set_id {
860 let selections = self
861 .selections
862 .get(&set_id)
863 .ok_or_else(|| anyhow!("invalid selection set {:?}", set_id))?;
864 Some((set_id, selections.clone()))
865 } else {
866 None
867 };
868
869 if let Some(transaction) = self.history.end_transaction(selections, now) {
870 let since = transaction.start.clone();
871 let was_dirty = transaction.buffer_was_dirty;
872 self.history.group();
873
874 if let Some(ctx) = ctx {
875 ctx.notify();
876
877 if self.edits_since(since).next().is_some() {
878 self.did_edit(was_dirty, ctx);
879 self.reparse(ctx);
880 }
881 }
882 }
883
884 Ok(())
885 }
886
887 pub fn edit<I, S, T>(
888 &mut self,
889 old_ranges: I,
890 new_text: T,
891 ctx: Option<&mut ModelContext<Self>>,
892 ) -> Result<Vec<Operation>>
893 where
894 I: IntoIterator<Item = Range<S>>,
895 S: ToOffset,
896 T: Into<String>,
897 {
898 self.start_transaction_at(None, Instant::now())?;
899
900 let new_text = new_text.into();
901 let old_ranges = old_ranges
902 .into_iter()
903 .map(|range| range.start.to_offset(self)..range.end.to_offset(self))
904 .collect::<Vec<Range<usize>>>();
905
906 let new_text = if new_text.len() > 0 {
907 Some(new_text)
908 } else {
909 None
910 };
911
912 let has_new_text = new_text.is_some();
913 let ops = self.splice_fragments(
914 old_ranges
915 .into_iter()
916 .filter(|old_range| has_new_text || old_range.end > old_range.start),
917 new_text.into(),
918 );
919
920 for op in &ops {
921 if let Operation::Edit { edit, .. } = op {
922 self.history.push(edit.clone());
923 self.history.push_undo(edit.id);
924 }
925 }
926
927 if let Some(op) = ops.last() {
928 if let Operation::Edit { edit, .. } = op {
929 self.last_edit = edit.id;
930 self.version.observe(edit.id);
931 } else {
932 unreachable!()
933 }
934 }
935
936 self.end_transaction_at(None, Instant::now(), ctx)?;
937
938 Ok(ops)
939 }
940
941 fn did_edit(&self, was_dirty: bool, ctx: &mut ModelContext<Self>) {
942 ctx.emit(Event::Edited);
943 if !was_dirty {
944 ctx.emit(Event::Dirtied);
945 }
946 }
947
948 pub fn add_selection_set(
949 &mut self,
950 selections: impl Into<Arc<[Selection]>>,
951 ctx: Option<&mut ModelContext<Self>>,
952 ) -> (SelectionSetId, Operation) {
953 let selections = selections.into();
954 let lamport_timestamp = self.lamport_clock.tick();
955 self.selections
956 .insert(lamport_timestamp, Arc::clone(&selections));
957 self.selections_last_update += 1;
958
959 if let Some(ctx) = ctx {
960 ctx.notify();
961 }
962
963 (
964 lamport_timestamp,
965 Operation::UpdateSelections {
966 set_id: lamport_timestamp,
967 selections: Some(selections),
968 lamport_timestamp,
969 },
970 )
971 }
972
973 pub fn update_selection_set(
974 &mut self,
975 set_id: SelectionSetId,
976 selections: impl Into<Arc<[Selection]>>,
977 ctx: Option<&mut ModelContext<Self>>,
978 ) -> Result<Operation> {
979 let selections = selections.into();
980 self.selections.insert(set_id, selections.clone());
981
982 let lamport_timestamp = self.lamport_clock.tick();
983 self.selections_last_update += 1;
984
985 if let Some(ctx) = ctx {
986 ctx.notify();
987 }
988
989 Ok(Operation::UpdateSelections {
990 set_id,
991 selections: Some(selections),
992 lamport_timestamp,
993 })
994 }
995
996 pub fn remove_selection_set(
997 &mut self,
998 set_id: SelectionSetId,
999 ctx: Option<&mut ModelContext<Self>>,
1000 ) -> Result<Operation> {
1001 self.selections
1002 .remove(&set_id)
1003 .ok_or_else(|| anyhow!("invalid selection set id {:?}", set_id))?;
1004 let lamport_timestamp = self.lamport_clock.tick();
1005 self.selections_last_update += 1;
1006
1007 if let Some(ctx) = ctx {
1008 ctx.notify();
1009 }
1010
1011 Ok(Operation::UpdateSelections {
1012 set_id,
1013 selections: None,
1014 lamport_timestamp,
1015 })
1016 }
1017
1018 pub fn selections(&self, set_id: SelectionSetId) -> Result<&[Selection]> {
1019 self.selections
1020 .get(&set_id)
1021 .map(|s| s.as_ref())
1022 .ok_or_else(|| anyhow!("invalid selection set id {:?}", set_id))
1023 }
1024
1025 pub fn apply_ops<I: IntoIterator<Item = Operation>>(
1026 &mut self,
1027 ops: I,
1028 ctx: Option<&mut ModelContext<Self>>,
1029 ) -> Result<()> {
1030 let was_dirty = self.is_dirty();
1031 let old_version = self.version.clone();
1032
1033 let mut deferred_ops = Vec::new();
1034 for op in ops {
1035 if self.can_apply_op(&op) {
1036 self.apply_op(op)?;
1037 } else {
1038 self.deferred_replicas.insert(op.replica_id());
1039 deferred_ops.push(op);
1040 }
1041 }
1042 self.deferred_ops.insert(deferred_ops);
1043 self.flush_deferred_ops()?;
1044
1045 if let Some(ctx) = ctx {
1046 ctx.notify();
1047 if self.edits_since(old_version).next().is_some() {
1048 self.did_edit(was_dirty, ctx);
1049 self.reparse(ctx);
1050 }
1051 }
1052
1053 Ok(())
1054 }
1055
1056 fn apply_op(&mut self, op: Operation) -> Result<()> {
1057 match op {
1058 Operation::Edit {
1059 edit,
1060 lamport_timestamp,
1061 ..
1062 } => {
1063 if !self.version.observed(edit.id) {
1064 self.apply_edit(
1065 edit.start_id,
1066 edit.start_offset,
1067 edit.end_id,
1068 edit.end_offset,
1069 edit.new_text.as_deref(),
1070 &edit.version_in_range,
1071 edit.id,
1072 lamport_timestamp,
1073 )?;
1074 self.version.observe(edit.id);
1075 self.history.push(edit);
1076 }
1077 }
1078 Operation::Undo {
1079 undo,
1080 lamport_timestamp,
1081 } => {
1082 if !self.version.observed(undo.id) {
1083 self.apply_undo(undo)?;
1084 self.version.observe(undo.id);
1085 self.lamport_clock.observe(lamport_timestamp);
1086 }
1087 }
1088 Operation::UpdateSelections {
1089 set_id,
1090 selections,
1091 lamport_timestamp,
1092 } => {
1093 if let Some(selections) = selections {
1094 self.selections.insert(set_id, selections);
1095 } else {
1096 self.selections.remove(&set_id);
1097 }
1098 self.lamport_clock.observe(lamport_timestamp);
1099 self.selections_last_update += 1;
1100 }
1101 }
1102 Ok(())
1103 }
1104
1105 fn apply_edit(
1106 &mut self,
1107 start_id: time::Local,
1108 start_offset: usize,
1109 end_id: time::Local,
1110 end_offset: usize,
1111 mut new_text: Option<&str>,
1112 version_in_range: &time::Global,
1113 local_timestamp: time::Local,
1114 lamport_timestamp: time::Lamport,
1115 ) -> Result<()> {
1116 let start_fragment_id = self.resolve_fragment_id(start_id, start_offset)?;
1117 let end_fragment_id = self.resolve_fragment_id(end_id, end_offset)?;
1118
1119 let mut old_visible_text = Rope::new();
1120 let mut old_deleted_text = Rope::new();
1121 let mut old_fragments = SumTree::new();
1122 mem::swap(&mut old_visible_text, &mut self.visible_text);
1123 mem::swap(&mut old_deleted_text, &mut self.deleted_text);
1124 mem::swap(&mut old_fragments, &mut self.fragments);
1125
1126 let mut fragments_cursor = old_fragments.cursor::<FragmentIdRef, FragmentTextSummary>();
1127
1128 let mut new_fragments =
1129 fragments_cursor.slice(&FragmentIdRef::new(&start_fragment_id), SeekBias::Left, &());
1130 let mut new_ropes =
1131 RopeBuilder::new(old_visible_text.cursor(0), old_deleted_text.cursor(0));
1132 new_ropes.push_tree(new_fragments.summary().text);
1133
1134 let start_fragment = fragments_cursor.item().unwrap();
1135 if start_offset == start_fragment.range_in_insertion.end {
1136 let fragment = fragments_cursor.item().unwrap().clone();
1137 new_ropes.push_fragment(&fragment, fragment.visible);
1138 new_fragments.push(fragment, &());
1139 fragments_cursor.next();
1140 }
1141
1142 while let Some(fragment) = fragments_cursor.item() {
1143 if new_text.is_none() && fragment.id > end_fragment_id {
1144 break;
1145 }
1146
1147 let mut fragment = fragment.clone();
1148
1149 if fragment.id == start_fragment_id || fragment.id == end_fragment_id {
1150 let split_start = if start_fragment_id == fragment.id {
1151 start_offset
1152 } else {
1153 fragment.range_in_insertion.start
1154 };
1155 let split_end = if end_fragment_id == fragment.id {
1156 end_offset
1157 } else {
1158 fragment.range_in_insertion.end
1159 };
1160 let (before_range, within_range, after_range) = self.split_fragment(
1161 fragments_cursor.prev_item().as_ref().unwrap(),
1162 &fragment,
1163 split_start..split_end,
1164 );
1165 let insertion = if let Some(new_text) = new_text {
1166 let prev_fragment = fragments_cursor.prev_item();
1167 Some(self.build_fragment_to_insert(
1168 before_range.as_ref().or(prev_fragment).unwrap(),
1169 within_range.as_ref().or(after_range.as_ref()),
1170 new_text,
1171 local_timestamp,
1172 lamport_timestamp,
1173 ))
1174 } else {
1175 None
1176 };
1177 if let Some(fragment) = before_range {
1178 new_ropes.push_fragment(&fragment, fragment.visible);
1179 new_fragments.push(fragment, &());
1180 }
1181 if let Some(fragment) = insertion {
1182 new_ropes.push_str(new_text.take().unwrap());
1183 new_fragments.push(fragment, &());
1184 }
1185 if let Some(mut fragment) = within_range {
1186 let fragment_was_visible = fragment.visible;
1187 if fragment.was_visible(&version_in_range, &self.undo_map) {
1188 fragment.deletions.insert(local_timestamp);
1189 if fragment.visible {
1190 fragment.visible = false;
1191 }
1192 }
1193
1194 new_ropes.push_fragment(&fragment, fragment_was_visible);
1195 new_fragments.push(fragment, &());
1196 }
1197 if let Some(fragment) = after_range {
1198 new_ropes.push_fragment(&fragment, fragment.visible);
1199 new_fragments.push(fragment, &());
1200 }
1201 } else {
1202 if new_text.is_some() && lamport_timestamp > fragment.insertion.lamport_timestamp {
1203 let new_text = new_text.take().unwrap();
1204 let fragment = self.build_fragment_to_insert(
1205 fragments_cursor.prev_item().as_ref().unwrap(),
1206 Some(&fragment),
1207 new_text,
1208 local_timestamp,
1209 lamport_timestamp,
1210 );
1211 new_ropes.push_str(new_text);
1212 new_fragments.push(fragment, &());
1213 }
1214
1215 let fragment_was_visible = fragment.visible;
1216 if fragment.id < end_fragment_id
1217 && fragment.was_visible(&version_in_range, &self.undo_map)
1218 {
1219 fragment.deletions.insert(local_timestamp);
1220 if fragment.visible {
1221 fragment.visible = false;
1222 }
1223 }
1224
1225 new_ropes.push_fragment(&fragment, fragment_was_visible);
1226 new_fragments.push(fragment, &());
1227 }
1228
1229 fragments_cursor.next();
1230 }
1231
1232 if let Some(new_text) = new_text {
1233 let fragment = self.build_fragment_to_insert(
1234 fragments_cursor.prev_item().as_ref().unwrap(),
1235 None,
1236 new_text,
1237 local_timestamp,
1238 lamport_timestamp,
1239 );
1240 new_ropes.push_str(new_text);
1241 new_fragments.push(fragment, &());
1242 }
1243
1244 let (visible_text, deleted_text) = new_ropes.finish();
1245 new_fragments.push_tree(fragments_cursor.suffix(&()), &());
1246
1247 self.fragments = new_fragments;
1248 self.visible_text = visible_text;
1249 self.deleted_text = deleted_text;
1250 self.local_clock.observe(local_timestamp);
1251 self.lamport_clock.observe(lamport_timestamp);
1252 Ok(())
1253 }
1254
1255 pub fn undo(&mut self, mut ctx: Option<&mut ModelContext<Self>>) -> Vec<Operation> {
1256 let was_dirty = self.is_dirty();
1257 let old_version = self.version.clone();
1258
1259 let mut ops = Vec::new();
1260 if let Some(transaction) = self.history.pop_undo() {
1261 let selections = transaction.selections_before.clone();
1262 for edit_id in transaction.edits.clone() {
1263 ops.push(self.undo_or_redo(edit_id).unwrap());
1264 }
1265
1266 if let Some((set_id, selections)) = selections {
1267 let _ = self.update_selection_set(set_id, selections, ctx.as_deref_mut());
1268 }
1269 }
1270
1271 if let Some(ctx) = ctx {
1272 ctx.notify();
1273 if self.edits_since(old_version).next().is_some() {
1274 self.did_edit(was_dirty, ctx);
1275 self.reparse(ctx);
1276 }
1277 }
1278
1279 ops
1280 }
1281
1282 pub fn redo(&mut self, mut ctx: Option<&mut ModelContext<Self>>) -> Vec<Operation> {
1283 let was_dirty = self.is_dirty();
1284 let old_version = self.version.clone();
1285
1286 let mut ops = Vec::new();
1287 if let Some(transaction) = self.history.pop_redo() {
1288 let selections = transaction.selections_after.clone();
1289 for edit_id in transaction.edits.clone() {
1290 ops.push(self.undo_or_redo(edit_id).unwrap());
1291 }
1292
1293 if let Some((set_id, selections)) = selections {
1294 let _ = self.update_selection_set(set_id, selections, ctx.as_deref_mut());
1295 }
1296 }
1297
1298 if let Some(ctx) = ctx {
1299 ctx.notify();
1300 if self.edits_since(old_version).next().is_some() {
1301 self.did_edit(was_dirty, ctx);
1302 self.reparse(ctx);
1303 }
1304 }
1305
1306 ops
1307 }
1308
1309 fn undo_or_redo(&mut self, edit_id: time::Local) -> Result<Operation> {
1310 let undo = UndoOperation {
1311 id: self.local_clock.tick(),
1312 edit_id,
1313 count: self.undo_map.undo_count(edit_id) + 1,
1314 };
1315 self.apply_undo(undo)?;
1316 self.version.observe(undo.id);
1317
1318 Ok(Operation::Undo {
1319 undo,
1320 lamport_timestamp: self.lamport_clock.tick(),
1321 })
1322 }
1323
1324 fn apply_undo(&mut self, undo: UndoOperation) -> Result<()> {
1325 let mut new_fragments;
1326 let mut old_visible_text = Rope::new();
1327 let mut old_deleted_text = Rope::new();
1328 mem::swap(&mut old_visible_text, &mut self.visible_text);
1329 mem::swap(&mut old_deleted_text, &mut self.deleted_text);
1330 let mut new_ropes =
1331 RopeBuilder::new(old_visible_text.cursor(0), old_deleted_text.cursor(0));
1332
1333 self.undo_map.insert(undo);
1334 let edit = &self.history.ops[&undo.edit_id];
1335 let start_fragment_id = self.resolve_fragment_id(edit.start_id, edit.start_offset)?;
1336 let end_fragment_id = self.resolve_fragment_id(edit.end_id, edit.end_offset)?;
1337
1338 let mut fragments_cursor = self.fragments.cursor::<FragmentIdRef, ()>();
1339
1340 if edit.start_id == edit.end_id && edit.start_offset == edit.end_offset {
1341 let splits = &self.insertion_splits[&undo.edit_id];
1342 let mut insertion_splits = splits.cursor::<(), ()>().map(|s| &s.fragment_id).peekable();
1343
1344 let first_split_id = insertion_splits.next().unwrap();
1345 new_fragments =
1346 fragments_cursor.slice(&FragmentIdRef::new(first_split_id), SeekBias::Left, &());
1347 new_ropes.push_tree(new_fragments.summary().text);
1348
1349 loop {
1350 let mut fragment = fragments_cursor.item().unwrap().clone();
1351 let was_visible = fragment.visible;
1352 fragment.visible = fragment.is_visible(&self.undo_map);
1353 fragment.max_undos.observe(undo.id);
1354
1355 new_ropes.push_fragment(&fragment, was_visible);
1356 new_fragments.push(fragment.clone(), &());
1357
1358 fragments_cursor.next();
1359 if let Some(split_id) = insertion_splits.next() {
1360 let slice =
1361 fragments_cursor.slice(&FragmentIdRef::new(split_id), SeekBias::Left, &());
1362 new_ropes.push_tree(slice.summary().text);
1363 new_fragments.push_tree(slice, &());
1364 } else {
1365 break;
1366 }
1367 }
1368 } else {
1369 new_fragments = fragments_cursor.slice(
1370 &FragmentIdRef::new(&start_fragment_id),
1371 SeekBias::Left,
1372 &(),
1373 );
1374 new_ropes.push_tree(new_fragments.summary().text);
1375
1376 while let Some(fragment) = fragments_cursor.item() {
1377 if fragment.id > end_fragment_id {
1378 break;
1379 } else {
1380 let mut fragment = fragment.clone();
1381 let fragment_was_visible = fragment.visible;
1382 if edit.version_in_range.observed(fragment.insertion.id)
1383 || fragment.insertion.id == undo.edit_id
1384 {
1385 fragment.visible = fragment.is_visible(&self.undo_map);
1386 fragment.max_undos.observe(undo.id);
1387 }
1388
1389 new_ropes.push_fragment(&fragment, fragment_was_visible);
1390 new_fragments.push(fragment, &());
1391 fragments_cursor.next();
1392 }
1393 }
1394 }
1395
1396 new_fragments.push_tree(fragments_cursor.suffix(&()), &());
1397 let (visible_text, deleted_text) = new_ropes.finish();
1398 drop(fragments_cursor);
1399
1400 self.fragments = new_fragments;
1401 self.visible_text = visible_text;
1402 self.deleted_text = deleted_text;
1403
1404 Ok(())
1405 }
1406
1407 fn flush_deferred_ops(&mut self) -> Result<()> {
1408 self.deferred_replicas.clear();
1409 let mut deferred_ops = Vec::new();
1410 for op in self.deferred_ops.drain().cursor().cloned() {
1411 if self.can_apply_op(&op) {
1412 self.apply_op(op)?;
1413 } else {
1414 self.deferred_replicas.insert(op.replica_id());
1415 deferred_ops.push(op);
1416 }
1417 }
1418 self.deferred_ops.insert(deferred_ops);
1419 Ok(())
1420 }
1421
1422 fn can_apply_op(&self, op: &Operation) -> bool {
1423 if self.deferred_replicas.contains(&op.replica_id()) {
1424 false
1425 } else {
1426 match op {
1427 Operation::Edit { edit, .. } => {
1428 self.version.observed(edit.start_id)
1429 && self.version.observed(edit.end_id)
1430 && edit.version_in_range <= self.version
1431 }
1432 Operation::Undo { undo, .. } => self.version.observed(undo.edit_id),
1433 Operation::UpdateSelections { selections, .. } => {
1434 if let Some(selections) = selections {
1435 selections.iter().all(|selection| {
1436 let contains_start = match selection.start {
1437 Anchor::Middle { insertion_id, .. } => {
1438 self.version.observed(insertion_id)
1439 }
1440 _ => true,
1441 };
1442 let contains_end = match selection.end {
1443 Anchor::Middle { insertion_id, .. } => {
1444 self.version.observed(insertion_id)
1445 }
1446 _ => true,
1447 };
1448 contains_start && contains_end
1449 })
1450 } else {
1451 true
1452 }
1453 }
1454 }
1455 }
1456 }
1457
1458 fn resolve_fragment_id(&self, edit_id: time::Local, offset: usize) -> Result<FragmentId> {
1459 let split_tree = self
1460 .insertion_splits
1461 .get(&edit_id)
1462 .ok_or_else(|| anyhow!("invalid operation"))?;
1463 let mut cursor = split_tree.cursor::<usize, ()>();
1464 cursor.seek(&offset, SeekBias::Left, &());
1465 Ok(cursor
1466 .item()
1467 .ok_or_else(|| anyhow!("invalid operation"))?
1468 .fragment_id
1469 .clone())
1470 }
1471
1472 fn splice_fragments<I>(&mut self, mut old_ranges: I, new_text: Option<String>) -> Vec<Operation>
1473 where
1474 I: Iterator<Item = Range<usize>>,
1475 {
1476 let mut cur_range = old_ranges.next();
1477 if cur_range.is_none() {
1478 return Vec::new();
1479 }
1480
1481 let mut ops = Vec::with_capacity(old_ranges.size_hint().0);
1482
1483 let mut old_fragments = SumTree::new();
1484 let mut old_visible_text = Rope::new();
1485 let mut old_deleted_text = Rope::new();
1486 mem::swap(&mut old_visible_text, &mut self.visible_text);
1487 mem::swap(&mut old_deleted_text, &mut self.deleted_text);
1488 mem::swap(&mut old_fragments, &mut self.fragments);
1489
1490 let mut fragments_cursor = old_fragments.cursor::<usize, usize>();
1491 let mut new_fragments =
1492 fragments_cursor.slice(&cur_range.as_ref().unwrap().start, SeekBias::Right, &());
1493
1494 let mut new_ropes =
1495 RopeBuilder::new(old_visible_text.cursor(0), old_deleted_text.cursor(0));
1496 new_ropes.push_tree(new_fragments.summary().text);
1497
1498 let mut start_id = None;
1499 let mut start_offset = None;
1500 let mut end_id = None;
1501 let mut end_offset = None;
1502 let mut version_in_range = time::Global::new();
1503
1504 let mut local_timestamp = self.local_clock.tick();
1505 let mut lamport_timestamp = self.lamport_clock.tick();
1506
1507 while cur_range.is_some() && fragments_cursor.item().is_some() {
1508 let mut fragment = fragments_cursor.item().unwrap().clone();
1509 let fragment_summary = fragments_cursor.item_summary().unwrap();
1510 let mut fragment_start = *fragments_cursor.start();
1511 let mut fragment_end = fragment_start + fragment.visible_len();
1512 let fragment_was_visible = fragment.visible;
1513
1514 let old_split_tree = self
1515 .insertion_splits
1516 .remove(&fragment.insertion.id)
1517 .unwrap();
1518 let mut splits_cursor = old_split_tree.cursor::<usize, ()>();
1519 let mut new_split_tree =
1520 splits_cursor.slice(&fragment.range_in_insertion.start, SeekBias::Right, &());
1521
1522 // Find all splices that start or end within the current fragment. Then, split the
1523 // fragment and reassemble it in both trees accounting for the deleted and the newly
1524 // inserted text.
1525 while cur_range.as_ref().map_or(false, |r| r.start < fragment_end) {
1526 let range = cur_range.clone().unwrap();
1527 if range.start > fragment_start {
1528 let mut prefix = fragment.clone();
1529 prefix.range_in_insertion.end =
1530 prefix.range_in_insertion.start + (range.start - fragment_start);
1531 prefix.id =
1532 FragmentId::between(&new_fragments.last().unwrap().id, &fragment.id);
1533 fragment.range_in_insertion.start = prefix.range_in_insertion.end;
1534
1535 new_ropes.push_fragment(&prefix, prefix.visible);
1536 new_fragments.push(prefix.clone(), &());
1537 new_split_tree.push(
1538 InsertionSplit {
1539 extent: prefix.range_in_insertion.end - prefix.range_in_insertion.start,
1540 fragment_id: prefix.id,
1541 },
1542 &(),
1543 );
1544 fragment_start = range.start;
1545 }
1546
1547 if range.end == fragment_start {
1548 end_id = Some(new_fragments.last().unwrap().insertion.id);
1549 end_offset = Some(new_fragments.last().unwrap().range_in_insertion.end);
1550 } else if range.end == fragment_end {
1551 end_id = Some(fragment.insertion.id);
1552 end_offset = Some(fragment.range_in_insertion.end);
1553 }
1554
1555 if range.start == fragment_start {
1556 start_id = Some(new_fragments.last().unwrap().insertion.id);
1557 start_offset = Some(new_fragments.last().unwrap().range_in_insertion.end);
1558
1559 if let Some(new_text) = new_text.clone() {
1560 let new_fragment = self.build_fragment_to_insert(
1561 &new_fragments.last().unwrap(),
1562 Some(&fragment),
1563 &new_text,
1564 local_timestamp,
1565 lamport_timestamp,
1566 );
1567
1568 new_ropes.push_str(&new_text);
1569 new_fragments.push(new_fragment, &());
1570 }
1571 }
1572
1573 if range.end < fragment_end {
1574 if range.end > fragment_start {
1575 let mut prefix = fragment.clone();
1576 prefix.range_in_insertion.end =
1577 prefix.range_in_insertion.start + (range.end - fragment_start);
1578 prefix.id =
1579 FragmentId::between(&new_fragments.last().unwrap().id, &fragment.id);
1580 version_in_range.observe_all(&fragment_summary.max_version);
1581 if prefix.visible {
1582 prefix.deletions.insert(local_timestamp);
1583 prefix.visible = false;
1584 }
1585 fragment.range_in_insertion.start = prefix.range_in_insertion.end;
1586 new_ropes.push_fragment(&prefix, fragment_was_visible);
1587 new_fragments.push(prefix.clone(), &());
1588 new_split_tree.push(
1589 InsertionSplit {
1590 extent: prefix.range_in_insertion.end
1591 - prefix.range_in_insertion.start,
1592 fragment_id: prefix.id,
1593 },
1594 &(),
1595 );
1596 fragment_start = range.end;
1597 end_id = Some(fragment.insertion.id);
1598 end_offset = Some(fragment.range_in_insertion.start);
1599 }
1600 } else {
1601 version_in_range.observe_all(&fragment_summary.max_version);
1602 if fragment.visible {
1603 fragment.deletions.insert(local_timestamp);
1604 fragment.visible = false;
1605 }
1606 }
1607
1608 // If the splice ends inside this fragment, we can advance to the next splice and
1609 // check if it also intersects the current fragment. Otherwise we break out of the
1610 // loop and find the first fragment that the splice does not contain fully.
1611 if range.end <= fragment_end {
1612 ops.push(Operation::Edit {
1613 edit: EditOperation {
1614 id: local_timestamp,
1615 start_id: start_id.unwrap(),
1616 start_offset: start_offset.unwrap(),
1617 end_id: end_id.unwrap(),
1618 end_offset: end_offset.unwrap(),
1619 version_in_range,
1620 new_text: new_text.clone(),
1621 },
1622 lamport_timestamp,
1623 });
1624
1625 start_id = None;
1626 start_offset = None;
1627 end_id = None;
1628 end_offset = None;
1629 version_in_range = time::Global::new();
1630 cur_range = old_ranges.next();
1631 if cur_range.is_some() {
1632 local_timestamp = self.local_clock.tick();
1633 lamport_timestamp = self.lamport_clock.tick();
1634 }
1635 } else {
1636 break;
1637 }
1638 }
1639 new_split_tree.push(
1640 InsertionSplit {
1641 extent: fragment.range_in_insertion.end - fragment.range_in_insertion.start,
1642 fragment_id: fragment.id.clone(),
1643 },
1644 &(),
1645 );
1646 splits_cursor.next();
1647 new_split_tree.push_tree(
1648 splits_cursor.slice(&old_split_tree.extent::<usize>(), SeekBias::Right, &()),
1649 &(),
1650 );
1651 self.insertion_splits
1652 .insert(fragment.insertion.id, new_split_tree);
1653
1654 new_ropes.push_fragment(&fragment, fragment_was_visible);
1655 new_fragments.push(fragment, &());
1656
1657 // Scan forward until we find a fragment that is not fully contained by the current splice.
1658 fragments_cursor.next();
1659 if let Some(range) = cur_range.clone() {
1660 while let Some(fragment) = fragments_cursor.item() {
1661 let fragment_summary = fragments_cursor.item_summary().unwrap();
1662 let fragment_was_visible = fragment.visible;
1663 fragment_start = *fragments_cursor.start();
1664 fragment_end = fragment_start + fragment.visible_len();
1665 if range.start < fragment_start && range.end >= fragment_end {
1666 let mut new_fragment = fragment.clone();
1667 version_in_range.observe_all(&fragment_summary.max_version);
1668 if new_fragment.visible {
1669 new_fragment.deletions.insert(local_timestamp);
1670 new_fragment.visible = false;
1671 }
1672
1673 new_ropes.push_fragment(&new_fragment, fragment_was_visible);
1674 new_fragments.push(new_fragment, &());
1675 fragments_cursor.next();
1676
1677 if range.end == fragment_end {
1678 end_id = Some(fragment.insertion.id);
1679 end_offset = Some(fragment.range_in_insertion.end);
1680 ops.push(Operation::Edit {
1681 edit: EditOperation {
1682 id: local_timestamp,
1683 start_id: start_id.unwrap(),
1684 start_offset: start_offset.unwrap(),
1685 end_id: end_id.unwrap(),
1686 end_offset: end_offset.unwrap(),
1687 version_in_range,
1688 new_text: new_text.clone(),
1689 },
1690 lamport_timestamp,
1691 });
1692
1693 start_id = None;
1694 start_offset = None;
1695 end_id = None;
1696 end_offset = None;
1697 version_in_range = time::Global::new();
1698
1699 cur_range = old_ranges.next();
1700 if cur_range.is_some() {
1701 local_timestamp = self.local_clock.tick();
1702 lamport_timestamp = self.lamport_clock.tick();
1703 }
1704 break;
1705 }
1706 } else {
1707 break;
1708 }
1709 }
1710
1711 // If the splice we are currently evaluating starts after the end of the fragment
1712 // that the cursor is parked at, we should seek to the next splice's start range
1713 // and push all the fragments in between into the new tree.
1714 if cur_range.as_ref().map_or(false, |r| r.start > fragment_end) {
1715 let slice = fragments_cursor.slice(
1716 &cur_range.as_ref().unwrap().start,
1717 SeekBias::Right,
1718 &(),
1719 );
1720 new_ropes.push_tree(slice.summary().text);
1721 new_fragments.push_tree(slice, &());
1722 }
1723 }
1724 }
1725
1726 // Handle range that is at the end of the buffer if it exists. There should never be
1727 // multiple because ranges must be disjoint.
1728 if cur_range.is_some() {
1729 debug_assert_eq!(old_ranges.next(), None);
1730 let last_fragment = new_fragments.last().unwrap();
1731 ops.push(Operation::Edit {
1732 edit: EditOperation {
1733 id: local_timestamp,
1734 start_id: last_fragment.insertion.id,
1735 start_offset: last_fragment.range_in_insertion.end,
1736 end_id: last_fragment.insertion.id,
1737 end_offset: last_fragment.range_in_insertion.end,
1738 version_in_range: time::Global::new(),
1739 // TODO: avoid cloning the String.
1740 new_text: new_text.clone(),
1741 },
1742 lamport_timestamp,
1743 });
1744
1745 if let Some(new_text) = new_text {
1746 let new_fragment = self.build_fragment_to_insert(
1747 &last_fragment,
1748 None,
1749 &new_text,
1750 local_timestamp,
1751 lamport_timestamp,
1752 );
1753
1754 new_ropes.push_str(&new_text);
1755 new_fragments.push(new_fragment, &());
1756 }
1757 }
1758
1759 new_fragments.push_tree(fragments_cursor.suffix(&()), &());
1760 let (visible_text, deleted_text) = new_ropes.finish();
1761
1762 self.fragments = new_fragments;
1763 self.visible_text = visible_text;
1764 self.deleted_text = deleted_text;
1765 ops
1766 }
1767
1768 fn split_fragment(
1769 &mut self,
1770 prev_fragment: &Fragment,
1771 fragment: &Fragment,
1772 range: Range<usize>,
1773 ) -> (Option<Fragment>, Option<Fragment>, Option<Fragment>) {
1774 debug_assert!(range.start >= fragment.range_in_insertion.start);
1775 debug_assert!(range.start <= fragment.range_in_insertion.end);
1776 debug_assert!(range.end <= fragment.range_in_insertion.end);
1777 debug_assert!(range.end >= fragment.range_in_insertion.start);
1778
1779 if range.end == fragment.range_in_insertion.start {
1780 (None, None, Some(fragment.clone()))
1781 } else if range.start == fragment.range_in_insertion.end {
1782 (Some(fragment.clone()), None, None)
1783 } else if range.start == fragment.range_in_insertion.start
1784 && range.end == fragment.range_in_insertion.end
1785 {
1786 (None, Some(fragment.clone()), None)
1787 } else {
1788 let mut prefix = fragment.clone();
1789
1790 let after_range = if range.end < fragment.range_in_insertion.end {
1791 let mut suffix = prefix.clone();
1792 suffix.range_in_insertion.start = range.end;
1793 prefix.range_in_insertion.end = range.end;
1794 prefix.id = FragmentId::between(&prev_fragment.id, &suffix.id);
1795 Some(suffix)
1796 } else {
1797 None
1798 };
1799
1800 let within_range = if range.start != range.end {
1801 let mut suffix = prefix.clone();
1802 suffix.range_in_insertion.start = range.start;
1803 prefix.range_in_insertion.end = range.start;
1804 prefix.id = FragmentId::between(&prev_fragment.id, &suffix.id);
1805 Some(suffix)
1806 } else {
1807 None
1808 };
1809
1810 let before_range = if range.start > fragment.range_in_insertion.start {
1811 Some(prefix)
1812 } else {
1813 None
1814 };
1815
1816 let old_split_tree = self
1817 .insertion_splits
1818 .remove(&fragment.insertion.id)
1819 .unwrap();
1820 let mut cursor = old_split_tree.cursor::<usize, ()>();
1821 let mut new_split_tree =
1822 cursor.slice(&fragment.range_in_insertion.start, SeekBias::Right, &());
1823
1824 if let Some(ref fragment) = before_range {
1825 new_split_tree.push(
1826 InsertionSplit {
1827 extent: range.start - fragment.range_in_insertion.start,
1828 fragment_id: fragment.id.clone(),
1829 },
1830 &(),
1831 );
1832 }
1833
1834 if let Some(ref fragment) = within_range {
1835 new_split_tree.push(
1836 InsertionSplit {
1837 extent: range.end - range.start,
1838 fragment_id: fragment.id.clone(),
1839 },
1840 &(),
1841 );
1842 }
1843
1844 if let Some(ref fragment) = after_range {
1845 new_split_tree.push(
1846 InsertionSplit {
1847 extent: fragment.range_in_insertion.end - range.end,
1848 fragment_id: fragment.id.clone(),
1849 },
1850 &(),
1851 );
1852 }
1853
1854 cursor.next();
1855 new_split_tree.push_tree(
1856 cursor.slice(&old_split_tree.extent::<usize>(), SeekBias::Right, &()),
1857 &(),
1858 );
1859
1860 self.insertion_splits
1861 .insert(fragment.insertion.id, new_split_tree);
1862
1863 (before_range, within_range, after_range)
1864 }
1865 }
1866
1867 fn build_fragment_to_insert(
1868 &mut self,
1869 prev_fragment: &Fragment,
1870 next_fragment: Option<&Fragment>,
1871 text: &str,
1872 insertion_id: time::Local,
1873 lamport_timestamp: time::Lamport,
1874 ) -> Fragment {
1875 let new_fragment_id = FragmentId::between(
1876 &prev_fragment.id,
1877 next_fragment
1878 .map(|f| &f.id)
1879 .unwrap_or(&FragmentId::max_value()),
1880 );
1881
1882 let range_in_insertion = 0..text.len();
1883 let mut split_tree = SumTree::new();
1884 split_tree.push(
1885 InsertionSplit {
1886 extent: range_in_insertion.len(),
1887 fragment_id: new_fragment_id.clone(),
1888 },
1889 &(),
1890 );
1891 self.insertion_splits.insert(insertion_id, split_tree);
1892
1893 Fragment::new(
1894 new_fragment_id,
1895 Arc::new(Insertion {
1896 id: insertion_id,
1897 parent_id: prev_fragment.insertion.id,
1898 offset_in_parent: prev_fragment.range_in_insertion.end,
1899 lamport_timestamp,
1900 }),
1901 range_in_insertion,
1902 )
1903 }
1904
1905 pub fn anchor_before<T: ToOffset>(&self, position: T) -> Anchor {
1906 self.anchor_at(position, AnchorBias::Left)
1907 }
1908
1909 pub fn anchor_after<T: ToOffset>(&self, position: T) -> Anchor {
1910 self.anchor_at(position, AnchorBias::Right)
1911 }
1912
1913 pub fn anchor_at<T: ToOffset>(&self, position: T, bias: AnchorBias) -> Anchor {
1914 let offset = position.to_offset(self);
1915 let max_offset = self.len();
1916 assert!(offset <= max_offset, "offset is out of range");
1917
1918 let seek_bias;
1919 match bias {
1920 AnchorBias::Left => {
1921 if offset == 0 {
1922 return Anchor::Start;
1923 } else {
1924 seek_bias = SeekBias::Left;
1925 }
1926 }
1927 AnchorBias::Right => {
1928 if offset == max_offset {
1929 return Anchor::End;
1930 } else {
1931 seek_bias = SeekBias::Right;
1932 }
1933 }
1934 };
1935
1936 let mut cursor = self.fragments.cursor::<usize, usize>();
1937 cursor.seek(&offset, seek_bias, &());
1938 let fragment = cursor.item().unwrap();
1939 let offset_in_fragment = offset - cursor.start();
1940 let offset_in_insertion = fragment.range_in_insertion.start + offset_in_fragment;
1941 let anchor = Anchor::Middle {
1942 insertion_id: fragment.insertion.id,
1943 offset: offset_in_insertion,
1944 bias,
1945 };
1946 anchor
1947 }
1948
1949 fn fragment_id_for_anchor(&self, anchor: &Anchor) -> Result<&FragmentId> {
1950 match anchor {
1951 Anchor::Start => Ok(FragmentId::max_value()),
1952 Anchor::End => Ok(FragmentId::min_value()),
1953 Anchor::Middle {
1954 insertion_id,
1955 offset,
1956 bias,
1957 ..
1958 } => {
1959 let seek_bias = match bias {
1960 AnchorBias::Left => SeekBias::Left,
1961 AnchorBias::Right => SeekBias::Right,
1962 };
1963
1964 let splits = self
1965 .insertion_splits
1966 .get(&insertion_id)
1967 .ok_or_else(|| anyhow!("split does not exist for insertion id"))?;
1968 let mut splits_cursor = splits.cursor::<usize, ()>();
1969 splits_cursor.seek(offset, seek_bias, &());
1970 splits_cursor
1971 .item()
1972 .ok_or_else(|| anyhow!("split offset is out of range"))
1973 .map(|split| &split.fragment_id)
1974 }
1975 }
1976 }
1977
1978 fn summary_for_anchor(&self, anchor: &Anchor) -> TextSummary {
1979 match anchor {
1980 Anchor::Start => TextSummary::default(),
1981 Anchor::End => self.text_summary(),
1982 Anchor::Middle {
1983 insertion_id,
1984 offset,
1985 bias,
1986 } => {
1987 let seek_bias = match bias {
1988 AnchorBias::Left => SeekBias::Left,
1989 AnchorBias::Right => SeekBias::Right,
1990 };
1991
1992 let splits = self
1993 .insertion_splits
1994 .get(&insertion_id)
1995 .expect("split does not exist for insertion id");
1996 let mut splits_cursor = splits.cursor::<usize, ()>();
1997 splits_cursor.seek(offset, seek_bias, &());
1998 let split = splits_cursor.item().expect("split offset is out of range");
1999
2000 let mut fragments_cursor = self.fragments.cursor::<FragmentIdRef, usize>();
2001 fragments_cursor.seek(&FragmentIdRef::new(&split.fragment_id), SeekBias::Left, &());
2002 let fragment = fragments_cursor.item().expect("fragment id does not exist");
2003
2004 let mut ix = *fragments_cursor.start();
2005 if fragment.visible {
2006 ix += offset - fragment.range_in_insertion.start;
2007 }
2008 self.text_summary_for_range(0..ix)
2009 }
2010 }
2011 }
2012
2013 pub fn point_for_offset(&self, offset: usize) -> Result<Point> {
2014 if offset <= self.len() {
2015 Ok(self.text_summary_for_range(0..offset).lines)
2016 } else {
2017 Err(anyhow!("offset out of bounds"))
2018 }
2019 }
2020
2021 pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
2022 self.visible_text.clip_point(point, bias)
2023 }
2024
2025 pub fn clip_offset(&self, offset: usize, bias: Bias) -> usize {
2026 self.visible_text.clip_offset(offset, bias)
2027 }
2028}
2029
2030impl Clone for Buffer {
2031 fn clone(&self) -> Self {
2032 Self {
2033 fragments: self.fragments.clone(),
2034 visible_text: self.visible_text.clone(),
2035 deleted_text: self.deleted_text.clone(),
2036 insertion_splits: self.insertion_splits.clone(),
2037 version: self.version.clone(),
2038 saved_version: self.saved_version.clone(),
2039 saved_mtime: self.saved_mtime,
2040 last_edit: self.last_edit.clone(),
2041 undo_map: self.undo_map.clone(),
2042 history: self.history.clone(),
2043 selections: self.selections.clone(),
2044 selections_last_update: self.selections_last_update.clone(),
2045 deferred_ops: self.deferred_ops.clone(),
2046 file: self.file.clone(),
2047 language: self.language.clone(),
2048 tree: self.tree.clone(),
2049 is_parsing: false,
2050 query_cursor: Mutex::new(Some(QueryCursor::new())),
2051 deferred_replicas: self.deferred_replicas.clone(),
2052 replica_id: self.replica_id,
2053 local_clock: self.local_clock.clone(),
2054 lamport_clock: self.lamport_clock.clone(),
2055 }
2056 }
2057}
2058
2059struct RopeBuilder<'a> {
2060 old_visible_cursor: rope::Cursor<'a>,
2061 old_deleted_cursor: rope::Cursor<'a>,
2062 new_visible: Rope,
2063 new_deleted: Rope,
2064}
2065
2066impl<'a> RopeBuilder<'a> {
2067 fn new(old_visible_cursor: rope::Cursor<'a>, old_deleted_cursor: rope::Cursor<'a>) -> Self {
2068 Self {
2069 old_visible_cursor,
2070 old_deleted_cursor,
2071 new_visible: Rope::new(),
2072 new_deleted: Rope::new(),
2073 }
2074 }
2075
2076 fn push_tree(&mut self, len: FragmentTextSummary) {
2077 self.push(len.visible, true, true);
2078 self.push(len.deleted, false, false);
2079 }
2080
2081 fn push_fragment(&mut self, fragment: &Fragment, was_visible: bool) {
2082 self.push(fragment.len(), was_visible, fragment.visible)
2083 }
2084
2085 fn push(&mut self, len: usize, was_visible: bool, is_visible: bool) {
2086 let text = if was_visible {
2087 self.old_visible_cursor
2088 .slice(self.old_visible_cursor.offset() + len)
2089 } else {
2090 self.old_deleted_cursor
2091 .slice(self.old_deleted_cursor.offset() + len)
2092 };
2093 if is_visible {
2094 self.new_visible.append(text);
2095 } else {
2096 self.new_deleted.append(text);
2097 }
2098 }
2099
2100 fn push_str(&mut self, text: &str) {
2101 self.new_visible.push(text);
2102 }
2103
2104 fn finish(mut self) -> (Rope, Rope) {
2105 self.new_visible.append(self.old_visible_cursor.suffix());
2106 self.new_deleted.append(self.old_deleted_cursor.suffix());
2107 (self.new_visible, self.new_deleted)
2108 }
2109}
2110
2111#[derive(Clone, Debug, Eq, PartialEq)]
2112pub enum Event {
2113 Edited,
2114 Dirtied,
2115 Saved,
2116 FileHandleChanged,
2117 Reloaded,
2118 Reparsed,
2119}
2120
2121impl Entity for Buffer {
2122 type Event = Event;
2123}
2124
2125impl<'a, F: Fn(&FragmentSummary) -> bool> Iterator for Edits<'a, F> {
2126 type Item = Edit;
2127
2128 fn next(&mut self) -> Option<Self::Item> {
2129 let mut change: Option<Edit> = None;
2130
2131 while let Some(fragment) = self.cursor.item() {
2132 let new_offset = self.cursor.start().visible;
2133 let old_offset = (new_offset as isize - self.delta) as usize;
2134
2135 if !fragment.was_visible(&self.since, &self.undos) && fragment.visible {
2136 if let Some(ref mut change) = change {
2137 if change.new_range.end == new_offset {
2138 change.new_range.end += fragment.len();
2139 self.delta += fragment.len() as isize;
2140 } else {
2141 break;
2142 }
2143 } else {
2144 change = Some(Edit {
2145 old_range: old_offset..old_offset,
2146 new_range: new_offset..new_offset + fragment.len(),
2147 old_lines: Point::zero(),
2148 });
2149 self.delta += fragment.len() as isize;
2150 }
2151 } else if fragment.was_visible(&self.since, &self.undos) && !fragment.visible {
2152 let deleted_start = self.cursor.start().deleted;
2153 let old_lines = self.deleted_text.to_point(deleted_start + fragment.len())
2154 - self.deleted_text.to_point(deleted_start);
2155 if let Some(ref mut change) = change {
2156 if change.new_range.end == new_offset {
2157 change.old_range.end += fragment.len();
2158 change.old_lines += &old_lines;
2159 self.delta -= fragment.len() as isize;
2160 } else {
2161 break;
2162 }
2163 } else {
2164 change = Some(Edit {
2165 old_range: old_offset..old_offset + fragment.len(),
2166 new_range: new_offset..new_offset,
2167 old_lines,
2168 });
2169 self.delta -= fragment.len() as isize;
2170 }
2171 }
2172
2173 self.cursor.next();
2174 }
2175
2176 change
2177 }
2178}
2179
2180pub struct HighlightedChunksIter<'a, T: tree_sitter::TextProvider<'a>> {
2181 chunks: Chunks<'a>,
2182 captures: iter::Peekable<tree_sitter::QueryCaptures<'a, 'a, T>>,
2183 stack: Vec<(usize, usize)>,
2184 offset: usize,
2185 query_cursor: Option<QueryCursor>,
2186 buffer: &'a Buffer,
2187}
2188
2189impl<'a, T: tree_sitter::TextProvider<'a>> Iterator for HighlightedChunksIter<'a, T> {
2190 type Item = (&'a str, Option<usize>);
2191
2192 fn next(&mut self) -> Option<Self::Item> {
2193 while let Some((parent_capture_end, _)) = self.stack.last() {
2194 if *parent_capture_end <= self.offset {
2195 self.stack.pop();
2196 } else {
2197 break;
2198 }
2199 }
2200
2201 let mut next_capture_start = usize::MAX;
2202 while let Some((mat, capture_ix)) = self.captures.peek() {
2203 let capture = mat.captures[*capture_ix as usize];
2204 if self.offset < capture.node.start_byte() {
2205 next_capture_start = capture.node.start_byte();
2206 break;
2207 } else {
2208 self.stack
2209 .push((capture.node.end_byte(), capture.index as usize));
2210 self.captures.next().unwrap();
2211 }
2212 }
2213
2214 if let Some(chunk) = self.chunks.peek() {
2215 let chunk_start = self.offset;
2216 let mut chunk_end = (self.chunks.offset() + chunk.len()).min(next_capture_start);
2217 let mut capture_ix = None;
2218 if let Some((parent_capture_end, parent_capture_ix)) = self.stack.last() {
2219 chunk_end = chunk_end.min(*parent_capture_end);
2220 capture_ix = Some(*parent_capture_ix);
2221 }
2222
2223 let slice =
2224 &chunk[chunk_start - self.chunks.offset()..chunk_end - self.chunks.offset()];
2225 self.offset = chunk_end;
2226 if self.offset == self.chunks.offset() + chunk.len() {
2227 self.chunks.next().unwrap();
2228 }
2229
2230 Some((slice, capture_ix))
2231 } else {
2232 None
2233 }
2234 }
2235}
2236
2237impl<'a, T: tree_sitter::TextProvider<'a>> Drop for HighlightedChunksIter<'a, T> {
2238 fn drop(&mut self) {
2239 let query_cursor = self.query_cursor.take().unwrap();
2240 let mut buffer_cursor = self.buffer.query_cursor.lock();
2241 if buffer_cursor.is_none() {
2242 *buffer_cursor = Some(query_cursor);
2243 }
2244 }
2245}
2246
2247#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Debug)]
2248struct FragmentId(Arc<[u16]>);
2249
2250lazy_static! {
2251 static ref FRAGMENT_ID_EMPTY: FragmentId = FragmentId(Arc::from([]));
2252 static ref FRAGMENT_ID_MIN_VALUE: FragmentId = FragmentId(Arc::from([0 as u16]));
2253 static ref FRAGMENT_ID_MAX_VALUE: FragmentId = FragmentId(Arc::from([u16::max_value()]));
2254}
2255
2256impl Default for FragmentId {
2257 fn default() -> Self {
2258 FRAGMENT_ID_EMPTY.clone()
2259 }
2260}
2261
2262impl FragmentId {
2263 fn min_value() -> &'static Self {
2264 &FRAGMENT_ID_MIN_VALUE
2265 }
2266
2267 fn max_value() -> &'static Self {
2268 &FRAGMENT_ID_MAX_VALUE
2269 }
2270
2271 fn between(left: &Self, right: &Self) -> Self {
2272 Self::between_with_max(left, right, u16::max_value())
2273 }
2274
2275 fn between_with_max(left: &Self, right: &Self, max_value: u16) -> Self {
2276 let mut new_entries = Vec::new();
2277
2278 let left_entries = left.0.iter().cloned().chain(iter::repeat(0));
2279 let right_entries = right.0.iter().cloned().chain(iter::repeat(max_value));
2280 for (l, r) in left_entries.zip(right_entries) {
2281 let interval = r - l;
2282 if interval > 1 {
2283 new_entries.push(l + cmp::max(1, cmp::min(8, interval / 2)));
2284 break;
2285 } else {
2286 new_entries.push(l);
2287 }
2288 }
2289
2290 FragmentId(Arc::from(new_entries))
2291 }
2292}
2293
2294#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Debug, Default)]
2295struct FragmentIdRef<'a>(Option<&'a FragmentId>);
2296
2297impl<'a> FragmentIdRef<'a> {
2298 fn new(id: &'a FragmentId) -> Self {
2299 Self(Some(id))
2300 }
2301}
2302
2303impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentIdRef<'a> {
2304 fn add_summary(&mut self, summary: &'a FragmentSummary) {
2305 self.0 = Some(&summary.max_fragment_id)
2306 }
2307}
2308
2309impl Fragment {
2310 fn new(id: FragmentId, insertion: Arc<Insertion>, range_in_insertion: Range<usize>) -> Self {
2311 Self {
2312 id,
2313 insertion,
2314 range_in_insertion,
2315 deletions: Default::default(),
2316 max_undos: Default::default(),
2317 visible: true,
2318 }
2319 }
2320
2321 fn is_visible(&self, undos: &UndoMap) -> bool {
2322 !undos.is_undone(self.insertion.id) && self.deletions.iter().all(|d| undos.is_undone(*d))
2323 }
2324
2325 fn was_visible(&self, version: &time::Global, undos: &UndoMap) -> bool {
2326 (version.observed(self.insertion.id) && !undos.was_undone(self.insertion.id, version))
2327 && self
2328 .deletions
2329 .iter()
2330 .all(|d| !version.observed(*d) || undos.was_undone(*d, version))
2331 }
2332
2333 fn len(&self) -> usize {
2334 self.range_in_insertion.len()
2335 }
2336
2337 fn visible_len(&self) -> usize {
2338 if self.visible {
2339 self.range_in_insertion.len()
2340 } else {
2341 0
2342 }
2343 }
2344}
2345
2346impl sum_tree::Item for Fragment {
2347 type Summary = FragmentSummary;
2348
2349 fn summary(&self) -> Self::Summary {
2350 let mut max_version = time::Global::new();
2351 max_version.observe(self.insertion.id);
2352 for deletion in &self.deletions {
2353 max_version.observe(*deletion);
2354 }
2355 max_version.observe_all(&self.max_undos);
2356
2357 if self.visible {
2358 FragmentSummary {
2359 text: FragmentTextSummary {
2360 visible: self.len(),
2361 deleted: 0,
2362 },
2363 max_fragment_id: self.id.clone(),
2364 max_version,
2365 }
2366 } else {
2367 FragmentSummary {
2368 text: FragmentTextSummary {
2369 visible: 0,
2370 deleted: self.len(),
2371 },
2372 max_fragment_id: self.id.clone(),
2373 max_version,
2374 }
2375 }
2376 }
2377}
2378
2379impl sum_tree::Summary for FragmentSummary {
2380 type Context = ();
2381
2382 fn add_summary(&mut self, other: &Self, _: &Self::Context) {
2383 self.text.visible += &other.text.visible;
2384 self.text.deleted += &other.text.deleted;
2385 debug_assert!(self.max_fragment_id <= other.max_fragment_id);
2386 self.max_fragment_id = other.max_fragment_id.clone();
2387 self.max_version.observe_all(&other.max_version);
2388 }
2389}
2390
2391impl Default for FragmentSummary {
2392 fn default() -> Self {
2393 FragmentSummary {
2394 text: FragmentTextSummary::default(),
2395 max_fragment_id: FragmentId::min_value().clone(),
2396 max_version: time::Global::new(),
2397 }
2398 }
2399}
2400
2401impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize {
2402 fn add_summary(&mut self, summary: &FragmentSummary) {
2403 *self += summary.text.visible;
2404 }
2405}
2406
2407impl sum_tree::Item for InsertionSplit {
2408 type Summary = InsertionSplitSummary;
2409
2410 fn summary(&self) -> Self::Summary {
2411 InsertionSplitSummary {
2412 extent: self.extent,
2413 }
2414 }
2415}
2416
2417impl sum_tree::Summary for InsertionSplitSummary {
2418 type Context = ();
2419
2420 fn add_summary(&mut self, other: &Self, _: &()) {
2421 self.extent += other.extent;
2422 }
2423}
2424
2425impl Default for InsertionSplitSummary {
2426 fn default() -> Self {
2427 InsertionSplitSummary { extent: 0 }
2428 }
2429}
2430
2431impl<'a> sum_tree::Dimension<'a, InsertionSplitSummary> for usize {
2432 fn add_summary(&mut self, summary: &InsertionSplitSummary) {
2433 *self += summary.extent;
2434 }
2435}
2436
2437impl Operation {
2438 fn replica_id(&self) -> ReplicaId {
2439 self.lamport_timestamp().replica_id
2440 }
2441
2442 fn lamport_timestamp(&self) -> time::Lamport {
2443 match self {
2444 Operation::Edit {
2445 lamport_timestamp, ..
2446 } => *lamport_timestamp,
2447 Operation::Undo {
2448 lamport_timestamp, ..
2449 } => *lamport_timestamp,
2450 Operation::UpdateSelections {
2451 lamport_timestamp, ..
2452 } => *lamport_timestamp,
2453 }
2454 }
2455
2456 pub fn is_edit(&self) -> bool {
2457 match self {
2458 Operation::Edit { .. } => true,
2459 _ => false,
2460 }
2461 }
2462}
2463
2464impl operation_queue::Operation for Operation {
2465 fn timestamp(&self) -> time::Lamport {
2466 self.lamport_timestamp()
2467 }
2468}
2469
2470pub trait ToOffset {
2471 fn to_offset(&self, buffer: &Buffer) -> usize;
2472}
2473
2474impl ToOffset for Point {
2475 fn to_offset(&self, buffer: &Buffer) -> usize {
2476 buffer.visible_text.to_offset(*self)
2477 }
2478}
2479
2480impl ToOffset for usize {
2481 fn to_offset(&self, _: &Buffer) -> usize {
2482 *self
2483 }
2484}
2485
2486impl ToOffset for Anchor {
2487 fn to_offset(&self, buffer: &Buffer) -> usize {
2488 buffer.summary_for_anchor(self).bytes
2489 }
2490}
2491
2492impl<'a> ToOffset for &'a Anchor {
2493 fn to_offset(&self, buffer: &Buffer) -> usize {
2494 buffer.summary_for_anchor(self).bytes
2495 }
2496}
2497
2498pub trait ToPoint {
2499 fn to_point(&self, buffer: &Buffer) -> Point;
2500}
2501
2502impl ToPoint for Anchor {
2503 fn to_point(&self, buffer: &Buffer) -> Point {
2504 buffer.summary_for_anchor(self).lines
2505 }
2506}
2507
2508impl ToPoint for usize {
2509 fn to_point(&self, buffer: &Buffer) -> Point {
2510 buffer.visible_text.to_point(*self)
2511 }
2512}
2513
2514#[cfg(test)]
2515mod tests {
2516 use super::*;
2517 use crate::{
2518 test::{build_app_state, temp_tree},
2519 util::RandomCharIter,
2520 worktree::{Worktree, WorktreeHandle},
2521 };
2522 use gpui::{App, ModelHandle};
2523 use rand::prelude::*;
2524 use serde_json::json;
2525 use std::{
2526 cell::RefCell,
2527 cmp::Ordering,
2528 fs,
2529 rc::Rc,
2530 sync::atomic::{self, AtomicUsize},
2531 };
2532
2533 #[gpui::test]
2534 fn test_edit(ctx: &mut gpui::MutableAppContext) {
2535 ctx.add_model(|ctx| {
2536 let mut buffer = Buffer::new(0, "abc", ctx);
2537 assert_eq!(buffer.text(), "abc");
2538 buffer.edit(vec![3..3], "def", None).unwrap();
2539 assert_eq!(buffer.text(), "abcdef");
2540 buffer.edit(vec![0..0], "ghi", None).unwrap();
2541 assert_eq!(buffer.text(), "ghiabcdef");
2542 buffer.edit(vec![5..5], "jkl", None).unwrap();
2543 assert_eq!(buffer.text(), "ghiabjklcdef");
2544 buffer.edit(vec![6..7], "", None).unwrap();
2545 assert_eq!(buffer.text(), "ghiabjlcdef");
2546 buffer.edit(vec![4..9], "mno", None).unwrap();
2547 assert_eq!(buffer.text(), "ghiamnoef");
2548 buffer
2549 });
2550 }
2551
2552 #[gpui::test]
2553 fn test_edit_events(app: &mut gpui::MutableAppContext) {
2554 let mut now = Instant::now();
2555 let buffer_1_events = Rc::new(RefCell::new(Vec::new()));
2556 let buffer_2_events = Rc::new(RefCell::new(Vec::new()));
2557
2558 let buffer1 = app.add_model(|ctx| Buffer::new(0, "abcdef", ctx));
2559 let buffer2 = app.add_model(|ctx| Buffer::new(1, "abcdef", ctx));
2560 let mut buffer_ops = Vec::new();
2561 buffer1.update(app, |buffer, ctx| {
2562 let buffer_1_events = buffer_1_events.clone();
2563 ctx.subscribe(&buffer1, move |_, event, _| {
2564 buffer_1_events.borrow_mut().push(event.clone())
2565 });
2566 let buffer_2_events = buffer_2_events.clone();
2567 ctx.subscribe(&buffer2, move |_, event, _| {
2568 buffer_2_events.borrow_mut().push(event.clone())
2569 });
2570
2571 // An edit emits an edited event, followed by a dirtied event,
2572 // since the buffer was previously in a clean state.
2573 let ops = buffer.edit(Some(2..4), "XYZ", Some(ctx)).unwrap();
2574 buffer_ops.extend_from_slice(&ops);
2575
2576 // An empty transaction does not emit any events.
2577 buffer.start_transaction(None).unwrap();
2578 buffer.end_transaction(None, Some(ctx)).unwrap();
2579
2580 // A transaction containing two edits emits one edited event.
2581 now += Duration::from_secs(1);
2582 buffer.start_transaction_at(None, now).unwrap();
2583 let ops = buffer.edit(Some(5..5), "u", Some(ctx)).unwrap();
2584 buffer_ops.extend_from_slice(&ops);
2585 let ops = buffer.edit(Some(6..6), "w", Some(ctx)).unwrap();
2586 buffer_ops.extend_from_slice(&ops);
2587 buffer.end_transaction_at(None, now, Some(ctx)).unwrap();
2588
2589 // Undoing a transaction emits one edited event.
2590 let ops = buffer.undo(Some(ctx));
2591 buffer_ops.extend_from_slice(&ops);
2592 });
2593
2594 // Incorporating a set of remote ops emits a single edited event,
2595 // followed by a dirtied event.
2596 buffer2.update(app, |buffer, ctx| {
2597 buffer.apply_ops(buffer_ops, Some(ctx)).unwrap();
2598 });
2599
2600 let buffer_1_events = buffer_1_events.borrow();
2601 assert_eq!(
2602 *buffer_1_events,
2603 vec![Event::Edited, Event::Dirtied, Event::Edited, Event::Edited]
2604 );
2605
2606 let buffer_2_events = buffer_2_events.borrow();
2607 assert_eq!(*buffer_2_events, vec![Event::Edited, Event::Dirtied]);
2608 }
2609
2610 #[gpui::test]
2611 fn test_random_edits(ctx: &mut gpui::MutableAppContext) {
2612 for seed in 0..100 {
2613 println!("{:?}", seed);
2614 let mut rng = &mut StdRng::seed_from_u64(seed);
2615
2616 let reference_string_len = rng.gen_range(0..3);
2617 let mut reference_string = RandomCharIter::new(&mut rng)
2618 .take(reference_string_len)
2619 .collect::<String>();
2620 ctx.add_model(|ctx| {
2621 let mut buffer = Buffer::new(0, reference_string.as_str(), ctx);
2622 let mut buffer_versions = Vec::new();
2623 for _i in 0..10 {
2624 let (old_ranges, new_text, _) = buffer.randomly_mutate(rng, None);
2625 for old_range in old_ranges.iter().rev() {
2626 reference_string.replace_range(old_range.clone(), &new_text);
2627 }
2628 assert_eq!(buffer.text(), reference_string);
2629
2630 if rng.gen_bool(0.25) {
2631 buffer.randomly_undo_redo(rng);
2632 reference_string = buffer.text();
2633 }
2634
2635 let range = buffer.random_byte_range(0, rng);
2636 assert_eq!(
2637 buffer.text_summary_for_range(range.clone()),
2638 TextSummary::from(&reference_string[range])
2639 );
2640
2641 if rng.gen_bool(0.3) {
2642 buffer_versions.push(buffer.clone());
2643 }
2644 }
2645
2646 for mut old_buffer in buffer_versions {
2647 let mut delta = 0_isize;
2648 for Edit {
2649 old_range,
2650 new_range,
2651 ..
2652 } in buffer.edits_since(old_buffer.version.clone())
2653 {
2654 let old_len = old_range.end - old_range.start;
2655 let new_len = new_range.end - new_range.start;
2656 let old_start = (old_range.start as isize + delta) as usize;
2657 let new_text: String = buffer.text_for_range(new_range).collect();
2658 old_buffer
2659 .edit(Some(old_start..old_start + old_len), new_text, None)
2660 .unwrap();
2661
2662 delta += new_len as isize - old_len as isize;
2663 }
2664 assert_eq!(old_buffer.text(), buffer.text());
2665 }
2666
2667 buffer
2668 });
2669 }
2670 }
2671
2672 #[gpui::test]
2673 fn test_line_len(ctx: &mut gpui::MutableAppContext) {
2674 ctx.add_model(|ctx| {
2675 let mut buffer = Buffer::new(0, "", ctx);
2676 buffer.edit(vec![0..0], "abcd\nefg\nhij", None).unwrap();
2677 buffer.edit(vec![12..12], "kl\nmno", None).unwrap();
2678 buffer.edit(vec![18..18], "\npqrs\n", None).unwrap();
2679 buffer.edit(vec![18..21], "\nPQ", None).unwrap();
2680
2681 assert_eq!(buffer.line_len(0), 4);
2682 assert_eq!(buffer.line_len(1), 3);
2683 assert_eq!(buffer.line_len(2), 5);
2684 assert_eq!(buffer.line_len(3), 3);
2685 assert_eq!(buffer.line_len(4), 4);
2686 assert_eq!(buffer.line_len(5), 0);
2687 buffer
2688 });
2689 }
2690
2691 #[gpui::test]
2692 fn test_text_summary_for_range(ctx: &mut gpui::MutableAppContext) {
2693 ctx.add_model(|ctx| {
2694 let buffer = Buffer::new(0, "ab\nefg\nhklm\nnopqrs\ntuvwxyz", ctx);
2695 assert_eq!(
2696 buffer.text_summary_for_range(1..3),
2697 TextSummary {
2698 bytes: 2,
2699 lines: Point::new(1, 0),
2700 first_line_chars: 1,
2701 last_line_chars: 0,
2702 longest_row: 0,
2703 longest_row_chars: 1,
2704 }
2705 );
2706 assert_eq!(
2707 buffer.text_summary_for_range(1..12),
2708 TextSummary {
2709 bytes: 11,
2710 lines: Point::new(3, 0),
2711 first_line_chars: 1,
2712 last_line_chars: 0,
2713 longest_row: 2,
2714 longest_row_chars: 4,
2715 }
2716 );
2717 assert_eq!(
2718 buffer.text_summary_for_range(0..20),
2719 TextSummary {
2720 bytes: 20,
2721 lines: Point::new(4, 1),
2722 first_line_chars: 2,
2723 last_line_chars: 1,
2724 longest_row: 3,
2725 longest_row_chars: 6,
2726 }
2727 );
2728 assert_eq!(
2729 buffer.text_summary_for_range(0..22),
2730 TextSummary {
2731 bytes: 22,
2732 lines: Point::new(4, 3),
2733 first_line_chars: 2,
2734 last_line_chars: 3,
2735 longest_row: 3,
2736 longest_row_chars: 6,
2737 }
2738 );
2739 assert_eq!(
2740 buffer.text_summary_for_range(7..22),
2741 TextSummary {
2742 bytes: 15,
2743 lines: Point::new(2, 3),
2744 first_line_chars: 4,
2745 last_line_chars: 3,
2746 longest_row: 1,
2747 longest_row_chars: 6,
2748 }
2749 );
2750 buffer
2751 });
2752 }
2753
2754 #[gpui::test]
2755 fn test_chars_at(ctx: &mut gpui::MutableAppContext) {
2756 ctx.add_model(|ctx| {
2757 let mut buffer = Buffer::new(0, "", ctx);
2758 buffer.edit(vec![0..0], "abcd\nefgh\nij", None).unwrap();
2759 buffer.edit(vec![12..12], "kl\nmno", None).unwrap();
2760 buffer.edit(vec![18..18], "\npqrs", None).unwrap();
2761 buffer.edit(vec![18..21], "\nPQ", None).unwrap();
2762
2763 let chars = buffer.chars_at(Point::new(0, 0));
2764 assert_eq!(chars.collect::<String>(), "abcd\nefgh\nijkl\nmno\nPQrs");
2765
2766 let chars = buffer.chars_at(Point::new(1, 0));
2767 assert_eq!(chars.collect::<String>(), "efgh\nijkl\nmno\nPQrs");
2768
2769 let chars = buffer.chars_at(Point::new(2, 0));
2770 assert_eq!(chars.collect::<String>(), "ijkl\nmno\nPQrs");
2771
2772 let chars = buffer.chars_at(Point::new(3, 0));
2773 assert_eq!(chars.collect::<String>(), "mno\nPQrs");
2774
2775 let chars = buffer.chars_at(Point::new(4, 0));
2776 assert_eq!(chars.collect::<String>(), "PQrs");
2777
2778 // Regression test:
2779 let mut buffer = Buffer::new(0, "", ctx);
2780 buffer.edit(vec![0..0], "[workspace]\nmembers = [\n \"xray_core\",\n \"xray_server\",\n \"xray_cli\",\n \"xray_wasm\",\n]\n", None).unwrap();
2781 buffer.edit(vec![60..60], "\n", None).unwrap();
2782
2783 let chars = buffer.chars_at(Point::new(6, 0));
2784 assert_eq!(chars.collect::<String>(), " \"xray_wasm\",\n]\n");
2785
2786 buffer
2787 });
2788 }
2789
2790 #[test]
2791 fn test_fragment_ids() {
2792 for seed in 0..10 {
2793 let rng = &mut StdRng::seed_from_u64(seed);
2794
2795 let mut ids = vec![FragmentId(Arc::from([0])), FragmentId(Arc::from([4]))];
2796 for _i in 0..100 {
2797 let index = rng.gen_range(1..ids.len());
2798
2799 let left = ids[index - 1].clone();
2800 let right = ids[index].clone();
2801 ids.insert(index, FragmentId::between_with_max(&left, &right, 4));
2802
2803 let mut sorted_ids = ids.clone();
2804 sorted_ids.sort();
2805 assert_eq!(ids, sorted_ids);
2806 }
2807 }
2808 }
2809
2810 #[gpui::test]
2811 fn test_anchors(ctx: &mut gpui::MutableAppContext) {
2812 ctx.add_model(|ctx| {
2813 let mut buffer = Buffer::new(0, "", ctx);
2814 buffer.edit(vec![0..0], "abc", None).unwrap();
2815 let left_anchor = buffer.anchor_before(2);
2816 let right_anchor = buffer.anchor_after(2);
2817
2818 buffer.edit(vec![1..1], "def\n", None).unwrap();
2819 assert_eq!(buffer.text(), "adef\nbc");
2820 assert_eq!(left_anchor.to_offset(&buffer), 6);
2821 assert_eq!(right_anchor.to_offset(&buffer), 6);
2822 assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 });
2823 assert_eq!(right_anchor.to_point(&buffer), Point { row: 1, column: 1 });
2824
2825 buffer.edit(vec![2..3], "", None).unwrap();
2826 assert_eq!(buffer.text(), "adf\nbc");
2827 assert_eq!(left_anchor.to_offset(&buffer), 5);
2828 assert_eq!(right_anchor.to_offset(&buffer), 5);
2829 assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 });
2830 assert_eq!(right_anchor.to_point(&buffer), Point { row: 1, column: 1 });
2831
2832 buffer.edit(vec![5..5], "ghi\n", None).unwrap();
2833 assert_eq!(buffer.text(), "adf\nbghi\nc");
2834 assert_eq!(left_anchor.to_offset(&buffer), 5);
2835 assert_eq!(right_anchor.to_offset(&buffer), 9);
2836 assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 });
2837 assert_eq!(right_anchor.to_point(&buffer), Point { row: 2, column: 0 });
2838
2839 buffer.edit(vec![7..9], "", None).unwrap();
2840 assert_eq!(buffer.text(), "adf\nbghc");
2841 assert_eq!(left_anchor.to_offset(&buffer), 5);
2842 assert_eq!(right_anchor.to_offset(&buffer), 7);
2843 assert_eq!(left_anchor.to_point(&buffer), Point { row: 1, column: 1 },);
2844 assert_eq!(right_anchor.to_point(&buffer), Point { row: 1, column: 3 });
2845
2846 // Ensure anchoring to a point is equivalent to anchoring to an offset.
2847 assert_eq!(
2848 buffer.anchor_before(Point { row: 0, column: 0 }),
2849 buffer.anchor_before(0)
2850 );
2851 assert_eq!(
2852 buffer.anchor_before(Point { row: 0, column: 1 }),
2853 buffer.anchor_before(1)
2854 );
2855 assert_eq!(
2856 buffer.anchor_before(Point { row: 0, column: 2 }),
2857 buffer.anchor_before(2)
2858 );
2859 assert_eq!(
2860 buffer.anchor_before(Point { row: 0, column: 3 }),
2861 buffer.anchor_before(3)
2862 );
2863 assert_eq!(
2864 buffer.anchor_before(Point { row: 1, column: 0 }),
2865 buffer.anchor_before(4)
2866 );
2867 assert_eq!(
2868 buffer.anchor_before(Point { row: 1, column: 1 }),
2869 buffer.anchor_before(5)
2870 );
2871 assert_eq!(
2872 buffer.anchor_before(Point { row: 1, column: 2 }),
2873 buffer.anchor_before(6)
2874 );
2875 assert_eq!(
2876 buffer.anchor_before(Point { row: 1, column: 3 }),
2877 buffer.anchor_before(7)
2878 );
2879 assert_eq!(
2880 buffer.anchor_before(Point { row: 1, column: 4 }),
2881 buffer.anchor_before(8)
2882 );
2883
2884 // Comparison between anchors.
2885 let anchor_at_offset_0 = buffer.anchor_before(0);
2886 let anchor_at_offset_1 = buffer.anchor_before(1);
2887 let anchor_at_offset_2 = buffer.anchor_before(2);
2888
2889 assert_eq!(
2890 anchor_at_offset_0
2891 .cmp(&anchor_at_offset_0, &buffer)
2892 .unwrap(),
2893 Ordering::Equal
2894 );
2895 assert_eq!(
2896 anchor_at_offset_1
2897 .cmp(&anchor_at_offset_1, &buffer)
2898 .unwrap(),
2899 Ordering::Equal
2900 );
2901 assert_eq!(
2902 anchor_at_offset_2
2903 .cmp(&anchor_at_offset_2, &buffer)
2904 .unwrap(),
2905 Ordering::Equal
2906 );
2907
2908 assert_eq!(
2909 anchor_at_offset_0
2910 .cmp(&anchor_at_offset_1, &buffer)
2911 .unwrap(),
2912 Ordering::Less
2913 );
2914 assert_eq!(
2915 anchor_at_offset_1
2916 .cmp(&anchor_at_offset_2, &buffer)
2917 .unwrap(),
2918 Ordering::Less
2919 );
2920 assert_eq!(
2921 anchor_at_offset_0
2922 .cmp(&anchor_at_offset_2, &buffer)
2923 .unwrap(),
2924 Ordering::Less
2925 );
2926
2927 assert_eq!(
2928 anchor_at_offset_1
2929 .cmp(&anchor_at_offset_0, &buffer)
2930 .unwrap(),
2931 Ordering::Greater
2932 );
2933 assert_eq!(
2934 anchor_at_offset_2
2935 .cmp(&anchor_at_offset_1, &buffer)
2936 .unwrap(),
2937 Ordering::Greater
2938 );
2939 assert_eq!(
2940 anchor_at_offset_2
2941 .cmp(&anchor_at_offset_0, &buffer)
2942 .unwrap(),
2943 Ordering::Greater
2944 );
2945 buffer
2946 });
2947 }
2948
2949 #[gpui::test]
2950 fn test_anchors_at_start_and_end(ctx: &mut gpui::MutableAppContext) {
2951 ctx.add_model(|ctx| {
2952 let mut buffer = Buffer::new(0, "", ctx);
2953 let before_start_anchor = buffer.anchor_before(0);
2954 let after_end_anchor = buffer.anchor_after(0);
2955
2956 buffer.edit(vec![0..0], "abc", None).unwrap();
2957 assert_eq!(buffer.text(), "abc");
2958 assert_eq!(before_start_anchor.to_offset(&buffer), 0);
2959 assert_eq!(after_end_anchor.to_offset(&buffer), 3);
2960
2961 let after_start_anchor = buffer.anchor_after(0);
2962 let before_end_anchor = buffer.anchor_before(3);
2963
2964 buffer.edit(vec![3..3], "def", None).unwrap();
2965 buffer.edit(vec![0..0], "ghi", None).unwrap();
2966 assert_eq!(buffer.text(), "ghiabcdef");
2967 assert_eq!(before_start_anchor.to_offset(&buffer), 0);
2968 assert_eq!(after_start_anchor.to_offset(&buffer), 3);
2969 assert_eq!(before_end_anchor.to_offset(&buffer), 6);
2970 assert_eq!(after_end_anchor.to_offset(&buffer), 9);
2971 buffer
2972 });
2973 }
2974
2975 #[test]
2976 fn test_is_dirty() {
2977 App::test_async((), |mut app| async move {
2978 let dir = temp_tree(json!({
2979 "file1": "",
2980 "file2": "",
2981 "file3": "",
2982 }));
2983 let tree = app.add_model(|ctx| Worktree::new(dir.path(), ctx));
2984 tree.flush_fs_events(&app).await;
2985 app.read(|ctx| tree.read(ctx).scan_complete()).await;
2986
2987 let file1 = app.update(|ctx| tree.file("file1", ctx)).await;
2988 let buffer1 = app.add_model(|ctx| {
2989 Buffer::from_history(0, History::new("abc".into()), Some(file1), None, ctx)
2990 });
2991 let events = Rc::new(RefCell::new(Vec::new()));
2992
2993 // initially, the buffer isn't dirty.
2994 buffer1.update(&mut app, |buffer, ctx| {
2995 ctx.subscribe(&buffer1, {
2996 let events = events.clone();
2997 move |_, event, _| events.borrow_mut().push(event.clone())
2998 });
2999
3000 assert!(!buffer.is_dirty());
3001 assert!(events.borrow().is_empty());
3002
3003 buffer.edit(vec![1..2], "", Some(ctx)).unwrap();
3004 });
3005
3006 // after the first edit, the buffer is dirty, and emits a dirtied event.
3007 buffer1.update(&mut app, |buffer, ctx| {
3008 assert!(buffer.text() == "ac");
3009 assert!(buffer.is_dirty());
3010 assert_eq!(*events.borrow(), &[Event::Edited, Event::Dirtied]);
3011 events.borrow_mut().clear();
3012
3013 buffer.did_save(buffer.version(), None, ctx);
3014 });
3015
3016 // after saving, the buffer is not dirty, and emits a saved event.
3017 buffer1.update(&mut app, |buffer, ctx| {
3018 assert!(!buffer.is_dirty());
3019 assert_eq!(*events.borrow(), &[Event::Saved]);
3020 events.borrow_mut().clear();
3021
3022 buffer.edit(vec![1..1], "B", Some(ctx)).unwrap();
3023 buffer.edit(vec![2..2], "D", Some(ctx)).unwrap();
3024 });
3025
3026 // after editing again, the buffer is dirty, and emits another dirty event.
3027 buffer1.update(&mut app, |buffer, ctx| {
3028 assert!(buffer.text() == "aBDc");
3029 assert!(buffer.is_dirty());
3030 assert_eq!(
3031 *events.borrow(),
3032 &[Event::Edited, Event::Dirtied, Event::Edited],
3033 );
3034 events.borrow_mut().clear();
3035
3036 // TODO - currently, after restoring the buffer to its
3037 // previously-saved state, the is still considered dirty.
3038 buffer.edit(vec![1..3], "", Some(ctx)).unwrap();
3039 assert!(buffer.text() == "ac");
3040 assert!(buffer.is_dirty());
3041 });
3042
3043 assert_eq!(*events.borrow(), &[Event::Edited]);
3044
3045 // When a file is deleted, the buffer is considered dirty.
3046 let events = Rc::new(RefCell::new(Vec::new()));
3047 let file2 = app.update(|ctx| tree.file("file2", ctx)).await;
3048 let buffer2 = app.add_model(|ctx: &mut ModelContext<Buffer>| {
3049 ctx.subscribe(&ctx.handle(), {
3050 let events = events.clone();
3051 move |_, event, _| events.borrow_mut().push(event.clone())
3052 });
3053
3054 Buffer::from_history(0, History::new("abc".into()), Some(file2), None, ctx)
3055 });
3056
3057 fs::remove_file(dir.path().join("file2")).unwrap();
3058 buffer2.condition(&app, |b, _| b.is_dirty()).await;
3059 assert_eq!(
3060 *events.borrow(),
3061 &[Event::Dirtied, Event::FileHandleChanged]
3062 );
3063
3064 // When a file is already dirty when deleted, we don't emit a Dirtied event.
3065 let events = Rc::new(RefCell::new(Vec::new()));
3066 let file3 = app.update(|ctx| tree.file("file3", ctx)).await;
3067 let buffer3 = app.add_model(|ctx: &mut ModelContext<Buffer>| {
3068 ctx.subscribe(&ctx.handle(), {
3069 let events = events.clone();
3070 move |_, event, _| events.borrow_mut().push(event.clone())
3071 });
3072
3073 Buffer::from_history(0, History::new("abc".into()), Some(file3), None, ctx)
3074 });
3075
3076 tree.flush_fs_events(&app).await;
3077 buffer3.update(&mut app, |buffer, ctx| {
3078 buffer.edit(Some(0..0), "x", Some(ctx)).unwrap();
3079 });
3080 events.borrow_mut().clear();
3081 fs::remove_file(dir.path().join("file3")).unwrap();
3082 buffer3
3083 .condition(&app, |_, _| !events.borrow().is_empty())
3084 .await;
3085 assert_eq!(*events.borrow(), &[Event::FileHandleChanged]);
3086 app.read(|ctx| assert!(buffer3.read(ctx).is_dirty()));
3087 });
3088 }
3089
3090 #[gpui::test]
3091 async fn test_file_changes_on_disk(mut app: gpui::TestAppContext) {
3092 let initial_contents = "aaa\nbbbbb\nc\n";
3093 let dir = temp_tree(json!({ "the-file": initial_contents }));
3094 let tree = app.add_model(|ctx| Worktree::new(dir.path(), ctx));
3095 app.read(|ctx| tree.read(ctx).scan_complete()).await;
3096
3097 let abs_path = dir.path().join("the-file");
3098 let file = app.update(|ctx| tree.file("the-file", ctx)).await;
3099 let buffer = app.add_model(|ctx| {
3100 Buffer::from_history(
3101 0,
3102 History::new(initial_contents.into()),
3103 Some(file),
3104 None,
3105 ctx,
3106 )
3107 });
3108
3109 // Add a cursor at the start of each row.
3110 let (selection_set_id, _) = buffer.update(&mut app, |buffer, ctx| {
3111 assert!(!buffer.is_dirty());
3112 buffer.add_selection_set(
3113 (0..3)
3114 .map(|row| {
3115 let anchor = buffer.anchor_at(Point::new(row, 0), AnchorBias::Right);
3116 Selection {
3117 id: row as usize,
3118 start: anchor.clone(),
3119 end: anchor,
3120 reversed: false,
3121 goal: SelectionGoal::None,
3122 }
3123 })
3124 .collect::<Vec<_>>(),
3125 Some(ctx),
3126 )
3127 });
3128
3129 // Change the file on disk, adding two new lines of text, and removing
3130 // one line.
3131 buffer.read_with(&app, |buffer, _| {
3132 assert!(!buffer.is_dirty());
3133 assert!(!buffer.has_conflict());
3134 });
3135 let new_contents = "AAAA\naaa\nBB\nbbbbb\n";
3136 fs::write(&abs_path, new_contents).unwrap();
3137
3138 // Because the buffer was not modified, it is reloaded from disk. Its
3139 // contents are edited according to the diff between the old and new
3140 // file contents.
3141 buffer
3142 .condition(&app, |buffer, _| buffer.text() != initial_contents)
3143 .await;
3144
3145 buffer.update(&mut app, |buffer, _| {
3146 assert_eq!(buffer.text(), new_contents);
3147 assert!(!buffer.is_dirty());
3148 assert!(!buffer.has_conflict());
3149
3150 let selections = buffer.selections(selection_set_id).unwrap();
3151 let cursor_positions = selections
3152 .iter()
3153 .map(|selection| {
3154 assert_eq!(selection.start, selection.end);
3155 selection.start.to_point(&buffer)
3156 })
3157 .collect::<Vec<_>>();
3158 assert_eq!(
3159 cursor_positions,
3160 &[Point::new(1, 0), Point::new(3, 0), Point::new(4, 0),]
3161 );
3162 });
3163
3164 // Modify the buffer
3165 buffer.update(&mut app, |buffer, ctx| {
3166 buffer.edit(vec![0..0], " ", Some(ctx)).unwrap();
3167 assert!(buffer.is_dirty());
3168 });
3169
3170 // Change the file on disk again, adding blank lines to the beginning.
3171 fs::write(&abs_path, "\n\n\nAAAA\naaa\nBB\nbbbbb\n").unwrap();
3172
3173 // Becaues the buffer is modified, it doesn't reload from disk, but is
3174 // marked as having a conflict.
3175 buffer
3176 .condition(&app, |buffer, _| buffer.has_conflict())
3177 .await;
3178 }
3179
3180 #[gpui::test]
3181 async fn test_set_text_via_diff(mut app: gpui::TestAppContext) {
3182 let text = "a\nbb\nccc\ndddd\neeeee\nffffff\n";
3183 let buffer = app.add_model(|ctx| Buffer::new(0, text, ctx));
3184
3185 let text = "a\nccc\ndddd\nffffff\n";
3186 let diff = buffer
3187 .read_with(&app, |b, ctx| b.diff(text.into(), ctx))
3188 .await;
3189 buffer.update(&mut app, |b, ctx| b.set_text_via_diff(diff, ctx));
3190 app.read(|ctx| assert_eq!(buffer.read(ctx).text(), text));
3191
3192 let text = "a\n1\n\nccc\ndd2dd\nffffff\n";
3193 let diff = buffer
3194 .read_with(&app, |b, ctx| b.diff(text.into(), ctx))
3195 .await;
3196 buffer.update(&mut app, |b, ctx| b.set_text_via_diff(diff, ctx));
3197 app.read(|ctx| assert_eq!(buffer.read(ctx).text(), text));
3198 }
3199
3200 #[gpui::test]
3201 fn test_undo_redo(app: &mut gpui::MutableAppContext) {
3202 app.add_model(|ctx| {
3203 let mut buffer = Buffer::new(0, "1234", ctx);
3204
3205 let edit1 = buffer.edit(vec![1..1], "abx", None).unwrap();
3206 let edit2 = buffer.edit(vec![3..4], "yzef", None).unwrap();
3207 let edit3 = buffer.edit(vec![3..5], "cd", None).unwrap();
3208 assert_eq!(buffer.text(), "1abcdef234");
3209
3210 buffer.undo_or_redo(edit1[0].edit_id().unwrap()).unwrap();
3211 assert_eq!(buffer.text(), "1cdef234");
3212 buffer.undo_or_redo(edit1[0].edit_id().unwrap()).unwrap();
3213 assert_eq!(buffer.text(), "1abcdef234");
3214
3215 buffer.undo_or_redo(edit2[0].edit_id().unwrap()).unwrap();
3216 assert_eq!(buffer.text(), "1abcdx234");
3217 buffer.undo_or_redo(edit3[0].edit_id().unwrap()).unwrap();
3218 assert_eq!(buffer.text(), "1abx234");
3219 buffer.undo_or_redo(edit2[0].edit_id().unwrap()).unwrap();
3220 assert_eq!(buffer.text(), "1abyzef234");
3221 buffer.undo_or_redo(edit3[0].edit_id().unwrap()).unwrap();
3222 assert_eq!(buffer.text(), "1abcdef234");
3223
3224 buffer.undo_or_redo(edit3[0].edit_id().unwrap()).unwrap();
3225 assert_eq!(buffer.text(), "1abyzef234");
3226 buffer.undo_or_redo(edit1[0].edit_id().unwrap()).unwrap();
3227 assert_eq!(buffer.text(), "1yzef234");
3228 buffer.undo_or_redo(edit2[0].edit_id().unwrap()).unwrap();
3229 assert_eq!(buffer.text(), "1234");
3230
3231 buffer
3232 });
3233 }
3234
3235 #[gpui::test]
3236 fn test_history(app: &mut gpui::MutableAppContext) {
3237 app.add_model(|ctx| {
3238 let mut now = Instant::now();
3239 let mut buffer = Buffer::new(0, "123456", ctx);
3240
3241 let (set_id, _) =
3242 buffer.add_selection_set(buffer.selections_from_ranges(vec![4..4]).unwrap(), None);
3243 buffer.start_transaction_at(Some(set_id), now).unwrap();
3244 buffer.edit(vec![2..4], "cd", None).unwrap();
3245 buffer.end_transaction_at(Some(set_id), now, None).unwrap();
3246 assert_eq!(buffer.text(), "12cd56");
3247 assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![4..4]);
3248
3249 buffer.start_transaction_at(Some(set_id), now).unwrap();
3250 buffer
3251 .update_selection_set(
3252 set_id,
3253 buffer.selections_from_ranges(vec![1..3]).unwrap(),
3254 None,
3255 )
3256 .unwrap();
3257 buffer.edit(vec![4..5], "e", None).unwrap();
3258 buffer.end_transaction_at(Some(set_id), now, None).unwrap();
3259 assert_eq!(buffer.text(), "12cde6");
3260 assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![1..3]);
3261
3262 now += UNDO_GROUP_INTERVAL + Duration::from_millis(1);
3263 buffer.start_transaction_at(Some(set_id), now).unwrap();
3264 buffer
3265 .update_selection_set(
3266 set_id,
3267 buffer.selections_from_ranges(vec![2..2]).unwrap(),
3268 None,
3269 )
3270 .unwrap();
3271 buffer.edit(vec![0..1], "a", None).unwrap();
3272 buffer.edit(vec![1..1], "b", None).unwrap();
3273 buffer.end_transaction_at(Some(set_id), now, None).unwrap();
3274 assert_eq!(buffer.text(), "ab2cde6");
3275 assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![3..3]);
3276
3277 // Last transaction happened past the group interval, undo it on its
3278 // own.
3279 buffer.undo(None);
3280 assert_eq!(buffer.text(), "12cde6");
3281 assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![1..3]);
3282
3283 // First two transactions happened within the group interval, undo them
3284 // together.
3285 buffer.undo(None);
3286 assert_eq!(buffer.text(), "123456");
3287 assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![4..4]);
3288
3289 // Redo the first two transactions together.
3290 buffer.redo(None);
3291 assert_eq!(buffer.text(), "12cde6");
3292 assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![1..3]);
3293
3294 // Redo the last transaction on its own.
3295 buffer.redo(None);
3296 assert_eq!(buffer.text(), "ab2cde6");
3297 assert_eq!(buffer.selection_ranges(set_id).unwrap(), vec![3..3]);
3298
3299 buffer
3300 });
3301 }
3302
3303 #[gpui::test]
3304 fn test_random_concurrent_edits(ctx: &mut gpui::MutableAppContext) {
3305 use crate::test::Network;
3306
3307 const PEERS: usize = 5;
3308
3309 for seed in 0..100 {
3310 println!("{:?}", seed);
3311 let mut rng = &mut StdRng::seed_from_u64(seed);
3312
3313 let base_text_len = rng.gen_range(0..10);
3314 let base_text = RandomCharIter::new(&mut rng)
3315 .take(base_text_len)
3316 .collect::<String>();
3317 let mut replica_ids = Vec::new();
3318 let mut buffers = Vec::new();
3319 let mut network = Network::new();
3320 for i in 0..PEERS {
3321 let buffer =
3322 ctx.add_model(|ctx| Buffer::new(i as ReplicaId, base_text.as_str(), ctx));
3323 buffers.push(buffer);
3324 replica_ids.push(i as u16);
3325 network.add_peer(i as u16);
3326 }
3327
3328 let mut mutation_count = 10;
3329 loop {
3330 let replica_index = rng.gen_range(0..PEERS);
3331 let replica_id = replica_ids[replica_index];
3332 buffers[replica_index].update(ctx, |buffer, _| match rng.gen_range(0..=100) {
3333 0..=50 if mutation_count != 0 => {
3334 let (_, _, ops) = buffer.randomly_mutate(&mut rng, None);
3335 network.broadcast(replica_id, ops, &mut rng);
3336 mutation_count -= 1;
3337 }
3338 51..=70 if mutation_count != 0 => {
3339 let ops = buffer.randomly_undo_redo(&mut rng);
3340 network.broadcast(replica_id, ops, &mut rng);
3341 mutation_count -= 1;
3342 }
3343 71..=100 if network.has_unreceived(replica_id) => {
3344 buffer
3345 .apply_ops(network.receive(replica_id, &mut rng), None)
3346 .unwrap();
3347 }
3348 _ => {}
3349 });
3350
3351 if mutation_count == 0 && network.is_idle() {
3352 break;
3353 }
3354 }
3355
3356 let first_buffer = buffers[0].read(ctx);
3357 for buffer in &buffers[1..] {
3358 let buffer = buffer.read(ctx);
3359 assert_eq!(buffer.text(), first_buffer.text());
3360 assert_eq!(
3361 buffer.all_selections().collect::<HashMap<_, _>>(),
3362 first_buffer.all_selections().collect::<HashMap<_, _>>()
3363 );
3364 assert_eq!(
3365 buffer.all_selection_ranges().collect::<HashMap<_, _>>(),
3366 first_buffer
3367 .all_selection_ranges()
3368 .collect::<HashMap<_, _>>()
3369 );
3370 }
3371 }
3372 }
3373
3374 #[gpui::test]
3375 async fn test_reparse(mut ctx: gpui::TestAppContext) {
3376 let app_state = ctx.read(build_app_state);
3377 let rust_lang = app_state
3378 .language_registry
3379 .select_language("test.rs")
3380 .cloned();
3381 assert!(rust_lang.is_some());
3382
3383 let buffer = ctx.add_model(|ctx| {
3384 let text = "fn a() {}";
3385
3386 let buffer = Buffer::from_history(0, History::new(text.into()), None, rust_lang, ctx);
3387 assert!(buffer.is_parsing);
3388 assert!(buffer.tree.is_none());
3389 buffer
3390 });
3391
3392 // Wait for the initial text to parse
3393 buffer.condition(&ctx, |buffer, _| !buffer.is_parsing).await;
3394 assert_eq!(
3395 get_tree_sexp(&buffer, &ctx),
3396 concat!(
3397 "(source_file (function_item name: (identifier) ",
3398 "parameters: (parameters) ",
3399 "body: (block)))"
3400 )
3401 );
3402
3403 // Perform some edits (add parameter and variable reference)
3404 // Parsing doesn't begin until the transaction is complete
3405 buffer.update(&mut ctx, |buf, ctx| {
3406 buf.start_transaction(None).unwrap();
3407
3408 let offset = buf.text().find(")").unwrap();
3409 buf.edit(vec![offset..offset], "b: C", Some(ctx)).unwrap();
3410 assert!(!buf.is_parsing);
3411
3412 let offset = buf.text().find("}").unwrap();
3413 buf.edit(vec![offset..offset], " d; ", Some(ctx)).unwrap();
3414 assert!(!buf.is_parsing);
3415
3416 buf.end_transaction(None, Some(ctx)).unwrap();
3417 assert_eq!(buf.text(), "fn a(b: C) { d; }");
3418 assert!(buf.is_parsing);
3419 });
3420 buffer.condition(&ctx, |buffer, _| !buffer.is_parsing).await;
3421 assert_eq!(
3422 get_tree_sexp(&buffer, &ctx),
3423 concat!(
3424 "(source_file (function_item name: (identifier) ",
3425 "parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ",
3426 "body: (block (identifier))))"
3427 )
3428 );
3429
3430 // Perform a series of edits without waiting for the current parse to complete:
3431 // * turn identifier into a field expression
3432 // * turn field expression into a method call
3433 // * add a turbofish to the method call
3434 buffer.update(&mut ctx, |buf, ctx| {
3435 let offset = buf.text().find(";").unwrap();
3436 buf.edit(vec![offset..offset], ".e", Some(ctx)).unwrap();
3437 assert_eq!(buf.text(), "fn a(b: C) { d.e; }");
3438 assert!(buf.is_parsing);
3439 });
3440 buffer.update(&mut ctx, |buf, ctx| {
3441 let offset = buf.text().find(";").unwrap();
3442 buf.edit(vec![offset..offset], "(f)", Some(ctx)).unwrap();
3443 assert_eq!(buf.text(), "fn a(b: C) { d.e(f); }");
3444 assert!(buf.is_parsing);
3445 });
3446 buffer.update(&mut ctx, |buf, ctx| {
3447 let offset = buf.text().find("(f)").unwrap();
3448 buf.edit(vec![offset..offset], "::<G>", Some(ctx)).unwrap();
3449 assert_eq!(buf.text(), "fn a(b: C) { d.e::<G>(f); }");
3450 assert!(buf.is_parsing);
3451 });
3452 buffer.condition(&ctx, |buffer, _| !buffer.is_parsing).await;
3453 assert_eq!(
3454 get_tree_sexp(&buffer, &ctx),
3455 concat!(
3456 "(source_file (function_item name: (identifier) ",
3457 "parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ",
3458 "body: (block (call_expression ",
3459 "function: (generic_function ",
3460 "function: (field_expression value: (identifier) field: (field_identifier)) ",
3461 "type_arguments: (type_arguments (type_identifier))) ",
3462 "arguments: (arguments (identifier))))))",
3463 )
3464 );
3465
3466 buffer.update(&mut ctx, |buf, ctx| {
3467 buf.undo(Some(ctx));
3468 assert_eq!(buf.text(), "fn a() {}");
3469 assert!(buf.is_parsing);
3470 });
3471 buffer.condition(&ctx, |buffer, _| !buffer.is_parsing).await;
3472 assert_eq!(
3473 get_tree_sexp(&buffer, &ctx),
3474 concat!(
3475 "(source_file (function_item name: (identifier) ",
3476 "parameters: (parameters) ",
3477 "body: (block)))"
3478 )
3479 );
3480
3481 buffer.update(&mut ctx, |buf, ctx| {
3482 buf.redo(Some(ctx));
3483 assert_eq!(buf.text(), "fn a(b: C) { d.e::<G>(f); }");
3484 assert!(buf.is_parsing);
3485 });
3486 buffer.condition(&ctx, |buffer, _| !buffer.is_parsing).await;
3487 assert_eq!(
3488 get_tree_sexp(&buffer, &ctx),
3489 concat!(
3490 "(source_file (function_item name: (identifier) ",
3491 "parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ",
3492 "body: (block (call_expression ",
3493 "function: (generic_function ",
3494 "function: (field_expression value: (identifier) field: (field_identifier)) ",
3495 "type_arguments: (type_arguments (type_identifier))) ",
3496 "arguments: (arguments (identifier))))))",
3497 )
3498 );
3499
3500 fn get_tree_sexp(buffer: &ModelHandle<Buffer>, ctx: &gpui::TestAppContext) -> String {
3501 buffer.read_with(ctx, |buffer, _| {
3502 buffer.tree.as_ref().unwrap().0.root_node().to_sexp()
3503 })
3504 }
3505 }
3506
3507 impl Buffer {
3508 fn random_byte_range(&mut self, start_offset: usize, rng: &mut impl Rng) -> Range<usize> {
3509 let end = self.clip_offset(rng.gen_range(start_offset..=self.len()), Bias::Right);
3510 let start = self.clip_offset(rng.gen_range(start_offset..=end), Bias::Left);
3511 start..end
3512 }
3513
3514 pub fn randomly_edit<T>(
3515 &mut self,
3516 rng: &mut T,
3517 old_range_count: usize,
3518 ctx: Option<&mut ModelContext<Self>>,
3519 ) -> (Vec<Range<usize>>, String, Vec<Operation>)
3520 where
3521 T: Rng,
3522 {
3523 let mut old_ranges: Vec<Range<usize>> = Vec::new();
3524 for _ in 0..old_range_count {
3525 let last_end = old_ranges.last().map_or(0, |last_range| last_range.end + 1);
3526 if last_end > self.len() {
3527 break;
3528 }
3529 old_ranges.push(self.random_byte_range(last_end, rng));
3530 }
3531 let new_text_len = rng.gen_range(0..10);
3532 let new_text: String = RandomCharIter::new(&mut *rng).take(new_text_len).collect();
3533
3534 let operations = self
3535 .edit(old_ranges.iter().cloned(), new_text.as_str(), ctx)
3536 .unwrap();
3537
3538 (old_ranges, new_text, operations)
3539 }
3540
3541 pub fn randomly_mutate<T>(
3542 &mut self,
3543 rng: &mut T,
3544 mut ctx: Option<&mut ModelContext<Self>>,
3545 ) -> (Vec<Range<usize>>, String, Vec<Operation>)
3546 where
3547 T: Rng,
3548 {
3549 // Randomly edit
3550 let (old_ranges, new_text, mut operations) =
3551 self.randomly_edit(rng, 5, ctx.as_deref_mut());
3552
3553 // Randomly add, remove or mutate selection sets.
3554 let replica_selection_sets = &self
3555 .all_selections()
3556 .map(|(set_id, _)| *set_id)
3557 .filter(|set_id| self.replica_id == set_id.replica_id)
3558 .collect::<Vec<_>>();
3559 let set_id = replica_selection_sets.choose(rng);
3560 if set_id.is_some() && rng.gen_bool(1.0 / 6.0) {
3561 let op = self.remove_selection_set(*set_id.unwrap(), None).unwrap();
3562 operations.push(op);
3563 } else {
3564 let mut ranges = Vec::new();
3565 for _ in 0..5 {
3566 ranges.push(self.random_byte_range(0, rng));
3567 }
3568 let new_selections = self.selections_from_ranges(ranges).unwrap();
3569
3570 let op = if set_id.is_none() || rng.gen_bool(1.0 / 5.0) {
3571 self.add_selection_set(new_selections, None).1
3572 } else {
3573 self.update_selection_set(*set_id.unwrap(), new_selections, None)
3574 .unwrap()
3575 };
3576 operations.push(op);
3577 }
3578
3579 (old_ranges, new_text, operations)
3580 }
3581
3582 pub fn randomly_undo_redo(&mut self, rng: &mut impl Rng) -> Vec<Operation> {
3583 let mut ops = Vec::new();
3584 for _ in 0..rng.gen_range(1..5) {
3585 if let Some(edit_id) = self.history.ops.keys().choose(rng).copied() {
3586 ops.push(self.undo_or_redo(edit_id).unwrap());
3587 }
3588 }
3589 ops
3590 }
3591
3592 fn selections_from_ranges<I>(&self, ranges: I) -> Result<Vec<Selection>>
3593 where
3594 I: IntoIterator<Item = Range<usize>>,
3595 {
3596 static NEXT_SELECTION_ID: AtomicUsize = AtomicUsize::new(0);
3597
3598 let mut ranges = ranges.into_iter().collect::<Vec<_>>();
3599 ranges.sort_unstable_by_key(|range| range.start);
3600
3601 let mut selections = Vec::with_capacity(ranges.len());
3602 for range in ranges {
3603 if range.start > range.end {
3604 selections.push(Selection {
3605 id: NEXT_SELECTION_ID.fetch_add(1, atomic::Ordering::SeqCst),
3606 start: self.anchor_before(range.end),
3607 end: self.anchor_before(range.start),
3608 reversed: true,
3609 goal: SelectionGoal::None,
3610 });
3611 } else {
3612 selections.push(Selection {
3613 id: NEXT_SELECTION_ID.fetch_add(1, atomic::Ordering::SeqCst),
3614 start: self.anchor_after(range.start),
3615 end: self.anchor_before(range.end),
3616 reversed: false,
3617 goal: SelectionGoal::None,
3618 });
3619 }
3620 }
3621 Ok(selections)
3622 }
3623
3624 pub fn selection_ranges<'a>(&'a self, set_id: SelectionSetId) -> Result<Vec<Range<usize>>> {
3625 Ok(self
3626 .selections(set_id)?
3627 .iter()
3628 .map(move |selection| {
3629 let start = selection.start.to_offset(self);
3630 let end = selection.end.to_offset(self);
3631 if selection.reversed {
3632 end..start
3633 } else {
3634 start..end
3635 }
3636 })
3637 .collect())
3638 }
3639
3640 pub fn all_selections(&self) -> impl Iterator<Item = (&SelectionSetId, &[Selection])> {
3641 self.selections
3642 .iter()
3643 .map(|(set_id, selections)| (set_id, selections.as_ref()))
3644 }
3645
3646 pub fn all_selection_ranges<'a>(
3647 &'a self,
3648 ) -> impl 'a + Iterator<Item = (SelectionSetId, Vec<Range<usize>>)> {
3649 self.selections
3650 .keys()
3651 .map(move |set_id| (*set_id, self.selection_ranges(*set_id).unwrap()))
3652 }
3653 }
3654
3655 impl Operation {
3656 fn edit_id(&self) -> Option<time::Local> {
3657 match self {
3658 Operation::Edit { edit, .. } => Some(edit.id),
3659 Operation::Undo { undo, .. } => Some(undo.edit_id),
3660 Operation::UpdateSelections { .. } => None,
3661 }
3662 }
3663 }
3664}