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