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