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