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