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