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