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