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