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