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