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