pepper/
buffer.rs

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
28// TODO: parse unicode database and implement this
29// reference algorithm: https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
30pub 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}