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