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