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