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