1#![cfg_attr(not(feature = "write"), no_std)]
2
3#![warn(clippy::all, clippy::pedantic, dead_code, clippy::cargo)]
4#![allow(
5 unused_assignments,
6 clippy::inline_always,
7 clippy::uninlined_format_args, clippy::borrow_as_ptr,
9 clippy::collapsible_if,
10 clippy::new_without_default,
11 clippy::redundant_field_names,
12 clippy::pub_underscore_fields,
13 clippy::struct_field_names,
14 clippy::ptr_as_ptr,
15 clippy::missing_transmute_annotations,
16 clippy::multiple_crate_versions,
17 clippy::cast_precision_loss,
18 clippy::cast_possible_truncation,
19 clippy::similar_names,
20 clippy::cast_sign_loss,
21 clippy::cast_possible_wrap,
22 clippy::used_underscore_binding,
23 clippy::nonstandard_macro_braces,
24 clippy::used_underscore_items,
25 clippy::enum_glob_use,
26 clippy::cast_lossless,
27 clippy::match_same_arms,
28 clippy::too_many_lines,
29 clippy::unnested_or_patterns,
30 clippy::blocks_in_conditions,
31 clippy::missing_errors_doc,
32 clippy::missing_panics_doc,
33)]
34
35#[cfg(feature = "write")]
36extern crate std;
37
38extern crate alloc;
39
40#[allow(unused)]
41use alloc::vec;
42use alloc::vec::Vec;
43use alloc::sync::Arc;
44use alloc::string::{String, ToString};
45
46use core::str;
47use core::cmp::Ordering;
48use core::ops::{Bound, Deref, RangeBounds};
49
50#[cfg(not(feature = "dont_vendor"))]
51mod cranelift_entity_vendor;
52#[cfg(not(feature = "dont_vendor"))]
53use cranelift_entity_vendor as cranelift_entity;
54
55#[cfg(not(feature = "dont_vendor"))]
56mod smallvec_vendor;
57#[cfg(not(feature = "dont_vendor"))]
58use smallvec_vendor as smallvec;
59
60#[cfg(not(feature = "dont_vendor"))]
61mod bytecount_vendor;
62#[cfg(not(feature = "dont_vendor"))]
63use bytecount_vendor as bytecount;
64
65use smallvec::SmallVec;
66use cranelift_entity::{EntityRef, PrimaryMap};
67#[cfg(feature = "dont_vendor")]
68use cranelift_entity::entity_impl;
69
70#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
71pub struct BufferRef(pub u32);
72entity_impl!(BufferRef);
73
74#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
75pub struct NodeRef(pub u32);
76entity_impl!(NodeRef);
77
78pub const NIL: NodeRef = NodeRef(0);
79
80pub const MOD_BUFFER: BufferRef = BufferRef(u32::MAX >> 1);
81
82pub const CHECKPOINT_INTERVAL: u32 = 64;
83
84pub const MAX_PIECE_SIZE: u32 = 64 * 1024;
85
86#[derive(Clone, Copy, PartialEq, Eq, Debug)]
87pub enum Color { Black = 0, Red = 1 }
88
89#[derive(Clone, Copy, Debug)]
90pub struct HistoryEntry {
91 pub root: NodeRef,
92 pub cursor_offset: u32,
93}
94
95#[derive(Default, Clone, Copy, Debug, PartialEq, Eq)]
96pub struct Piece {
97 pub buffer: BufferRef,
98
99 pub byte_offset: u32,
100 pub byte_length: u32,
101
102 pub newline_count: u32,
103 pub char_count: u32,
104
105 pub buffer_start_line: u32, pub piece_start_char: u32, }
109
110#[derive(Clone, Copy, Debug)]
112pub enum Edit {
113 Insert { offset: u32, text: &'static str },
114 Remove { offset: u32, length: u32 },
115}
116
117impl Edit {
118 #[inline(always)]
119 #[must_use]
120 pub fn offset(&self) -> u32 {
121 match self {
122 Edit::Insert { offset, .. } => *offset,
123 Edit::Remove { offset, .. } => *offset,
124 }
125 }
126}
127
128#[derive(Clone, Copy, Debug)]
129#[repr(C)]
130pub struct Node {
131 pub left: NodeRef, pub right: NodeRef, pub offset: u32, pub subtree_len: u32, pub subtree_chars: u32, pub subtree_newlines: u32, pub meta: u32, pub buffer_start_line: u32, pub piece_start_char: u32, }
141
142const _: () = assert!(size_of::<Node>() == 36);
143
144impl Node {
145 #[inline(always)]
146 #[must_use]
147 pub fn color(&self) -> Color {
148 if (self.meta & 1) == 1 { Color::Red } else { Color::Black }
149 }
150
151 #[inline(always)]
152 pub fn set_color(&mut self, color: Color) {
153 self.meta = (self.meta & !1) | (color as u32);
154 }
155
156 #[inline(always)]
157 #[must_use]
158 pub fn buffer_index(&self) -> BufferRef {
159 BufferRef(self.meta >> 1)
160 }
161
162 #[inline(always)]
163 pub fn set_buffer(&mut self, buffer: BufferRef) {
164 self.meta = (buffer.as_u32() << 1) | (self.meta & 1);
165 }
166}
167
168#[derive(Debug, Clone)]
169pub struct OriginalBuffer {
170 pub text: Arc<str>,
171 pub newline_offsets: Arc<[u32]>,
172 pub char_checkpoints: Arc<[(u32, u32)]>,
173}
174
175impl Deref for OriginalBuffer {
176 type Target = str;
177
178 #[inline(always)]
179 fn deref(&self) -> &Self::Target {
180 self.text.as_ref()
181 }
182}
183
184#[derive(Debug, Clone)]
185pub struct Buffers {
186 pub original_buffers: PrimaryMap<BufferRef, OriginalBuffer>,
187
188 pub modifications_buffer: String,
189 pub modifications_newline_offsets: Vec<u32>,
190 pub modifications_char_checkpoints: Vec<(u32, u32)>,
191}
192
193impl Default for Buffers {
194 #[inline(always)]
195 fn default() -> Self {
196 Self {
197 original_buffers: PrimaryMap::new(),
198 modifications_newline_offsets: Vec::with_capacity(1024),
199 modifications_char_checkpoints: Vec::with_capacity(128),
200 modifications_buffer: String::with_capacity(1024 * 64),
201 }
202 }
203}
204
205#[must_use]
206#[inline(always)]
207pub fn count_chars_and_newlines(bytes: &[u8]) -> (u32, u32) {
208 let mut chars = 0u32;
209 let mut newlines = 0u32;
210
211 for &b in bytes {
212 newlines += (b == b'\n') as u32;
213 chars += ((b & 0xC0) != 0x80) as u32;
214 }
215
216 (chars, newlines)
217}
218
219#[must_use]
220#[inline(always)]
221pub fn count_chars_and_newlines_with_offsets_and_checkpoints(
222 bytes: &[u8],
223 offsets: &mut Vec<u32>,
224 checkpoints: &mut Vec<(u32, u32)>,
225) -> (u32, u32) {
226 let mut chars = 0u32;
227 let mut newlines = 0u32;
228
229 let mut next_checkpoint = CHECKPOINT_INTERVAL;
230
231 for (i, &b) in bytes.iter().enumerate() {
232 if (b as i8) >= -0x40 {
233 if chars == next_checkpoint {
234 checkpoints.push((chars, i as u32));
235 next_checkpoint += CHECKPOINT_INTERVAL;
236 }
237 chars += 1;
238 }
239
240 if b == b'\n' {
241 offsets.push(i as u32);
242 newlines += 1;
243 }
244 }
245
246 (chars, newlines)
247}
248
249impl Buffers {
250 #[inline(always)]
251 #[must_use]
252 pub fn new() -> Self { Self::default() }
253
254 #[inline(always)]
255 #[must_use]
256 pub fn get(&self, buffer: BufferRef) -> &str {
257 if buffer == MOD_BUFFER {
258 &self.modifications_buffer
259 } else {
260 &self.original_buffers[buffer]
261 }
262 }
263
264 #[inline(always)]
265 #[must_use]
266 pub fn get_slice(&self, buffer: BufferRef, offset: u32, len: u32) -> &str {
267 let buf = self.get(buffer);
268 let start = offset as usize;
269 let end = start + len as usize;
270 unsafe { str::from_utf8_unchecked(buf.as_bytes().get_unchecked(start..end)) }
271 }
272
273 #[inline]
274 pub fn count_chars_and_newlines(&self, buffer: BufferRef, start_offset: u32, len: u32) -> (u32, u32) {
275 if len == 0 { return (0, 0) }
276
277 let end_offset = start_offset + len;
278
279 let nl_offsets = self.get_newlines(buffer);
283 let start_nl_index = nl_offsets.binary_search(&start_offset).unwrap_or_else(|x| x);
284 let end_nl_index = nl_offsets.binary_search(&end_offset).unwrap_or_else(|x| x);
285 let newlines = (end_nl_index - start_nl_index) as u32;
286
287 let checkpoints = self.get_checkpoints(buffer);
292 let buffer_text = self.get(buffer);
293
294 let chars_up_to = |target_offset: u32| -> u32 {
298 if target_offset == 0 { return 0; }
299
300 let partition_index = checkpoints.partition_point(|&(_char_cnt, byte_offset)| byte_offset <= target_offset);
304
305 let (base_chars, base_bytes) = if partition_index > 0 {
306 checkpoints[partition_index - 1]
307 } else {
308 (0, 0)
309 };
310
311 let tail_bytes = &buffer_text[base_bytes as usize .. target_offset as usize];
315 base_chars + bytecount::num_chars(tail_bytes.as_bytes()) as u32
316 };
317
318 let chars = chars_up_to(end_offset) - chars_up_to(start_offset);
319
320 (chars, newlines)
321 }
322
323 #[inline(always)]
324 #[must_use]
325 pub fn count_chars(&self, buffer: BufferRef, offset: u32, len: u32) -> u32 {
326 bytecount::num_chars(self.get_slice(buffer, offset, len).as_bytes()) as u32
327 }
328
329 #[inline(always)]
330 #[must_use]
331 pub fn count_newlines(&self, buffer: BufferRef, offset: u32, len: u32) -> u32 {
332 bytecount::count(self.get_slice(buffer, offset, len).as_bytes(), b'\n') as _
333 }
334
335 #[inline(always)]
336 fn get_newlines(&self, buffer: BufferRef) -> &[u32] {
337 if buffer == MOD_BUFFER {
338 &self.modifications_newline_offsets
339 } else {
340 &self.original_buffers[buffer].newline_offsets
341 }
342 }
343
344 #[inline(always)]
345 fn get_checkpoints(&self, buffer: BufferRef) -> &[(u32, u32)] {
346 if buffer == MOD_BUFFER {
347 &self.modifications_char_checkpoints
348 } else {
349 &self.original_buffers[buffer].char_checkpoints
350 }
351 }
352
353 #[must_use]
355 #[inline]
356 pub fn char_to_byte_absolute(&self, buffer: BufferRef, target_char: u32) -> u32 {
357 if target_char == 0 { return 0; }
358
359 let checkpoints = self.get_checkpoints(buffer);
360 let cp_index = checkpoints.partition_point(|&(c, _)| c <= target_char);
361
362 let (current_char, current_byte) = if cp_index == 0 {
363 (0, 0)
364 } else {
365 unsafe { *checkpoints.get_unchecked(cp_index - 1) }
366 };
367
368 let remainder_chars = target_char - current_char;
369 if remainder_chars == 0 { return current_byte; }
370
371 let text = self.get(buffer);
372 let slice = unsafe { text.get_unchecked(current_byte as usize..) };
373
374 let additional_bytes = slice
375 .char_indices()
376 .nth(remainder_chars as usize)
377 .map(|(b, _)| b as u32)
378 .unwrap_or_else(|| slice.len() as u32); current_byte + additional_bytes
381 }
382
383 #[must_use]
385 #[inline]
386 pub fn byte_to_char_absolute(&self, buffer: BufferRef, target_byte: u32) -> u32 {
387 if target_byte == 0 { return 0; }
388
389 let checkpoints = self.get_checkpoints(buffer);
390 let cp_index = checkpoints.partition_point(|&(_, b)| b <= target_byte);
391
392 let (current_char, current_byte) = if cp_index == 0 {
393 (0, 0)
394 } else {
395 unsafe { *checkpoints.get_unchecked(cp_index - 1) }
396 };
397
398 let remainder_bytes = target_byte - current_byte;
399 if remainder_bytes == 0 { return current_char; }
400
401 let text = self.get(buffer);
402 let slice = unsafe { text.get_unchecked(current_byte as usize..target_byte as usize) };
403 let additional_chars = bytecount::num_chars(slice.as_bytes()) as u32;
404
405 current_char + additional_chars
406 }
407}
408
409#[derive(Debug, Clone)]
410pub struct Pieces {
411 pub nodes: PrimaryMap<NodeRef, Node>,
412}
413
414impl Default for Pieces {
415 #[inline(always)]
416 fn default() -> Self {
417 Self::new()
418 }
419}
420
421impl Pieces {
422 #[inline(always)]
423 #[must_use]
424 pub fn new() -> Self {
425 let mut nodes = PrimaryMap::new();
426 nodes.push(Node {
427 left: NIL, right: NIL, offset: 0,
428 subtree_len: 0, subtree_chars: 0, subtree_newlines: 0,
429 meta: 0, buffer_start_line: 0,
430 piece_start_char: 0
431 });
432 Self { nodes }
433 }
434
435 #[inline(always)]
436 #[must_use]
437 pub fn len(&self) -> usize { self.nodes.len() }
438
439 #[inline(always)]
440 #[must_use]
441 pub fn is_empty(&self) -> bool { self.nodes.is_empty() }
442
443 #[inline(always)]
444 #[must_use]
445 pub fn get(&self, index: NodeRef) -> &Node { &self.nodes[index] }
446
447 #[inline(always)]
448 #[must_use]
449 pub fn get_piece(&self, index: NodeRef) -> Piece {
450 if index == NIL { return Piece::default(); }
451
452 let node = &self.nodes[index];
453 let l = &self.nodes[node.left];
454 let r = &self.nodes[node.right];
455
456 Piece {
457 buffer: node.buffer_index(),
458 byte_offset: node.offset,
459 byte_length: node.subtree_len - l.subtree_len - r.subtree_len,
460 char_count: node.subtree_chars - l.subtree_chars - r.subtree_chars,
461 newline_count: node.subtree_newlines - l.subtree_newlines - r.subtree_newlines,
462 buffer_start_line: node.buffer_start_line,
463 piece_start_char: node.piece_start_char,
464 }
465 }
466
467 #[inline(always)]
468 pub fn alloc(&mut self, color: Color, left: NodeRef, piece: Piece, right: NodeRef) -> NodeRef {
469 let l = &self.nodes[left];
470 let r = &self.nodes[right];
471
472 let mut node = Node {
473 left, right,
474 offset: piece.byte_offset,
475 subtree_len: l.subtree_len + piece.byte_length + r.subtree_len,
476 subtree_chars: l.subtree_chars + piece.char_count + r.subtree_chars,
477 subtree_newlines: l.subtree_newlines + piece.newline_count + r.subtree_newlines,
478 buffer_start_line: piece.buffer_start_line,
479 piece_start_char: piece.piece_start_char,
480 meta: 0,
481 };
482 node.set_color(color);
483 node.set_buffer(piece.buffer);
484
485 self.nodes.push(node)
486 }
487
488 pub fn extend_piece(
491 &mut self,
492 root: NodeRef,
493 piece_start_offset: u32,
494 add_len: u32,
495 add_chars: u32,
496 add_nl: u32,
497 ) -> NodeRef {
498 if root == NIL { return NIL }
499
500 let node = self.nodes[root];
501 let mut new_node = node;
502
503 let left_len = self.nodes[node.left].subtree_len;
504 let piece_len = node.subtree_len - left_len - self.nodes[node.right].subtree_len;
505
506 if piece_start_offset < left_len {
507 new_node.left = self.extend_piece(node.left, piece_start_offset, add_len, add_chars, add_nl);
508 } else if piece_start_offset > left_len {
509 new_node.right = self.extend_piece(node.right, piece_start_offset - (left_len + piece_len), add_len, add_chars, add_nl);
510 } else {
511 }
514
515 new_node.subtree_len += add_len;
516 new_node.subtree_chars += add_chars;
517 new_node.subtree_newlines += add_nl;
518
519 self.nodes.push(new_node)
520 }
521
522 #[inline]
523 pub fn insert_node(&mut self, root: NodeRef, piece: Piece, at: u32) -> NodeRef {
524 let new_root = self.ins(root, piece, at, 0);
525 let r_node = self.nodes[new_root];
526 let p = self.get_piece(new_root);
527 self.alloc(Color::Black, r_node.left, p, r_node.right)
528 }
529
530 #[inline]
531 pub fn remove_node(&mut self, root: NodeRef, at: u32) -> NodeRef {
532 let new_root = self.rem(root, at, 0);
533 if new_root == NIL { return NIL }
534
535 let r_node = self.nodes[new_root];
536 self.alloc(Color::Black, r_node.left, self.get_piece(new_root), r_node.right)
537 }
538
539 #[inline]
540 fn rem(&mut self, root: NodeRef, at: u32, total: u32) -> NodeRef {
541 if root == NIL { return NIL }
542
543 let node = self.nodes[root];
544 let node_piece = self.get_piece(root);
545 let left_len = self.nodes[node.left].subtree_len;
546
547 match at.cmp(&(total + left_len)) {
548 Ordering::Less => self.remove_left(root, at, total),
549 Ordering::Equal => self.fuse(node.left, node.right),
550 Ordering::Greater => {
551 let next_total = total + left_len + node_piece.byte_length;
552 self.remove_right(root, at, next_total)
553 }
554 }
555 }
556
557 #[inline]
558 fn remove_left(&mut self, root: NodeRef, at: u32, total: u32) -> NodeRef {
559 let node = self.nodes[root];
560 let new_left = self.rem(node.left, at, total);
561 let new_node = self.alloc(Color::Red, new_left, self.get_piece(root), node.right);
562 if self.nodes[node.left].color() == Color::Black {
563 self.balance_left(new_node)
564 } else {
565 new_node
566 }
567 }
568
569 #[inline]
570 fn remove_right(&mut self, root: NodeRef, at: u32, total: u32) -> NodeRef {
571 let node = self.nodes[root];
572 let new_right = self.rem(node.right, at, total);
573 let new_node = self.alloc(Color::Red, node.left, self.get_piece(root), new_right);
574 if self.nodes[node.right].color() == Color::Black {
575 self.balance_right(new_node)
576 } else {
577 new_node
578 }
579 }
580
581 #[inline]
582 fn ins(&mut self, root: NodeRef, p: Piece, at: u32, total_offset: u32) -> NodeRef {
583 if root == NIL { return self.alloc(Color::Red, NIL, p, NIL); }
584
585 let node = self.nodes[root];
586 let node_piece = self.get_piece(root);
587 let left_len = self.nodes[node.left].subtree_len;
588
589 if at < total_offset + left_len + node_piece.byte_length {
590 let lft = self.ins(node.left, p, at, total_offset);
591 self.balance(node.color(), lft, node_piece, node.right)
592 } else {
593 let next_offset = total_offset + left_len + node_piece.byte_length;
594 let rgt = self.ins(node.right, p, at, next_offset);
595 self.balance(node.color(), node.left, node_piece, rgt)
596 }
597 }
598
599 #[inline]
600 fn balance(&mut self, c: Color, l_index: NodeRef, p: Piece, r_index: NodeRef) -> NodeRef {
601 let l = self.nodes[l_index];
602 let r = self.nodes[r_index];
603
604 if c == Color::Black {
605 if l.color() == Color::Red {
606 let ll = self.nodes[l.left];
607 let lr = self.nodes[l.right];
608 if ll.color() == Color::Red {
609 let new_l = self.alloc(Color::Black, ll.left, self.get_piece(l.left), ll.right);
610 let new_r = self.alloc(Color::Black, l.right, p, r_index);
611 return self.alloc(Color::Red, new_l, self.get_piece(l_index), new_r);
612 } else if lr.color() == Color::Red {
613 let new_l = self.alloc(Color::Black, l.left, self.get_piece(l_index), lr.left);
614 let new_r = self.alloc(Color::Black, lr.right, p, r_index);
615 return self.alloc(Color::Red, new_l, self.get_piece(l.right), new_r);
616 }
617 }
618
619 if r.color() == Color::Red {
620 let rl = self.nodes[r.left];
621 let rr = self.nodes[r.right];
622 if rl.color() == Color::Red {
623 let new_l = self.alloc(Color::Black, l_index, p, rl.left);
624 let new_r = self.alloc(Color::Black, rl.right, self.get_piece(r_index), r.right);
625 return self.alloc(Color::Red, new_l, self.get_piece(r.left), new_r);
626 } else if rr.color() == Color::Red {
627 let new_l = self.alloc(Color::Black, l_index, p, r.left);
628 let new_r = self.alloc(Color::Black, rr.left, self.get_piece(r.right), rr.right);
629 return self.alloc(Color::Red, new_l, self.get_piece(r_index), new_r);
630 }
631 }
632 }
633
634 self.alloc(c, l_index, p, r_index)
635 }
636
637 #[inline]
638 fn fuse(&mut self, left: NodeRef, right: NodeRef) -> NodeRef {
639 if left == NIL { return right }
643 if right == NIL { return left }
644
645 let l_node = self.nodes[left];
646 let r_node = self.nodes[right];
647
648 if l_node.color() == Color::Black && r_node.color() == Color::Red {
652 let fused = self.fuse(left, r_node.left);
653 return self.alloc(Color::Red, fused, self.get_piece(right), r_node.right);
654 }
655
656 if l_node.color() == Color::Red && r_node.color() == Color::Black {
658 let fused = self.fuse(l_node.right, right);
659 return self.alloc(Color::Red, l_node.left, self.get_piece(left), fused);
660 }
661
662 if l_node.color() == Color::Red && r_node.color() == Color::Red {
664 let fused = self.fuse(l_node.right, r_node.left);
665 let f_node = self.nodes[fused];
666 if fused != NIL && f_node.color() == Color::Red {
667 let new_l = self.alloc(Color::Red, l_node.left, self.get_piece(left), f_node.left);
668 let new_r = self.alloc(Color::Red, f_node.right, self.get_piece(right), r_node.right);
669 return self.alloc(Color::Red, new_l, self.get_piece(fused), new_r);
670 }
671 let new_r = self.alloc(Color::Red, fused, self.get_piece(right), r_node.right);
672 return self.alloc(Color::Red, l_node.left, self.get_piece(left), new_r);
673 }
674
675 let fused = self.fuse(l_node.right, r_node.left);
678 let f_node = self.nodes[fused];
679 if fused != NIL && f_node.color() == Color::Red {
680 let new_l = self.alloc(Color::Black, l_node.left, self.get_piece(left), f_node.left);
681 let new_r = self.alloc(Color::Black, f_node.right, self.get_piece(right), r_node.right);
682 return self.alloc(Color::Red, new_l, self.get_piece(fused), new_r);
683 }
684
685 let new_r = self.alloc(Color::Black, fused, self.get_piece(right), r_node.right);
686 let new_node = self.alloc(Color::Red, l_node.left, self.get_piece(left), new_r);
687 self.balance_left(new_node)
688 }
689
690 #[inline]
691 fn balance_left(&mut self, left: NodeRef) -> NodeRef {
692 let l_node = self.nodes[left];
693 let ll_node = self.nodes[l_node.left];
694 let lr_node = self.nodes[l_node.right];
695
696 if l_node.left != NIL && ll_node.color() == Color::Red {
700 let new_ll = self.alloc(Color::Black, ll_node.left, self.get_piece(l_node.left), ll_node.right);
701 return self.alloc(Color::Red, new_ll, self.get_piece(left), l_node.right);
702 }
703
704 if l_node.right != NIL && lr_node.color() == Color::Black {
706 let new_lr = self.alloc(Color::Red, lr_node.left, self.get_piece(l_node.right), lr_node.right);
707 let new_l = self.alloc(Color::Black, l_node.left, self.get_piece(left), new_lr);
708 let nl = self.nodes[new_l];
709 return self.balance(Color::Black, nl.left, self.get_piece(new_l), nl.right);
710 }
711
712 if l_node.right != NIL && lr_node.color() == Color::Red {
714 let lrl_node = self.nodes[lr_node.left];
715 if lr_node.left != NIL && lrl_node.color() == Color::Black {
716 let lrr_node = self.nodes[lr_node.right];
717 let new_lrr = self.alloc(Color::Red, lrr_node.left, self.get_piece(lr_node.right), lrr_node.right);
718 let unbal_r = self.alloc(Color::Black, lrl_node.right, self.get_piece(l_node.right), new_lrr);
719 let ur_node = self.nodes[unbal_r];
720 let new_r = self.balance(ur_node.color(), ur_node.left, self.get_piece(unbal_r), ur_node.right);
721 let new_l = self.alloc(Color::Black, l_node.left, self.get_piece(left), lrl_node.left);
722 return self.alloc(Color::Red, new_l, self.get_piece(lr_node.left), new_r);
723 }
724 }
725
726 left
727 }
728
729 #[inline]
730 fn balance_right(&mut self, right: NodeRef) -> NodeRef {
731 let r_node = self.nodes[right];
732 let rl_node = self.nodes[r_node.left];
733 let rr_node = self.nodes[r_node.right];
734
735 if r_node.right != NIL && rr_node.color() == Color::Red {
739 let new_rr = self.alloc(Color::Black, rr_node.left, self.get_piece(r_node.right), rr_node.right);
740 return self.alloc(Color::Red, r_node.left, self.get_piece(right), new_rr);
741 }
742
743 if r_node.left != NIL && rl_node.color() == Color::Black {
745 let new_rl = self.alloc(Color::Red, rl_node.left, self.get_piece(r_node.left), rl_node.right);
746 let new_r = self.alloc(Color::Black, new_rl, self.get_piece(right), r_node.right);
747 let nr = self.nodes[new_r];
748 return self.balance(Color::Black, nr.left, self.get_piece(new_r), nr.right);
749 }
750
751 if r_node.left != NIL && rl_node.color() == Color::Red {
753 let rlr_node = self.nodes[rl_node.right];
754 if rl_node.right != NIL && rlr_node.color() == Color::Black {
755 let rll_node = self.nodes[rl_node.left];
756 let new_rll = self.alloc(Color::Red, rll_node.left, self.get_piece(rl_node.left), rll_node.right);
757 let unbal_l = self.alloc(Color::Black, new_rll, self.get_piece(r_node.left), rlr_node.left);
758 let ul_node = self.nodes[unbal_l];
759 let new_l = self.balance(ul_node.color(), ul_node.left, self.get_piece(unbal_l), ul_node.right);
760 let new_r = self.alloc(Color::Black, rlr_node.right, self.get_piece(right), r_node.right);
761 return self.alloc(Color::Red, new_l, self.get_piece(rl_node.right), new_r);
762 }
763 }
764
765 right
766 }
767
768 #[inline]
769 #[must_use]
770 pub fn find_offset(
771 &self,
772 mut root: NodeRef,
773 mut target_offset: u32,
774 prefer_left: bool
775 ) -> Option<(NodeRef, u32)> {
776 while root != NIL {
777 let node = &self.nodes[root];
778 let left_len = self.nodes[node.left].subtree_len;
779 let piece_len = self.get_piece(root).byte_length;
780
781 if target_offset < left_len {
782 root = node.left;
783
784 } else if target_offset == left_len + piece_len && prefer_left {
785 return Some((root, piece_len));
787
788 } else if target_offset < left_len + piece_len {
789 return Some((root, target_offset - left_len));
790
791 } else {
792 target_offset -= left_len + piece_len;
793 root = node.right;
794 }
795 }
796
797 None
798 }
799}
800
801impl PieceTree {
802 #[inline]
804 pub fn split(&mut self, root: NodeRef, offset: u32) -> (NodeRef, NodeRef) {
805 if root == NIL {
806 return (NIL, NIL);
807 }
808
809 let node = self.pieces.nodes[root];
810 let p = self.pieces.get_piece(root);
811 let left_len = self.pieces.nodes[node.left].subtree_len;
812
813 if offset < left_len {
814 let (ll, lr) = self.split(node.left, offset);
815
816 let new_right = self.pieces.join_with_middle(lr, p, node.right);
818 (ll, new_right)
819
820 } else if offset > left_len + p.byte_length {
821 let (rl, rr) = self.split(node.right, offset - left_len - p.byte_length);
822
823 let new_left = self.pieces.join_with_middle(node.left, p, rl);
825 (new_left, rr)
826
827 } else {
828 let rel_offset = offset - left_len;
829
830 if rel_offset == 0 {
831 (node.left, self.pieces.join_with_middle(NIL, p, node.right))
832
833 } else if rel_offset == p.byte_length {
834 (self.pieces.join_with_middle(node.left, p, NIL), node.right)
835
836 } else {
837 let left_len = rel_offset;
841 let right_len = p.byte_length - rel_offset;
842
843 let (left_chars, left_nl) = if left_len <= right_len {
847 self.buffers.count_chars_and_newlines(p.buffer, p.byte_offset, left_len)
849 } else {
850 let (r_chars, r_nl) = self.buffers.count_chars_and_newlines(
852 p.buffer, p.byte_offset + left_len, right_len
853 );
854
855 (p.char_count - r_chars, p.newline_count - r_nl)
856 };
857
858 let left_stump = Piece {
859 buffer: p.buffer,
860 byte_offset: p.byte_offset,
861 byte_length: left_len,
862 newline_count: left_nl,
863 char_count: left_chars,
864 buffer_start_line: p.buffer_start_line,
865 piece_start_char: p.piece_start_char,
866 };
867
868 let right_stump = Piece {
869 buffer: p.buffer,
870 byte_offset: p.byte_offset + left_len,
871 byte_length: right_len,
872 newline_count: p.newline_count - left_nl,
873 char_count: p.char_count - left_chars,
874 buffer_start_line: p.buffer_start_line + left_nl,
875 piece_start_char: p.piece_start_char + left_chars,
876 };
877
878 let new_left = self.pieces.join_with_middle(node.left, left_stump, NIL);
879 let new_right = self.pieces.join_with_middle(NIL, right_stump, node.right);
880 (new_left, new_right)
881 }
882 }
883 }
884
885 #[inline]
887 pub fn concat(&mut self, left: NodeRef, right: NodeRef) -> NodeRef {
888 let new_root = if left == NIL {
892 right
893 } else if right == NIL {
894 left
895 } else {
896 let mut curr = left;
897 while self.pieces.nodes[curr].right != NIL {
898 curr = self.pieces.nodes[curr].right;
899 }
900 let max_piece = self.pieces.get_piece(curr);
901 let max_offset = self.pieces.nodes[left].subtree_len - max_piece.byte_length;
902
903 let left_without_max = self.pieces.remove_node(left, max_offset);
904
905 self.pieces.join_with_middle(left_without_max, max_piece, right)
906 };
907
908 if new_root != NIL && self.pieces.nodes[new_root].color() == Color::Red {
912 let p = self.pieces.get_piece(new_root);
913 let r = self.pieces.nodes[new_root];
914 return self.pieces.alloc(Color::Black, r.left, p, r.right);
915 }
916
917 new_root
918 }
919}
920
921impl Pieces {
922 #[inline(always)]
924 pub fn black_height(&self, mut node: NodeRef) -> u32 {
925 let mut h = 0;
926 while node != NIL {
927 if self.nodes[node].color() == Color::Black {
928 h += 1;
929 }
930 node = self.nodes[node].left;
931 }
932 h
933 }
934
935 #[inline(always)]
937 pub fn join_with_middle(&mut self, left: NodeRef, piece: Piece, right: NodeRef) -> NodeRef {
938 let hl = self.black_height(left);
939 let hr = self.black_height(right);
940
941 let new_root = if hl > hr {
942 self.join_right(left, piece, right, hl, hr)
943 } else if hr > hl {
944 self.join_left(left, piece, right, hl, hr)
945 } else {
946 self.alloc(Color::Red, left, piece, right)
947 };
948
949 if new_root != NIL && self.nodes[new_root].color() == Color::Red {
951 let p = self.get_piece(new_root);
952 let r = self.nodes[new_root];
953 return self.alloc(Color::Black, r.left, p, r.right);
954 }
955
956 new_root
957 }
958
959 #[inline(always)]
960 fn join_right(&mut self, left: NodeRef, piece: Piece, right: NodeRef, hl: u32, hr: u32) -> NodeRef {
961 if hl == hr {
962 return self.alloc(Color::Red, left, piece, right);
963 }
964
965 let l_node = self.nodes[left];
966 let next_hl = if l_node.color() == Color::Black { hl - 1 } else { hl };
967
968 let new_right = self.join_right(l_node.right, piece, right, next_hl, hr);
969 let p = self.get_piece(left);
970
971 self.balance(l_node.color(), l_node.left, p, new_right)
972 }
973
974 #[inline(always)]
975 fn join_left(&mut self, left: NodeRef, piece: Piece, right: NodeRef, hl: u32, hr: u32) -> NodeRef {
976 if hl == hr {
977 return self.alloc(Color::Red, left, piece, right);
978 }
979
980 let r_node = self.nodes[right];
981 let next_hr = if r_node.color() == Color::Black { hr - 1 } else { hr };
982
983 let new_left = self.join_left(left, piece, r_node.left, hl, next_hr);
984 let p = self.get_piece(right);
985
986 self.balance(r_node.color(), new_left, p, r_node.right)
987 }
988}
989
990#[derive(Default, Debug, Clone)]
991pub struct PieceTree {
992 last_mod_end: u32, last_tree_end: u32, pub root: NodeRef,
1002
1003 pub transaction_depth: usize,
1005
1006 pub undo_stack: Vec<HistoryEntry>,
1007 pub redo_stack: Vec<HistoryEntry>,
1008
1009 pub pieces: Pieces,
1010 pub buffers: Buffers,
1011
1012 pub scratch_index_map: Vec<u32>,
1013}
1014
1015impl core::fmt::Display for PieceTree {
1016 #[inline(always)]
1017 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1018 let walker = TreeWalker::new(self);
1019 for char in walker {
1020 write!(f, "{char}")?;
1021 }
1022
1023 Ok(())
1024 }
1025}
1026
1027impl<T> From<T> for PieceTree where T: AsRef<str> {
1028 #[inline(always)]
1029 fn from(value: T) -> Self {
1030 Self::from_str(value.as_ref())
1031 }
1032}
1033
1034impl str::FromStr for PieceTree {
1035 type Err = core::convert::Infallible;
1036
1037 #[inline(always)]
1038 fn from_str(s: &str) -> Result<Self, Self::Err> {
1039 Ok(PieceTree::from(s))
1040 }
1041}
1042
1043impl PieceTree {
1044 #[inline(always)]
1045 #[must_use]
1046 pub fn new() -> Self {
1047 Self::default()
1048 }
1049
1050 #[inline(always)]
1051 #[must_use]
1052 pub fn from_str(text: &str) -> Self {
1053 #[inline(always)]
1054 fn is_utf8_char_boundary(b: u8) -> bool { (b as i8) >= -0x40 }
1055
1056 let mut tree = PieceTree::new();
1057
1058 let mut offset = 0;
1059
1060 let text_bytes = text.as_bytes();
1061 let total_len = text.len() as u32;
1062
1063 while offset < total_len {
1064 let mut chunk_len = (total_len - offset).min(MAX_PIECE_SIZE);
1066
1067 while offset + chunk_len < total_len && !is_utf8_char_boundary(text_bytes[(offset + chunk_len) as usize]) {
1069 chunk_len += 1;
1070 }
1071
1072 let chunk_text = &text[offset as usize .. (offset + chunk_len) as usize];
1073
1074 tree.insert(tree.total_length(), chunk_text);
1076
1077 offset += chunk_len;
1078 }
1079
1080 tree
1081 }
1082}
1083
1084impl PieceTree {
1085 #[inline]
1087 pub fn begin_undo_group(&mut self, cursor_offset: u32) {
1088 if self.transaction_depth == 0 {
1089 self.commit_head(cursor_offset);
1090 }
1091
1092 self.transaction_depth += 1;
1093 }
1094
1095 #[inline]
1097 pub fn end_undo_group(&mut self) {
1098 if self.transaction_depth > 0 {
1099 self.transaction_depth -= 1;
1100 }
1101 }
1102
1103 #[inline(always)]
1104 pub fn commit_head(&mut self, cursor_offset: u32) {
1105 if let Some(last) = self.undo_stack.last() {
1106 if last.root == self.root {
1107 return; }
1109 }
1110
1111 self.undo_stack.push(HistoryEntry { root: self.root, cursor_offset });
1112 self.redo_stack.clear();
1113 }
1114
1115 #[inline(always)]
1116 pub fn try_undo(&mut self, current_cursor: u32) -> Option<u32> {
1117 if self.transaction_depth > 0 {
1118 return None;
1119 }
1120
1121 if let Some(entry) = self.undo_stack.pop() {
1122 self.last_tree_end = u32::MAX;
1123 self.last_mod_end = u32::MAX;
1124
1125 self.redo_stack.push(HistoryEntry {
1126 root: self.root, cursor_offset: current_cursor
1127 });
1128 self.root = entry.root;
1129 return Some(entry.cursor_offset);
1130 }
1131
1132 None
1133 }
1134
1135 #[inline(always)]
1136 pub fn try_redo(&mut self, current_cursor: u32) -> Option<u32> {
1137 if let Some(entry) = self.redo_stack.pop() {
1138 self.last_tree_end = u32::MAX;
1139 self.last_mod_end = u32::MAX;
1140
1141 self.undo_stack.push(HistoryEntry {
1142 root: self.root, cursor_offset: current_cursor
1143 });
1144 self.root = entry.root;
1145 return Some(entry.cursor_offset);
1146 }
1147
1148 None
1149 }
1150
1151 #[inline(always)]
1152 #[must_use]
1153 pub fn total_length(&self) -> u32 {
1154 self.pieces.get(self.root).subtree_len
1155 }
1156
1157 #[inline(always)]
1158 pub fn apply_edits(&mut self, primary_cursor_offset: u32, edits: &mut [Edit]) {
1159 if edits.is_empty() { return }
1160
1161 self.begin_undo_group(primary_cursor_offset);
1162
1163 edits.sort_by_key(|b| core::cmp::Reverse(b.offset()));
1164 for edit in edits {
1165 match edit {
1166 Edit::Insert { offset, text } => self.insert_no_commit(*offset, text),
1167 Edit::Remove { offset, length } => self.remove_no_commit(*offset, *length),
1168 }
1169 }
1170
1171 self.end_undo_group();
1172 }
1173
1174 #[inline(always)]
1176 pub fn insert_char(&mut self, offset: u32, ch: char) {
1177 self.commit_head(offset);
1178 self.insert_char_no_commit(offset, ch);
1179 }
1180
1181 #[inline(always)]
1183 pub fn insert_char_no_commit(&mut self, offset: u32, ch: char) {
1184 let mut buf = [0; 4];
1185 self.insert_no_commit(offset, ch.encode_utf8(&mut buf));
1186 }
1187
1188 #[inline(always)]
1189 pub fn insert(&mut self, offset: u32, text: &str) {
1190 if text.is_empty() { return }
1191
1192 let auto_group = self.transaction_depth == 0;
1193 if auto_group {
1194 self.begin_undo_group(offset);
1195 }
1196
1197 self.insert_no_commit(offset, text);
1198
1199 if auto_group {
1200 self.end_undo_group();
1201 }
1202 }
1203
1204 #[inline(always)]
1205 pub fn remove_at(&mut self, offset: u32, length: u32) {
1206 if length == 0 || self.root == NIL { return }
1207
1208 let auto_group = self.transaction_depth == 0;
1209 if auto_group {
1210 self.begin_undo_group(offset);
1211 }
1212
1213 self.remove_no_commit(offset, length);
1214
1215 if auto_group {
1216 self.end_undo_group();
1217 }
1218 }
1219
1220 pub fn insert_no_commit(&mut self, offset: u32, text: &str) {
1221 let mod_offset = self.buffers.modifications_buffer.len() as u32;
1222 let start_line_in_buffer = self.buffers.modifications_newline_offsets.len() as u32;
1223
1224 let mut total_char_count = if let Some(&(c, b)) = self.buffers.modifications_char_checkpoints.last() {
1225 let tail_bytes = &self.buffers.modifications_buffer[b as usize..mod_offset as usize];
1226 c + bytecount::num_chars(tail_bytes.as_bytes()) as u32
1227 } else {
1228 bytecount::num_chars(self.buffers.modifications_buffer[..mod_offset as usize].as_bytes()) as u32
1229 };
1230
1231 let mut newline_count = 0;
1232 let mut char_count = 0;
1233 {
1234 let rem = total_char_count % CHECKPOINT_INTERVAL;
1235 let mut next_checkpoint = total_char_count + ((CHECKPOINT_INTERVAL - rem) % CHECKPOINT_INTERVAL);
1236
1237 if next_checkpoint == 0 {
1238 next_checkpoint = CHECKPOINT_INTERVAL;
1239 }
1240
1241 for (i, b) in text.bytes().enumerate() {
1245 if (b as i8) >= -0x40 {
1246 if total_char_count == next_checkpoint {
1247 self.buffers.modifications_char_checkpoints.push((total_char_count, mod_offset + i as u32));
1248 next_checkpoint += CHECKPOINT_INTERVAL;
1249 }
1250
1251 total_char_count += 1;
1252 char_count += 1;
1253 }
1254
1255 if b == b'\n' {
1256 self.buffers.modifications_newline_offsets.push(mod_offset + i as u32);
1257 newline_count += 1;
1258 }
1259 }
1260 }
1261
1262 self.buffers.modifications_buffer.push_str(text);
1263 let text_len = text.len() as u32;
1264
1265 let new_mod_end = mod_offset + text_len;
1266 let new_tree_end = offset + text_len;
1267
1268 if offset > 0
1272 && self.last_tree_end == offset
1273 && self.last_mod_end == mod_offset
1274 && let Some((prev_index, prev_rel)) = self.find_position(offset - 1, false)
1275 {
1276 let prev = self.pieces.get_piece(prev_index);
1277
1278 if prev.buffer == MOD_BUFFER && prev.byte_offset + prev.byte_length == mod_offset {
1282 let prev_start = (offset - 1) - prev_rel;
1283
1284 self.root = self.pieces.extend_piece(
1285 self.root,
1286 prev_start,
1287 text_len,
1288 char_count,
1289 newline_count
1290 );
1291
1292 self.last_mod_end = new_mod_end;
1293 self.last_tree_end = new_tree_end;
1294 return;
1295 }
1296 }
1297
1298 let new_piece = Piece {
1299 buffer: MOD_BUFFER,
1300 byte_offset: mod_offset,
1301 byte_length: text_len,
1302 newline_count,
1303 char_count,
1304 buffer_start_line: start_line_in_buffer,
1305 piece_start_char: total_char_count - char_count,
1306 };
1307
1308 if self.root == NIL {
1309 self.root = self.pieces.insert_node(self.root, new_piece, offset);
1310 } else {
1311 let (left, right) = self.split(self.root, offset);
1315
1316 self.root = self.pieces.join_with_middle(left, new_piece, right);
1320
1321 self.try_merge_at(offset);
1327
1328 self.try_merge_at(offset + text_len);
1330 }
1331
1332 self.last_mod_end = new_mod_end;
1333 self.last_tree_end = new_tree_end;
1334 }
1335
1336 pub fn remove_no_commit(&mut self, offset: u32, mut length: u32) {
1337 let total = self.total_length();
1338 if offset >= total { return; }
1339 if offset + length > total { length = total - offset; }
1340 if length == 0 { return }
1341
1342 let (left, remainder) = self.split(self.root, offset);
1346
1347 let (_deleted, right) = self.split(remainder, length);
1351
1352 self.root = self.concat(left, right);
1356
1357 self.try_merge_at(offset);
1361 }
1362
1363 #[inline]
1364 fn try_merge_at(&mut self, pos: u32) {
1365 if pos == 0 { return }
1366
1367 let Some((right_index, right_rel)) = self.find_position(pos, false) else { return };
1368
1369 if right_rel != 0 { return }
1370
1371 let right = self.pieces.get_piece(right_index);
1372 self.try_merge_right_with_left(pos, right);
1373 }
1374
1375 #[inline]
1377 fn try_merge_right_with_left(&mut self, right_start: u32, right: Piece) -> Option<(u32, Piece)> {
1378 if right_start == 0 { return None; }
1379 if right.buffer != MOD_BUFFER { return None; }
1380
1381 let Some((left_index, left_rel)) = self.find_position(right_start - 1, false) else { return None };
1382 let left = self.pieces.get_piece(left_index);
1383
1384 if left.buffer != MOD_BUFFER { return None; }
1385 if left.byte_offset + left.byte_length != right.byte_offset { return None; }
1386
1387 let left_start = (right_start - 1) - left_rel;
1388
1389 self.root = self.pieces.remove_node(self.root, left_start);
1390 self.root = self.pieces.remove_node(self.root, left_start);
1391
1392 let merged = Piece {
1393 buffer: MOD_BUFFER,
1394 byte_offset: left.byte_offset,
1395 byte_length: left.byte_length + right.byte_length,
1396 newline_count: left.newline_count + right.newline_count,
1397 char_count: left.char_count + right.char_count,
1398 buffer_start_line: left.buffer_start_line,
1399 piece_start_char: left.piece_start_char, };
1401 self.root = self.pieces.insert_node(self.root, merged, left_start);
1402 Some((left_start, merged))
1403 }
1404
1405 #[inline(always)]
1406 #[must_use]
1407 pub fn get_piece(&self, index: NodeRef) -> Piece {
1408 self.pieces.get_piece(index)
1409 }
1410
1411 #[inline]
1412 #[must_use]
1413 pub fn find_position(&self, offset: u32, prefer_left: bool) -> Option<(NodeRef, u32)> {
1414 let total = self.total_length();
1415 if offset > total { return None; }
1416
1417 if offset == total && total > 0 {
1418 let mut current = self.root;
1419 let mut last_valid = NIL;
1420 while current != NIL {
1421 last_valid = current;
1422 current = self.pieces.get(current).right;
1423 }
1424 let len = self.pieces.get_piece(last_valid).byte_length;
1425 return Some((last_valid, len));
1426 }
1427
1428 self.pieces.find_offset(self.root, offset, prefer_left)
1429 }
1430
1431 #[cfg(feature = "write")]
1432 #[inline]
1433 pub fn write_to<W: std::io::Write>(&self, mut writer: W) -> std::io::Result<()> {
1434 if self.root == NIL {
1435 return Ok(());
1436 }
1437
1438 for (_, piece) in self.pieces() {
1439 let slice = self.buffers.get_slice(piece.buffer, piece.byte_offset, piece.byte_length);
1440 writer.write_all(slice.as_bytes())?;
1441 }
1442
1443 writer.flush()
1444 }
1445}
1446
1447impl PieceTree {
1448 #[inline]
1449 pub fn compact(&mut self) {
1450 #[inline(always)]
1451 fn copy_node(
1452 old_index: NodeRef, old_arena: &Pieces,
1453 new_arena: &mut Pieces, index_map: &mut [u32]
1454 ) -> NodeRef {
1455 if old_index == NIL { return NIL }
1456
1457 if index_map[old_index.index()] != 0 {
1458 return NodeRef::new(index_map[old_index.index()] as usize);
1459 }
1460
1461 let node = old_arena.get(old_index);
1462 let left_new = copy_node(node.left, old_arena, new_arena, index_map);
1463 let right_new = copy_node(node.right, old_arena, new_arena, index_map);
1464
1465 let new_index = NodeRef::new(new_arena.nodes.len());
1466 new_arena.nodes.push(Node {
1467 left: left_new,
1468 right: right_new,
1469 offset: node.offset,
1470 subtree_len: node.subtree_len,
1471 subtree_chars: node.subtree_chars,
1472 subtree_newlines: node.subtree_newlines,
1473 piece_start_char: node.piece_start_char,
1474 meta: node.meta,
1475 buffer_start_line: node.buffer_start_line
1476 });
1477
1478 index_map[old_index.index()] = new_index.index() as u32;
1479 new_index
1480 }
1481
1482 let mut new_pieces = Pieces::new();
1483
1484 self.scratch_index_map.clear();
1485 self.scratch_index_map.resize(self.pieces.nodes.len(), 0);
1486
1487 self.root = copy_node(self.root, &self.pieces, &mut new_pieces, &mut self.scratch_index_map);
1488 for entry in &mut self.undo_stack {
1489 entry.root = copy_node(entry.root, &self.pieces, &mut new_pieces, &mut self.scratch_index_map);
1490 }
1491 for entry in &mut self.redo_stack {
1492 entry.root = copy_node(entry.root, &self.pieces, &mut new_pieces, &mut self.scratch_index_map);
1493 }
1494
1495 self.pieces = new_pieces;
1496 }
1497
1498 #[inline]
1499 pub fn squash(&mut self) { if self.root == NIL { return }
1501
1502 let squashed_text = self.to_string(); let length = squashed_text.len() as u32;
1504
1505 let mut offsets = Vec::new();
1506 let mut checkpoints = Vec::new();
1507
1508 let (char_count, newline_count) =
1509 count_chars_and_newlines_with_offsets_and_checkpoints(
1510 squashed_text.as_bytes(),
1511 &mut offsets,
1512 &mut checkpoints
1513 );
1514
1515 self.buffers = Buffers::new();
1516 let buffer = self.buffers.original_buffers.push(OriginalBuffer {
1517 newline_offsets: offsets.into(),
1518 char_checkpoints: checkpoints.into(),
1519 text: squashed_text.into()
1520 });
1521 self.pieces = Pieces::new();
1522
1523 let piece = Piece {
1524 byte_length: length, newline_count, char_count,
1525 buffer, byte_offset: 0,
1526 buffer_start_line: 0, piece_start_char: 0
1527 };
1528 self.root = self.pieces.insert_node(NIL, piece, 0);
1529
1530 self.undo_stack.clear();
1531 self.redo_stack.clear();
1532 }
1533}
1534
1535impl PieceTree {
1536 #[inline(always)]
1539 #[must_use]
1540 pub fn node_arena_bytes(&self) -> u32 {
1541 (self.pieces.nodes.len() * size_of::<Node>()) as _
1542 }
1543
1544 #[inline(always)]
1546 #[must_use]
1547 pub fn mod_buffer_bytes(&self) -> u32 {
1548 self.buffers.modifications_buffer.len() as _
1549 }
1550
1551 #[inline(always)]
1553 #[must_use]
1554 pub fn original_buffers_bytes(&self) -> u32 {
1555 self.buffers.original_buffers.values().map(|s| s.len()).sum::<usize>() as _
1556 }
1557
1558 #[inline(always)]
1560 #[must_use]
1561 pub fn history_bytes(&self) -> u32 {
1562 ((self.undo_stack.len() + self.redo_stack.len()) * size_of::<HistoryEntry>()) as _
1563 }
1564
1565 #[inline(always)]
1567 #[must_use]
1568 pub fn node_count(&self) -> u32 {
1569 self.pieces.nodes.len() as _
1570 }
1571
1572 #[inline(always)]
1574 #[must_use]
1575 pub fn memory_usage(&self) -> MemoryUsage {
1576 MemoryUsage {
1577 node_arena: self.node_arena_bytes(),
1578 mod_buffer: self.mod_buffer_bytes(),
1579 original_buffers: self.original_buffers_bytes(),
1580 history: self.history_bytes(),
1581 }
1582 }
1583}
1584
1585#[derive(Debug, Clone, Copy)]
1586pub struct MemoryUsage {
1587 pub node_arena: u32,
1588 pub mod_buffer: u32,
1589 pub original_buffers: u32,
1590 pub history: u32,
1591}
1592
1593impl MemoryUsage {
1594 #[inline(always)]
1595 #[must_use]
1596 pub const fn total(&self) -> u32 {
1597 self.node_arena + self.mod_buffer + self.original_buffers + self.history
1598 }
1599
1600 #[inline(always)]
1602 #[must_use]
1603 pub const fn overhead(&self) -> u32 {
1604 self.node_arena + self.history
1605 }
1606}
1607
1608#[derive(Debug)]
1609pub struct LinesIter<'a> {
1610 tree: &'a PieceTree,
1611 current_line: u32,
1612 total_lines: u32,
1613}
1614
1615impl Iterator for LinesIter<'_> {
1616 type Item = String;
1617
1618 fn next(&mut self) -> Option<Self::Item> {
1619 if self.current_line >= self.total_lines { return None }
1620
1621 let line = self.tree.get_line_content_allocating(self.current_line)?;
1622 self.current_line += 1;
1623 Some(line)
1624 }
1625}
1626
1627#[derive(Debug)]
1629pub struct ChunkIter<'a> {
1630 tree: &'a PieceTree,
1631 pieces: PieceTreeIter<'a>,
1632 start: u32,
1634 end: u32,
1635 piece_start: u32,
1637}
1638
1639impl<'a> ChunkIter<'a> {
1640 #[inline]
1641 #[must_use]
1642 pub fn new(tree: &'a PieceTree, start: u32, end: u32) -> Self {
1643 Self {
1644 tree,
1645 pieces: PieceTreeIter::new(&tree.pieces, tree.root),
1646 start,
1647 end,
1648 piece_start: 0,
1649 }
1650 }
1651}
1652
1653impl<'a> Iterator for ChunkIter<'a> {
1654 type Item = &'a str;
1655
1656 #[inline]
1657 fn next(&mut self) -> Option<&'a str> {
1658 loop {
1659 let (_, p) = self.pieces.next()?;
1660 let piece_end = self.piece_start + p.byte_length;
1661
1662 if piece_end <= self.start {
1664 self.piece_start = piece_end;
1665 continue;
1666 }
1667 if self.piece_start >= self.end {
1669 return None;
1670 }
1671
1672 let slice_start = self.start.saturating_sub(self.piece_start);
1673 let slice_end = (self.end - self.piece_start).min(p.byte_length);
1674
1675 self.piece_start = piece_end;
1676
1677 let text = self.tree.buffers.get_slice(p.buffer, p.byte_offset + slice_start, slice_end - slice_start);
1678 if text.is_empty() { continue; }
1679 return Some(text);
1680 }
1681 }
1682}
1683
1684#[derive(Debug)]
1686pub struct SliceChars<'a> {
1687 walker: TreeWalker<'a>,
1688 byte_end: u32,
1689}
1690
1691impl Iterator for SliceChars<'_> {
1692 type Item = char;
1693 #[inline]
1694 fn next(&mut self) -> Option<char> {
1695 if self.walker.offset >= self.byte_end { return None; }
1696 self.walker.next()
1697 }
1698}
1699
1700pub struct TreeSlice<'a> {
1703 tree: &'a PieceTree,
1704 start: u32, end: u32, }
1707
1708impl core::fmt::Display for TreeSlice<'_> {
1709 #[inline(always)]
1710 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1711 for char in self.chars() {
1712 write!(f, "{char}")?;
1713 }
1714 Ok(())
1715 }
1716}
1717
1718impl<'a> TreeSlice<'a> {
1719 #[inline(always)]
1720 #[must_use]
1721 pub fn new(tree: &'a PieceTree, start: u32, end: u32) -> Self {
1722 let end = end.min(tree.len_bytes());
1723 debug_assert!(start <= end);
1724 Self { tree, start, end }
1725 }
1726
1727 #[inline(always)]
1728 #[must_use]
1729 pub fn len_bytes(&self) -> u32 { self.end - self.start }
1730
1731 #[inline(always)]
1732 #[must_use]
1733 pub fn is_empty(&self) -> bool { self.start == self.end }
1734
1735 #[inline(always)]
1736 #[must_use]
1737 pub fn len_chars(&self) -> u32 {
1738 let a = self.tree.byte_to_char(self.start).unwrap_or(0);
1739 let b = self.tree.byte_to_char(self.end).unwrap_or_else(|| self.tree.len_chars());
1740 b - a
1741 }
1742
1743 #[inline(always)]
1744 #[must_use]
1745 pub fn len_lines(&self) -> u32 {
1746 self.tree.chunks_at_byte(self.start, self.end)
1747 .map(|s| bytecount::count(s.as_bytes(), b'\n') as u32)
1748 .sum::<u32>() + 1
1749 }
1750
1751 #[inline(always)]
1753 #[must_use]
1754 pub fn chunks(&self) -> ChunkIter<'a> {
1755 self.tree.chunks_at_byte(self.start, self.end)
1756 }
1757
1758 #[inline(always)]
1760 #[must_use]
1761 pub fn chars(&self) -> SliceChars<'a> {
1762 self.tree.slice_bytes(self.start, self.end)
1763 }
1764
1765 #[inline(always)]
1767 #[must_use]
1768 pub fn byte(&self, offset: u32) -> Option<u8> {
1769 if offset >= self.len_bytes() { return None; }
1770 self.tree.byte(self.start + offset)
1771 }
1772
1773 #[inline(always)]
1775 #[must_use]
1776 pub fn char(&self, char_index: u32) -> Option<char> {
1777 let abs_char = self.tree.byte_to_char(self.start)? + char_index;
1778 self.tree.char(abs_char)
1779 }
1780
1781 #[inline(always)]
1783 #[must_use]
1784 pub fn line(&self, line: u32) -> Option<ChunkIter<'a>> {
1785 let (abs_start, abs_end) = self.abs_line_range(line)?;
1786 Some(self.tree.chunks_at_byte(abs_start, abs_end))
1787 }
1788
1789 #[inline(always)]
1791 #[must_use]
1792 pub fn slice<R: RangeBounds<u32>>(&self, range: R) -> TreeSlice<'a> {
1793 let s = match range.start_bound() {
1794 Bound::Included(&n) => n,
1795 Bound::Excluded(&n) => n + 1,
1796 Bound::Unbounded => 0,
1797 };
1798 let e = match range.end_bound() {
1799 Bound::Included(&n) => n + 1,
1800 Bound::Excluded(&n) => n,
1801 Bound::Unbounded => self.len_bytes(),
1802 };
1803 TreeSlice::new(self.tree, self.start + s, self.start + e)
1804 }
1805
1806 #[inline(always)]
1807 #[must_use]
1808 pub fn byte_to_char(&self, byte_offset: u32) -> Option<u32> {
1809 let base = self.tree.byte_to_char(self.start)?;
1810 let abs = self.tree.byte_to_char(self.start + byte_offset)?;
1811 Some(abs - base)
1812 }
1813
1814 #[inline(always)]
1815 #[must_use]
1816 pub fn char_to_byte(&self, char_index: u32) -> Option<u32> {
1817 let base_char = self.tree.byte_to_char(self.start)?;
1818 let abs_byte = self.tree.char_to_byte(base_char + char_index)?;
1819 Some(abs_byte - self.start)
1820 }
1821
1822 #[inline(always)]
1823 #[must_use]
1824 pub fn byte_to_line(&self, byte_offset: u32) -> Option<u32> {
1825 let (abs_line, _) = self.tree.byte_to_line_col(self.start + byte_offset)?;
1826 let base_line = self.tree.byte_to_line_col(self.start).map(|(l, _)| l)?;
1827 Some(abs_line - base_line)
1828 }
1829
1830 #[inline(always)]
1831 #[must_use]
1832 pub fn line_to_byte(&self, line: u32) -> Option<u32> {
1833 let (abs_start, _) = self.abs_line_range(line)?;
1834 Some(abs_start - self.start)
1835 }
1836
1837 #[inline]
1838 #[must_use]
1839 pub fn abs_line_range(&self, rel_line: u32) -> Option<(u32, u32)> {
1840 let base_line = self.tree.byte_to_line_col(self.start).map(|(l, _)| l)?;
1841 let abs_line = base_line + rel_line;
1842
1843 let line_start = self.tree.line_to_byte(abs_line)?;
1844 let line_end = self.tree.line_to_byte(abs_line + 1)
1845 .unwrap_or_else(|| self.tree.len_bytes());
1846
1847 let s = line_start.max(self.start);
1851 let e = line_end.min(self.end);
1852 if s > e { return None; }
1853
1854 Some((s, e))
1855 }
1856}
1857
1858impl PieceTree {
1860 #[inline]
1861 pub fn slice<R: RangeBounds<u32>>(&self, range: R) -> TreeSlice<'_> {
1862 let s = match range.start_bound() {
1863 Bound::Included(&n) => n,
1864 Bound::Excluded(&n) => n + 1,
1865 Bound::Unbounded => 0,
1866 };
1867 let e = match range.end_bound() {
1868 Bound::Included(&n) => n + 1,
1869 Bound::Excluded(&n) => n,
1870 Bound::Unbounded => self.len_bytes(),
1871 };
1872 TreeSlice::new(self, s, e)
1873 }
1874
1875 #[inline]
1877 pub fn slice_chars_range<R: RangeBounds<u32>>(&self, range: R) -> TreeSlice<'_> {
1878 let sc = match range.start_bound() {
1879 Bound::Included(&n) => n,
1880 Bound::Excluded(&n) => n + 1,
1881 Bound::Unbounded => 0,
1882 };
1883 let ec = match range.end_bound() {
1884 Bound::Included(&n) => n + 1,
1885 Bound::Excluded(&n) => n,
1886 Bound::Unbounded => self.len_chars(),
1887 };
1888 let s = self.char_to_byte(sc).unwrap_or(0);
1889 let e = self.char_to_byte(ec).unwrap_or_else(|| self.len_bytes());
1890 TreeSlice::new(self, s, e)
1891 }
1892}
1893
1894impl PieceTree {
1895 #[inline]
1899 #[must_use]
1900 pub fn read_largest_contigous_chunk_at_byte(&self, offset: u32) -> &[u8] {
1901 let total = self.total_length();
1902 if offset >= total {
1903 return &[];
1904 }
1905
1906 let mut current = self.root;
1907 let mut current_offset = offset;
1908
1909 while current != NIL {
1910 let node = self.pieces.get(current);
1911 let p = self.pieces.get_piece(current);
1912 let left_len = self.pieces.get(node.left).subtree_len;
1913 let piece_len = p.byte_length;
1914
1915 if current_offset < left_len {
1916 current = node.left;
1917
1918 } else if current_offset < left_len + piece_len {
1919 let rel_offset = current_offset - left_len;
1924 let text = self.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
1925
1926 return &text.as_bytes()[rel_offset as usize..];
1927
1928 } else {
1929 current_offset -= left_len + piece_len;
1930 current = node.right;
1931 }
1932 }
1933
1934 &[]
1935 }
1936
1937 #[inline]
1938 #[must_use]
1939 pub fn line_to_byte(&self, target_line: u32) -> Option<u32> {
1940 if target_line == 0 { return Some(0) }
1941 let mut current = self.root;
1942 let mut current_offset = 0;
1943 let mut current_line = 0;
1944 while current != NIL {
1945 let node = self.pieces.get(current);
1946 let p = self.pieces.get_piece(current);
1947 let left_newlines = self.pieces.get(node.left).subtree_newlines;
1948 let left_len = self.pieces.get(node.left).subtree_len;
1949 let piece_newlines = p.newline_count;
1950 let piece_len = p.byte_length;
1951
1952 if target_line <= current_line + left_newlines {
1953 current = node.left;
1957
1958 } else if target_line <= current_line + left_newlines + piece_newlines {
1959 current_line += left_newlines;
1964 current_offset += left_len;
1965
1966 let rel_line = target_line - current_line; let absolute_newline_index = p.buffer_start_line + rel_line - 1;
1968 let absolute_byte_offset = if p.buffer == MOD_BUFFER {
1969 self.buffers.modifications_newline_offsets[absolute_newline_index as usize]
1970 } else {
1971 self.buffers.original_buffers[p.buffer].newline_offsets[absolute_newline_index as usize]
1972 };
1973
1974 let local_piece_offset = absolute_byte_offset - p.byte_offset + 1;
1975 return Some(current_offset + local_piece_offset);
1976
1977 } else {
1978 current_line += left_newlines + piece_newlines;
1979 current_offset += left_len + piece_len;
1980 current = node.right;
1981 }
1982 }
1983
1984 None
1985 }
1986
1987 #[inline]
1988 #[must_use]
1989 pub fn char_to_byte(&self, char_index: u32) -> Option<u32> {
1990 let total_chars = self.len_chars();
1991 if char_index > total_chars { return None; }
1992 if char_index == total_chars { return Some(self.len_bytes()); }
1993
1994 let mut current = self.root;
1995 let mut current_byte = 0;
1996 let mut current_char = 0;
1997
1998 while current != NIL {
1999 let node = self.pieces.get(current);
2000 let left_node = self.pieces.get(node.left);
2001
2002 let left_chars = left_node.subtree_chars;
2003 let left_bytes = left_node.subtree_len;
2004
2005 let p = self.pieces.get_piece(current);
2006 let piece_chars = p.char_count;
2007
2008 if char_index < current_char + left_chars {
2009 current = node.left;
2010
2011 } else if char_index < current_char + left_chars + piece_chars {
2012 let rel_char = char_index - (current_char + left_chars);
2019 let absolute_target_byte =
2020 self.buffers.char_to_byte_absolute(p.buffer, p.piece_start_char + rel_char);
2021
2022 return Some(current_byte + left_bytes + (absolute_target_byte - p.byte_offset));
2023
2024 } else {
2025 current_char += left_chars + piece_chars;
2026 current_byte += left_bytes + p.byte_length;
2027 current = node.right;
2028 }
2029 }
2030
2031 None
2032 }
2033
2034 #[inline]
2035 #[must_use]
2036 pub fn byte_to_char(&self, byte_offset: u32) -> Option<u32> {
2037 let total_bytes = self.len_bytes();
2038 if byte_offset > total_bytes { return None; }
2039 if byte_offset == total_bytes { return Some(self.len_chars()); }
2040
2041 let mut current = self.root;
2042 let mut current_byte = 0;
2043 let mut current_char = 0;
2044
2045 while current != NIL {
2046 let node = self.pieces.get(current);
2047 let left_node = self.pieces.get(node.left);
2048
2049 let left_bytes = left_node.subtree_len;
2050 let left_chars = left_node.subtree_chars;
2051
2052 let p = self.pieces.get_piece(current);
2053 let piece_bytes = p.byte_length;
2054
2055 if byte_offset < current_byte + left_bytes {
2056 current = node.left;
2057
2058 } else if byte_offset < current_byte + left_bytes + piece_bytes {
2059 let rel_byte = byte_offset - (current_byte + left_bytes);
2064 let absolute_target_char =
2065 self.buffers.byte_to_char_absolute(p.buffer, p.byte_offset + rel_byte);
2066
2067 return Some(current_char + left_chars + (absolute_target_char - p.piece_start_char));
2068
2069 } else {
2070 current_byte += left_bytes + piece_bytes;
2071 current_char += left_chars + p.char_count;
2072 current = node.right;
2073 }
2074 }
2075
2076 None
2077 }
2078
2079 #[inline]
2080 #[must_use]
2081 pub fn byte_to_line_col(&self, offset: u32) -> Option<(u32, u32)> {
2082 let total_bytes = self.len_bytes();
2083 if offset > total_bytes { return None }
2084 if offset == total_bytes {
2085 let line = self.pieces.get(self.root).subtree_newlines;
2089 let line_start_byte = self.line_to_byte(line).unwrap_or(0);
2090 let target_char = self.len_chars();
2091 let line_start_char = self.byte_to_char(line_start_byte)?;
2092 return Some((line, target_char - line_start_char));
2093 }
2094
2095 let mut current = self.root;
2096 let mut current_line = 0u32;
2097 let mut current_byte = 0u32;
2098 let mut current_char = 0u32;
2099
2100 while current != NIL {
2101 let node = self.pieces.get(current);
2102 let left_node = self.pieces.get(node.left);
2103 let left_bytes = left_node.subtree_len;
2104 let left_newlines = left_node.subtree_newlines;
2105 let left_chars = left_node.subtree_chars;
2106 let p = self.pieces.get_piece(current);
2107 let piece_bytes = p.byte_length;
2108
2109 if offset < current_byte + left_bytes {
2110 current = node.left;
2111
2112 } else if offset < current_byte + left_bytes + piece_bytes {
2113 current_line += left_newlines;
2114 current_char += left_chars;
2115
2116 let rel_byte = offset - (current_byte + left_bytes);
2117
2118 let (local_newlines, col) = if p.newline_count == 0 {
2119 let target_char = self.buffers.byte_to_char_absolute(p.buffer, p.byte_offset + rel_byte);
2120 let rel_char = target_char - p.piece_start_char;
2121 let abs_char = current_char + rel_char;
2122
2123 let line_start_byte = self.line_to_byte(current_line)?;
2124 let line_start_char = self.byte_to_char(line_start_byte)?;
2125
2126 (0, abs_char - line_start_char)
2127 } else {
2128 let start_index = p.buffer_start_line as usize;
2129 let end_index = start_index + p.newline_count as usize;
2130 let absolute_target = p.byte_offset + rel_byte;
2131
2132 let offsets = &self.buffers.get_newlines(p.buffer)[start_index..end_index];
2133
2134 let local_nl = offsets.partition_point(|&off| off < absolute_target) as u32;
2135
2136 let target_char = self.buffers.byte_to_char_absolute(p.buffer, p.byte_offset + rel_byte);
2137 let col = if local_nl > 0 {
2138 let last_nl_abs_byte = offsets[local_nl as usize - 1];
2139 let last_nl_char = self.buffers.byte_to_char_absolute(p.buffer, last_nl_abs_byte);
2140 target_char - (last_nl_char + 1)
2141 } else {
2142 let line_start_byte = self.line_to_byte(current_line)?;
2143 let line_start_char = self.byte_to_char(line_start_byte)?;
2144 let rel_char = target_char - p.piece_start_char;
2145 (current_char + rel_char) - line_start_char
2146 };
2147
2148 (local_nl, col)
2149 };
2150
2151 return Some((current_line + local_newlines, col));
2152
2153 } else {
2154 current_line += left_newlines + p.newline_count;
2155 current_byte += left_bytes + piece_bytes;
2156 current_char += left_chars + p.char_count;
2157 current = node.right;
2158 }
2159 }
2160
2161 None
2162 }
2163
2164 #[inline]
2165 #[must_use]
2166 pub fn pieces(&self) -> PieceTreeIter<'_> {
2167 PieceTreeIter::new(&self.pieces, self.root)
2168 }
2169
2170 #[inline]
2171 #[must_use]
2172 pub fn get_line_range(&self, line: u32) -> Option<(u32, u32)> {
2173 let start = self.line_to_byte(line)?;
2174 let end = self.line_to_byte(line + 1).unwrap_or_else(|| self.total_length());
2175 Some((start, end))
2176 }
2177
2178 #[inline]
2179 #[must_use]
2180 pub fn get_line_content_allocating(&self, line: u32) -> Option<String> {
2181 let (start, end) = self.get_line_range(line)?;
2182
2183 let mut content = String::with_capacity((end - start) as usize);
2184 let mut walker = TreeWalker::new(self);
2185
2186 walker.seek(start);
2187 while walker.offset < end {
2188 if let Some(c) = walker.next() {
2189 content.push(c);
2190 } else {
2191 break;
2192 }
2193 }
2194
2195 Some(content)
2196 }
2197
2198 #[inline]
2201 #[must_use]
2202 pub fn chunks_at_byte(&self, start: u32, end: u32) -> ChunkIter<'_> {
2203 let end = end.min(self.total_length());
2204 ChunkIter::new(self, start, end)
2205 }
2206
2207 #[inline]
2209 #[must_use]
2210 pub fn byte(&self, offset: u32) -> Option<u8> {
2211 let (node, rel) = self.find_position(offset, false)?;
2212 let p = self.get_piece(node);
2213 let text = self.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
2214 text.as_bytes().get(rel as usize).copied()
2215 }
2216
2217 #[inline]
2220 #[must_use]
2221 pub fn char(&self, char_index: u32) -> Option<char> {
2222 let byte_offset = self.char_to_byte(char_index)?;
2223 let (node, rel) = self.find_position(byte_offset, false)?;
2224 let p = self.get_piece(node);
2225 let text = self.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
2226 text[rel as usize..].chars().next()
2227 }
2228
2229 #[inline]
2232 #[must_use]
2233 pub fn slice_chars(&self, char_start: u32, char_end: u32) -> SliceChars<'_> {
2234 let byte_start = self.char_to_byte(char_start).unwrap_or(0);
2235 let byte_end = self.char_to_byte(char_end).unwrap_or_else(|| self.total_length());
2236 SliceChars {
2237 walker: { let mut w = TreeWalker::new(self); w.seek(byte_start); w },
2238 byte_end,
2239 }
2240 }
2241
2242 #[inline]
2244 #[must_use]
2245 pub fn slice_bytes(&self, byte_start: u32, byte_end: u32) -> SliceChars<'_> {
2246 SliceChars {
2247 walker: { let mut w = TreeWalker::new(self); w.seek(byte_start); w },
2248 byte_end,
2249 }
2250 }
2251
2252 #[inline]
2255 #[must_use]
2256 pub fn line(&self, line: u32) -> Option<ChunkIter<'_>> {
2257 let start = self.line_to_byte(line)?;
2258 let end = self.line_to_byte(line + 1)
2259 .unwrap_or_else(|| self.total_length());
2260 Some(self.chunks_at_byte(start, end))
2261 }
2262
2263 #[inline]
2265 #[must_use]
2266 pub fn len_lines(&self) -> u32 { self.pieces.get(self.root).subtree_newlines + 1 }
2267
2268 #[inline(always)]
2269 #[must_use]
2270 pub fn len_chars(&self) -> u32 { self.pieces.get(self.root).subtree_chars }
2271
2272 #[inline]
2273 #[must_use]
2274 pub fn len_bytes(&self) -> u32 { self.total_length() }
2275
2276 #[inline]
2277 #[must_use]
2278 pub fn chars(&self) -> TreeWalker<'_> { TreeWalker::new(self) }
2279
2280 #[inline(always)]
2281 #[must_use]
2282 pub fn chars_rev(&self) -> ReverseTreeWalker<'_> { ReverseTreeWalker::new(self) }
2283
2284 #[inline]
2285 #[must_use]
2286 pub fn lines(&self) -> LinesIter<'_> {
2287 LinesIter { tree: self, current_line: 0, total_lines: self.len_lines() }
2288 }
2289
2290 #[inline]
2291 pub fn remove<R>(&mut self, range: R) where R: RangeBounds<u32> {
2292 let start = match range.start_bound() {
2293 Bound::Included(&n) => n,
2294 Bound::Excluded(&n) => n + 1,
2295 Bound::Unbounded => 0,
2296 };
2297 let end = match range.end_bound() {
2298 Bound::Included(&n) => n + 1,
2299 Bound::Excluded(&n) => n,
2300 Bound::Unbounded => self.len_bytes(),
2301 };
2302 if end > start { self.remove_at(start, end - start) }
2303 }
2304
2305 #[inline]
2306 #[must_use]
2307 pub fn char_to_line(&self, char_index: u32) -> Option<u32> {
2308 let byte_index = self.char_to_byte(char_index)?;
2309 self.byte_to_line_col(byte_index).map(|(line, _)| line)
2310 }
2311
2312 #[inline]
2313 #[must_use]
2314 pub fn char_to_line_col(&self, char_index: u32) -> Option<(u32, u32)> {
2315 let byte_index = self.char_to_byte(char_index)?;
2316 self.byte_to_line_col(byte_index)
2317 }
2318
2319 #[inline]
2320 #[must_use]
2321 pub fn line_to_char(&self, line: u32) -> Option<u32> {
2322 let byte_index = self.line_to_byte(line)?;
2323 self.byte_to_char(byte_index)
2324 }
2325}
2326
2327#[derive(Debug)]
2328pub struct PieceTreeIter<'a, const MAX_INLINE_TREE_DEPTH: usize = 32> {
2329 arena: &'a Pieces,
2330 stack: SmallVec<[NodeRef; MAX_INLINE_TREE_DEPTH]>,
2331}
2332
2333impl<'a, const MAX_INLINE_TREE_DEPTH: usize> PieceTreeIter<'a, MAX_INLINE_TREE_DEPTH> {
2334 #[inline]
2335 #[must_use]
2336 pub fn new(arena: &'a Pieces, mut root: NodeRef) -> Self {
2337 let mut stack = SmallVec::new();
2338 while root != NIL {
2339 stack.push(root);
2340 root = arena.get(root).left;
2341 }
2342
2343 Self { arena, stack }
2344 }
2345}
2346
2347impl<const MAX_INLINE_TREE_DEPTH: usize> Iterator for PieceTreeIter<'_, MAX_INLINE_TREE_DEPTH> {
2348 type Item = (NodeRef, Piece);
2349
2350 #[inline]
2351 fn next(&mut self) -> Option<Self::Item> {
2352 let node_index = self.stack.pop()?;
2353 let node = self.arena.get(node_index);
2354 let p = self.arena.get_piece(node_index);
2355
2356 let mut current = node.right;
2357 while current != NIL {
2358 self.stack.push(current);
2359 current = self.arena.get(current).left;
2360 }
2361
2362 Some((node_index, p))
2363 }
2364}
2365
2366#[derive(Clone, Copy, PartialEq, Debug)]
2367enum Direction { Left, Center, Right }
2368
2369#[derive(Debug)]
2370pub struct TreeWalker<'a, const MAX_INLINE_TREE_DEPTH: usize = 32> {
2371 tree: &'a PieceTree,
2372 stack: SmallVec<[(NodeRef, Direction); MAX_INLINE_TREE_DEPTH]>,
2373 current_str: str::Chars<'a>,
2374 pub offset: u32,
2375}
2376
2377impl<'a, const MAX_INLINE_TREE_DEPTH: usize> TreeWalker<'a, MAX_INLINE_TREE_DEPTH> {
2378 #[inline]
2379 #[must_use]
2380 pub fn new(tree: &'a PieceTree) -> Self {
2381 let mut walker = Self {
2382 tree,
2383 stack: SmallVec::new(),
2384 current_str: "".chars(),
2385 offset: 0,
2386 };
2387 if tree.root != NIL {
2388 walker.stack.push((tree.root, Direction::Left));
2389 }
2390 walker.populate_chars();
2391 walker
2392 }
2393
2394 #[inline]
2395 pub fn seek(&mut self, target: u32) {
2396 self.stack.clear();
2397 self.offset = target;
2398 self.current_str = "".chars();
2399
2400 if self.tree.root == NIL { return; }
2401
2402 let mut current = self.tree.root;
2403 let mut current_offset = target;
2404
2405 while current != NIL {
2406 let node = self.tree.pieces.get(current);
2407 let p = self.tree.pieces.get_piece(current);
2408 let left_len = self.tree.pieces.get(node.left).subtree_len;
2409 let piece_len = p.byte_length;
2410
2411 if current_offset < left_len {
2412 self.stack.push((current, Direction::Center));
2413 current = node.left;
2414 } else if current_offset < left_len + piece_len {
2415 self.stack.push((current, Direction::Right));
2416 let text = self.tree.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
2417 let rel_offset = current_offset - left_len;
2418 self.current_str = text[rel_offset as usize..].chars();
2419 break;
2420 } else {
2421 current_offset -= left_len + piece_len;
2422 current = node.right;
2423 }
2424 }
2425 }
2426
2427 #[inline]
2428 fn populate_chars(&mut self) {
2429 while let Some((node_index, dir)) = self.stack.pop() {
2430 let node = self.tree.pieces.get(node_index);
2431 match dir {
2432 Direction::Left => {
2433 self.stack.push((node_index, Direction::Center));
2434 if node.left != NIL { self.stack.push((node.left, Direction::Left)); }
2435 }
2436
2437 Direction::Center => {
2438 self.stack.push((node_index, Direction::Right));
2439 let p = self.tree.pieces.get_piece(node_index);
2440 let text = self.tree.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
2441 self.current_str = text.chars();
2442 return;
2443 }
2444
2445 Direction::Right => {
2446 if node.right != NIL { self.stack.push((node.right, Direction::Left)); }
2447 }
2448 }
2449 }
2450 }
2451}
2452
2453impl Iterator for TreeWalker<'_> {
2454 type Item = char;
2455
2456 #[inline(always)]
2457 fn next(&mut self) -> Option<char> {
2458 loop {
2459 if let Some(c) = self.current_str.next() {
2460 self.offset += c.len_utf8() as u32;
2461 return Some(c);
2462 }
2463
2464 if self.stack.is_empty() { return None; }
2465 self.populate_chars();
2466 }
2467 }
2468}
2469
2470#[derive(Debug)]
2471pub struct ReverseTreeWalker<'a, const MAX_INLINE_TREE_DEPTH: usize = 32> {
2472 tree: &'a PieceTree,
2473 stack: SmallVec<[(NodeRef, bool); MAX_INLINE_TREE_DEPTH]>,
2474 current_str: str::Chars<'a>,
2475}
2476
2477impl<'a, const MAX_INLINE_TREE_DEPTH: usize> ReverseTreeWalker<'a, MAX_INLINE_TREE_DEPTH> {
2478 #[inline(always)]
2479 #[must_use]
2480 pub fn new(tree: &'a PieceTree) -> Self {
2481 let mut walker = Self {
2482 tree,
2483 stack: SmallVec::new(),
2484 current_str: "".chars(),
2485 };
2486 walker.push_rightmost(tree.root);
2487 walker
2488 }
2489
2490 #[inline(always)]
2491 fn push_rightmost(&mut self, mut node: NodeRef) {
2492 while node != NIL {
2493 self.stack.push((node, false));
2494 node = self.tree.pieces.get(node).right;
2495 }
2496 }
2497
2498 #[inline]
2499 pub fn seek(&mut self, mut target_offset: u32) {
2500 self.stack.clear();
2501 self.current_str = "".chars();
2502
2503 if self.tree.root == NIL { return; }
2504
2505 let total_bytes = self.tree.len_bytes();
2506
2507 if target_offset > total_bytes {
2508 target_offset = total_bytes;
2509 }
2510 if target_offset == total_bytes {
2511 self.push_rightmost(self.tree.root);
2512 return;
2513 }
2514
2515 let mut current = self.tree.root;
2516 let mut current_offset = target_offset;
2517
2518 while current != NIL {
2519 let node = self.tree.pieces.get(current);
2520 let p = self.tree.pieces.get_piece(current);
2521 let left_len = self.tree.pieces.get(node.left).subtree_len;
2522 let piece_len = p.byte_length;
2523
2524 if current_offset < left_len {
2525 self.stack.push((current, true));
2526 current = node.left;
2527
2528 } else if current_offset < left_len + piece_len {
2529 self.stack.push((current, true));
2530
2531 let text = self.tree.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
2532 let rel_offset = current_offset - left_len;
2533
2534 self.current_str = text[..rel_offset as usize].chars();
2536
2537 break;
2538
2539 } else {
2540 self.stack.push((current, false));
2541 current_offset -= left_len + piece_len;
2542 current = node.right;
2543 }
2544 }
2545 }
2546}
2547
2548impl Iterator for ReverseTreeWalker<'_> {
2549 type Item = char;
2550
2551 #[inline]
2552 fn next(&mut self) -> Option<Self::Item> {
2553 if let Some(c) = self.current_str.next_back() { return Some(c); }
2554
2555 while let Some((node_index, visited_right)) = self.stack.pop() {
2556 let node = self.tree.pieces.get(node_index);
2557 if visited_right {
2558 self.push_rightmost(node.left);
2559 } else {
2560 self.stack.push((node_index, true));
2561
2562 let p = self.tree.pieces.get_piece(node_index);
2563 let text_slice = self.tree.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
2564
2565 self.current_str = text_slice.chars();
2566
2567 if let Some(c) = self.current_str.next_back() { return Some(c); }
2568 }
2569 }
2570
2571 None
2572 }
2573}
2574
2575impl PieceTree {
2576 #[inline]
2577 pub fn debug(&self, f: &mut impl core::fmt::Write) -> core::fmt::Result {
2578 writeln!(f, "\n--- Tree State (Root: {:?}) ---", self.root)?;
2579 self.print_inorder(f, self.root, &mut None, 0)?;
2580 writeln!(f, "------------------------------\n")
2581 }
2582
2583 fn print_inorder(&self, f: &mut impl core::fmt::Write, node: NodeRef, last: &mut Option<Piece>, depth: usize) -> core::fmt::Result {
2584 if node == NIL { return Ok(()) }
2585
2586 let n = self.pieces.nodes[node];
2587
2588 self.print_inorder(f, n.left, last, depth + 1)?;
2589
2590 let cur = self.get_piece(node);
2591
2592 let warning = if let Some(prev) = last {
2596 if prev.buffer == cur.buffer
2597 && prev.byte_offset + prev.byte_length == cur.byte_offset
2598 {
2599 " --------- [!!! MERGEABLE NEIGHBORS NOT MERGED !!!] ---------"
2600 } else {
2601 ""
2602 }
2603 } else {
2604 ""
2605 };
2606
2607 let Piece { buffer, byte_offset: offset, byte_length: length, .. } = cur;
2608
2609 writeln!(
2610 f,
2611 "{:indent$}Node {node:?}: Buf={}, Off={offset}, Len={length}{warning}",
2612 "", buffer.as_u32(), indent = depth * 4
2613 )?;
2614
2615 *last = Some(cur);
2616
2617 self.print_inorder(f, n.right, last, depth + 1)
2618 }
2619}
2620
2621pub fn assert_state(tree: &PieceTree, expected: &str) {
2622 let tree_text = tree.to_string();
2623
2624 assert_eq!(tree_text, expected, "Text mismatch");
2625
2626 if !expected.is_empty() {
2627 let offsets = [0, expected.len() / 2, expected.len() - 1];
2628 for off in offsets {
2629 let chunk = tree.read_largest_contigous_chunk_at_byte(off as u32);
2630 let chunk_str = str::from_utf8(chunk).unwrap();
2631 assert!(
2632 expected[off..].starts_with(chunk_str),
2633 "Chunk mismatch at offset {}",
2634 off
2635 );
2636 }
2637 }
2638}
2639
2640pub fn assert_invariants(tree: &PieceTree) {
2641 fn check(tree: &PieceTree, node: NodeRef) -> (usize, usize) {
2642 if node == NIL { return (0, 1) }
2643
2644 let n = tree.pieces.nodes[node];
2645 let piece = tree.get_piece(node);
2646
2647 let (l_len, l_bh) = check(tree, n.left);
2648 let (r_len, r_bh) = check(tree, n.right);
2649
2650 let expected_len = l_len + piece.byte_length as usize + r_len;
2651 assert_eq!(n.subtree_len as usize, expected_len, "subtree_len mismatch");
2652
2653 if n.color() == Color::Red {
2654 assert_eq!(
2655 tree.pieces.nodes[n.left].color(),
2656 Color::Black,
2657 "red node with red left child"
2658 );
2659 assert_eq!(
2660 tree.pieces.nodes[n.right].color(),
2661 Color::Black,
2662 "red node with red right child"
2663 );
2664 }
2665
2666 assert_eq!(l_bh, r_bh, "black height mismatch");
2667
2668 let bh = l_bh + if n.color() == Color::Black { 1 } else { 0 };
2669 (expected_len, bh)
2670 }
2671
2672 if tree.root != NIL {
2673 assert_eq!(
2674 tree.pieces.nodes[tree.root].color(),
2675 Color::Black,
2676 "root is not black"
2677 );
2678 let (len, _) = check(tree, tree.root);
2679 assert_eq!(len, tree.total_length() as usize, "Tree length and root length differ");
2680
2681 } else {
2682 assert_eq!(tree.total_length(), 0, "Empty tree has nonzero length");
2683 }
2684}
2685
2686pub fn assert_piece_metadata(tree: &PieceTree) {
2687 fn collect(tree: &PieceTree, node: NodeRef, out: &mut Vec<Piece>) {
2688 if node == NIL { return }
2689
2690 let n = tree.pieces.nodes[node];
2691
2692 collect(tree, n.left, out);
2693 out.push(tree.pieces.get_piece(node));
2694 collect(tree, n.right, out);
2695 }
2696
2697 let mut pieces = Vec::new();
2698 collect(tree, tree.root, &mut pieces);
2699
2700 for p in &pieces {
2701 let buf = tree.buffers.get(p.buffer);
2702 let start = p.byte_offset as usize;
2703 let end = start + p.byte_length as usize;
2704
2705 assert!(end <= buf.len(), "Piece points past end of buffer");
2706 assert!(p.byte_length > 0, "Zero-length piece found");
2707
2708 let slice = &buf[start..end];
2709 let (actual_chars, actual_nl) = count_chars_and_newlines(slice.as_bytes());
2710 assert_eq!(p.char_count, actual_chars, "char_count mismatch");
2711 assert_eq!(p.newline_count, actual_nl, "newline_count mismatch");
2712
2713 let prefix = &buf.as_bytes()[..p.byte_offset as usize];
2717 let actual_start_char = bytecount::num_chars(prefix) as u32;
2718 let actual_start_line = prefix.iter().filter(|&&b| b == b'\n').count() as u32;
2719
2720 assert_eq!(p.piece_start_char, actual_start_char,
2721 "piece_start_char mismatch buffer={} offset={}", p.buffer.as_u32(), p.byte_offset);
2722
2723 assert_eq!(p.buffer_start_line, actual_start_line,
2724 "buffer_start_line mismatch buffer={} offset={}", p.buffer.as_u32(), p.byte_offset);
2725
2726 let nl_offsets = &tree.buffers.get_newlines(p.buffer)
2730 [p.buffer_start_line as usize..(p.buffer_start_line + p.newline_count) as usize];
2731
2732 for (i, &abs_byte) in nl_offsets.iter().enumerate() {
2733 assert!(
2734 abs_byte >= p.byte_offset && abs_byte < p.byte_offset + p.byte_length,
2735 "newline_offsets[{}] outside piece", p.buffer_start_line as usize + i
2736 );
2737
2738 assert_eq!(
2739 buf.as_bytes()[abs_byte as usize], b'\n',
2740 "newline_offsets[{}] not a newline", p.buffer_start_line as usize + i
2741 );
2742 }
2743 }
2744}
2745
2746pub fn assert_no_mergeable_neighbors(tree: &PieceTree) {
2747 fn inorder(tree: &PieceTree, node: NodeRef, last: &mut Option<Piece>) {
2748 if node == NIL { return }
2749
2750 let n = tree.pieces.nodes[node];
2751 inorder(tree, n.left, last);
2752
2753 let cur = tree.get_piece(node);
2754
2755 if let Some(prev) = *last {
2756 if prev.buffer == cur.buffer
2757 && prev.byte_offset + prev.byte_length == cur.byte_offset
2758 {
2759 panic!("Mergeable neighboring pieces were left unmerged");
2760 }
2761 }
2762
2763 *last = Some(cur);
2764 inorder(tree, n.right, last);
2765 }
2766
2767 let mut last = None;
2768 inorder(tree, tree.root, &mut last);
2769}
2770
2771pub fn assert_coordinates(tree: &PieceTree, oracle: &str) {
2772 #[inline]
2773 fn oracle_offset_to_line_col(s: &str, byte_offset: usize) -> (usize, usize) {
2774 let slice = &s[..byte_offset];
2775 let line = bytecount::count(slice.as_bytes(), b'\n');
2776 let last_nl = slice.rfind('\n').map(|i| i + 1).unwrap_or(0);
2777 let col = bytecount::num_chars(s[last_nl..byte_offset].as_bytes());
2778 (line, col)
2779 }
2780
2781 #[inline]
2782 fn oracle_line_to_offset(s: &str, target_line: usize) -> usize {
2783 if target_line == 0 { return 0 }
2784
2785 let mut line = 0;
2786 for (i, c) in s.char_indices() {
2787 if c == '\n' {
2788 line += 1;
2789 if line == target_line { return i + 1; }
2790 }
2791 }
2792
2793 s.len()
2794 }
2795
2796 fn check_coordinate(tree: &PieceTree, oracle: &str, byte_index: u32) {
2797 let char_index = bytecount::num_chars(oracle[..byte_index as usize].as_bytes()) as u32;
2798
2799 assert_eq!(tree.char_to_byte(char_index), Some(byte_index),
2800 "char_to_byte({}) wrong", char_index);
2801
2802 assert_eq!(tree.byte_to_char(byte_index), Some(char_index),
2803 "byte_to_char({}) wrong", byte_index);
2804
2805 let expected_lc = oracle_offset_to_line_col(oracle, byte_index as usize);
2806 assert_eq!(
2807 tree.byte_to_line_col(byte_index),
2808 Some((expected_lc.0 as u32, expected_lc.1 as u32)),
2809 "offset_to_line_col({}) wrong", byte_index
2810 );
2811 }
2812
2813 let total_bytes = oracle.len() as u32;
2814 let total_chars = oracle.chars().count() as u32;
2815
2816 check_coordinate(tree, oracle, 0);
2820 if total_bytes > 0 {
2821 check_coordinate(tree, oracle, total_bytes - 1);
2822 check_coordinate(tree, oracle, total_bytes / 2);
2823 }
2824
2825
2826 for i in 0u32..8 {
2830 let byte = ((total_bytes as u64 * ((i as u64 * 2654435761) & 0xFFFFFFFF)) >> 32) as u32 % total_bytes.max(1);
2831
2832 let byte = oracle.as_bytes()[..byte as usize]
2834 .iter().rposition(|&b| b < 0x80 || b >= 0xC0)
2835 .map(|i| i as u32)
2836 .unwrap_or(0);
2837
2838 check_coordinate(tree, oracle, byte);
2839 }
2840
2841 assert_eq!(tree.char_to_byte(total_chars), Some(total_bytes));
2845 assert_eq!(tree.byte_to_char(total_bytes), Some(total_chars));
2846 assert_eq!(tree.char_to_byte(total_chars + 1), None);
2847 assert_eq!(tree.byte_to_char(total_bytes + 1), None);
2848 assert_eq!(tree.byte_to_line_col(total_bytes + 1), None);
2849
2850 let total_lines = oracle.chars().filter(|&c| c == '\n').count() + 1;
2854 for line in [0, total_lines / 2, total_lines.saturating_sub(1)] {
2855 let expected = oracle_line_to_offset(oracle, line) as u32;
2856 assert_eq!(tree.line_to_byte(line as u32), Some(expected),
2857 "line_to_offset({}) wrong", line);
2858 }
2859
2860 assert_eq!(tree.line_to_byte(total_lines as u32), None);
2861}