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