1use std::{
2 fmt,
3 fs::File,
4 io,
5 ops::{Add, Range, RangeBounds, Sub},
6 path::{Component, Path, PathBuf},
7 process::{Command, Stdio},
8 str::CharIndices,
9};
10
11use crate::{
12 buffer_history::{BufferHistory, Edit, EditKind},
13 buffer_position::{BufferPosition, BufferPositionIndex, BufferRange},
14 cursor::Cursor,
15 editor_utils::{find_delimiter_pair_at, ResidualStrBytes},
16 events::{
17 BufferEditMutGuard, BufferRangeDeletesMutGuard, BufferTextInsertsMutGuard, EditorEvent,
18 EditorEventTextInsert, EditorEventWriter,
19 },
20 help,
21 pattern::Pattern,
22 platform::{Platform, PlatformProcessHandle, PlatformRequest, PooledBuf, ProcessTag},
23 plugin::PluginHandle,
24 syntax::{HighlightResult, HighlightedBuffer, SyntaxCollection, SyntaxHandle},
25 word_database::{WordDatabase, WordIter, WordKind},
26};
27
28pub fn char_display_len(_: char) -> u8 {
31 1
32}
33
34#[derive(Clone, Copy)]
35pub struct DisplayLen {
36 pub len: u32,
37 pub tab_count: u32,
38}
39impl DisplayLen {
40 pub const fn zero() -> Self {
41 Self {
42 len: 0,
43 tab_count: 0,
44 }
45 }
46
47 pub fn total_len(&self, tab_size: u8) -> usize {
48 self.len as usize + self.tab_count as usize * tab_size as usize
49 }
50}
51impl<'a> From<&'a str> for DisplayLen {
52 fn from(s: &'a str) -> Self {
53 let mut len = 0;
54 let mut tab_count = 0;
55 for c in s.chars() {
56 match c {
57 '\t' => tab_count += 1,
58 _ => len += char_display_len(c) as u32,
59 }
60 }
61 Self { len, tab_count }
62 }
63}
64impl Add for DisplayLen {
65 type Output = Self;
66 fn add(self, other: Self) -> Self {
67 Self {
68 len: self.len + other.len,
69 tab_count: self.tab_count + other.tab_count,
70 }
71 }
72}
73impl Sub for DisplayLen {
74 type Output = Self;
75 fn sub(self, other: Self) -> Self {
76 Self {
77 len: self.len - other.len,
78 tab_count: self.tab_count - other.tab_count,
79 }
80 }
81}
82
83pub struct CharDisplayDistance {
84 pub distance: u32,
85 pub char: char,
86 pub char_index: u32,
87}
88pub struct CharDisplayDistances<'a> {
89 char_indices: CharIndices<'a>,
90 len: u32,
91 tab_size: u8,
92}
93impl<'a> CharDisplayDistances<'a> {
94 pub fn new(text: &'a str, tab_size: u8) -> Self {
95 Self {
96 char_indices: text.char_indices(),
97 len: 0,
98 tab_size,
99 }
100 }
101}
102impl<'a> CharDisplayDistances<'a> {
103 fn calc_next(&mut self, char_index: usize, c: char) -> CharDisplayDistance {
104 self.len += match c {
105 '\t' => self.tab_size as u32,
106 _ => char_display_len(c) as u32,
107 };
108 CharDisplayDistance {
109 distance: self.len,
110 char: c,
111 char_index: char_index as _,
112 }
113 }
114}
115impl<'a> Iterator for CharDisplayDistances<'a> {
116 type Item = CharDisplayDistance;
117 fn next(&mut self) -> Option<Self::Item> {
118 let (i, c) = self.char_indices.next()?;
119 Some(self.calc_next(i, c))
120 }
121}
122impl<'a> DoubleEndedIterator for CharDisplayDistances<'a> {
123 fn next_back(&mut self) -> Option<Self::Item> {
124 let (i, c) = self.char_indices.next_back()?;
125 Some(self.calc_next(i, c))
126 }
127}
128
129pub struct WordRefWithIndex<'a> {
130 pub kind: WordKind,
131 pub text: &'a str,
132 pub index: usize,
133}
134impl<'a> WordRefWithIndex<'a> {
135 pub fn to_word_ref_with_position(self, line_index: usize) -> WordRefWithPosition<'a> {
136 WordRefWithPosition {
137 kind: self.kind,
138 text: self.text,
139 position: BufferPosition::line_col(line_index as _, self.index as _),
140 }
141 }
142}
143
144pub struct WordRefWithPosition<'a> {
145 pub kind: WordKind,
146 pub text: &'a str,
147 pub position: BufferPosition,
148}
149impl<'a> WordRefWithPosition<'a> {
150 pub fn end_position(&self) -> BufferPosition {
151 BufferPosition::line_col(
152 self.position.line_index,
153 self.position.column_byte_index + self.text.len() as BufferPositionIndex,
154 )
155 }
156}
157
158pub struct BufferLint {
159 pub message_range: Range<u32>,
160 pub range: BufferRange,
161 pub plugin_handle: PluginHandle,
162}
163impl BufferLint {
164 pub fn message<'a>(&self, buffer_lints: &'a BufferLintCollection) -> &'a str {
165 let message_range = self.message_range.start as usize..self.message_range.end as usize;
166 let plugin_messages = &buffer_lints.plugin_messages[self.plugin_handle.0 as usize];
167 &plugin_messages[message_range]
168 }
169}
170
171#[derive(Default)]
172pub struct BufferLintCollection {
173 lints: Vec<BufferLint>,
174 plugin_messages: Vec<String>,
175}
176impl BufferLintCollection {
177 pub fn all(&self) -> &[BufferLint] {
178 &self.lints
179 }
180
181 fn clear(&mut self) {
182 self.lints.clear();
183 }
184
185 fn insert_range(&mut self, range: BufferRange) {
186 for lint in &mut self.lints {
187 lint.range.from = lint.range.from.insert(range);
188 lint.range.to = lint.range.to.insert(range);
189 }
190 }
191
192 fn delete_range(&mut self, range: BufferRange) {
193 for lint in &mut self.lints {
194 lint.range.from = lint.range.from.delete(range);
195 lint.range.to = lint.range.to.delete(range);
196 }
197 }
198
199 pub fn mut_guard(&mut self, plugin_handle: PluginHandle) -> BufferLintCollectionMutGuard {
200 let min_messages_len = plugin_handle.0 as usize + 1;
201 if self.plugin_messages.len() < min_messages_len {
202 self.plugin_messages.resize(min_messages_len, String::new());
203 }
204 BufferLintCollectionMutGuard {
205 inner: self,
206 plugin_handle,
207 }
208 }
209}
210
211pub struct BufferLintCollectionMutGuard<'a> {
212 inner: &'a mut BufferLintCollection,
213 plugin_handle: PluginHandle,
214}
215impl<'a> BufferLintCollectionMutGuard<'a> {
216 pub fn clear(&mut self) {
217 self.inner.plugin_messages[self.plugin_handle.0 as usize].clear();
218 for i in (0..self.inner.lints.len()).rev() {
219 if self.inner.lints[i].plugin_handle == self.plugin_handle {
220 self.inner.lints.swap_remove(i);
221 }
222 }
223 }
224
225 pub fn add(&mut self, message: &str, range: BufferRange) {
226 let plugin_messages = &mut self.inner.plugin_messages[self.plugin_handle.0 as usize];
227 let message_start = plugin_messages.len() as _;
228 plugin_messages.push_str(message);
229 let message_end = plugin_messages.len() as _;
230
231 self.inner.lints.push(BufferLint {
232 message_range: message_start..message_end,
233 range,
234 plugin_handle: self.plugin_handle,
235 });
236 }
237}
238impl<'a> Drop for BufferLintCollectionMutGuard<'a> {
239 fn drop(&mut self) {
240 self.inner.lints.sort_unstable_by_key(|l| l.range.from);
241 }
242}
243
244#[derive(Default, Clone, Copy, PartialEq, Eq)]
245pub struct BufferBreakpointId(pub u32);
246
247#[derive(Clone, Copy)]
248pub struct BufferBreakpoint {
249 pub id: BufferBreakpointId,
250 pub line_index: BufferPositionIndex,
251}
252
253#[derive(Default)]
254pub struct BufferBreakpointCollection {
255 breakpoints: Vec<BufferBreakpoint>,
256 next_breakpoint_id: BufferBreakpointId,
257}
258impl BufferBreakpointCollection {
259 fn clear(&mut self) {
260 self.breakpoints.clear();
261 }
262
263 fn insert_range(&mut self, range: BufferRange) -> bool {
264 let line_count = range.to.line_index - range.from.line_index;
265 if line_count == 0 {
266 return false;
267 }
268
269 let mut changed = false;
270 for breakpoint in &mut self.breakpoints {
271 let from = range.from;
272 if from.line_index < breakpoint.line_index
273 || from.line_index == breakpoint.line_index && from.column_byte_index == 0
274 {
275 breakpoint.line_index += line_count;
276 changed = true;
277 } else {
278 break;
279 }
280 }
281
282 return changed;
283 }
284
285 fn delete_range(&mut self, range: BufferRange) -> bool {
286 let line_count = range.to.line_index - range.from.line_index;
287 if line_count == 0 {
288 return false;
289 }
290
291 let mut changed = false;
292 let mut removed_breakpoint = false;
293 for i in (0..self.breakpoints.len()).rev() {
294 let breakpoint_line_index = self.breakpoints[i].line_index;
295
296 if range.to.line_index <= breakpoint_line_index {
297 changed = true;
298 self.breakpoints[i].line_index -= line_count;
299 } else if range.from.line_index < breakpoint_line_index {
300 self.breakpoints.swap_remove(i);
301 changed = true;
302 removed_breakpoint = true;
303 } else {
304 break;
305 }
306 }
307
308 if removed_breakpoint {
309 self.breakpoints.sort_unstable_by_key(|b| b.line_index);
310 }
311
312 return changed;
313 }
314}
315
316pub struct BufferBreakpointMutCollection<'a> {
317 inner: &'a mut BufferBreakpointCollection,
318 buffer_handle: BufferHandle,
319 needs_sorting: bool,
320 enqueued_breakpoints_changed_event: bool,
321}
322impl<'a> BufferBreakpointMutCollection<'a> {
323 pub fn as_slice(&self) -> &[BufferBreakpoint] {
324 &self.inner.breakpoints
325 }
326
327 pub fn clear(&mut self, events: &mut EditorEventWriter) {
328 if self.inner.breakpoints.len() > 0 {
329 self.enqueue_breakpoints_changed_event(events);
330 }
331 self.inner.breakpoints.clear();
332 }
333
334 pub fn add(
335 &mut self,
336 line_index: BufferPositionIndex,
337 events: &mut EditorEventWriter,
338 ) -> BufferBreakpoint {
339 self.needs_sorting = true;
340 let id = self.alloc_breakpoint_id();
341 let breakpoint = BufferBreakpoint { id, line_index };
342 self.inner.breakpoints.push(breakpoint);
343 self.enqueue_breakpoints_changed_event(events);
344 breakpoint
345 }
346
347 pub fn remove_at(&mut self, index: usize, events: &mut EditorEventWriter) -> BufferBreakpoint {
348 self.needs_sorting = true;
349 let breakpoint = self.inner.breakpoints.swap_remove(index);
350 self.enqueue_breakpoints_changed_event(events);
351 breakpoint
352 }
353
354 pub fn remove_under_cursors(&mut self, cursors: &[Cursor], events: &mut EditorEventWriter) {
355 let previous_breakpoints_len = self.inner.breakpoints.len();
356
357 let mut breakpoint_index = self.inner.breakpoints.len().saturating_sub(1);
358 'cursors_loop: for cursor in cursors.iter().rev() {
359 let range = cursor.to_range();
360
361 loop {
362 if self.inner.breakpoints.is_empty() {
363 break 'cursors_loop;
364 }
365
366 let breakpoint_line_index = self.inner.breakpoints[breakpoint_index].line_index;
367 if breakpoint_line_index < range.from.line_index {
368 break;
369 }
370
371 if breakpoint_line_index <= range.to.line_index {
372 self.inner.breakpoints.swap_remove(breakpoint_index);
373 }
374
375 if breakpoint_index == 0 {
376 break 'cursors_loop;
377 }
378 breakpoint_index -= 1;
379 }
380 }
381
382 if self.inner.breakpoints.len() < previous_breakpoints_len {
383 self.needs_sorting = true;
384 self.enqueue_breakpoints_changed_event(events);
385 }
386 }
387
388 pub fn toggle_under_cursors(&mut self, cursors: &[Cursor], events: &mut EditorEventWriter) {
389 let mut previous_line_index = BufferPositionIndex::MAX;
390 for cursor in cursors {
391 let range = cursor.to_range();
392
393 let from_line_index = previous_line_index
394 .wrapping_add(1)
395 .max(range.from.line_index);
396 let to_line_index = range.to.line_index;
397 previous_line_index = to_line_index;
398
399 for line_index in from_line_index..=to_line_index {
400 let id = self.alloc_breakpoint_id();
401 self.inner
402 .breakpoints
403 .push(BufferBreakpoint { id, line_index });
404 }
405 }
406
407 self.needs_sorting = true;
408 self.sort_if_needed();
409
410 {
411 let id = self.alloc_breakpoint_id();
412 self.inner.breakpoints.push(BufferBreakpoint {
413 id,
414 line_index: BufferPositionIndex::MAX,
415 });
416 }
417
418 let breakpoints = &mut self.inner.breakpoints[..];
419 let mut write_needle = 0;
420 let mut check_needle = 0;
421
422 let breakpoints_len = breakpoints.len() - 1;
423 while check_needle < breakpoints_len {
424 let left_breakpoint_line_index = breakpoints[check_needle].line_index;
425 if left_breakpoint_line_index == breakpoints[check_needle + 1].line_index {
426 check_needle += 2;
427 } else {
428 breakpoints[write_needle].line_index = left_breakpoint_line_index;
429 check_needle += 1;
430 write_needle += 1;
431 }
432 }
433
434 self.inner.breakpoints.truncate(write_needle);
435 self.enqueue_breakpoints_changed_event(events);
436 }
437
438 fn alloc_breakpoint_id(&mut self) -> BufferBreakpointId {
439 let id = self.inner.next_breakpoint_id;
440 self.inner.next_breakpoint_id.0 = self.inner.next_breakpoint_id.0.wrapping_add(1);
441 id
442 }
443
444 fn sort_if_needed(&mut self) {
445 if self.needs_sorting {
446 self.needs_sorting = false;
447 self.inner
448 .breakpoints
449 .sort_unstable_by_key(|b| b.line_index);
450 }
451 }
452
453 fn enqueue_breakpoints_changed_event(&mut self, events: &mut EditorEventWriter) {
454 if !self.enqueued_breakpoints_changed_event {
455 self.enqueued_breakpoints_changed_event = true;
456 events.enqueue(EditorEvent::BufferBreakpointsChanged {
457 handle: self.buffer_handle,
458 });
459 }
460 }
461}
462impl<'a> Drop for BufferBreakpointMutCollection<'a> {
463 fn drop(&mut self) {
464 self.sort_if_needed();
465 self.inner.breakpoints.dedup_by_key(|b| b.line_index);
466 }
467}
468
469struct BufferLinePool {
470 pool: Vec<BufferLine>,
471}
472
473impl BufferLinePool {
474 pub const fn new() -> Self {
475 Self { pool: Vec::new() }
476 }
477
478 pub fn acquire(&mut self) -> BufferLine {
479 match self.pool.pop() {
480 Some(mut line) => {
481 line.0.clear();
482 line
483 }
484 None => BufferLine::new(),
485 }
486 }
487
488 pub fn release(&mut self, line: BufferLine) {
489 self.pool.push(line);
490 }
491}
492
493pub struct BufferLine(String);
494
495impl BufferLine {
496 fn new() -> Self {
497 Self(String::new())
498 }
499
500 pub fn as_str(&self) -> &str {
501 &self.0
502 }
503
504 pub fn chars_from(
505 &self,
506 index: usize,
507 ) -> (
508 impl '_ + Iterator<Item = (usize, char)>,
509 impl '_ + Iterator<Item = (usize, char)>,
510 ) {
511 let (left, right) = self.0.split_at(index);
512 let left_chars = left.char_indices().rev();
513 let right_chars = right.char_indices().map(move |(i, c)| (index + i, c));
514 (left_chars, right_chars)
515 }
516
517 pub fn words_from(
518 &self,
519 index: usize,
520 ) -> (
521 WordRefWithIndex,
522 impl Iterator<Item = WordRefWithIndex>,
523 impl Iterator<Item = WordRefWithIndex>,
524 ) {
525 let mid_word = self.word_at(index);
526 let mid_start_index = mid_word.index;
527 let mid_end_index = mid_start_index + mid_word.text.len();
528
529 let left = &self.0[..mid_start_index];
530 let right = &self.0[mid_end_index..];
531
532 let mut left_column_index = mid_start_index;
533 let left_words = WordIter(left).rev().map(move |w| {
534 left_column_index -= w.text.len();
535 WordRefWithIndex {
536 kind: w.kind,
537 text: w.text,
538 index: left_column_index,
539 }
540 });
541
542 let mut right_column_index = mid_end_index;
543 let right_words = WordIter(right).map(move |w| {
544 let index = right_column_index;
545 right_column_index += w.text.len();
546 WordRefWithIndex {
547 kind: w.kind,
548 text: w.text,
549 index,
550 }
551 });
552
553 (mid_word, left_words, right_words)
554 }
555
556 pub fn word_at(&self, index: usize) -> WordRefWithIndex {
557 let (before, after) = self.0.split_at(index);
558 match WordIter(after).next() {
559 Some(right) => match WordIter(before).next_back() {
560 Some(left) => {
561 if left.kind == right.kind {
562 let end_index = index + right.text.len();
563 let index = index - left.text.len();
564 WordRefWithIndex {
565 kind: left.kind,
566 text: &self.0[index..end_index],
567 index,
568 }
569 } else {
570 WordRefWithIndex {
571 kind: right.kind,
572 text: right.text,
573 index,
574 }
575 }
576 }
577 None => WordRefWithIndex {
578 kind: right.kind,
579 text: right.text,
580 index,
581 },
582 },
583 None => WordRefWithIndex {
584 kind: WordKind::Whitespace,
585 text: "",
586 index,
587 },
588 }
589 }
590
591 pub fn split_off(
592 &mut self,
593 self_display_len: &mut DisplayLen,
594 other: &mut BufferLine,
595 other_display_len: &mut DisplayLen,
596 index: usize,
597 ) {
598 other.0.clear();
599 other.0.push_str(&self.0[index..]);
600
601 if index < other.0.len() {
602 let display_len = DisplayLen::from(&self.0[..index]);
603 *other_display_len = *self_display_len - display_len;
604 *self_display_len = display_len;
605 } else {
606 *other_display_len = DisplayLen::from(&other.0[..]);
607 *self_display_len = *self_display_len - *other_display_len;
608 }
609
610 self.0.truncate(index);
611 }
612
613 pub fn insert_text(&mut self, display_len: &mut DisplayLen, index: usize, text: &str) {
614 self.0.insert_str(index, text);
615 *display_len = *display_len + DisplayLen::from(text);
616 }
617
618 pub fn push_text(&mut self, display_len: &mut DisplayLen, text: &str) {
619 let text = match text.strip_suffix('\r') {
620 Some(text) => text,
621 None => text,
622 };
623 self.0.push_str(text);
624 *display_len = *display_len + DisplayLen::from(text);
625 }
626
627 pub fn delete_range<R>(&mut self, display_len: &mut DisplayLen, range: R)
628 where
629 R: RangeBounds<usize>,
630 {
631 let deleted = self.0.drain(range);
632 *display_len = *display_len - DisplayLen::from(deleted.as_str());
633 }
634}
635
636pub struct TextRangeIter<'a> {
637 content: &'a BufferContent,
638 from: BufferPosition,
639 to: BufferPosition,
640}
641impl<'a> Iterator for TextRangeIter<'a> {
642 type Item = &'a str;
643 fn next(&mut self) -> Option<Self::Item> {
644 if self.from == self.to {
645 return None;
646 }
647
648 let line = self.content.lines[self.from.line_index as usize].as_str();
649
650 if self.from.column_byte_index == line.len() as _ {
651 self.from.line_index += 1;
652 self.from.column_byte_index = 0;
653 Some("\n")
654 } else if self.from.line_index == self.to.line_index {
655 let text =
656 &line[self.from.column_byte_index as usize..self.to.column_byte_index as usize];
657 self.from = self.to;
658 Some(text)
659 } else {
660 let text = &line[self.from.column_byte_index as usize..];
661 self.from.column_byte_index = line.len() as _;
662 Some(text)
663 }
664 }
665}
666
667pub struct BufferContent {
668 lines: Vec<BufferLine>,
669 line_display_lens: Vec<DisplayLen>,
670 line_pool: BufferLinePool,
671}
672
673impl BufferContent {
674 pub fn new() -> Self {
675 Self {
676 lines: vec![BufferLine::new()],
677 line_display_lens: vec![DisplayLen::zero()],
678 line_pool: BufferLinePool::new(),
679 }
680 }
681
682 pub fn lines(&self) -> &[BufferLine] {
683 &self.lines
684 }
685
686 pub fn line_display_lens(&self) -> &[DisplayLen] {
687 &self.line_display_lens
688 }
689
690 pub fn end(&self) -> BufferPosition {
691 let last_line_index = self.lines.len() - 1;
692 BufferPosition::line_col(
693 last_line_index as _,
694 self.lines[last_line_index].as_str().len() as _,
695 )
696 }
697
698 pub fn read(&mut self, read: &mut dyn io::BufRead) -> io::Result<()> {
699 for line in self.lines.drain(..) {
700 self.line_pool.release(line);
701 }
702 self.line_display_lens.clear();
703
704 let mut push_empty = true;
705 loop {
706 let mut line = self.line_pool.acquire();
707 match read.read_line(&mut line.0) {
708 Ok(0) => {
709 if push_empty {
710 self.lines.push(line);
711 self.line_display_lens.push(DisplayLen::zero());
712 } else {
713 self.line_pool.release(line);
714 }
715 break;
716 }
717 Ok(_) => {
718 push_empty = false;
719
720 if line.0.ends_with('\n') {
721 push_empty = true;
722 line.0.pop();
723 }
724 if line.0.ends_with('\r') {
725 line.0.pop();
726 }
727 let display_len = DisplayLen::from(&line.0[..]);
728
729 self.lines.push(line);
730 self.line_display_lens.push(display_len);
731 }
732 Err(e) => {
733 for line in self.lines.drain(..) {
734 self.line_pool.release(line);
735 }
736 self.lines.push(self.line_pool.acquire());
737 self.line_display_lens.clear();
738 self.line_display_lens.push(DisplayLen::zero());
739 return Err(e);
740 }
741 }
742 }
743
744 let byte_order_mark = b"\xef\xbb\xbf";
745 if self.lines[0]
746 .as_str()
747 .as_bytes()
748 .starts_with(byte_order_mark)
749 {
750 self.lines[0].delete_range(&mut self.line_display_lens[0], ..byte_order_mark.len());
751 }
752
753 Ok(())
754 }
755
756 pub fn write(&self, write: &mut dyn io::Write) -> io::Result<()> {
757 let end_index = self.lines.len() - 1;
758 for line in &self.lines[..end_index] {
759 write!(write, "{}\n", line.as_str())?;
760 }
761 write!(write, "{}", self.lines[end_index].as_str())?;
762 Ok(())
763 }
764
765 pub fn saturate_position(&self, mut position: BufferPosition) -> BufferPosition {
766 position.line_index = position.line_index.min((self.lines.len() - 1) as _);
767 let line = self.lines[position.line_index as usize].as_str();
768 position.column_byte_index = position.column_byte_index.min(line.len() as _);
769 position
770 }
771
772 pub fn text_range(&self, range: BufferRange) -> TextRangeIter {
773 let from = self.saturate_position(range.from);
774 let to = self.saturate_position(range.to);
775 TextRangeIter {
776 content: self,
777 from,
778 to,
779 }
780 }
781
782 pub fn find_search_ranges(&self, pattern: &Pattern, ranges: &mut Vec<BufferRange>) {
783 if pattern.is_empty() {
784 return;
785 }
786 let search_anchor = pattern.search_anchor();
787 for (line_index, line) in self.lines.iter().enumerate() {
788 let line = line.as_str();
789 for range in pattern.match_indices(line, search_anchor) {
790 let from = BufferPosition::line_col(line_index as _, range.start as _);
791 let to = BufferPosition::line_col(line_index as _, range.end as _);
792 ranges.push(BufferRange::between(from, to));
793 }
794 }
795 }
796
797 pub fn insert_text(&mut self, position: BufferPosition, text: &str) -> BufferRange {
798 if !text.contains(&['\n', '\r']) {
799 let line = &mut self.lines[position.line_index as usize];
800 let display_len = &mut self.line_display_lens[position.line_index as usize];
801
802 let previous_len = line.as_str().len();
803 line.insert_text(display_len, position.column_byte_index as _, text);
804 let len_diff = line.as_str().len() - previous_len;
805
806 let end_position = BufferPosition::line_col(
807 position.line_index,
808 position.column_byte_index + len_diff as BufferPositionIndex,
809 );
810 BufferRange::between(position, end_position)
811 } else {
812 let mut split_line = self.line_pool.acquire();
813 let mut split_display_len = DisplayLen::zero();
814
815 let position_line = &mut self.lines[position.line_index as usize];
816 let position_display_len = &mut self.line_display_lens[position.line_index as usize];
817
818 position_line.split_off(
819 position_display_len,
820 &mut split_line,
821 &mut split_display_len,
822 position.column_byte_index as _,
823 );
824
825 let mut line_count = 0 as BufferPositionIndex;
826 let mut lines = text.lines();
827 if let Some(line) = lines.next() {
828 position_line.push_text(position_display_len, line);
829 }
830 for line_text in lines {
831 line_count += 1;
832
833 let mut line = self.line_pool.acquire();
834 let mut display_len = DisplayLen::zero();
835 line.push_text(&mut display_len, line_text);
836
837 let insert_index = (position.line_index + line_count) as _;
838 self.lines.insert(insert_index, line);
839 self.line_display_lens.insert(insert_index, display_len);
840 }
841
842 let end_position = if text.ends_with('\n') {
843 line_count += 1;
844
845 let insert_index = (position.line_index + line_count) as _;
846 self.lines.insert(insert_index, split_line);
847 self.line_display_lens
848 .insert(insert_index, split_display_len);
849
850 BufferPosition::line_col(position.line_index + line_count, 0)
851 } else {
852 let index = (position.line_index + line_count) as usize;
853 let line = &mut self.lines[index];
854 let display_len = &mut self.line_display_lens[index];
855
856 let column_byte_index = line.as_str().len() as _;
857 line.push_text(display_len, split_line.as_str());
858
859 self.line_pool.release(split_line);
860 BufferPosition::line_col(position.line_index + line_count, column_byte_index)
861 };
862
863 BufferRange::between(position, end_position)
864 }
865 }
866
867 pub fn delete_range(&mut self, range: BufferRange) {
868 let from = range.from;
869 let to = range.to;
870
871 if from.line_index == to.line_index {
872 let line = &mut self.lines[from.line_index as usize];
873 let display_len = &mut self.line_display_lens[from.line_index as usize];
874
875 line.delete_range(
876 display_len,
877 from.column_byte_index as usize..to.column_byte_index as usize,
878 );
879 } else {
880 let from_line = &mut self.lines[from.line_index as usize];
881 let from_display_len = &mut self.line_display_lens[from.line_index as usize];
882 from_line.delete_range(from_display_len, from.column_byte_index as usize..);
883
884 let lines_range = (from.line_index as usize + 1)..to.line_index as usize;
885 if lines_range.start < lines_range.end {
886 for line in self.lines.drain(lines_range.clone()) {
887 self.line_pool.release(line);
888 }
889 self.line_display_lens.drain(lines_range);
890 }
891
892 let to_line_index = from.line_index as usize + 1;
893 if to_line_index < self.lines.len() {
894 let to_line = self.lines.remove(to_line_index);
895 self.line_display_lens.remove(to_line_index);
896
897 let from_line = &mut self.lines[from.line_index as usize];
898 let from_display_len = &mut self.line_display_lens[from.line_index as usize];
899
900 from_line.push_text(
901 from_display_len,
902 &to_line.as_str()[to.column_byte_index as usize..],
903 );
904 }
905 }
906 }
907
908 pub fn clear(&mut self) {
909 for line in self.lines.drain(..) {
910 self.line_pool.release(line);
911 }
912 self.lines.push(self.line_pool.acquire());
913 self.line_display_lens.clear();
914 self.line_display_lens.push(DisplayLen::zero());
915 }
916
917 pub fn words_from(
918 &self,
919 position: BufferPosition,
920 ) -> (
921 WordRefWithPosition,
922 impl Iterator<Item = WordRefWithPosition>,
923 impl Iterator<Item = WordRefWithPosition>,
924 ) {
925 let position = self.saturate_position(position);
926 let line_index = position.line_index as _;
927 let column_byte_index = position.column_byte_index as _;
928
929 let (mid_word, left_words, right_words) =
930 self.lines[line_index as usize].words_from(column_byte_index);
931
932 (
933 mid_word.to_word_ref_with_position(line_index),
934 left_words.map(move |w| w.to_word_ref_with_position(line_index)),
935 right_words.map(move |w| w.to_word_ref_with_position(line_index)),
936 )
937 }
938
939 pub fn word_at(&self, position: BufferPosition) -> WordRefWithPosition {
940 let position = self.saturate_position(position);
941 self.lines[position.line_index as usize]
942 .word_at(position.column_byte_index as _)
943 .to_word_ref_with_position(position.line_index as _)
944 }
945
946 pub fn position_before(&self, mut position: BufferPosition) -> BufferPosition {
947 position.column_byte_index = self.lines[position.line_index as usize].as_str()
948 [..position.column_byte_index as usize]
949 .char_indices()
950 .next_back()
951 .map(|(i, _)| i as _)
952 .unwrap_or(0);
953 position
954 }
955
956 pub fn find_delimiter_pair_at(
957 &self,
958 position: BufferPosition,
959 delimiter: char,
960 ) -> Option<BufferRange> {
961 let position = self.saturate_position(position);
962 let line = self.lines[position.line_index as usize].as_str();
963 let range = find_delimiter_pair_at(line, position.column_byte_index as _, delimiter)?;
964 Some(BufferRange::between(
965 BufferPosition::line_col(position.line_index, range.0 as _),
966 BufferPosition::line_col(position.line_index, range.1 as _),
967 ))
968 }
969
970 pub fn find_balanced_chars_at(
971 &self,
972 position: BufferPosition,
973 left: char,
974 right: char,
975 ) -> Option<BufferRange> {
976 fn find<I>(iter: I, target: char, other: char, balance: &mut usize) -> Option<usize>
977 where
978 I: Iterator<Item = (usize, char)>,
979 {
980 let mut b = *balance;
981 for (i, c) in iter {
982 if c == target {
983 if b == 0 {
984 *balance = 0;
985 return Some(i);
986 } else {
987 b -= 1;
988 }
989 } else if c == other {
990 b += 1;
991 }
992 }
993 *balance = b;
994 None
995 }
996
997 let position = self.saturate_position(position);
998 let line = self.lines[position.line_index as usize].as_str();
999 let (before, after) = line.split_at(position.column_byte_index as _);
1000
1001 let mut balance = 0;
1002
1003 let mut left_position = None;
1004 let mut right_position = None;
1005
1006 let mut after_chars = after.char_indices();
1007 if let Some((i, c)) = after_chars.next() {
1008 if c == left {
1009 left_position = Some(position.column_byte_index as usize + i + c.len_utf8());
1010 } else if c == right {
1011 right_position = Some(position.column_byte_index as usize + i);
1012 }
1013 }
1014
1015 let right_position = match right_position {
1016 Some(column_index) => BufferPosition::line_col(position.line_index, column_index as _),
1017 None => match find(after_chars, right, left, &mut balance) {
1018 Some(column_byte_index) => {
1019 let column_byte_index = position.column_byte_index as usize + column_byte_index;
1020 BufferPosition::line_col(position.line_index, column_byte_index as _)
1021 }
1022 None => {
1023 let mut pos = None;
1024 for line_index in (position.line_index as usize + 1)..self.lines.len() {
1025 let line = self.lines[line_index].as_str();
1026 if let Some(column_byte_index) =
1027 find(line.char_indices(), right, left, &mut balance)
1028 {
1029 pos = Some(BufferPosition::line_col(
1030 line_index as _,
1031 column_byte_index as _,
1032 ));
1033 break;
1034 }
1035 }
1036 pos?
1037 }
1038 },
1039 };
1040
1041 balance = 0;
1042
1043 let left_position = match left_position {
1044 Some(column_index) => BufferPosition::line_col(position.line_index, column_index as _),
1045 None => match find(before.char_indices().rev(), left, right, &mut balance) {
1046 Some(column_byte_index) => {
1047 let column_byte_index = column_byte_index + left.len_utf8();
1048 BufferPosition::line_col(position.line_index, column_byte_index as _)
1049 }
1050 None => {
1051 let mut pos = None;
1052 for line_index in (0..position.line_index).rev() {
1053 let line = self.lines[line_index as usize].as_str();
1054 if let Some(column_byte_index) =
1055 find(line.char_indices().rev(), left, right, &mut balance)
1056 {
1057 let column_byte_index = column_byte_index + left.len_utf8();
1058 pos =
1059 Some(BufferPosition::line_col(line_index, column_byte_index as _));
1060 break;
1061 }
1062 }
1063 pos?
1064 }
1065 },
1066 };
1067
1068 Some(BufferRange::between(left_position, right_position))
1069 }
1070}
1071
1072impl fmt::Display for BufferContent {
1073 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1074 let end_index = self.lines.len() - 1;
1075 for line in &self.lines[..end_index] {
1076 f.write_str(line.as_str())?;
1077 f.write_str("\n")?;
1078 }
1079 f.write_str(self.lines[end_index].as_str())
1080 }
1081}
1082
1083pub enum BufferReadError {
1084 FileNotFound,
1085 InvalidData,
1086 Other,
1087}
1088impl fmt::Display for BufferReadError {
1089 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1090 match self {
1091 Self::FileNotFound => f.write_str("file not found"),
1092 Self::InvalidData => f.write_str("invalid data while reading from file"),
1093 Self::Other => f.write_str("could not read from file"),
1094 }
1095 }
1096}
1097impl From<io::Error> for BufferReadError {
1098 fn from(other: io::Error) -> Self {
1099 match other.kind() {
1100 io::ErrorKind::NotFound | io::ErrorKind::Unsupported => Self::FileNotFound,
1101 io::ErrorKind::InvalidData => Self::InvalidData,
1102 _ => Self::Other,
1103 }
1104 }
1105}
1106
1107pub enum BufferWriteError {
1108 SavingDisabled,
1109 CouldNotWriteToFile,
1110}
1111impl fmt::Display for BufferWriteError {
1112 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1113 match self {
1114 Self::SavingDisabled => f.write_str("buffer has saving disabled"),
1115 Self::CouldNotWriteToFile => f.write_str("could not write to file"),
1116 }
1117 }
1118}
1119impl From<io::Error> for BufferWriteError {
1120 fn from(_: io::Error) -> Self {
1121 Self::CouldNotWriteToFile
1122 }
1123}
1124
1125#[derive(Default)]
1126pub struct BufferProperties {
1127 pub history_enabled: bool,
1128 pub saving_enabled: bool,
1129 pub file_backed_enabled: bool,
1130 pub word_database_enabled: bool,
1131}
1132impl BufferProperties {
1133 pub fn text() -> Self {
1134 Self {
1135 history_enabled: true,
1136 saving_enabled: true,
1137 file_backed_enabled: true,
1138 word_database_enabled: true,
1139 }
1140 }
1141
1142 pub fn scratch() -> Self {
1143 Self {
1144 history_enabled: true,
1145 saving_enabled: false,
1146 file_backed_enabled: false,
1147 word_database_enabled: false,
1148 }
1149 }
1150
1151 pub fn log() -> Self {
1152 Self {
1153 history_enabled: false,
1154 saving_enabled: false,
1155 file_backed_enabled: true,
1156 word_database_enabled: false,
1157 }
1158 }
1159
1160 pub fn output() -> Self {
1161 Self {
1162 history_enabled: false,
1163 saving_enabled: false,
1164 file_backed_enabled: false,
1165 word_database_enabled: false,
1166 }
1167 }
1168}
1169
1170#[derive(Clone, Copy)]
1171pub struct BufferIndentationConfig {
1172 pub indent_with_tabs: bool,
1173 pub tab_size: u8,
1174}
1175
1176pub struct Buffer {
1177 alive: bool,
1178 handle: BufferHandle,
1179 pub path: PathBuf,
1180 content: BufferContent,
1181 syntax_handle: SyntaxHandle,
1182 highlighted: HighlightedBuffer,
1183 history: BufferHistory,
1184 pub lints: BufferLintCollection,
1185 breakpoints: BufferBreakpointCollection,
1186 search_ranges: Vec<BufferRange>,
1187 needs_save: bool,
1188 pub properties: BufferProperties,
1189}
1190
1191impl Buffer {
1192 fn new(handle: BufferHandle) -> Self {
1193 Self {
1194 alive: true,
1195 handle,
1196 path: PathBuf::new(),
1197 content: BufferContent::new(),
1198 syntax_handle: SyntaxHandle::default(),
1199 highlighted: HighlightedBuffer::new(),
1200 history: BufferHistory::new(),
1201 lints: BufferLintCollection::default(),
1202 breakpoints: BufferBreakpointCollection::default(),
1203 search_ranges: Vec::new(),
1204 needs_save: false,
1205 properties: BufferProperties::default(),
1206 }
1207 }
1208
1209 fn dispose(&mut self, word_database: &mut WordDatabase) {
1210 self.remove_all_words_from_database(word_database);
1211 self.content.clear();
1212 self.highlighted.clear();
1213
1214 self.alive = false;
1215 self.path.clear();
1216 self.syntax_handle = SyntaxHandle::default();
1217 self.history.clear();
1218 self.lints.clear();
1219 self.breakpoints.clear();
1220 self.search_ranges.clear();
1221 self.needs_save = false;
1222 self.properties = BufferProperties::default();
1223 }
1224
1225 fn remove_all_words_from_database(&mut self, word_database: &mut WordDatabase) {
1226 if self.properties.word_database_enabled {
1227 for line in &self.content.lines {
1228 for word in WordIter(line.as_str()).of_kind(WordKind::Identifier) {
1229 word_database.remove(word);
1230 }
1231 }
1232 }
1233 }
1234
1235 pub fn handle(&self) -> BufferHandle {
1236 self.handle
1237 }
1238
1239 pub fn set_path(&mut self, path: &Path) {
1240 self.path.clear();
1241 let mut components = path.components();
1242 match components.next() {
1243 Some(Component::CurDir) => self.path.push(components.as_path()),
1244 Some(_) => self.path.push(path),
1245 None => (),
1246 }
1247 }
1248
1249 pub fn content(&self) -> &BufferContent {
1250 &self.content
1251 }
1252
1253 pub fn highlighted(&self) -> &HighlightedBuffer {
1254 &self.highlighted
1255 }
1256
1257 pub fn update_highlighting(&mut self, syntaxes: &SyntaxCollection) -> HighlightResult {
1258 self.highlighted
1259 .highlight_dirty_lines(syntaxes.get(self.syntax_handle), &self.content)
1260 }
1261
1262 pub fn refresh_syntax(&mut self, syntaxes: &SyntaxCollection) {
1263 let path = self.path.to_str().unwrap_or("");
1264 if path.is_empty() {
1265 return;
1266 }
1267
1268 let syntax_handle = syntaxes.find_handle_by_path(path).unwrap_or_default();
1269
1270 if self.syntax_handle != syntax_handle {
1271 self.syntax_handle = syntax_handle;
1272 self.highlighted.clear();
1273 }
1274 }
1275
1276 pub fn breakpoints(&self) -> &[BufferBreakpoint] {
1277 &self.breakpoints.breakpoints
1278 }
1279
1280 pub fn breakpoints_mut(&mut self) -> BufferBreakpointMutCollection {
1281 BufferBreakpointMutCollection {
1282 inner: &mut self.breakpoints,
1283 buffer_handle: self.handle,
1284 needs_sorting: false,
1285 enqueued_breakpoints_changed_event: false,
1286 }
1287 }
1288
1289 pub fn needs_save(&self) -> bool {
1290 self.properties.saving_enabled && self.needs_save
1291 }
1292
1293 pub fn insert_text(
1294 &mut self,
1295 word_database: &mut WordDatabase,
1296 position: BufferPosition,
1297 text: &str,
1298 events: &mut BufferTextInsertsMutGuard,
1299 ) -> BufferRange {
1300 self.search_ranges.clear();
1301 let position = self.content.saturate_position(position);
1302
1303 if text.is_empty() {
1304 return BufferRange::between(position, position);
1305 }
1306 self.needs_save = true;
1307
1308 let range = Self::insert_text_no_history(
1309 &mut self.content,
1310 self.properties
1311 .word_database_enabled
1312 .then_some(word_database),
1313 position,
1314 text,
1315 );
1316
1317 events.add(range, text);
1318
1319 if self.properties.history_enabled {
1320 self.history.add_edit(Edit {
1321 kind: EditKind::Insert,
1322 range,
1323 text,
1324 });
1325 }
1326
1327 range
1328 }
1329
1330 fn insert_text_no_history(
1331 content: &mut BufferContent,
1332 mut word_database: Option<&mut WordDatabase>,
1333 position: BufferPosition,
1334 text: &str,
1335 ) -> BufferRange {
1336 if let Some(word_database) = &mut word_database {
1337 for word in WordIter(content.lines()[position.line_index as usize].as_str())
1338 .of_kind(WordKind::Identifier)
1339 {
1340 word_database.remove(word);
1341 }
1342 }
1343
1344 let range = content.insert_text(position, text);
1345
1346 if let Some(word_database) = &mut word_database {
1347 for line in
1348 &content.lines()[range.from.line_index as usize..=range.to.line_index as usize]
1349 {
1350 for word in WordIter(line.as_str()).of_kind(WordKind::Identifier) {
1351 word_database.add(word);
1352 }
1353 }
1354 }
1355
1356 range
1357 }
1358
1359 pub fn delete_range(
1360 &mut self,
1361 word_database: &mut WordDatabase,
1362 mut range: BufferRange,
1363 events: &mut BufferRangeDeletesMutGuard,
1364 ) {
1365 self.search_ranges.clear();
1366 range.from = self.content.saturate_position(range.from);
1367 range.to = self.content.saturate_position(range.to);
1368
1369 if range.from == range.to {
1370 return;
1371 }
1372 self.needs_save = true;
1373
1374 events.add(range);
1375
1376 let from = range.from;
1377 let to = range.to;
1378
1379 if self.properties.history_enabled {
1380 fn add_history_delete_line(buffer: &mut Buffer, from: BufferPosition) {
1381 let line = buffer.content.lines()[from.line_index as usize].as_str();
1382 let range = BufferRange::between(
1383 BufferPosition::line_col(from.line_index, line.len() as _),
1384 BufferPosition::line_col(from.line_index + 1, 0),
1385 );
1386 buffer.history.add_edit(Edit {
1387 kind: EditKind::Delete,
1388 range,
1389 text: "\n",
1390 });
1391 buffer.history.add_edit(Edit {
1392 kind: EditKind::Delete,
1393 range: BufferRange::between(from, range.from),
1394 text: &line[from.column_byte_index as usize..],
1395 });
1396 }
1397
1398 if from.line_index == to.line_index {
1399 let text = &self.content.lines()[from.line_index as usize].as_str()
1400 [from.column_byte_index as usize..to.column_byte_index as usize];
1401 self.history.add_edit(Edit {
1402 kind: EditKind::Delete,
1403 range,
1404 text,
1405 });
1406 } else {
1407 let text = &self.content.lines()[to.line_index as usize].as_str()
1408 [..to.column_byte_index as usize];
1409 self.history.add_edit(Edit {
1410 kind: EditKind::Delete,
1411 range: BufferRange::between(BufferPosition::line_col(to.line_index, 0), to),
1412 text,
1413 });
1414 for line_index in ((from.line_index + 1)..to.line_index).rev() {
1415 add_history_delete_line(self, BufferPosition::line_col(line_index, 0));
1416 }
1417 add_history_delete_line(self, from);
1418 }
1419 }
1420
1421 Self::delete_range_no_history(
1422 &mut self.content,
1423 self.properties
1424 .word_database_enabled
1425 .then_some(word_database),
1426 range,
1427 );
1428 }
1429
1430 fn delete_range_no_history(
1431 content: &mut BufferContent,
1432 mut word_database: Option<&mut WordDatabase>,
1433 range: BufferRange,
1434 ) {
1435 if let Some(word_database) = &mut word_database {
1436 for line in
1437 &content.lines()[range.from.line_index as usize..=range.to.line_index as usize]
1438 {
1439 for word in WordIter(line.as_str()).of_kind(WordKind::Identifier) {
1440 word_database.remove(word);
1441 }
1442 }
1443 }
1444
1445 content.delete_range(range);
1446
1447 if let Some(word_database) = &mut word_database {
1448 for word in WordIter(content.lines()[range.from.line_index as usize].as_str())
1449 .of_kind(WordKind::Identifier)
1450 {
1451 word_database.add(word);
1452 }
1453 }
1454 }
1455
1456 pub fn fix_line_indentation(
1457 &mut self,
1458 indentation_config: BufferIndentationConfig,
1459 line_index: BufferPositionIndex,
1460 events: &mut BufferEditMutGuard,
1461 ) {
1462 if indentation_config.tab_size == 0 {
1463 return;
1464 }
1465
1466 let mut previous_line_text = "";
1467 for line in self.content.lines[..line_index as usize].iter().rev() {
1468 previous_line_text = line.as_str();
1469 if !previous_line_text.is_empty() {
1470 break;
1471 }
1472 }
1473
1474 let mut indentation: usize = 0;
1475 let mut pending_spaces = 0;
1476 let mut chars = previous_line_text.chars();
1477 loop {
1478 match chars.next() {
1479 Some('\t') => {
1480 indentation += 1;
1481 pending_spaces = 0;
1482 }
1483 Some(' ') => {
1484 if pending_spaces > 0 {
1485 pending_spaces -= 1;
1486 } else {
1487 indentation += 1;
1488 pending_spaces = indentation_config.tab_size - 1;
1489 }
1490 }
1491 _ => break,
1492 }
1493 }
1494
1495 if previous_line_text.ends_with(&['(', '[', '{', '<']) {
1496 indentation += 1;
1497 }
1498
1499 let line = &mut self.content.lines[line_index as usize];
1500 let display_lens = &mut self.content.line_display_lens[line_index as usize];
1501 let first_word = line.word_at(0);
1502 let delete_len = match first_word.kind {
1503 WordKind::Whitespace => first_word.text.len(),
1504 _ => 0,
1505 };
1506
1507 let delete_range = BufferRange::between(
1508 BufferPosition::line_col(line_index, 0),
1509 BufferPosition::line_col(line_index, delete_len as _),
1510 );
1511 let delete_text = &line.as_str()[..delete_len];
1512
1513 events.to_range_deletes().add(delete_range);
1514 if self.properties.history_enabled {
1515 self.history.add_edit(Edit {
1516 kind: EditKind::Delete,
1517 range: delete_range,
1518 text: delete_text,
1519 });
1520 }
1521
1522 line.delete_range(display_lens, ..delete_len);
1523
1524 if line.0.trim_start().starts_with(&[')', ']', '}', '>']) {
1525 indentation = indentation.saturating_sub(1);
1526 }
1527
1528 let insert_len = if line.0.is_empty() {
1529 0
1530 } else {
1531 let (insert_byte, insert_len) = if indentation_config.indent_with_tabs {
1532 (b'\t', indentation)
1533 } else {
1534 (b' ', indentation * indentation_config.tab_size as usize)
1535 };
1536
1537 let line_vec = unsafe { line.0.as_mut_vec() };
1538 line_vec.splice(..0, std::iter::repeat(insert_byte).take(insert_len));
1539
1540 let insert_display_len = if indentation_config.indent_with_tabs {
1541 DisplayLen {
1542 len: 0,
1543 tab_count: insert_len as _,
1544 }
1545 } else {
1546 DisplayLen {
1547 len: insert_len as _,
1548 tab_count: 0,
1549 }
1550 };
1551
1552 let line_display_len = &mut self.content.line_display_lens[line_index as usize];
1553 *line_display_len = *line_display_len + insert_display_len;
1554
1555 insert_len
1556 };
1557
1558 let insert_range = BufferRange::between(
1559 BufferPosition::line_col(line_index, 0),
1560 BufferPosition::line_col(line_index, insert_len as _),
1561 );
1562
1563 let insert_text = &self.content.lines()[line_index as usize].as_str()[..insert_len];
1564
1565 events.to_text_inserts().add(insert_range, insert_text);
1566 if self.properties.history_enabled {
1567 self.history.add_edit(Edit {
1568 kind: EditKind::Insert,
1569 range: insert_range,
1570 text: insert_text,
1571 });
1572 }
1573 }
1574
1575 pub fn commit_edits(&mut self) {
1576 self.history.commit_edits();
1577 }
1578
1579 pub fn undo(
1580 &mut self,
1581 word_database: &mut WordDatabase,
1582 events: &mut EditorEventWriter,
1583 ) -> impl '_ + ExactSizeIterator<Item = Edit<'_>> + DoubleEndedIterator<Item = Edit<'_>> {
1584 self.apply_history_edits(word_database, events, BufferHistory::undo_edits)
1585 }
1586
1587 pub fn redo(
1588 &mut self,
1589 word_database: &mut WordDatabase,
1590 events: &mut EditorEventWriter,
1591 ) -> impl '_ + ExactSizeIterator<Item = Edit<'_>> + DoubleEndedIterator<Item = Edit<'_>> {
1592 self.apply_history_edits(word_database, events, BufferHistory::redo_edits)
1593 }
1594
1595 fn apply_history_edits<'a, F, I>(
1596 &'a mut self,
1597 word_database: &mut WordDatabase,
1598 events: &mut EditorEventWriter,
1599 selector: F,
1600 ) -> I
1601 where
1602 F: FnOnce(&'a mut BufferHistory) -> I,
1603 I: 'a + Clone + ExactSizeIterator<Item = Edit<'a>>,
1604 {
1605 self.search_ranges.clear();
1606 self.needs_save = true;
1607
1608 let content = &mut self.content;
1609 let uses_word_database = self.properties.word_database_enabled;
1610
1611 let edits = selector(&mut self.history);
1612
1613 let mut events = BufferEditMutGuard::new(events, self.handle);
1614 for edit in edits.clone() {
1615 match edit.kind {
1616 EditKind::Insert => {
1617 Self::insert_text_no_history(
1618 content,
1619 uses_word_database.then_some(word_database),
1620 edit.range.from,
1621 edit.text,
1622 );
1623 events.to_text_inserts().add(edit.range, edit.text);
1624 }
1625 EditKind::Delete => {
1626 Self::delete_range_no_history(
1627 content,
1628 uses_word_database.then_some(word_database),
1629 edit.range,
1630 );
1631 events.to_range_deletes().add(edit.range);
1632 }
1633 }
1634 }
1635
1636 edits
1637 }
1638
1639 pub fn set_search(&mut self, pattern: &Pattern) {
1640 self.search_ranges.clear();
1641 self.content
1642 .find_search_ranges(pattern, &mut self.search_ranges);
1643 }
1644
1645 pub fn search_ranges(&self) -> &[BufferRange] {
1646 &self.search_ranges
1647 }
1648
1649 pub fn read_from_file(
1650 &mut self,
1651 word_database: &mut WordDatabase,
1652 events: &mut EditorEventWriter,
1653 ) -> Result<(), BufferReadError> {
1654 fn clear_buffer(buffer: &mut Buffer, word_database: &mut WordDatabase) {
1655 buffer.remove_all_words_from_database(word_database);
1656 buffer.content.clear();
1657 buffer.highlighted.clear();
1658 }
1659
1660 self.needs_save = false;
1661 self.history.clear();
1662 self.search_ranges.clear();
1663
1664 events.enqueue(EditorEvent::BufferRead {
1665 handle: self.handle,
1666 });
1667
1668 let help_page_name = self.path.to_str().and_then(help::parse_help_page_name);
1669 if help_page_name.is_none() && !self.properties.file_backed_enabled {
1670 return Ok(());
1671 }
1672
1673 let help_page = help_page_name.map(help::open);
1674
1675 if let Some((name, mut reader)) = help_page {
1676 clear_buffer(self, word_database);
1677 self.content.read(&mut reader)?;
1678
1679 let path = std::mem::take(&mut self.path);
1680 let mut path = path.into_os_string();
1681 path.clear();
1682 path.push(help::HELP_PREFIX);
1683 path.push(name);
1684 self.path = path.into();
1685 } else if self.path.as_os_str().is_empty() {
1686 return Err(BufferReadError::FileNotFound);
1687 } else {
1688 match File::open(&self.path) {
1689 Ok(file) => {
1690 clear_buffer(self, word_database);
1691 let mut reader = io::BufReader::new(file);
1692 self.content.read(&mut reader)?;
1693 }
1694 Err(error) => {
1695 if self.properties.saving_enabled {
1696 return Err(error.into());
1697 } else {
1698 clear_buffer(self, word_database);
1699 }
1700 }
1701 }
1702 }
1703
1704 if self.properties.word_database_enabled {
1705 for line in &self.content.lines {
1706 for word in WordIter(line.as_str()).of_kind(WordKind::Identifier) {
1707 word_database.add(word);
1708 }
1709 }
1710 }
1711
1712 Ok(())
1713 }
1714
1715 pub fn write_to_file(
1716 &mut self,
1717 new_path: Option<&Path>,
1718 events: &mut EditorEventWriter,
1719 ) -> Result<(), BufferWriteError> {
1720 let new_path = match new_path {
1721 Some(path) => {
1722 self.properties.saving_enabled = true;
1723 self.properties.file_backed_enabled = true;
1724 self.set_path(path);
1725 true
1726 }
1727 None => false,
1728 };
1729
1730 if !self.properties.saving_enabled {
1731 return Err(BufferWriteError::SavingDisabled);
1732 }
1733
1734 if self.properties.file_backed_enabled {
1735 let file = File::create(&self.path)?;
1736 self.content.write(&mut io::BufWriter::new(file))?;
1737 }
1738
1739 self.needs_save = false;
1740
1741 events.enqueue(EditorEvent::BufferWrite {
1742 handle: self.handle,
1743 new_path,
1744 });
1745 Ok(())
1746 }
1747}
1748
1749#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1750pub struct BufferHandle(pub u32);
1751
1752pub struct InsertProcess {
1753 pub alive: bool,
1754 pub handle: Option<PlatformProcessHandle>,
1755 pub buffer_handle: BufferHandle,
1756 pub position: BufferPosition,
1757 pub input: Option<PooledBuf>,
1758 pub output_residual_bytes: ResidualStrBytes,
1759}
1760
1761#[derive(Default)]
1762pub struct BufferCollection {
1763 buffers: Vec<Buffer>,
1764 insert_processes: Vec<InsertProcess>,
1765}
1766
1767impl BufferCollection {
1768 pub fn add_new(&mut self) -> &mut Buffer {
1769 let mut handle = None;
1770 for (i, buffer) in self.buffers.iter_mut().enumerate() {
1771 if !buffer.alive {
1772 handle = Some(BufferHandle(i as _));
1773 break;
1774 }
1775 }
1776 let handle = match handle {
1777 Some(handle) => handle,
1778 None => {
1779 let handle = BufferHandle(self.buffers.len() as _);
1780 self.buffers.push(Buffer::new(handle));
1781 handle
1782 }
1783 };
1784
1785 let buffer = &mut self.buffers[handle.0 as usize];
1786 buffer.alive = true;
1787 buffer
1788 }
1789
1790 pub fn try_get(&self, handle: BufferHandle) -> Option<&Buffer> {
1791 let index = handle.0 as usize;
1792 if self.buffers.len() <= index {
1793 return None;
1794 }
1795 let buffer = &self.buffers[index];
1796 if buffer.alive {
1797 Some(buffer)
1798 } else {
1799 None
1800 }
1801 }
1802
1803 pub fn get(&self, handle: BufferHandle) -> &Buffer {
1804 &self.buffers[handle.0 as usize]
1805 }
1806
1807 pub fn get_mut(&mut self, handle: BufferHandle) -> &mut Buffer {
1808 &mut self.buffers[handle.0 as usize]
1809 }
1810
1811 pub fn find_with_path(&self, buffers_root: &Path, path: &Path) -> Option<BufferHandle> {
1812 let mut components = path.components();
1813 let path = match components.next()? {
1814 Component::CurDir => components.as_path(),
1815 Component::RootDir | Component::Prefix(_) => match path.strip_prefix(buffers_root) {
1816 Ok(path) => path,
1817 Err(_) => path,
1818 },
1819 _ => path,
1820 };
1821
1822 for buffer in self.iter() {
1823 let buffer_path = buffer.path.as_path();
1824 let buffer_path = buffer_path
1825 .strip_prefix(buffers_root)
1826 .unwrap_or(buffer_path);
1827
1828 if buffer_path == path {
1829 return Some(buffer.handle());
1830 }
1831 }
1832
1833 None
1834 }
1835
1836 pub fn iter(&self) -> impl Iterator<Item = &Buffer> {
1837 self.buffers.iter().filter(|b| b.alive)
1838 }
1839
1840 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Buffer> {
1841 self.buffers.iter_mut().filter(|b| b.alive)
1842 }
1843
1844 pub fn defer_remove(&self, handle: BufferHandle, events: &mut EditorEventWriter) {
1845 let buffer = &self.buffers[handle.0 as usize];
1846 if buffer.alive {
1847 events.enqueue(EditorEvent::BufferClose { handle });
1848 }
1849 }
1850
1851 pub(crate) fn remove_now(
1852 &mut self,
1853 platform: &mut Platform,
1854 handle: BufferHandle,
1855 word_database: &mut WordDatabase,
1856 ) {
1857 let buffer = &mut self.buffers[handle.0 as usize];
1858 if buffer.alive {
1859 buffer.dispose(word_database);
1860 }
1861
1862 for process in &mut self.insert_processes {
1863 if process.buffer_handle != handle {
1864 continue;
1865 }
1866
1867 if let Some(handle) = process.handle.take() {
1868 platform
1869 .requests
1870 .enqueue(PlatformRequest::KillProcess { handle });
1871 }
1872 }
1873 }
1874
1875 pub(crate) fn on_buffer_text_inserts(
1876 &mut self,
1877 buffer_handle: BufferHandle,
1878 inserts: &[EditorEventTextInsert],
1879 events: &mut EditorEventWriter,
1880 ) {
1881 let buffer = self.get_mut(buffer_handle);
1882
1883 let mut breakpoints_changed = false;
1884 for insert in inserts {
1885 let range = insert.range;
1886 buffer.highlighted.insert_range(range);
1887 buffer.lints.insert_range(range);
1888 if buffer.breakpoints.insert_range(range) {
1889 breakpoints_changed = true;
1890 }
1891 }
1892
1893 if breakpoints_changed {
1894 events.enqueue(EditorEvent::BufferBreakpointsChanged {
1895 handle: buffer_handle,
1896 });
1897 }
1898
1899 for process in self.insert_processes.iter_mut() {
1900 if process.alive && process.buffer_handle == buffer_handle {
1901 let mut position = process.position;
1902 for insert in inserts {
1903 position = position.insert(insert.range);
1904 }
1905 process.position = position;
1906 }
1907 }
1908 }
1909
1910 pub(crate) fn on_buffer_range_deletes(
1911 &mut self,
1912 buffer_handle: BufferHandle,
1913 deletes: &[BufferRange],
1914 events: &mut EditorEventWriter,
1915 ) {
1916 let buffer = self.get_mut(buffer_handle);
1917
1918 let mut breakpoints_changed = false;
1919 for &range in deletes {
1920 buffer.highlighted.delete_range(range);
1921 buffer.lints.delete_range(range);
1922 if buffer.breakpoints.delete_range(range) {
1923 breakpoints_changed = true;
1924 }
1925 }
1926
1927 if breakpoints_changed {
1928 events.enqueue(EditorEvent::BufferBreakpointsChanged {
1929 handle: buffer_handle,
1930 });
1931 }
1932
1933 for process in self.insert_processes.iter_mut() {
1934 if process.alive && process.buffer_handle == buffer_handle {
1935 let mut position = process.position;
1936 for &range in deletes {
1937 position = position.delete(range);
1938 }
1939 process.position = position;
1940 }
1941 }
1942 }
1943
1944 pub fn spawn_insert_process(
1945 &mut self,
1946 platform: &mut Platform,
1947 mut command: Command,
1948 buffer_handle: BufferHandle,
1949 position: BufferPosition,
1950 input: Option<PooledBuf>,
1951 ) {
1952 let mut index = None;
1953 for (i, process) in self.insert_processes.iter_mut().enumerate() {
1954 if !process.alive {
1955 index = Some(i);
1956 break;
1957 }
1958 }
1959 let index = match index {
1960 Some(index) => index,
1961 None => {
1962 let index = self.insert_processes.len();
1963 self.insert_processes.push(InsertProcess {
1964 alive: false,
1965 handle: None,
1966 buffer_handle,
1967 position,
1968 input: None,
1969 output_residual_bytes: ResidualStrBytes::default(),
1970 });
1971 index
1972 }
1973 };
1974
1975 let process = &mut self.insert_processes[index];
1976 process.alive = true;
1977 process.handle = None;
1978 process.buffer_handle = buffer_handle;
1979 process.position = position;
1980 process.input = input;
1981 process.output_residual_bytes = ResidualStrBytes::default();
1982
1983 let stdin = match &process.input {
1984 Some(_) => Stdio::piped(),
1985 None => Stdio::null(),
1986 };
1987
1988 command.stdin(stdin);
1989 command.stdout(Stdio::piped());
1990 command.stderr(Stdio::null());
1991
1992 platform.requests.enqueue(PlatformRequest::SpawnProcess {
1993 tag: ProcessTag::Buffer(index as _),
1994 command,
1995 buf_len: 4 * 1024,
1996 });
1997 }
1998
1999 pub(crate) fn on_process_spawned(
2000 &mut self,
2001 platform: &mut Platform,
2002 index: u32,
2003 handle: PlatformProcessHandle,
2004 ) {
2005 let process = &mut self.insert_processes[index as usize];
2006 process.handle = Some(handle);
2007
2008 if let Some(buf) = process.input.take() {
2009 platform
2010 .requests
2011 .enqueue(PlatformRequest::WriteToProcess { handle, buf });
2012 platform
2013 .requests
2014 .enqueue(PlatformRequest::CloseProcessInput { handle });
2015 }
2016 }
2017
2018 pub(crate) fn on_process_output(
2019 &mut self,
2020 word_database: &mut WordDatabase,
2021 index: u32,
2022 bytes: &[u8],
2023 events: &mut EditorEventWriter,
2024 ) {
2025 let process = &mut self.insert_processes[index as usize];
2026 if process.handle.is_none() {
2027 return;
2028 }
2029
2030 let mut buf = Default::default();
2031 let texts = process.output_residual_bytes.receive_bytes(&mut buf, bytes);
2032
2033 let buffer = &mut self.buffers[process.buffer_handle.0 as usize];
2034 let mut events = events.buffer_text_inserts_mut_guard(buffer.handle());
2035 let mut position = process.position;
2036 for text in texts {
2037 let insert_range = buffer.insert_text(word_database, position, text, &mut events);
2038 position = position.insert(insert_range);
2039 }
2040 buffer.commit_edits();
2041 }
2042
2043 pub(crate) fn on_process_exit(
2044 &mut self,
2045 word_database: &mut WordDatabase,
2046 index: u32,
2047 events: &mut EditorEventWriter,
2048 ) {
2049 self.on_process_output(word_database, index, &[], events);
2050 let process = &mut self.insert_processes[index as usize];
2051 process.alive = false;
2052 process.handle = None;
2053 }
2054}
2055
2056#[cfg(test)]
2057mod tests {
2058 use super::*;
2059 use crate::{buffer_position::BufferPosition, events::EditorEventQueue};
2060
2061 #[test]
2062 fn display_distance() {
2063 fn display_len(text: &str) -> usize {
2064 CharDisplayDistances::new(text, 4)
2065 .last()
2066 .map(|d| d.distance as _)
2067 .unwrap_or(0)
2068 }
2069
2070 assert_eq!(0, display_len(""));
2071 assert_eq!(1, display_len("a"));
2072 assert_eq!(1, display_len("é"));
2073 assert_eq!(4, display_len(" "));
2074 assert_eq!(4, display_len("\t"));
2075 assert_eq!(8, display_len("\t\t"));
2076 assert_eq!(8, display_len(" \t"));
2077 assert_eq!(5, display_len("x\t"));
2078 assert_eq!(6, display_len("xx\t"));
2079 assert_eq!(7, display_len("xxx\t"));
2080 assert_eq!(8, display_len("xxxx\t"));
2081 }
2082
2083 fn buffer_from_str(text: &str) -> BufferContent {
2084 let mut buffer = BufferContent::new();
2085 buffer.insert_text(BufferPosition::zero(), text);
2086 buffer
2087 }
2088
2089 #[test]
2090 fn buffer_utf8_support() {
2091 let mut buffer = buffer_from_str("abd");
2092 let range = buffer.insert_text(BufferPosition::line_col(0, 2), "ç");
2093 assert_eq!(
2094 BufferRange::between(
2095 BufferPosition::line_col(0, 2),
2096 BufferPosition::line_col(0, (2 + 'ç'.len_utf8()) as _)
2097 ),
2098 range
2099 );
2100 }
2101
2102 #[test]
2103 fn buffer_content_insert_text() {
2104 let mut buffer = BufferContent::new();
2105
2106 assert_eq!(1, buffer.lines().len());
2107 assert_eq!("", buffer.to_string());
2108
2109 buffer.insert_text(BufferPosition::line_col(0, 0), "hold");
2110 buffer.insert_text(BufferPosition::line_col(0, 2), "r");
2111 buffer.insert_text(BufferPosition::line_col(0, 1), "ello w");
2112 assert_eq!(1, buffer.lines().len());
2113 assert_eq!("hello world", buffer.to_string());
2114
2115 buffer.insert_text(BufferPosition::line_col(0, 5), "\n");
2116 buffer.insert_text(
2117 BufferPosition::line_col(1, 6),
2118 " appending more\nand more\nand even more\nlines",
2119 );
2120 assert_eq!(5, buffer.lines().len());
2121 assert_eq!(
2122 "hello\n world appending more\nand more\nand even more\nlines",
2123 buffer.to_string()
2124 );
2125
2126 let mut buffer = buffer_from_str("this is content");
2127 buffer.insert_text(BufferPosition::line_col(0, 8), "some\nmultiline ");
2128 assert_eq!(2, buffer.lines().len());
2129 assert_eq!("this is some\nmultiline content", buffer.to_string());
2130
2131 let mut buffer = buffer_from_str("this is content");
2132 buffer.insert_text(
2133 BufferPosition::line_col(0, 8),
2134 "some\nmore\nextensive\nmultiline ",
2135 );
2136 assert_eq!(4, buffer.lines().len());
2137 assert_eq!(
2138 "this is some\nmore\nextensive\nmultiline content",
2139 buffer.to_string()
2140 );
2141
2142 let mut buffer = buffer_from_str("abc");
2143 let range = buffer.insert_text(BufferPosition::line_col(0, 3), "\n");
2144 assert_eq!(
2145 BufferRange::between(
2146 BufferPosition::line_col(0, 3),
2147 BufferPosition::line_col(1, 0)
2148 ),
2149 range
2150 );
2151 }
2152
2153 #[test]
2154 fn buffer_content_delete_range() {
2155 let mut buffer = buffer_from_str("abc");
2156 buffer.delete_range(BufferRange::between(
2157 BufferPosition::line_col(0, 1),
2158 BufferPosition::line_col(0, 1),
2159 ));
2160 assert_eq!("abc", buffer.to_string());
2161 buffer.delete_range(BufferRange::between(
2162 BufferPosition::line_col(0, 1),
2163 BufferPosition::line_col(0, 2),
2164 ));
2165 assert_eq!("ac", buffer.to_string());
2166
2167 let mut buffer = buffer_from_str("this is the initial\ncontent of the buffer");
2168
2169 assert_eq!(2, buffer.lines().len());
2170 assert_eq!(
2171 "this is the initial\ncontent of the buffer",
2172 buffer.to_string()
2173 );
2174
2175 buffer.delete_range(BufferRange::between(
2176 BufferPosition::zero(),
2177 BufferPosition::zero(),
2178 ));
2179 assert_eq!(2, buffer.lines().len());
2180 assert_eq!(
2181 "this is the initial\ncontent of the buffer",
2182 buffer.to_string()
2183 );
2184
2185 buffer.delete_range(BufferRange::between(
2186 BufferPosition::line_col(0, 11),
2187 BufferPosition::line_col(0, 19),
2188 ));
2189 assert_eq!(2, buffer.lines().len());
2190 assert_eq!("this is the\ncontent of the buffer", buffer.to_string());
2191
2192 buffer.delete_range(BufferRange::between(
2193 BufferPosition::line_col(0, 8),
2194 BufferPosition::line_col(1, 15),
2195 ));
2196 assert_eq!(1, buffer.lines().len());
2197 assert_eq!("this is buffer", buffer.to_string());
2198
2199 let mut buffer = buffer_from_str("this\nbuffer\ncontains\nmultiple\nlines\nyes");
2200 assert_eq!(6, buffer.lines().len());
2201 buffer.delete_range(BufferRange::between(
2202 BufferPosition::line_col(1, 4),
2203 BufferPosition::line_col(4, 1),
2204 ));
2205 assert_eq!("this\nbuffines\nyes", buffer.to_string());
2206 }
2207
2208 #[test]
2209 fn buffer_content_delete_lines() {
2210 let mut buffer = buffer_from_str("first line\nsecond line\nthird line");
2211 assert_eq!(3, buffer.lines().len());
2212 buffer.delete_range(BufferRange::between(
2213 BufferPosition::line_col(1, 0),
2214 BufferPosition::line_col(2, 0),
2215 ));
2216 assert_eq!("first line\nthird line", buffer.to_string());
2217
2218 let mut buffer = buffer_from_str("first line\nsecond line\nthird line");
2219 assert_eq!(3, buffer.lines().len());
2220 buffer.delete_range(BufferRange::between(
2221 BufferPosition::line_col(1, 0),
2222 BufferPosition::line_col(1, 11),
2223 ));
2224 assert_eq!("first line\n\nthird line", buffer.to_string());
2225 }
2226
2227 #[test]
2228 fn buffer_delete_undo_redo_single_line() {
2229 let mut word_database = WordDatabase::new();
2230 let mut events = EditorEventQueue::default();
2231
2232 let mut buffer = Buffer::new(BufferHandle(0));
2233 buffer.properties = BufferProperties::text();
2234 buffer.insert_text(
2235 &mut word_database,
2236 BufferPosition::zero(),
2237 "single line content",
2238 &mut events
2239 .writer()
2240 .buffer_text_inserts_mut_guard(buffer.handle()),
2241 );
2242 let range = BufferRange::between(
2243 BufferPosition::line_col(0, 7),
2244 BufferPosition::line_col(0, 12),
2245 );
2246 buffer.delete_range(
2247 &mut word_database,
2248 range,
2249 &mut events
2250 .writer()
2251 .buffer_range_deletes_mut_guard(buffer.handle()),
2252 );
2253
2254 assert_eq!("single content", buffer.content.to_string());
2255 {
2256 let mut ranges = buffer.undo(&mut word_database, &mut events.writer());
2257 assert_eq!(range, ranges.next().unwrap().range);
2258 ranges.next().unwrap();
2259 assert!(ranges.next().is_none());
2260 }
2261 assert!(buffer.content.to_string().is_empty());
2262 let mut redo_iter = buffer.redo(&mut word_database, &mut events.writer());
2263 redo_iter.next().unwrap();
2264 redo_iter.next().unwrap();
2265 assert!(redo_iter.next().is_none());
2266 drop(redo_iter);
2267 assert_eq!("single content", buffer.content.to_string());
2268 }
2269
2270 #[test]
2271 fn buffer_delete_undo_redo_multi_line() {
2272 let mut word_database = WordDatabase::new();
2273 let mut events = EditorEventQueue::default();
2274
2275 let mut buffer = Buffer::new(BufferHandle(0));
2276 buffer.properties = BufferProperties::text();
2277 let insert_range = buffer.insert_text(
2278 &mut word_database,
2279 BufferPosition::zero(),
2280 "multi\nline\ncontent",
2281 &mut events
2282 .writer()
2283 .buffer_text_inserts_mut_guard(buffer.handle()),
2284 );
2285 assert_eq!("multi\nline\ncontent", buffer.content.to_string());
2286
2287 let delete_range = BufferRange::between(
2288 BufferPosition::line_col(0, 1),
2289 BufferPosition::line_col(1, 3),
2290 );
2291 buffer.delete_range(
2292 &mut word_database,
2293 delete_range,
2294 &mut events
2295 .writer()
2296 .buffer_range_deletes_mut_guard(buffer.handle()),
2297 );
2298 assert_eq!("me\ncontent", buffer.content.to_string());
2299
2300 {
2301 let mut undo_edits = buffer.undo(&mut word_database, &mut events.writer());
2302 assert_eq!(delete_range, undo_edits.next().unwrap().range);
2303 assert_eq!(insert_range, undo_edits.next().unwrap().range);
2304 assert!(undo_edits.next().is_none());
2305 }
2306 assert_eq!("", buffer.content.to_string());
2307
2308 {
2309 let mut redo_edits = buffer.redo(&mut word_database, &mut events.writer());
2310 redo_edits.next().unwrap();
2311 redo_edits.next().unwrap();
2312 assert!(redo_edits.next().is_none());
2313 }
2314 assert_eq!("me\ncontent", buffer.content.to_string());
2315 }
2316
2317 #[test]
2318 fn buffer_insert_delete_forward_insert_undo() {
2319 let mut word_database = WordDatabase::new();
2320 let mut events = EditorEventQueue::default();
2321
2322 let mut buffer = Buffer::new(BufferHandle(0));
2323 buffer.properties = BufferProperties::text();
2324 let insert_range = buffer.insert_text(
2325 &mut word_database,
2326 BufferPosition::zero(),
2327 "\n",
2328 &mut events
2329 .writer()
2330 .buffer_text_inserts_mut_guard(buffer.handle()),
2331 );
2332 let assert_range = BufferRange::between(
2333 BufferPosition::line_col(0, 0),
2334 BufferPosition::line_col(1, 0),
2335 );
2336 assert_eq!(assert_range, insert_range);
2337
2338 buffer.commit_edits();
2339 assert_eq!("\n", buffer.content.to_string());
2340
2341 let insert_range = buffer.insert_text(
2342 &mut word_database,
2343 BufferPosition::zero(),
2344 "a",
2345 &mut events
2346 .writer()
2347 .buffer_text_inserts_mut_guard(buffer.handle()),
2348 );
2349 let assert_range = BufferRange::between(
2350 BufferPosition::line_col(0, 0),
2351 BufferPosition::line_col(0, 1),
2352 );
2353 assert_eq!(assert_range, insert_range);
2354
2355 buffer.delete_range(
2356 &mut word_database,
2357 BufferRange::between(
2358 BufferPosition::line_col(0, 1),
2359 BufferPosition::line_col(1, 0),
2360 ),
2361 &mut events
2362 .writer()
2363 .buffer_range_deletes_mut_guard(buffer.handle()),
2364 );
2365
2366 let insert_range = buffer.insert_text(
2367 &mut word_database,
2368 BufferPosition::line_col(0, 1),
2369 "b",
2370 &mut events
2371 .writer()
2372 .buffer_text_inserts_mut_guard(buffer.handle()),
2373 );
2374 let assert_range = BufferRange::between(
2375 BufferPosition::line_col(0, 1),
2376 BufferPosition::line_col(0, 2),
2377 );
2378 assert_eq!(assert_range, insert_range);
2379
2380 let ranges = buffer.undo(&mut word_database, &mut events.writer());
2381 for _ in ranges {}
2382 }
2383
2384 #[test]
2385 fn buffer_content_text_range() {
2386 let buffer = buffer_from_str("abc\ndef\nghi");
2387 let range = BufferRange::between(
2388 BufferPosition::line_col(0, 2),
2389 BufferPosition::line_col(2, 1),
2390 );
2391
2392 let mut text_range = buffer.text_range(range);
2393 assert_eq!(Some("c"), text_range.next());
2394 assert_eq!(Some("\n"), text_range.next());
2395 assert_eq!(Some("def"), text_range.next());
2396 assert_eq!(Some("\n"), text_range.next());
2397 assert_eq!(Some("g"), text_range.next());
2398 assert_eq!(None, text_range.next());
2399 }
2400
2401 #[test]
2402 fn buffer_content_word_at() {
2403 fn col(column: usize) -> BufferPosition {
2404 BufferPosition::line_col(0, column as _)
2405 }
2406
2407 fn assert_word(word: WordRefWithPosition, pos: BufferPosition, kind: WordKind, text: &str) {
2408 assert_eq!(pos, word.position);
2409 assert_eq!(kind, word.kind);
2410 assert_eq!(text, word.text);
2411 }
2412
2413 let buffer = buffer_from_str("word");
2414 assert_word(buffer.word_at(col(0)), col(0), WordKind::Identifier, "word");
2415 assert_word(buffer.word_at(col(2)), col(0), WordKind::Identifier, "word");
2416 assert_word(buffer.word_at(col(4)), col(4), WordKind::Whitespace, "");
2417
2418 let buffer = buffer_from_str("asd word+? asd");
2419 assert_word(buffer.word_at(col(3)), col(3), WordKind::Whitespace, " ");
2420 assert_word(buffer.word_at(col(4)), col(4), WordKind::Identifier, "word");
2421 assert_word(buffer.word_at(col(6)), col(4), WordKind::Identifier, "word");
2422 assert_word(buffer.word_at(col(8)), col(8), WordKind::Symbol, "+?");
2423 assert_word(buffer.word_at(col(9)), col(8), WordKind::Symbol, "+?");
2424 assert_word(buffer.word_at(col(10)), col(10), WordKind::Whitespace, " ");
2425 }
2426
2427 #[test]
2428 fn buffer_content_words_from() {
2429 fn col(column: usize) -> BufferPosition {
2430 BufferPosition::line_col(0, column as _)
2431 }
2432
2433 fn assert_word(word: WordRefWithPosition, pos: BufferPosition, kind: WordKind, text: &str) {
2434 assert_eq!(pos, word.position);
2435 assert_eq!(kind, word.kind);
2436 assert_eq!(text, word.text);
2437 }
2438
2439 let buffer = buffer_from_str("word");
2440 let (w, mut lw, mut rw) = buffer.words_from(col(0));
2441 assert_word(w, col(0), WordKind::Identifier, "word");
2442 assert!(lw.next().is_none());
2443 assert!(rw.next().is_none());
2444 let (w, mut lw, mut rw) = buffer.words_from(col(2));
2445 assert_word(w, col(0), WordKind::Identifier, "word");
2446 assert!(lw.next().is_none());
2447 assert!(rw.next().is_none());
2448 let (w, mut lw, mut rw) = buffer.words_from(col(4));
2449 assert_word(w, col(4), WordKind::Whitespace, "");
2450 assert_word(lw.next().unwrap(), col(0), WordKind::Identifier, "word");
2451 assert!(lw.next().is_none());
2452 assert!(rw.next().is_none());
2453
2454 let buffer = buffer_from_str("first second third");
2455 let (w, mut lw, mut rw) = buffer.words_from(col(8));
2456 assert_word(w, col(6), WordKind::Identifier, "second");
2457 assert_word(lw.next().unwrap(), col(5), WordKind::Whitespace, " ");
2458 assert_word(lw.next().unwrap(), col(0), WordKind::Identifier, "first");
2459 assert!(lw.next().is_none());
2460 assert_word(rw.next().unwrap(), col(12), WordKind::Whitespace, " ");
2461 assert_word(rw.next().unwrap(), col(13), WordKind::Identifier, "third");
2462 assert!(rw.next().is_none());
2463 }
2464
2465 #[test]
2466 fn buffer_find_balanced_chars() {
2467 let buffer = buffer_from_str("(\n(\na\n)\nbc)");
2468
2469 assert_eq!(
2470 Some(BufferRange::between(
2471 BufferPosition::line_col(0, 1),
2472 BufferPosition::line_col(4, 2)
2473 )),
2474 buffer.find_balanced_chars_at(BufferPosition::line_col(0, 0), '(', ')')
2475 );
2476 assert_eq!(
2477 Some(BufferRange::between(
2478 BufferPosition::line_col(1, 1),
2479 BufferPosition::line_col(3, 0)
2480 )),
2481 buffer.find_balanced_chars_at(BufferPosition::line_col(2, 0), '(', ')')
2482 );
2483 assert_eq!(
2484 Some(BufferRange::between(
2485 BufferPosition::line_col(0, 1),
2486 BufferPosition::line_col(4, 2)
2487 )),
2488 buffer.find_balanced_chars_at(BufferPosition::line_col(0, 1), '(', ')')
2489 );
2490 assert_eq!(
2491 Some(BufferRange::between(
2492 BufferPosition::line_col(0, 1),
2493 BufferPosition::line_col(4, 2)
2494 )),
2495 buffer.find_balanced_chars_at(BufferPosition::line_col(4, 0), '(', ')')
2496 );
2497 assert_eq!(
2498 Some(BufferRange::between(
2499 BufferPosition::line_col(0, 1),
2500 BufferPosition::line_col(4, 2)
2501 )),
2502 buffer.find_balanced_chars_at(BufferPosition::line_col(0, 0), '(', ')')
2503 );
2504 assert_eq!(
2505 Some(BufferRange::between(
2506 BufferPosition::line_col(0, 1),
2507 BufferPosition::line_col(4, 2)
2508 )),
2509 buffer.find_balanced_chars_at(BufferPosition::line_col(4, 2), '(', ')')
2510 );
2511 }
2512
2513 #[test]
2514 fn buffer_display_len() {
2515 fn len(buffer: &BufferContent, line: usize) -> usize {
2516 buffer.line_display_lens()[line].total_len(4)
2517 }
2518
2519 let mut buffer = buffer_from_str("abc\tdef");
2520
2521 assert_eq!(10, len(&buffer, 0));
2522
2523 buffer.insert_text(BufferPosition::line_col(0, 3), "\n");
2524
2525 assert_eq!(3, len(&buffer, 0));
2526 assert_eq!(7, len(&buffer, 1));
2527
2528 buffer.insert_text(BufferPosition::line_col(1, 3), "\n");
2529
2530 assert_eq!(3, len(&buffer, 0));
2531 assert_eq!(6, len(&buffer, 1));
2532 assert_eq!(1, len(&buffer, 2));
2533
2534 buffer.insert_text(BufferPosition::line_col(2, 0), "xx");
2535
2536 assert_eq!(3, len(&buffer, 0));
2537 assert_eq!(6, len(&buffer, 1));
2538 assert_eq!(3, len(&buffer, 2));
2539
2540 buffer.delete_range(BufferRange::between(
2541 BufferPosition::zero(),
2542 BufferPosition::line_col(0, 3),
2543 ));
2544
2545 assert_eq!(0, len(&buffer, 0));
2546 assert_eq!(6, len(&buffer, 1));
2547 assert_eq!(3, len(&buffer, 2));
2548 }
2549
2550 #[test]
2551 fn buffer_fix_line_indentation() {
2552 fn new_buffer(text: &str) -> Buffer {
2553 let handle = BufferHandle(0);
2554 let mut buffer = Buffer::new(handle);
2555 let mut word_database = WordDatabase::new();
2556 let mut events = EditorEventQueue::default();
2557 let mut events = events.writer().buffer_text_inserts_mut_guard(handle);
2558 buffer.insert_text(
2559 &mut word_database,
2560 BufferPosition::zero(),
2561 text,
2562 &mut events,
2563 );
2564 buffer
2565 }
2566
2567 let mut events = EditorEventQueue::default();
2568 let mut events = BufferEditMutGuard::new(events.writer(), BufferHandle(0));
2569
2570 let indentation_config = BufferIndentationConfig {
2571 tab_size: 4,
2572 indent_with_tabs: true,
2573 };
2574
2575 let mut buffer = new_buffer("");
2576 buffer.fix_line_indentation(indentation_config, 0, &mut events);
2577 assert_eq!("", buffer.content().lines()[0].as_str());
2578
2579 let mut buffer = new_buffer("first\nsecond");
2580 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2581 assert_eq!("second", buffer.content().lines()[1].as_str());
2582
2583 let mut buffer = new_buffer("\tfirst\nsecond");
2584 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2585 assert_eq!("\tsecond", buffer.content().lines()[1].as_str());
2586
2587 let mut buffer = new_buffer("\tfirst\n second");
2588 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2589 assert_eq!("\tsecond", buffer.content().lines()[1].as_str());
2590
2591 let mut buffer = new_buffer("\t\tfirst\n \tsecond");
2592 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2593 assert_eq!("\t\tsecond", buffer.content().lines()[1].as_str());
2594
2595 let mut buffer = new_buffer("\t\tfirst\n\t second");
2596 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2597 assert_eq!("\t\tsecond", buffer.content().lines()[1].as_str());
2598
2599 let mut buffer = new_buffer("\t\tfirst }\n second");
2600 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2601 assert_eq!("\t\tsecond", buffer.content().lines()[1].as_str());
2602
2603 let mut buffer = new_buffer("\t\tfirst } {}\n second");
2604 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2605 assert_eq!("\t\tsecond", buffer.content().lines()[1].as_str());
2606
2607 let mut buffer = new_buffer("\t\tfirst {}\n second");
2608 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2609 assert_eq!("\t\tsecond", buffer.content().lines()[1].as_str());
2610
2611 let mut buffer = new_buffer("\t\tfirst { ( }\n second");
2612 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2613 assert_eq!("\t\tsecond", buffer.content().lines()[1].as_str());
2614
2615 let mut buffer = new_buffer("\t\tfirst {\n second");
2616 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2617 assert_eq!("\t\t\tsecond", buffer.content().lines()[1].as_str());
2618
2619 let mut buffer = new_buffer("\t\t{\n second");
2620 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2621 assert_eq!("\t\t\tsecond", buffer.content().lines()[1].as_str());
2622
2623 let mut buffer = new_buffer("{\n second");
2624 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2625 assert_eq!("\tsecond", buffer.content().lines()[1].as_str());
2626
2627 let mut buffer = new_buffer("{}()[\n second");
2628 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2629 assert_eq!("\tsecond", buffer.content().lines()[1].as_str());
2630
2631 let mut buffer = new_buffer("{}()[]>\n second");
2632 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2633 assert_eq!("second", buffer.content().lines()[1].as_str());
2634
2635 let mut buffer = new_buffer("\t\n\t");
2636 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2637 assert_eq!("", buffer.content().lines()[1].as_str());
2638
2639 let mut buffer = new_buffer("\t\n ");
2640 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2641 assert_eq!("", buffer.content().lines()[1].as_str());
2642
2643 let mut buffer = new_buffer("{\n}");
2644 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2645 assert_eq!("}", buffer.content().lines()[1].as_str());
2646
2647 let mut buffer = new_buffer("\t{}\n}");
2648 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2649 assert_eq!("}", buffer.content().lines()[1].as_str());
2650
2651 let mut buffer = new_buffer("first\n}");
2652 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2653 assert_eq!("}", buffer.content().lines()[1].as_str());
2654
2655 let mut buffer = new_buffer("{{\n}");
2656 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2657 assert_eq!("}", buffer.content().lines()[1].as_str());
2658
2659 let mut buffer = new_buffer("\tfirst\n\nsecond");
2660 buffer.fix_line_indentation(indentation_config, 2, &mut events);
2661 assert_eq!("\tsecond", buffer.content().lines()[2].as_str());
2662
2663 let indentation_config = BufferIndentationConfig {
2664 tab_size: 4,
2665 indent_with_tabs: false,
2666 };
2667
2668 let mut buffer = new_buffer("\tfirst\n second");
2669 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2670 assert_eq!(" second", buffer.content().lines()[1].as_str());
2671
2672 let mut buffer = new_buffer(" first\n second");
2673 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2674 assert_eq!(" second", buffer.content().lines()[1].as_str());
2675
2676 let mut buffer = new_buffer(" first\n second");
2677 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2678 assert_eq!(" second", buffer.content().lines()[1].as_str());
2679
2680 let mut buffer = new_buffer(" first\n second");
2681 buffer.fix_line_indentation(indentation_config, 1, &mut events);
2682 assert_eq!(" second", buffer.content().lines()[1].as_str());
2683 }
2684}