Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:53:25.446Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

buffer.rs

6306 lines · 233.1 KB · rust
1pub mod row_chunk;
2
3use crate::{
4    ByteContent, DebuggerTextObject, LanguageScope, ModelineSettings, Outline, OutlineConfig,
5    PLAIN_TEXT, RunnableTag, TextObject, TreeSitterOptions, analyze_byte_content,
6    diagnostic_set::{DiagnosticEntry, DiagnosticEntryRef, DiagnosticGroup},
7    language_settings::{AutoIndentMode, LanguageSettings},
8    outline::OutlineItem,
9    row_chunk::RowChunks,
10    runnable::{self, RunnableRange},
11    syntax_map::{
12        MAX_BYTES_TO_QUERY, SyntaxLayer, SyntaxMap, SyntaxMapCapture, SyntaxMapCaptures,
13        SyntaxMapMatch, SyntaxMapMatches, SyntaxSnapshot, ToTreeSitterPoint,
14    },
15    text_diff::text_diff,
16    unified_diff_with_offsets,
17};
18pub use crate::{
19    Grammar, HighlightId, HighlightMap, Language, LanguageRegistry, diagnostic_set::DiagnosticSet,
20    proto,
21};
22
23use anyhow::{Context as _, Result};
24use clock::Lamport;
25pub use clock::ReplicaId;
26use collections::{HashMap, HashSet};
27use encoding_rs::Encoding;
28use fs::MTime;
29use futures::channel::oneshot;
30use futures_lite::future::yield_now;
31use gpui::{
32    App, AppContext as _, Context, Entity, EventEmitter, HighlightStyle, SharedString, StyledText,
33    Task, TextStyle,
34};
35
36use lsp::LanguageServerId;
37use parking_lot::Mutex;
38use settings::WorktreeId;
39use smallvec::SmallVec;
40use std::{
41    any::Any,
42    borrow::Cow,
43    cell::Cell,
44    cmp::{self, Ordering, Reverse},
45    collections::{BTreeMap, BTreeSet},
46    fmt::Write as _,
47    future::Future,
48    iter::{self, Iterator, Peekable},
49    mem,
50    num::NonZeroU32,
51    ops::{Deref, Range},
52    path::PathBuf,
53    rc,
54    sync::Arc,
55    time::{Duration, Instant},
56    vec,
57};
58use sum_tree::TreeMap;
59use text::operation_queue::OperationQueue;
60use text::*;
61pub use text::{
62    Anchor, Bias, Buffer as TextBuffer, BufferId, BufferSnapshot as TextBufferSnapshot, Edit,
63    LineIndent, OffsetRangeExt, OffsetUtf16, Patch, Point, PointUtf16, Rope, Selection,
64    SelectionGoal, Subscription, TextDimension, TextSummary, ToOffset, ToOffsetUtf16, ToPoint,
65    ToPointUtf16, Transaction, TransactionId, Unclipped,
66};
67use theme::{ActiveTheme as _, SyntaxTheme};
68#[cfg(any(test, feature = "test-support"))]
69use util::RandomCharIter;
70use util::{RangeExt, debug_panic, maybe, paths::PathStyle, rel_path::RelPath};
71
72#[cfg(any(test, feature = "test-support"))]
73pub use {tree_sitter_python, tree_sitter_rust, tree_sitter_typescript};
74
75pub use lsp::DiagnosticSeverity;
76
77/// Indicate whether a [`Buffer`] has permissions to edit.
78#[derive(PartialEq, Clone, Copy, Debug)]
79pub enum Capability {
80    /// The buffer is a mutable replica.
81    ReadWrite,
82    /// The buffer is a mutable replica, but toggled to be only readable.
83    Read,
84    /// The buffer is a read-only replica.
85    ReadOnly,
86}
87
88impl Capability {
89    /// Returns `true` if the capability is `ReadWrite`.
90    pub fn editable(self) -> bool {
91        matches!(self, Capability::ReadWrite)
92    }
93}
94
95pub type BufferRow = u32;
96
97/// An in-memory representation of a source code file, including its text,
98/// syntax trees, git status, and diagnostics.
99pub struct Buffer {
100    text: TextBuffer,
101    branch_state: Option<BufferBranchState>,
102    /// Filesystem state, `None` when there is no path.
103    file: Option<Arc<dyn File>>,
104    /// The mtime of the file when this buffer was last loaded from
105    /// or saved to disk.
106    saved_mtime: Option<MTime>,
107    /// The version vector when this buffer was last loaded from
108    /// or saved to disk.
109    saved_version: clock::Global,
110    preview_version: clock::Global,
111    transaction_depth: usize,
112    was_dirty_before_starting_transaction: Option<bool>,
113    reload_task: Option<Task<Result<()>>>,
114    language: Option<Arc<Language>>,
115    autoindent_requests: Vec<Arc<AutoindentRequest>>,
116    wait_for_autoindent_txs: Vec<oneshot::Sender<()>>,
117    pending_autoindent: Option<Task<()>>,
118    sync_parse_timeout: Option<Duration>,
119    syntax_map: Mutex<SyntaxMap>,
120    reparse: Option<Task<()>>,
121    parse_status: (watch::Sender<ParseStatus>, watch::Receiver<ParseStatus>),
122    non_text_state_update_count: usize,
123    diagnostics: TreeMap<LanguageServerId, DiagnosticSet>,
124    remote_selections: TreeMap<ReplicaId, SelectionSet>,
125    diagnostics_timestamp: clock::Lamport,
126    completion_triggers: BTreeSet<String>,
127    completion_triggers_per_language_server: HashMap<LanguageServerId, BTreeSet<String>>,
128    completion_triggers_timestamp: clock::Lamport,
129    deferred_ops: OperationQueue<Operation>,
130    capability: Capability,
131    has_conflict: bool,
132    /// Memoize calls to has_changes_since(saved_version).
133    /// The contents of a cell are (self.version, has_changes) at the time of a last call.
134    has_unsaved_edits: Cell<(clock::Global, bool)>,
135    change_bits: Vec<rc::Weak<Cell<bool>>>,
136    modeline: Option<Arc<ModelineSettings>>,
137    _subscriptions: Vec<gpui::Subscription>,
138    tree_sitter_data: Arc<TreeSitterData>,
139    encoding: &'static Encoding,
140    has_bom: bool,
141    reload_with_encoding_txns: HashMap<TransactionId, (&'static Encoding, bool)>,
142}
143
144#[derive(Debug)]
145pub struct TreeSitterData {
146    chunks: RowChunks,
147    brackets_by_chunks: Mutex<HashMap<usize, Vec<BracketMatch<usize>>>>,
148}
149
150const MAX_ROWS_IN_A_CHUNK: u32 = 50;
151
152impl TreeSitterData {
153    fn clear(&mut self, snapshot: &text::BufferSnapshot) {
154        self.chunks = RowChunks::new(snapshot, MAX_ROWS_IN_A_CHUNK);
155        self.brackets_by_chunks.get_mut().clear();
156    }
157
158    fn new(snapshot: &text::BufferSnapshot) -> Self {
159        Self {
160            chunks: RowChunks::new(snapshot, MAX_ROWS_IN_A_CHUNK),
161            brackets_by_chunks: Mutex::new(HashMap::default()),
162        }
163    }
164
165    fn version(&self) -> &clock::Global {
166        self.chunks.version()
167    }
168}
169
170#[derive(Copy, Clone, Debug, PartialEq, Eq)]
171pub enum ParseStatus {
172    Idle,
173    Parsing,
174}
175
176struct BufferBranchState {
177    base_buffer: Entity<Buffer>,
178    merged_operations: Vec<Lamport>,
179}
180
181/// An immutable, cheaply cloneable representation of a fixed
182/// state of a buffer.
183pub struct BufferSnapshot {
184    pub text: text::BufferSnapshot,
185    pub(crate) syntax: SyntaxSnapshot,
186    tree_sitter_data: Arc<TreeSitterData>,
187    diagnostics: TreeMap<LanguageServerId, DiagnosticSet>,
188    remote_selections: TreeMap<ReplicaId, SelectionSet>,
189    language: Option<Arc<Language>>,
190    file: Option<Arc<dyn File>>,
191    non_text_state_update_count: usize,
192    pub capability: Capability,
193    modeline: Option<Arc<ModelineSettings>>,
194}
195
196/// The kind and amount of indentation in a particular line. For now,
197/// assumes that indentation is all the same character.
198#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
199pub struct IndentSize {
200    /// The number of bytes that comprise the indentation.
201    pub len: u32,
202    /// The kind of whitespace used for indentation.
203    pub kind: IndentKind,
204}
205
206/// A whitespace character that's used for indentation.
207#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
208pub enum IndentKind {
209    /// An ASCII space character.
210    #[default]
211    Space,
212    /// An ASCII tab character.
213    Tab,
214}
215
216/// The shape of a selection cursor.
217#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
218pub enum CursorShape {
219    /// A vertical bar
220    #[default]
221    Bar,
222    /// A block that surrounds the following character
223    Block,
224    /// An underline that runs along the following character
225    Underline,
226    /// A box drawn around the following character
227    Hollow,
228}
229
230impl From<settings::CursorShape> for CursorShape {
231    fn from(shape: settings::CursorShape) -> Self {
232        match shape {
233            settings::CursorShape::Bar => CursorShape::Bar,
234            settings::CursorShape::Block => CursorShape::Block,
235            settings::CursorShape::Underline => CursorShape::Underline,
236            settings::CursorShape::Hollow => CursorShape::Hollow,
237        }
238    }
239}
240
241#[derive(Clone, Debug)]
242struct SelectionSet {
243    line_mode: bool,
244    cursor_shape: CursorShape,
245    selections: Arc<[Selection<Anchor>]>,
246    lamport_timestamp: clock::Lamport,
247}
248
249/// An operation used to synchronize this buffer with its other replicas.
250#[derive(Clone, Debug, PartialEq)]
251pub enum Operation {
252    /// A text operation.
253    Buffer(text::Operation),
254
255    /// An update to the buffer's diagnostics.
256    UpdateDiagnostics {
257        /// The id of the language server that produced the new diagnostics.
258        server_id: LanguageServerId,
259        /// The diagnostics.
260        diagnostics: Arc<[DiagnosticEntry<Anchor>]>,
261        /// The buffer's lamport timestamp.
262        lamport_timestamp: clock::Lamport,
263    },
264
265    /// An update to the most recent selections in this buffer.
266    UpdateSelections {
267        /// The selections.
268        selections: Arc<[Selection<Anchor>]>,
269        /// The buffer's lamport timestamp.
270        lamport_timestamp: clock::Lamport,
271        /// Whether the selections are in 'line mode'.
272        line_mode: bool,
273        /// The [`CursorShape`] associated with these selections.
274        cursor_shape: CursorShape,
275    },
276
277    /// An update to the characters that should trigger autocompletion
278    /// for this buffer.
279    UpdateCompletionTriggers {
280        /// The characters that trigger autocompletion.
281        triggers: Vec<String>,
282        /// The buffer's lamport timestamp.
283        lamport_timestamp: clock::Lamport,
284        /// The language server ID.
285        server_id: LanguageServerId,
286    },
287
288    /// An update to the line ending type of this buffer.
289    UpdateLineEnding {
290        /// The line ending type.
291        line_ending: LineEnding,
292        /// The buffer's lamport timestamp.
293        lamport_timestamp: clock::Lamport,
294    },
295}
296
297#[derive(Clone, Copy, Debug, PartialEq, Eq)]
298pub enum BufferEditSource {
299    User,
300    Agent,
301    Remote,
302}
303
304impl BufferEditSource {
305    pub fn is_local(self) -> bool {
306        !matches!(self, Self::Remote)
307    }
308}
309
310/// An event that occurs in a buffer.
311#[derive(Clone, Debug, PartialEq)]
312pub enum BufferEvent {
313    /// The buffer was changed in a way that must be
314    /// propagated to its other replicas.
315    Operation {
316        operation: Operation,
317        is_local: bool,
318    },
319    /// The buffer was edited.
320    Edited { source: BufferEditSource },
321    /// The buffer's `dirty` bit changed.
322    DirtyChanged,
323    /// The buffer was saved.
324    Saved,
325    /// The buffer's file was changed on disk.
326    FileHandleChanged,
327    /// The buffer was reloaded.
328    Reloaded,
329    /// The buffer is in need of a reload
330    ReloadNeeded,
331    /// The buffer's language was changed.
332    /// The boolean indicates whether this buffer did not have a language before, but does now.
333    LanguageChanged(bool),
334    /// The buffer's syntax trees were updated.
335    Reparsed,
336    /// The buffer's diagnostics were updated.
337    DiagnosticsUpdated,
338    /// The buffer gained or lost editing capabilities.
339    CapabilityChanged,
340}
341
342/// The file associated with a buffer.
343pub trait File: Send + Sync + Any {
344    /// Returns the [`LocalFile`] associated with this file, if the
345    /// file is local.
346    fn as_local(&self) -> Option<&dyn LocalFile>;
347
348    /// Returns whether this file is local.
349    fn is_local(&self) -> bool {
350        self.as_local().is_some()
351    }
352
353    /// Returns whether the file is new, exists in storage, or has been deleted. Includes metadata
354    /// only available in some states, such as modification time.
355    fn disk_state(&self) -> DiskState;
356
357    /// Returns the path of this file relative to the worktree's root directory.
358    fn path(&self) -> &Arc<RelPath>;
359
360    /// Returns the path of this file relative to the worktree's parent directory (this means it
361    /// includes the name of the worktree's root folder).
362    fn full_path(&self, cx: &App) -> PathBuf;
363
364    /// Returns the path style of this file.
365    fn path_style(&self, cx: &App) -> PathStyle;
366
367    /// Returns the last component of this handle's absolute path. If this handle refers to the root
368    /// of its worktree, then this method will return the name of the worktree itself.
369    fn file_name<'a>(&'a self, cx: &'a App) -> &'a str;
370
371    /// Returns the id of the worktree to which this file belongs.
372    ///
373    /// This is needed for looking up project-specific settings.
374    fn worktree_id(&self, cx: &App) -> WorktreeId;
375
376    /// Converts this file into a protobuf message.
377    fn to_proto(&self, cx: &App) -> rpc::proto::File;
378
379    /// Return whether Zed considers this to be a private file.
380    fn is_private(&self) -> bool;
381
382    fn can_open(&self) -> bool {
383        !self.is_local()
384    }
385}
386
387/// The file's storage status - whether it's stored (`Present`), and if so when it was last
388/// modified. In the case where the file is not stored, it can be either `New` or `Deleted`. In the
389/// UI these two states are distinguished. For example, the buffer tab does not display a deletion
390/// indicator for new files.
391#[derive(Copy, Clone, Debug, PartialEq)]
392pub enum DiskState {
393    /// File created in Zed that has not been saved.
394    New,
395    /// File present on the filesystem.
396    Present { mtime: MTime, size: u64 },
397    /// Deleted file that was previously present.
398    Deleted,
399    /// An old version of a file that was previously present
400    /// usually from a version control system. e.g. A git blob
401    Historic { was_deleted: bool },
402}
403
404impl DiskState {
405    /// Returns the file's last known modification time on disk.
406    pub fn mtime(self) -> Option<MTime> {
407        match self {
408            DiskState::New => None,
409            DiskState::Present { mtime, .. } => Some(mtime),
410            DiskState::Deleted => None,
411            DiskState::Historic { .. } => None,
412        }
413    }
414
415    /// Returns the file's size on disk in bytes.
416    pub fn size(self) -> Option<u64> {
417        match self {
418            DiskState::New => None,
419            DiskState::Present { size, .. } => Some(size),
420            DiskState::Deleted => None,
421            DiskState::Historic { .. } => None,
422        }
423    }
424
425    pub fn exists(&self) -> bool {
426        match self {
427            DiskState::New => false,
428            DiskState::Present { .. } => true,
429            DiskState::Deleted => false,
430            DiskState::Historic { .. } => false,
431        }
432    }
433
434    /// Returns true if this state represents a deleted file.
435    pub fn is_deleted(&self) -> bool {
436        match self {
437            DiskState::Deleted => true,
438            DiskState::Historic { was_deleted } => *was_deleted,
439            _ => false,
440        }
441    }
442}
443
444/// The file associated with a buffer, in the case where the file is on the local disk.
445pub trait LocalFile: File {
446    /// Returns the absolute path of this file
447    fn abs_path(&self, cx: &App) -> PathBuf;
448
449    /// Loads the file contents from disk and returns them as a UTF-8 encoded string.
450    fn load(&self, cx: &App) -> Task<Result<String>>;
451
452    /// Loads the file's contents from disk.
453    fn load_bytes(&self, cx: &App) -> Task<Result<Vec<u8>>>;
454}
455
456/// The auto-indent behavior associated with an editing operation.
457/// For some editing operations, each affected line of text has its
458/// indentation recomputed. For other operations, the entire block
459/// of edited text is adjusted uniformly.
460#[derive(Clone, Debug)]
461pub enum AutoindentMode {
462    /// Indent each line of inserted text.
463    EachLine,
464    /// Apply the same indentation adjustment to all of the lines
465    /// in a given insertion.
466    Block {
467        /// The original indentation column of the first line of each
468        /// insertion, if it has been copied.
469        ///
470        /// Knowing this makes it possible to preserve the relative indentation
471        /// of every line in the insertion from when it was copied.
472        ///
473        /// If the original indent column is `a`, and the first line of insertion
474        /// is then auto-indented to column `b`, then every other line of
475        /// the insertion will be auto-indented to column `b - a`
476        original_indent_columns: Vec<Option<u32>>,
477    },
478}
479
480#[derive(Clone)]
481struct AutoindentRequest {
482    before_edit: BufferSnapshot,
483    entries: Vec<AutoindentRequestEntry>,
484    is_block_mode: bool,
485    ignore_empty_lines: bool,
486}
487
488#[derive(Debug, Clone)]
489struct AutoindentRequestEntry {
490    /// A range of the buffer whose indentation should be adjusted.
491    range: Range<Anchor>,
492    /// The row of the edit start in the buffer before the edit was applied.
493    /// This is stored here because the anchor in range is created after
494    /// the edit, so it cannot be used with the before_edit snapshot.
495    old_row: Option<u32>,
496    indent_size: IndentSize,
497    original_indent_column: Option<u32>,
498}
499
500#[derive(Debug)]
501struct IndentSuggestion {
502    basis_row: u32,
503    delta: Ordering,
504    within_error: bool,
505}
506
507struct BufferChunkHighlights<'a> {
508    captures: SyntaxMapCaptures<'a>,
509    next_capture: Option<SyntaxMapCapture<'a>>,
510    stack: Vec<(usize, HighlightId)>,
511    highlight_maps: Vec<HighlightMap>,
512}
513
514/// An iterator that yields chunks of a buffer's text, along with their
515/// syntax highlights and diagnostic status.
516pub struct BufferChunks<'a> {
517    buffer_snapshot: Option<&'a BufferSnapshot>,
518    range: Range<usize>,
519    chunks: text::Chunks<'a>,
520    diagnostic_endpoints: Option<Peekable<vec::IntoIter<DiagnosticEndpoint>>>,
521    error_depth: usize,
522    warning_depth: usize,
523    information_depth: usize,
524    hint_depth: usize,
525    unnecessary_depth: usize,
526    underline: bool,
527    highlights: Option<BufferChunkHighlights<'a>>,
528}
529
530/// A chunk of a buffer's text, along with its syntax highlight and
531/// diagnostic status.
532#[derive(Clone, Debug, Default)]
533pub struct Chunk<'a> {
534    /// The text of the chunk.
535    pub text: &'a str,
536    /// The syntax highlighting style of the chunk.
537    pub syntax_highlight_id: Option<HighlightId>,
538    /// The highlight style that has been applied to this chunk in
539    /// the editor.
540    pub highlight_style: Option<HighlightStyle>,
541    /// The severity of diagnostic associated with this chunk, if any.
542    pub diagnostic_severity: Option<DiagnosticSeverity>,
543    /// A bitset of which characters are tabs in this string.
544    pub tabs: u128,
545    /// Bitmap of character indices in this chunk
546    pub chars: u128,
547    /// Bitmap of newline indices in this chunk
548    pub newlines: u128,
549    /// Whether this chunk of text is marked as unnecessary.
550    pub is_unnecessary: bool,
551    /// Whether this chunk of text was originally a tab character.
552    pub is_tab: bool,
553    /// Whether this chunk of text was originally an inlay.
554    pub is_inlay: bool,
555    /// Whether to underline the corresponding text range in the editor.
556    pub underline: bool,
557}
558
559/// A set of edits to a given version of a buffer, computed asynchronously.
560#[derive(Debug, Clone)]
561pub struct Diff {
562    pub base_version: clock::Global,
563    pub line_ending: LineEnding,
564    pub edits: Vec<(Range<usize>, Arc<str>)>,
565}
566
567#[derive(Debug, Clone, Copy)]
568pub(crate) struct DiagnosticEndpoint {
569    offset: usize,
570    is_start: bool,
571    underline: bool,
572    severity: DiagnosticSeverity,
573    is_unnecessary: bool,
574}
575
576/// A class of characters, used for characterizing a run of text.
577#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug)]
578pub enum CharKind {
579    /// Whitespace.
580    Whitespace,
581    /// Punctuation.
582    Punctuation,
583    /// Word.
584    Word,
585}
586
587/// Context for character classification within a specific scope.
588#[derive(Copy, Clone, Eq, PartialEq, Debug)]
589pub enum CharScopeContext {
590    /// Character classification for completion queries.
591    ///
592    /// This context treats certain characters as word constituents that would
593    /// normally be considered punctuation, such as '-' in Tailwind classes
594    /// ("bg-yellow-100") or '.' in import paths ("foo.ts").
595    Completion,
596    /// Character classification for linked edits.
597    ///
598    /// This context handles characters that should be treated as part of
599    /// identifiers during linked editing operations, such as '.' in JSX
600    /// component names like `<Animated.View>`.
601    LinkedEdit,
602}
603
604/// A runnable is a set of data about a region that could be resolved into a task
605pub struct Runnable {
606    pub tags: SmallVec<[RunnableTag; 1]>,
607    pub language: Arc<Language>,
608    pub buffer: BufferId,
609}
610
611#[derive(Default, Clone, Debug)]
612pub struct HighlightedText {
613    pub text: SharedString,
614    pub highlights: Vec<(Range<usize>, HighlightStyle)>,
615}
616
617#[derive(Default, Debug)]
618pub struct HighlightedTextBuilder {
619    text: String,
620    highlights: Vec<(Range<usize>, HighlightStyle)>,
621}
622
623impl HighlightedText {
624    pub fn from_buffer_range<T: ToOffset>(
625        range: Range<T>,
626        snapshot: &text::BufferSnapshot,
627        syntax_snapshot: &SyntaxSnapshot,
628        override_style: Option<HighlightStyle>,
629        syntax_theme: &SyntaxTheme,
630    ) -> Self {
631        let mut highlighted_text = HighlightedTextBuilder::default();
632        highlighted_text.add_text_from_buffer_range(
633            range,
634            snapshot,
635            syntax_snapshot,
636            override_style,
637            syntax_theme,
638        );
639        highlighted_text.build()
640    }
641
642    pub fn to_styled_text(&self, default_style: &TextStyle) -> StyledText {
643        gpui::StyledText::new(self.text.clone())
644            .with_default_highlights(default_style, self.highlights.iter().cloned())
645    }
646
647    /// Returns the first line without leading whitespace unless highlighted
648    /// and a boolean indicating if there are more lines after
649    pub fn first_line_preview(self) -> (Self, bool) {
650        let newline_ix = self.text.find('\n').unwrap_or(self.text.len());
651        let first_line = &self.text[..newline_ix];
652
653        // Trim leading whitespace, unless an edit starts prior to it.
654        let mut preview_start_ix = first_line.len() - first_line.trim_start().len();
655        if let Some((first_highlight_range, _)) = self.highlights.first() {
656            preview_start_ix = preview_start_ix.min(first_highlight_range.start);
657        }
658
659        let preview_text = &first_line[preview_start_ix..];
660        let preview_highlights = self
661            .highlights
662            .into_iter()
663            .skip_while(|(range, _)| range.end <= preview_start_ix)
664            .take_while(|(range, _)| range.start < newline_ix)
665            .filter_map(|(mut range, highlight)| {
666                range.start = range.start.saturating_sub(preview_start_ix);
667                range.end = range.end.min(newline_ix).saturating_sub(preview_start_ix);
668                if range.is_empty() {
669                    None
670                } else {
671                    Some((range, highlight))
672                }
673            });
674
675        let preview = Self {
676            text: SharedString::new(preview_text),
677            highlights: preview_highlights.collect(),
678        };
679
680        (preview, self.text.len() > newline_ix)
681    }
682}
683
684impl HighlightedTextBuilder {
685    pub fn build(self) -> HighlightedText {
686        HighlightedText {
687            text: self.text.into(),
688            highlights: self.highlights,
689        }
690    }
691
692    /// Append a displayable value to the text, highlighting its range with
693    /// `style`.
694    pub fn push_styled(&mut self, value: impl std::fmt::Display, style: HighlightStyle) {
695        let start = self.text.len();
696        let _ = write!(&mut self.text, "{value}");
697        let end = self.text.len();
698        if end > start {
699            self.highlights.push((start..end, style));
700        }
701    }
702
703    /// Append a displayable value to the text without any highlighting.
704    pub fn push_plain(&mut self, value: impl std::fmt::Display) {
705        let _ = write!(&mut self.text, "{value}");
706    }
707
708    pub fn add_text_from_buffer_range<T: ToOffset>(
709        &mut self,
710        range: Range<T>,
711        snapshot: &text::BufferSnapshot,
712        syntax_snapshot: &SyntaxSnapshot,
713        override_style: Option<HighlightStyle>,
714        syntax_theme: &SyntaxTheme,
715    ) {
716        let range = range.to_offset(snapshot);
717        for chunk in Self::highlighted_chunks(range, snapshot, syntax_snapshot) {
718            let start = self.text.len();
719            self.text.push_str(chunk.text);
720            let end = self.text.len();
721
722            if let Some(highlight_style) = chunk
723                .syntax_highlight_id
724                .and_then(|id| syntax_theme.get(id).cloned())
725            {
726                let highlight_style = override_style.map_or(highlight_style, |override_style| {
727                    highlight_style.highlight(override_style)
728                });
729                self.highlights.push((start..end, highlight_style));
730            } else if let Some(override_style) = override_style {
731                self.highlights.push((start..end, override_style));
732            }
733        }
734    }
735
736    fn highlighted_chunks<'a>(
737        range: Range<usize>,
738        snapshot: &'a text::BufferSnapshot,
739        syntax_snapshot: &'a SyntaxSnapshot,
740    ) -> BufferChunks<'a> {
741        let captures = syntax_snapshot.captures(range.clone(), snapshot, |grammar| {
742            grammar
743                .highlights_config
744                .as_ref()
745                .map(|config| &config.query)
746        });
747
748        let highlight_maps = captures
749            .grammars()
750            .iter()
751            .map(|grammar| grammar.highlight_map())
752            .collect();
753
754        BufferChunks::new(
755            snapshot.as_rope(),
756            range,
757            Some((captures, highlight_maps)),
758            false,
759            None,
760        )
761    }
762}
763
764#[derive(Clone)]
765pub struct EditPreview {
766    old_snapshot: text::BufferSnapshot,
767    applied_edits_snapshot: text::BufferSnapshot,
768    syntax_snapshot: SyntaxSnapshot,
769}
770
771impl EditPreview {
772    pub fn unchanged(snapshot: &BufferSnapshot) -> Self {
773        Self {
774            old_snapshot: snapshot.text.clone(),
775            applied_edits_snapshot: snapshot.text.clone(),
776            syntax_snapshot: snapshot.syntax.clone(),
777        }
778    }
779
780    pub fn as_unified_diff(
781        &self,
782        file: Option<&Arc<dyn File>>,
783        edits: &[(Range<Anchor>, impl AsRef<str>)],
784    ) -> Option<String> {
785        let (first, _) = edits.first()?;
786        let (last, _) = edits.last()?;
787
788        let start = first.start.to_point(&self.old_snapshot);
789        let old_end = last.end.to_point(&self.old_snapshot);
790        let new_end = last
791            .end
792            .bias_right(&self.old_snapshot)
793            .to_point(&self.applied_edits_snapshot);
794
795        let start = Point::new(start.row.saturating_sub(3), 0);
796        let old_end = Point::new(old_end.row + 4, 0).min(self.old_snapshot.max_point());
797        let new_end = Point::new(new_end.row + 4, 0).min(self.applied_edits_snapshot.max_point());
798
799        let diff_body = unified_diff_with_offsets(
800            &self
801                .old_snapshot
802                .text_for_range(start..old_end)
803                .collect::<String>(),
804            &self
805                .applied_edits_snapshot
806                .text_for_range(start..new_end)
807                .collect::<String>(),
808            start.row,
809            start.row,
810        );
811
812        let path = file.map(|f| f.path().as_unix_str());
813        let header = match path {
814            Some(p) => format!("--- a/{}\n+++ b/{}\n", p, p),
815            None => String::new(),
816        };
817
818        Some(format!("{}{}", header, diff_body))
819    }
820
821    pub fn highlight_edits(
822        &self,
823        current_snapshot: &BufferSnapshot,
824        edits: &[(Range<Anchor>, impl AsRef<str>)],
825        include_deletions: bool,
826        cx: &App,
827    ) -> HighlightedText {
828        let Some(visible_range_in_preview_snapshot) = self.compute_visible_range(edits) else {
829            return HighlightedText::default();
830        };
831
832        let mut highlighted_text = HighlightedTextBuilder::default();
833
834        let visible_range_in_preview_snapshot =
835            visible_range_in_preview_snapshot.to_offset(&self.applied_edits_snapshot);
836        let mut offset_in_preview_snapshot = visible_range_in_preview_snapshot.start;
837
838        let insertion_highlight_style = HighlightStyle {
839            background_color: Some(cx.theme().status().created_background),
840            ..Default::default()
841        };
842        let deletion_highlight_style = HighlightStyle {
843            background_color: Some(cx.theme().status().deleted_background),
844            ..Default::default()
845        };
846        let syntax_theme = cx.theme().syntax();
847
848        for (range, edit_text) in edits {
849            let edit_new_end_in_preview_snapshot = range
850                .end
851                .bias_right(&self.old_snapshot)
852                .to_offset(&self.applied_edits_snapshot);
853            let edit_start_in_preview_snapshot =
854                edit_new_end_in_preview_snapshot - edit_text.as_ref().len();
855
856            let unchanged_range_in_preview_snapshot =
857                offset_in_preview_snapshot..edit_start_in_preview_snapshot;
858            if !unchanged_range_in_preview_snapshot.is_empty() {
859                highlighted_text.add_text_from_buffer_range(
860                    unchanged_range_in_preview_snapshot,
861                    &self.applied_edits_snapshot,
862                    &self.syntax_snapshot,
863                    None,
864                    syntax_theme,
865                );
866            }
867
868            let range_in_current_snapshot = range.to_offset(current_snapshot);
869            if include_deletions && !range_in_current_snapshot.is_empty() {
870                highlighted_text.add_text_from_buffer_range(
871                    range_in_current_snapshot,
872                    &current_snapshot.text,
873                    &current_snapshot.syntax,
874                    Some(deletion_highlight_style),
875                    syntax_theme,
876                );
877            }
878
879            if !edit_text.as_ref().is_empty() {
880                highlighted_text.add_text_from_buffer_range(
881                    edit_start_in_preview_snapshot..edit_new_end_in_preview_snapshot,
882                    &self.applied_edits_snapshot,
883                    &self.syntax_snapshot,
884                    Some(insertion_highlight_style),
885                    syntax_theme,
886                );
887            }
888
889            offset_in_preview_snapshot = edit_new_end_in_preview_snapshot;
890        }
891
892        highlighted_text.add_text_from_buffer_range(
893            offset_in_preview_snapshot..visible_range_in_preview_snapshot.end,
894            &self.applied_edits_snapshot,
895            &self.syntax_snapshot,
896            None,
897            syntax_theme,
898        );
899
900        highlighted_text.build()
901    }
902
903    pub fn build_result_buffer(&self, cx: &mut App) -> Entity<Buffer> {
904        cx.new(|cx| {
905            let mut buffer = Buffer::local_normalized(
906                self.applied_edits_snapshot.as_rope().clone(),
907                self.applied_edits_snapshot.line_ending(),
908                cx,
909            );
910            buffer.set_language_async(self.syntax_snapshot.root_language(), cx);
911            buffer
912        })
913    }
914
915    pub fn result_text_snapshot(&self) -> &text::BufferSnapshot {
916        &self.applied_edits_snapshot
917    }
918
919    pub fn result_syntax_snapshot(&self) -> &SyntaxSnapshot {
920        &self.syntax_snapshot
921    }
922
923    pub fn anchor_to_offset_in_result(&self, anchor: Anchor) -> usize {
924        anchor
925            .bias_right(&self.old_snapshot)
926            .to_offset(&self.applied_edits_snapshot)
927    }
928
929    pub fn compute_visible_range<T>(&self, edits: &[(Range<Anchor>, T)]) -> Option<Range<Point>> {
930        let (first, _) = edits.first()?;
931        let (last, _) = edits.last()?;
932
933        let start = first
934            .start
935            .bias_left(&self.old_snapshot)
936            .to_point(&self.applied_edits_snapshot);
937        let end = last
938            .end
939            .bias_right(&self.old_snapshot)
940            .to_point(&self.applied_edits_snapshot);
941
942        // Ensure that the first line of the first edit and the last line of the last edit are always fully visible
943        let range = Point::new(start.row, 0)
944            ..Point::new(end.row, self.applied_edits_snapshot.line_len(end.row));
945
946        Some(range)
947    }
948}
949
950#[derive(Clone, Debug, PartialEq, Eq)]
951pub struct BracketMatch<T> {
952    pub open_range: Range<T>,
953    pub close_range: Range<T>,
954    pub newline_only: bool,
955    pub syntax_layer_depth: usize,
956    pub color_index: Option<usize>,
957}
958
959impl<T> BracketMatch<T> {
960    pub fn bracket_ranges(self) -> (Range<T>, Range<T>) {
961        (self.open_range, self.close_range)
962    }
963}
964
965/// A single bracket pair candidate produced by a brackets query, before
966/// bogus tree-sitter matches are repaired and color indices are assigned.
967#[derive(Clone, Debug)]
968struct BracketMatchCandidate {
969    bracket_match: BracketMatch<usize>,
970    pattern: BracketPatternKey,
971    rainbow_exclude: bool,
972}
973
974impl BracketMatchCandidate {
975    fn open_delimiter(&self) -> BracketDelimiter {
976        BracketDelimiter {
977            start: self.bracket_match.open_range.start,
978            end: self.bracket_match.open_range.end,
979            pattern: self.pattern,
980        }
981    }
982
983    fn close_delimiter(&self) -> BracketDelimiter {
984        BracketDelimiter {
985            start: self.bracket_match.close_range.start,
986            end: self.bracket_match.close_range.end,
987            pattern: self.pattern,
988        }
989    }
990}
991
992/// Identifies a brackets query pattern, unique across all grammars of a syntax map.
993#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
994struct BracketPatternKey {
995    grammar_index: usize,
996    pattern_index: usize,
997}
998
999/// One delimiter (open or close) of a bracket pair candidate.
1000/// Ordered by buffer position first, so sorting yields document order.
1001#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1002struct BracketDelimiter {
1003    start: usize,
1004    end: usize,
1005    pattern: BracketPatternKey,
1006}
1007
1008impl Buffer {
1009    /// Create a new buffer with the given base text.
1010    pub fn local<T: Into<String>>(base_text: T, cx: &Context<Self>) -> Self {
1011        Self::build(
1012            TextBuffer::new(
1013                ReplicaId::LOCAL,
1014                cx.entity_id().as_non_zero_u64().into(),
1015                base_text.into(),
1016            ),
1017            None,
1018            Capability::ReadWrite,
1019        )
1020    }
1021
1022    /// Create a new buffer with the given base text that has proper line endings and other normalization applied.
1023    pub fn local_normalized(
1024        base_text_normalized: Rope,
1025        line_ending: LineEnding,
1026        cx: &Context<Self>,
1027    ) -> Self {
1028        Self::build(
1029            TextBuffer::new_normalized(
1030                ReplicaId::LOCAL,
1031                cx.entity_id().as_non_zero_u64().into(),
1032                line_ending,
1033                base_text_normalized,
1034            ),
1035            None,
1036            Capability::ReadWrite,
1037        )
1038    }
1039
1040    /// Create a new buffer that is a replica of a remote buffer.
1041    pub fn remote(
1042        remote_id: BufferId,
1043        replica_id: ReplicaId,
1044        capability: Capability,
1045        base_text: impl Into<String>,
1046    ) -> Self {
1047        Self::build(
1048            TextBuffer::new(replica_id, remote_id, base_text.into()),
1049            None,
1050            capability,
1051        )
1052    }
1053
1054    /// Create a new buffer that is a replica of a remote buffer, populating its
1055    /// state from the given protobuf message.
1056    pub fn from_proto(
1057        replica_id: ReplicaId,
1058        capability: Capability,
1059        message: proto::BufferState,
1060        file: Option<Arc<dyn File>>,
1061    ) -> Result<Self> {
1062        let buffer_id = BufferId::new(message.id).context("Could not deserialize buffer_id")?;
1063        let buffer = TextBuffer::new(replica_id, buffer_id, message.base_text);
1064        let mut this = Self::build(buffer, file, capability);
1065        this.text.set_line_ending(proto::deserialize_line_ending(
1066            rpc::proto::LineEnding::from_i32(message.line_ending).context("missing line_ending")?,
1067        ));
1068        this.saved_version = proto::deserialize_version(&message.saved_version);
1069        this.saved_mtime = message.saved_mtime.map(|time| time.into());
1070        Ok(this)
1071    }
1072
1073    /// Serialize the buffer's state to a protobuf message.
1074    pub fn to_proto(&self, cx: &App) -> proto::BufferState {
1075        proto::BufferState {
1076            id: self.remote_id().into(),
1077            file: self.file.as_ref().map(|f| f.to_proto(cx)),
1078            base_text: self.base_text().to_string(),
1079            line_ending: proto::serialize_line_ending(self.line_ending()) as i32,
1080            saved_version: proto::serialize_version(&self.saved_version),
1081            saved_mtime: self.saved_mtime.map(|time| time.into()),
1082        }
1083    }
1084
1085    /// Serialize as protobufs all of the changes to the buffer since the given version.
1086    pub fn serialize_ops(
1087        &self,
1088        since: Option<clock::Global>,
1089        cx: &App,
1090    ) -> Task<Vec<proto::Operation>> {
1091        let mut operations = Vec::new();
1092        operations.extend(self.deferred_ops.iter().map(proto::serialize_operation));
1093
1094        operations.extend(self.remote_selections.iter().map(|(_, set)| {
1095            proto::serialize_operation(&Operation::UpdateSelections {
1096                selections: set.selections.clone(),
1097                lamport_timestamp: set.lamport_timestamp,
1098                line_mode: set.line_mode,
1099                cursor_shape: set.cursor_shape,
1100            })
1101        }));
1102
1103        for (server_id, diagnostics) in self.diagnostics.iter() {
1104            operations.push(proto::serialize_operation(&Operation::UpdateDiagnostics {
1105                lamport_timestamp: self.diagnostics_timestamp,
1106                server_id: *server_id,
1107                diagnostics: diagnostics.iter().cloned().collect(),
1108            }));
1109        }
1110
1111        for (server_id, completions) in &self.completion_triggers_per_language_server {
1112            operations.push(proto::serialize_operation(
1113                &Operation::UpdateCompletionTriggers {
1114                    triggers: completions.iter().cloned().collect(),
1115                    lamport_timestamp: self.completion_triggers_timestamp,
1116                    server_id: *server_id,
1117                },
1118            ));
1119        }
1120
1121        let text_operations = self.text.operations().clone();
1122        cx.background_spawn(async move {
1123            let since = since.unwrap_or_default();
1124            operations.extend(
1125                text_operations
1126                    .iter()
1127                    .filter(|(_, op)| !since.observed(op.timestamp()))
1128                    .map(|(_, op)| proto::serialize_operation(&Operation::Buffer(op.clone()))),
1129            );
1130            operations.sort_unstable_by_key(proto::lamport_timestamp_for_operation);
1131            operations
1132        })
1133    }
1134
1135    /// Assign a language to the buffer, returning the buffer.
1136    pub fn with_language_async(mut self, language: Arc<Language>, cx: &mut Context<Self>) -> Self {
1137        self.set_language_async(Some(language), cx);
1138        self
1139    }
1140
1141    /// Assign a language to the buffer, blocking for up to 1ms to reparse the buffer, returning the buffer.
1142    #[ztracing::instrument(skip_all, fields(lang = language.config.name.0.as_str()))]
1143    pub fn with_language(mut self, language: Arc<Language>, cx: &mut Context<Self>) -> Self {
1144        self.set_language(Some(language), cx);
1145        self
1146    }
1147
1148    /// Returns the [`Capability`] of this buffer.
1149    pub fn capability(&self) -> Capability {
1150        self.capability
1151    }
1152
1153    /// Whether this buffer can only be read.
1154    pub fn read_only(&self) -> bool {
1155        !self.capability.editable()
1156    }
1157
1158    /// Builds a [`Buffer`] with the given underlying [`TextBuffer`], diff base, [`File`] and [`Capability`].
1159    pub fn build(buffer: TextBuffer, file: Option<Arc<dyn File>>, capability: Capability) -> Self {
1160        let saved_mtime = file.as_ref().and_then(|file| file.disk_state().mtime());
1161        let snapshot = buffer.snapshot();
1162        let syntax_map = Mutex::new(SyntaxMap::new(&snapshot));
1163        let tree_sitter_data = TreeSitterData::new(snapshot);
1164        Self {
1165            saved_mtime,
1166            tree_sitter_data: Arc::new(tree_sitter_data),
1167            saved_version: buffer.version(),
1168            preview_version: buffer.version(),
1169            reload_task: None,
1170            transaction_depth: 0,
1171            was_dirty_before_starting_transaction: None,
1172            has_unsaved_edits: Cell::new((buffer.version(), false)),
1173            text: buffer,
1174            branch_state: None,
1175            file,
1176            capability,
1177            syntax_map,
1178            reparse: None,
1179            non_text_state_update_count: 0,
1180            sync_parse_timeout: if cfg!(any(test, feature = "test-support")) {
1181                Some(Duration::from_millis(10))
1182            } else {
1183                Some(Duration::from_millis(1))
1184            },
1185            parse_status: watch::channel(ParseStatus::Idle),
1186            autoindent_requests: Default::default(),
1187            wait_for_autoindent_txs: Default::default(),
1188            pending_autoindent: Default::default(),
1189            language: None,
1190            remote_selections: Default::default(),
1191            diagnostics: Default::default(),
1192            diagnostics_timestamp: Lamport::MIN,
1193            completion_triggers: Default::default(),
1194            completion_triggers_per_language_server: Default::default(),
1195            completion_triggers_timestamp: Lamport::MIN,
1196            deferred_ops: OperationQueue::new(),
1197            has_conflict: false,
1198            change_bits: Default::default(),
1199            modeline: None,
1200            _subscriptions: Vec::new(),
1201            encoding: encoding_rs::UTF_8,
1202            has_bom: false,
1203            reload_with_encoding_txns: HashMap::default(),
1204        }
1205    }
1206
1207    #[ztracing::instrument(skip_all)]
1208    pub fn build_snapshot(
1209        text: Rope,
1210        language: Option<Arc<Language>>,
1211        language_registry: Option<Arc<LanguageRegistry>>,
1212        modeline: Option<Arc<ModelineSettings>>,
1213        cx: &mut App,
1214    ) -> impl Future<Output = BufferSnapshot> + use<> {
1215        let entity_id = cx.reserve_entity::<Self>().entity_id();
1216        let buffer_id = entity_id.as_non_zero_u64().into();
1217        async move {
1218            let text =
1219                TextBuffer::new_normalized(ReplicaId::LOCAL, buffer_id, Default::default(), text);
1220            let text = text.into_snapshot();
1221            let mut syntax = SyntaxMap::new(&text).snapshot();
1222            if let Some(language) = language.clone() {
1223                let language_registry = language_registry.clone();
1224                syntax.reparse(&text, language_registry, language);
1225            }
1226            let tree_sitter_data = TreeSitterData::new(&text);
1227            BufferSnapshot {
1228                text,
1229                syntax,
1230                file: None,
1231                diagnostics: Default::default(),
1232                remote_selections: Default::default(),
1233                tree_sitter_data: Arc::new(tree_sitter_data),
1234                language,
1235                non_text_state_update_count: 0,
1236                capability: Capability::ReadOnly,
1237                modeline,
1238            }
1239        }
1240    }
1241
1242    pub fn build_empty_snapshot(cx: &mut App) -> BufferSnapshot {
1243        let entity_id = cx.reserve_entity::<Self>().entity_id();
1244        let buffer_id = entity_id.as_non_zero_u64().into();
1245        let text = TextBuffer::new_normalized(
1246            ReplicaId::LOCAL,
1247            buffer_id,
1248            Default::default(),
1249            Rope::new(),
1250        );
1251        let text = text.into_snapshot();
1252        let syntax = SyntaxMap::new(&text).snapshot();
1253        let tree_sitter_data = TreeSitterData::new(&text);
1254        BufferSnapshot {
1255            text,
1256            syntax,
1257            tree_sitter_data: Arc::new(tree_sitter_data),
1258            file: None,
1259            diagnostics: Default::default(),
1260            remote_selections: Default::default(),
1261            language: None,
1262            non_text_state_update_count: 0,
1263            capability: Capability::ReadOnly,
1264            modeline: None,
1265        }
1266    }
1267
1268    #[cfg(any(test, feature = "test-support"))]
1269    pub fn build_snapshot_sync(
1270        text: Rope,
1271        language: Option<Arc<Language>>,
1272        language_registry: Option<Arc<LanguageRegistry>>,
1273        cx: &mut App,
1274    ) -> BufferSnapshot {
1275        let entity_id = cx.reserve_entity::<Self>().entity_id();
1276        let buffer_id = entity_id.as_non_zero_u64().into();
1277        let text =
1278            TextBuffer::new_normalized(ReplicaId::LOCAL, buffer_id, Default::default(), text)
1279                .into_snapshot();
1280        let mut syntax = SyntaxMap::new(&text).snapshot();
1281        if let Some(language) = language.clone() {
1282            syntax.reparse(&text, language_registry, language);
1283        }
1284        let tree_sitter_data = TreeSitterData::new(&text);
1285        BufferSnapshot {
1286            text,
1287            syntax,
1288            tree_sitter_data: Arc::new(tree_sitter_data),
1289            file: None,
1290            diagnostics: Default::default(),
1291            remote_selections: Default::default(),
1292            language,
1293            non_text_state_update_count: 0,
1294            capability: Capability::ReadOnly,
1295            modeline: None,
1296        }
1297    }
1298
1299    /// Retrieve a snapshot of the buffer's current state. This is computationally
1300    /// cheap, and allows reading from the buffer on a background thread.
1301    pub fn snapshot(&self) -> BufferSnapshot {
1302        let text = self.text.snapshot();
1303
1304        let syntax = {
1305            let mut syntax_map = self.syntax_map.lock();
1306            syntax_map.interpolate(text);
1307            syntax_map.snapshot()
1308        };
1309
1310        let tree_sitter_data = if self.text.version() != *self.tree_sitter_data.version() {
1311            Arc::new(TreeSitterData::new(text))
1312        } else {
1313            self.tree_sitter_data.clone()
1314        };
1315
1316        BufferSnapshot {
1317            text: text.clone(),
1318            syntax,
1319            tree_sitter_data,
1320            file: self.file.clone(),
1321            remote_selections: self.remote_selections.clone(),
1322            diagnostics: self.diagnostics.clone(),
1323            language: self.language.clone(),
1324            non_text_state_update_count: self.non_text_state_update_count,
1325            capability: self.capability,
1326            modeline: self.modeline.clone(),
1327        }
1328    }
1329
1330    pub fn branch(&mut self, cx: &mut Context<Self>) -> Entity<Self> {
1331        let this = cx.entity();
1332        cx.new(|cx| {
1333            let mut branch = Self {
1334                branch_state: Some(BufferBranchState {
1335                    base_buffer: this.clone(),
1336                    merged_operations: Default::default(),
1337                }),
1338                language: self.language.clone(),
1339                has_conflict: self.has_conflict,
1340                has_unsaved_edits: Cell::new(self.has_unsaved_edits.get_mut().clone()),
1341                _subscriptions: vec![cx.subscribe(&this, Self::on_base_buffer_event)],
1342                ..Self::build(self.text.branch(), self.file.clone(), self.capability())
1343            };
1344            if let Some(language_registry) = self.language_registry() {
1345                branch.set_language_registry(language_registry);
1346            }
1347
1348            // Reparse the branch buffer so that we get syntax highlighting immediately.
1349            branch.reparse(cx, true);
1350
1351            branch
1352        })
1353    }
1354
1355    #[ztracing::instrument(skip_all)]
1356    pub fn preview_edits(
1357        &self,
1358        edits: Arc<[(Range<Anchor>, Arc<str>)]>,
1359        cx: &App,
1360    ) -> Task<EditPreview> {
1361        let registry = self.language_registry();
1362        let language = self.language().cloned();
1363        let old_snapshot = self.text.snapshot().clone();
1364        let mut branch_buffer = self.text.branch();
1365        let mut syntax_snapshot = self.syntax_map.lock().snapshot();
1366        cx.background_spawn(async move {
1367            if !edits.is_empty() {
1368                if let Some(language) = language.clone() {
1369                    syntax_snapshot.reparse(&old_snapshot, registry.clone(), language);
1370                }
1371
1372                branch_buffer.edit(edits.iter().cloned());
1373                let snapshot = branch_buffer.snapshot();
1374                syntax_snapshot.interpolate(&snapshot);
1375
1376                if let Some(language) = language {
1377                    syntax_snapshot.reparse(&snapshot, registry, language);
1378                }
1379            }
1380            EditPreview {
1381                old_snapshot,
1382                applied_edits_snapshot: branch_buffer.into_snapshot(),
1383                syntax_snapshot,
1384            }
1385        })
1386    }
1387
1388    /// Applies all of the changes in this buffer that intersect any of the
1389    /// given `ranges` to its base buffer.
1390    ///
1391    /// If `ranges` is empty, then all changes will be applied. This buffer must
1392    /// be a branch buffer to call this method.
1393    pub fn merge_into_base(&mut self, ranges: Vec<Range<usize>>, cx: &mut Context<Self>) {
1394        let Some(base_buffer) = self.base_buffer() else {
1395            debug_panic!("not a branch buffer");
1396            return;
1397        };
1398
1399        let mut ranges = if ranges.is_empty() {
1400            &[0..usize::MAX]
1401        } else {
1402            ranges.as_slice()
1403        }
1404        .iter()
1405        .peekable();
1406
1407        let mut edits = Vec::new();
1408        for edit in self.edits_since::<usize>(&base_buffer.read(cx).version()) {
1409            let mut is_included = false;
1410            while let Some(range) = ranges.peek() {
1411                if range.end < edit.new.start {
1412                    ranges.next().unwrap();
1413                } else {
1414                    if range.start <= edit.new.end {
1415                        is_included = true;
1416                    }
1417                    break;
1418                }
1419            }
1420
1421            if is_included {
1422                edits.push((
1423                    edit.old.clone(),
1424                    self.text_for_range(edit.new.clone()).collect::<String>(),
1425                ));
1426            }
1427        }
1428
1429        let operation = base_buffer.update(cx, |base_buffer, cx| {
1430            // cx.emit(BufferEvent::DiffBaseChanged);
1431            base_buffer.edit(edits, None, cx)
1432        });
1433
1434        if let Some(operation) = operation
1435            && let Some(BufferBranchState {
1436                merged_operations, ..
1437            }) = &mut self.branch_state
1438        {
1439            merged_operations.push(operation);
1440        }
1441    }
1442
1443    fn on_base_buffer_event(
1444        &mut self,
1445        _: Entity<Buffer>,
1446        event: &BufferEvent,
1447        cx: &mut Context<Self>,
1448    ) {
1449        let BufferEvent::Operation { operation, .. } = event else {
1450            return;
1451        };
1452        let Some(BufferBranchState {
1453            merged_operations, ..
1454        }) = &mut self.branch_state
1455        else {
1456            return;
1457        };
1458
1459        let mut operation_to_undo = None;
1460        if let Operation::Buffer(text::Operation::Edit(operation)) = &operation
1461            && let Ok(ix) = merged_operations.binary_search(&operation.timestamp)
1462        {
1463            merged_operations.remove(ix);
1464            operation_to_undo = Some(operation.timestamp);
1465        }
1466
1467        self.apply_ops([operation.clone()], cx);
1468
1469        if let Some(timestamp) = operation_to_undo {
1470            let counts = [(timestamp, u32::MAX)].into_iter().collect();
1471            self.undo_operations(counts, cx);
1472        }
1473    }
1474
1475    pub fn as_text_snapshot(&self) -> &text::BufferSnapshot {
1476        &self.text
1477    }
1478
1479    /// Retrieve a snapshot of the buffer's raw text, without any
1480    /// language-related state like the syntax tree or diagnostics.
1481    #[ztracing::instrument(skip_all)]
1482    pub fn text_snapshot(&self) -> text::BufferSnapshot {
1483        // todo lw
1484        self.text.snapshot().clone()
1485    }
1486
1487    /// The file associated with the buffer, if any.
1488    pub fn file(&self) -> Option<&Arc<dyn File>> {
1489        self.file.as_ref()
1490    }
1491
1492    /// The version of the buffer that was last saved or reloaded from disk.
1493    pub fn saved_version(&self) -> &clock::Global {
1494        &self.saved_version
1495    }
1496
1497    /// The mtime of the buffer's file when the buffer was last saved or reloaded from disk.
1498    pub fn saved_mtime(&self) -> Option<MTime> {
1499        self.saved_mtime
1500    }
1501
1502    /// Returns the character encoding of the buffer's file.
1503    pub fn encoding(&self) -> &'static Encoding {
1504        self.encoding
1505    }
1506
1507    /// Sets the character encoding of the buffer.
1508    pub fn set_encoding(&mut self, encoding: &'static Encoding) {
1509        self.encoding = encoding;
1510    }
1511
1512    /// Returns whether the buffer has a Byte Order Mark.
1513    pub fn has_bom(&self) -> bool {
1514        self.has_bom
1515    }
1516
1517    /// Sets whether the buffer has a Byte Order Mark.
1518    pub fn set_has_bom(&mut self, has_bom: bool) {
1519        self.has_bom = has_bom;
1520    }
1521
1522    /// Assign a language to the buffer.
1523    pub fn set_language_async(&mut self, language: Option<Arc<Language>>, cx: &mut Context<Self>) {
1524        self.set_language_(language, cfg!(any(test, feature = "test-support")), cx);
1525    }
1526
1527    /// Assign a language to the buffer, blocking for up to 1ms to reparse the buffer.
1528    pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut Context<Self>) {
1529        self.set_language_(language, true, cx);
1530    }
1531
1532    #[ztracing::instrument(skip_all)]
1533    fn set_language_(
1534        &mut self,
1535        language: Option<Arc<Language>>,
1536        may_block: bool,
1537        cx: &mut Context<Self>,
1538    ) {
1539        if language == self.language {
1540            return;
1541        }
1542        self.non_text_state_update_count += 1;
1543        self.syntax_map.lock().clear(&self.text);
1544        let old_language = std::mem::replace(&mut self.language, language);
1545        self.was_changed();
1546        self.reparse(cx, may_block);
1547        let has_fresh_language =
1548            self.language.is_some() && old_language.is_none_or(|old| old == *PLAIN_TEXT);
1549        cx.emit(BufferEvent::LanguageChanged(has_fresh_language));
1550    }
1551
1552    /// Assign a language registry to the buffer. This allows the buffer to retrieve
1553    /// other languages if parts of the buffer are written in different languages.
1554    pub fn set_language_registry(&self, language_registry: Arc<LanguageRegistry>) {
1555        self.syntax_map
1556            .lock()
1557            .set_language_registry(language_registry);
1558    }
1559
1560    pub fn language_registry(&self) -> Option<Arc<LanguageRegistry>> {
1561        self.syntax_map.lock().language_registry()
1562    }
1563
1564    /// Assign the line ending type to the buffer.
1565    pub fn set_line_ending(&mut self, line_ending: LineEnding, cx: &mut Context<Self>) {
1566        self.text.set_line_ending(line_ending);
1567
1568        let lamport_timestamp = self.text.lamport_clock.tick();
1569        self.send_operation(
1570            Operation::UpdateLineEnding {
1571                line_ending,
1572                lamport_timestamp,
1573            },
1574            true,
1575            cx,
1576        );
1577    }
1578
1579    /// Assign the buffer [`ModelineSettings`].
1580    pub fn set_modeline(&mut self, modeline: Option<ModelineSettings>) -> bool {
1581        if modeline.as_ref() != self.modeline.as_deref() {
1582            self.modeline = modeline.map(Arc::new);
1583            true
1584        } else {
1585            false
1586        }
1587    }
1588
1589    /// Returns the [`ModelineSettings`].
1590    pub fn modeline(&self) -> Option<&Arc<ModelineSettings>> {
1591        self.modeline.as_ref()
1592    }
1593
1594    /// Assign the buffer a new [`Capability`].
1595    pub fn set_capability(&mut self, capability: Capability, cx: &mut Context<Self>) {
1596        if self.capability != capability {
1597            self.capability = capability;
1598            cx.emit(BufferEvent::CapabilityChanged)
1599        }
1600    }
1601
1602    /// This method is called to signal that the buffer has been saved.
1603    pub fn did_save(
1604        &mut self,
1605        version: clock::Global,
1606        mtime: Option<MTime>,
1607        cx: &mut Context<Self>,
1608    ) {
1609        self.saved_version = version.clone();
1610        self.has_unsaved_edits.set((version, false));
1611        self.has_conflict = false;
1612        self.saved_mtime = mtime;
1613        self.was_changed();
1614        cx.emit(BufferEvent::Saved);
1615        cx.notify();
1616    }
1617
1618    /// Reloads the contents of the buffer from disk.
1619    pub fn reload(&mut self, cx: &Context<Self>) -> oneshot::Receiver<Option<Transaction>> {
1620        self.reload_impl(None, cx)
1621    }
1622
1623    /// Reloads the contents of the buffer from disk using the specified encoding.
1624    ///
1625    /// This bypasses automatic encoding detection heuristics (like BOM checks) for non-Unicode encodings,
1626    /// allowing users to force a specific interpretation of the bytes.
1627    pub fn reload_with_encoding(
1628        &mut self,
1629        encoding: &'static Encoding,
1630        cx: &Context<Self>,
1631    ) -> oneshot::Receiver<Option<Transaction>> {
1632        self.reload_impl(Some(encoding), cx)
1633    }
1634
1635    fn reload_impl(
1636        &mut self,
1637        force_encoding: Option<&'static Encoding>,
1638        cx: &Context<Self>,
1639    ) -> oneshot::Receiver<Option<Transaction>> {
1640        let (tx, rx) = futures::channel::oneshot::channel();
1641        let prev_version = self.text.version();
1642
1643        self.reload_task = Some(cx.spawn(async move |this, cx| {
1644            let Some((new_mtime, load_bytes_task, current_encoding)) =
1645                this.update(cx, |this, cx| {
1646                    let file = this.file.as_ref()?.as_local()?;
1647                    Some((
1648                        file.disk_state().mtime(),
1649                        file.load_bytes(cx),
1650                        this.encoding,
1651                    ))
1652                })?
1653            else {
1654                return Ok(());
1655            };
1656
1657            let target_encoding = force_encoding.unwrap_or(current_encoding);
1658
1659            let bytes = load_bytes_task.await?;
1660
1661            anyhow::ensure!(
1662                analyze_byte_content(&bytes) != ByteContent::Binary,
1663                "Binary files are not supported"
1664            );
1665
1666            let is_unicode = target_encoding == encoding_rs::UTF_8
1667                || target_encoding == encoding_rs::UTF_16LE
1668                || target_encoding == encoding_rs::UTF_16BE;
1669
1670            let (new_text, has_bom, encoding_used) = if force_encoding.is_some() && !is_unicode {
1671                let (cow, _had_errors) = target_encoding.decode_without_bom_handling(&bytes);
1672                (cow.into_owned(), false, target_encoding)
1673            } else {
1674                let (cow, used_enc, _had_errors) = target_encoding.decode(&bytes);
1675
1676                let actual_has_bom = if used_enc == encoding_rs::UTF_8 {
1677                    bytes.starts_with(&[0xEF, 0xBB, 0xBF])
1678                } else if used_enc == encoding_rs::UTF_16LE {
1679                    bytes.starts_with(&[0xFF, 0xFE])
1680                } else if used_enc == encoding_rs::UTF_16BE {
1681                    bytes.starts_with(&[0xFE, 0xFF])
1682                } else {
1683                    false
1684                };
1685                (cow.into_owned(), actual_has_bom, used_enc)
1686            };
1687
1688            let diff = this.update(cx, |this, cx| this.diff(new_text, cx))?.await;
1689            this.update(cx, |this, cx| {
1690                if this.version() == diff.base_version {
1691                    this.finalize_last_transaction();
1692                    let old_encoding = this.encoding;
1693                    let old_has_bom = this.has_bom;
1694                    this.apply_diff(diff, cx);
1695                    this.encoding = encoding_used;
1696                    this.has_bom = has_bom;
1697                    let transaction = this.finalize_last_transaction().cloned();
1698                    if let Some(ref txn) = transaction {
1699                        if old_encoding != encoding_used || old_has_bom != has_bom {
1700                            this.reload_with_encoding_txns
1701                                .insert(txn.id, (old_encoding, old_has_bom));
1702                        }
1703                    }
1704                    tx.send(transaction).ok();
1705                    this.has_conflict = false;
1706                    this.did_reload(this.version(), this.line_ending(), new_mtime, cx);
1707                } else {
1708                    if !diff.edits.is_empty()
1709                        || this
1710                            .edits_since::<usize>(&diff.base_version)
1711                            .next()
1712                            .is_some()
1713                    {
1714                        this.has_conflict = true;
1715                    }
1716
1717                    this.did_reload(prev_version, this.line_ending(), this.saved_mtime, cx);
1718                }
1719
1720                this.reload_task.take();
1721            })
1722        }));
1723        rx
1724    }
1725
1726    /// This method is called to signal that the buffer has been reloaded.
1727    pub fn did_reload(
1728        &mut self,
1729        version: clock::Global,
1730        line_ending: LineEnding,
1731        mtime: Option<MTime>,
1732        cx: &mut Context<Self>,
1733    ) {
1734        self.saved_version = version;
1735        self.has_unsaved_edits
1736            .set((self.saved_version.clone(), false));
1737        self.text.set_line_ending(line_ending);
1738        self.saved_mtime = mtime;
1739        cx.emit(BufferEvent::Reloaded);
1740        cx.notify();
1741    }
1742
1743    /// Updates the [`File`] backing this buffer. This should be called when
1744    /// the file has changed or has been deleted.
1745    pub fn file_updated(&mut self, new_file: Arc<dyn File>, cx: &mut Context<Self>) {
1746        let was_dirty = self.is_dirty();
1747        let mut file_changed = false;
1748
1749        if let Some(old_file) = self.file.as_ref() {
1750            if new_file.path() != old_file.path() {
1751                file_changed = true;
1752            }
1753
1754            let old_state = old_file.disk_state();
1755            let new_state = new_file.disk_state();
1756            if old_state != new_state {
1757                file_changed = true;
1758                if !was_dirty && matches!(new_state, DiskState::Present { .. }) {
1759                    cx.emit(BufferEvent::ReloadNeeded)
1760                }
1761            }
1762        } else {
1763            file_changed = true;
1764        };
1765
1766        self.file = Some(new_file);
1767        if file_changed {
1768            self.was_changed();
1769            self.non_text_state_update_count += 1;
1770            if was_dirty != self.is_dirty() {
1771                cx.emit(BufferEvent::DirtyChanged);
1772            }
1773            cx.emit(BufferEvent::FileHandleChanged);
1774            cx.notify();
1775        }
1776    }
1777
1778    pub fn base_buffer(&self) -> Option<Entity<Self>> {
1779        Some(self.branch_state.as_ref()?.base_buffer.clone())
1780    }
1781
1782    /// Returns the primary [`Language`] assigned to this [`Buffer`].
1783    pub fn language(&self) -> Option<&Arc<Language>> {
1784        self.language.as_ref()
1785    }
1786
1787    /// Returns the [`Language`] at the given location.
1788    pub fn language_at<D: ToOffset>(&self, position: D) -> Option<Arc<Language>> {
1789        let offset = position.to_offset(self);
1790        let text: &TextBufferSnapshot = &self.text;
1791        self.syntax_map
1792            .lock()
1793            .layers_for_range(offset..offset, text, false)
1794            .filter(|layer| {
1795                layer
1796                    .included_sub_ranges
1797                    .is_none_or(|ranges| offset_in_sub_ranges(ranges, offset, text))
1798            })
1799            .last()
1800            .map(|info| info.language.clone())
1801            .or_else(|| self.language.clone())
1802    }
1803
1804    /// Returns each [`Language`] for the active syntax layers at the given location.
1805    pub fn languages_at<D: ToOffset>(&self, position: D) -> Vec<Arc<Language>> {
1806        let offset = position.to_offset(self);
1807        let text: &TextBufferSnapshot = &self.text;
1808        let mut languages: Vec<Arc<Language>> = self
1809            .syntax_map
1810            .lock()
1811            .layers_for_range(offset..offset, text, false)
1812            .filter(|layer| {
1813                // For combined injections, check if offset is within the actual sub-ranges.
1814                layer
1815                    .included_sub_ranges
1816                    .is_none_or(|ranges| offset_in_sub_ranges(ranges, offset, text))
1817            })
1818            .map(|info| info.language.clone())
1819            .collect();
1820
1821        if languages.is_empty()
1822            && let Some(buffer_language) = self.language()
1823        {
1824            languages.push(buffer_language.clone());
1825        }
1826
1827        languages
1828    }
1829
1830    /// An integer version number that accounts for all updates besides
1831    /// the buffer's text itself (which is versioned via a version vector).
1832    pub fn non_text_state_update_count(&self) -> usize {
1833        self.non_text_state_update_count
1834    }
1835
1836    /// Whether the buffer is being parsed in the background.
1837    #[cfg(any(test, feature = "test-support"))]
1838    pub fn is_parsing(&self) -> bool {
1839        self.reparse.is_some()
1840    }
1841
1842    /// Indicates whether the buffer contains any regions that may be
1843    /// written in a language that hasn't been loaded yet.
1844    pub fn contains_unknown_injections(&self) -> bool {
1845        self.syntax_map.lock().contains_unknown_injections()
1846    }
1847
1848    /// Sets the sync parse timeout for this buffer.
1849    ///
1850    /// Setting this to `None` disables sync parsing entirely.
1851    pub fn set_sync_parse_timeout(&mut self, timeout: Option<Duration>) {
1852        self.sync_parse_timeout = timeout;
1853    }
1854
1855    fn invalidate_tree_sitter_data(
1856        tree_sitter_data: &mut Arc<TreeSitterData>,
1857        snapshot: &text::BufferSnapshot,
1858    ) {
1859        match Arc::get_mut(tree_sitter_data) {
1860            Some(tree_sitter_data) => tree_sitter_data.clear(snapshot),
1861            None => {
1862                let new_tree_sitter_data = TreeSitterData::new(snapshot);
1863                *tree_sitter_data = Arc::new(new_tree_sitter_data)
1864            }
1865        }
1866    }
1867
1868    /// Called after an edit to synchronize the buffer's main parse tree with
1869    /// the buffer's new underlying state.
1870    ///
1871    /// Locks the syntax map and interpolates the edits since the last reparse
1872    /// into the foreground syntax tree.
1873    ///
1874    /// Then takes a stable snapshot of the syntax map before unlocking it.
1875    /// The snapshot with the interpolated edits is sent to a background thread,
1876    /// where we ask Tree-sitter to perform an incremental parse.
1877    ///
1878    /// Meanwhile, in the foreground if `may_block` is true, we block the main
1879    /// thread for up to 1ms waiting on the parse to complete. As soon as it
1880    /// completes, we proceed synchronously, unless a 1ms timeout elapses.
1881    ///
1882    /// If we time out waiting on the parse, we spawn a second task waiting
1883    /// until the parse does complete and return with the interpolated tree still
1884    /// in the foreground. When the background parse completes, call back into
1885    /// the main thread and assign the foreground parse state.
1886    ///
1887    /// If the buffer or grammar changed since the start of the background parse,
1888    /// initiate an additional reparse recursively. To avoid concurrent parses
1889    /// for the same buffer, we only initiate a new parse if we are not already
1890    /// parsing in the background.
1891    #[ztracing::instrument(skip_all)]
1892    pub fn reparse(&mut self, cx: &mut Context<Self>, may_block: bool) {
1893        if self.text.version() != *self.tree_sitter_data.version() {
1894            Self::invalidate_tree_sitter_data(&mut self.tree_sitter_data, self.text.snapshot());
1895        }
1896        if self.reparse.is_some() {
1897            return;
1898        }
1899        let language = if let Some(language) = self.language.clone() {
1900            language
1901        } else {
1902            return;
1903        };
1904
1905        let text = self.text_snapshot();
1906        let parsed_version = self.version();
1907
1908        let mut syntax_map = self.syntax_map.lock();
1909        syntax_map.interpolate(&text);
1910        let language_registry = syntax_map.language_registry();
1911        let mut syntax_snapshot = syntax_map.snapshot();
1912        drop(syntax_map);
1913
1914        self.parse_status.0.send(ParseStatus::Parsing).unwrap();
1915        if may_block && let Some(sync_parse_timeout) = self.sync_parse_timeout {
1916            if let Ok(()) = syntax_snapshot.reparse_with_timeout(
1917                &text,
1918                language_registry.clone(),
1919                language.clone(),
1920                sync_parse_timeout,
1921            ) {
1922                self.did_finish_parsing(syntax_snapshot, Some(Duration::from_millis(300)), cx);
1923                self.reparse = None;
1924                return;
1925            }
1926        }
1927
1928        let parse_task = cx.background_spawn({
1929            let language = language.clone();
1930            let language_registry = language_registry.clone();
1931            async move {
1932                syntax_snapshot.reparse(&text, language_registry, language);
1933                syntax_snapshot
1934            }
1935        });
1936
1937        self.reparse = Some(cx.spawn(async move |this, cx| {
1938            let new_syntax_map = parse_task.await;
1939            this.update(cx, move |this, cx| {
1940                let grammar_changed = || {
1941                    this.language
1942                        .as_ref()
1943                        .is_none_or(|current_language| !Arc::ptr_eq(&language, current_language))
1944                };
1945                let language_registry_changed = || {
1946                    new_syntax_map.contains_unknown_injections()
1947                        && language_registry.is_some_and(|registry| {
1948                            registry.version() != new_syntax_map.language_registry_version()
1949                        })
1950                };
1951                let parse_again = this.version.changed_since(&parsed_version)
1952                    || language_registry_changed()
1953                    || grammar_changed();
1954                this.did_finish_parsing(new_syntax_map, None, cx);
1955                this.reparse = None;
1956                if parse_again {
1957                    this.reparse(cx, false);
1958                }
1959            })
1960            .ok();
1961        }));
1962    }
1963
1964    fn did_finish_parsing(
1965        &mut self,
1966        syntax_snapshot: SyntaxSnapshot,
1967        block_budget: Option<Duration>,
1968        cx: &mut Context<Self>,
1969    ) {
1970        self.non_text_state_update_count += 1;
1971        self.syntax_map.lock().did_parse(syntax_snapshot);
1972        self.was_changed();
1973        self.request_autoindent(cx, block_budget);
1974        self.parse_status.0.send(ParseStatus::Idle).unwrap();
1975        Self::invalidate_tree_sitter_data(&mut self.tree_sitter_data, &self.text.snapshot());
1976        cx.emit(BufferEvent::Reparsed);
1977        cx.notify();
1978    }
1979
1980    pub fn parse_status(&self) -> watch::Receiver<ParseStatus> {
1981        self.parse_status.1.clone()
1982    }
1983
1984    /// Wait until the buffer is no longer parsing
1985    pub fn parsing_idle(&self) -> impl Future<Output = ()> + use<> {
1986        let mut parse_status = self.parse_status();
1987        async move {
1988            while *parse_status.borrow() != ParseStatus::Idle {
1989                if parse_status.changed().await.is_err() {
1990                    break;
1991                }
1992            }
1993        }
1994    }
1995
1996    /// Assign to the buffer a set of diagnostics created by a given language server.
1997    pub fn update_diagnostics(
1998        &mut self,
1999        server_id: LanguageServerId,
2000        diagnostics: DiagnosticSet,
2001        cx: &mut Context<Self>,
2002    ) {
2003        let lamport_timestamp = self.text.lamport_clock.tick();
2004        let op = Operation::UpdateDiagnostics {
2005            server_id,
2006            diagnostics: diagnostics.iter().cloned().collect(),
2007            lamport_timestamp,
2008        };
2009
2010        self.apply_diagnostic_update(server_id, diagnostics, lamport_timestamp, cx);
2011        self.send_operation(op, true, cx);
2012    }
2013
2014    pub fn buffer_diagnostics(
2015        &self,
2016        for_server: Option<LanguageServerId>,
2017    ) -> Vec<&DiagnosticEntry<Anchor>> {
2018        match for_server {
2019            Some(server_id) => self
2020                .diagnostics
2021                .get(&server_id)
2022                .map_or_else(Vec::new, |diagnostics| diagnostics.iter().collect()),
2023            None => self
2024                .diagnostics
2025                .iter()
2026                .flat_map(|(_, diagnostic_set)| diagnostic_set.iter())
2027                .collect(),
2028        }
2029    }
2030
2031    fn request_autoindent(&mut self, cx: &mut Context<Self>, block_budget: Option<Duration>) {
2032        if let Some(indent_sizes) = self.compute_autoindents() {
2033            let indent_sizes = cx.background_spawn(indent_sizes);
2034            let Some(block_budget) = block_budget else {
2035                self.pending_autoindent = Some(cx.spawn(async move |this, cx| {
2036                    let indent_sizes = indent_sizes.await;
2037                    this.update(cx, |this, cx| {
2038                        this.apply_autoindents(indent_sizes, cx);
2039                    })
2040                    .ok();
2041                }));
2042                return;
2043            };
2044            match cx
2045                .foreground_executor()
2046                .block_with_timeout(block_budget, indent_sizes)
2047            {
2048                Ok(indent_sizes) => self.apply_autoindents(indent_sizes, cx),
2049                Err(indent_sizes) => {
2050                    self.pending_autoindent = Some(cx.spawn(async move |this, cx| {
2051                        let indent_sizes = indent_sizes.await;
2052                        this.update(cx, |this, cx| {
2053                            this.apply_autoindents(indent_sizes, cx);
2054                        })
2055                        .ok();
2056                    }));
2057                }
2058            }
2059        } else {
2060            self.autoindent_requests.clear();
2061            for tx in self.wait_for_autoindent_txs.drain(..) {
2062                tx.send(()).ok();
2063            }
2064        }
2065    }
2066
2067    fn compute_autoindents(
2068        &self,
2069    ) -> Option<impl Future<Output = BTreeMap<u32, IndentSize>> + use<>> {
2070        let max_rows_between_yields = 100;
2071        let snapshot = self.snapshot();
2072        if snapshot.syntax.is_empty() || self.autoindent_requests.is_empty() {
2073            return None;
2074        }
2075
2076        let autoindent_requests = self.autoindent_requests.clone();
2077        Some(async move {
2078            let mut indent_sizes = BTreeMap::<u32, (IndentSize, bool)>::new();
2079            for request in autoindent_requests {
2080                // Resolve each edited range to its row in the current buffer and in the
2081                // buffer before this batch of edits.
2082                let mut row_ranges = Vec::new();
2083                let mut old_to_new_rows = BTreeMap::new();
2084                let mut language_indent_sizes_by_new_row = Vec::new();
2085                for entry in &request.entries {
2086                    let position = entry.range.start;
2087                    let new_row = position.to_point(&snapshot).row;
2088                    let new_end_row = entry.range.end.to_point(&snapshot).row + 1;
2089                    language_indent_sizes_by_new_row.push((new_row, entry.indent_size));
2090
2091                    if let Some(old_row) = entry.old_row {
2092                        old_to_new_rows.insert(old_row, new_row);
2093                    }
2094                    row_ranges.push((new_row..new_end_row, entry.original_indent_column));
2095                }
2096
2097                // Build a map containing the suggested indentation for each of the edited lines
2098                // with respect to the state of the buffer before these edits. This map is keyed
2099                // by the rows for these lines in the current state of the buffer.
2100                let mut old_suggestions = BTreeMap::<u32, (IndentSize, bool)>::default();
2101                let old_edited_ranges =
2102                    contiguous_ranges(old_to_new_rows.keys().copied(), max_rows_between_yields);
2103                let mut language_indent_sizes = language_indent_sizes_by_new_row.iter().peekable();
2104                let mut language_indent_size = IndentSize::default();
2105                for old_edited_range in old_edited_ranges {
2106                    let suggestions = request
2107                        .before_edit
2108                        .suggest_autoindents(old_edited_range.clone())
2109                        .into_iter()
2110                        .flatten();
2111                    for (old_row, suggestion) in old_edited_range.zip(suggestions) {
2112                        if let Some(suggestion) = suggestion {
2113                            let new_row = *old_to_new_rows.get(&old_row).unwrap();
2114
2115                            // Find the indent size based on the language for this row.
2116                            while let Some((row, size)) = language_indent_sizes.peek() {
2117                                if *row > new_row {
2118                                    break;
2119                                }
2120                                language_indent_size = *size;
2121                                language_indent_sizes.next();
2122                            }
2123
2124                            let suggested_indent = old_to_new_rows
2125                                .get(&suggestion.basis_row)
2126                                .and_then(|from_row| {
2127                                    Some(old_suggestions.get(from_row).copied()?.0)
2128                                })
2129                                .unwrap_or_else(|| {
2130                                    request
2131                                        .before_edit
2132                                        .indent_size_for_line(suggestion.basis_row)
2133                                })
2134                                .with_delta(suggestion.delta, language_indent_size);
2135                            old_suggestions
2136                                .insert(new_row, (suggested_indent, suggestion.within_error));
2137                        }
2138                    }
2139                    yield_now().await;
2140                }
2141
2142                // Compute new suggestions for each line, but only include them in the result
2143                // if they differ from the old suggestion for that line.
2144                let mut language_indent_sizes = language_indent_sizes_by_new_row.iter().peekable();
2145                let mut language_indent_size = IndentSize::default();
2146                for (row_range, original_indent_column) in row_ranges {
2147                    let new_edited_row_range = if request.is_block_mode {
2148                        row_range.start..row_range.start + 1
2149                    } else {
2150                        row_range.clone()
2151                    };
2152
2153                    let suggestions = snapshot
2154                        .suggest_autoindents(new_edited_row_range.clone())
2155                        .into_iter()
2156                        .flatten();
2157                    for (new_row, suggestion) in new_edited_row_range.zip(suggestions) {
2158                        if let Some(suggestion) = suggestion {
2159                            // Find the indent size based on the language for this row.
2160                            while let Some((row, size)) = language_indent_sizes.peek() {
2161                                if *row > new_row {
2162                                    break;
2163                                }
2164                                language_indent_size = *size;
2165                                language_indent_sizes.next();
2166                            }
2167
2168                            let suggested_indent = indent_sizes
2169                                .get(&suggestion.basis_row)
2170                                .copied()
2171                                .map(|e| e.0)
2172                                .unwrap_or_else(|| {
2173                                    snapshot.indent_size_for_line(suggestion.basis_row)
2174                                })
2175                                .with_delta(suggestion.delta, language_indent_size);
2176
2177                            if old_suggestions.get(&new_row).is_none_or(
2178                                |(old_indentation, was_within_error)| {
2179                                    suggested_indent != *old_indentation
2180                                        && (!suggestion.within_error || *was_within_error)
2181                                },
2182                            ) {
2183                                indent_sizes.insert(
2184                                    new_row,
2185                                    (suggested_indent, request.ignore_empty_lines),
2186                                );
2187                            }
2188                        }
2189                    }
2190
2191                    if let (true, Some(original_indent_column)) =
2192                        (request.is_block_mode, original_indent_column)
2193                    {
2194                        let new_indent =
2195                            if let Some((indent, _)) = indent_sizes.get(&row_range.start) {
2196                                *indent
2197                            } else {
2198                                snapshot.indent_size_for_line(row_range.start)
2199                            };
2200                        let delta = new_indent.len as i64 - original_indent_column as i64;
2201                        if delta != 0 {
2202                            for row in row_range.skip(1) {
2203                                indent_sizes.entry(row).or_insert_with(|| {
2204                                    let mut size = snapshot.indent_size_for_line(row);
2205                                    // A line with no indentation has an arbitrary
2206                                    // indent kind, so it can adopt the new kind.
2207                                    if size.len == 0 {
2208                                        size.kind = new_indent.kind;
2209                                    }
2210                                    if size.kind == new_indent.kind {
2211                                        match delta.cmp(&0) {
2212                                            Ordering::Greater => size.len += delta as u32,
2213                                            Ordering::Less => {
2214                                                size.len = size.len.saturating_sub(-delta as u32)
2215                                            }
2216                                            Ordering::Equal => {}
2217                                        }
2218                                    }
2219                                    (size, request.ignore_empty_lines)
2220                                });
2221                            }
2222                        }
2223                    }
2224
2225                    yield_now().await;
2226                }
2227            }
2228
2229            indent_sizes
2230                .into_iter()
2231                .filter_map(|(row, (indent, ignore_empty_lines))| {
2232                    if ignore_empty_lines && snapshot.line_len(row) == 0 {
2233                        None
2234                    } else {
2235                        Some((row, indent))
2236                    }
2237                })
2238                .collect()
2239        })
2240    }
2241
2242    fn apply_autoindents(
2243        &mut self,
2244        indent_sizes: BTreeMap<u32, IndentSize>,
2245        cx: &mut Context<Self>,
2246    ) {
2247        self.autoindent_requests.clear();
2248        for tx in self.wait_for_autoindent_txs.drain(..) {
2249            tx.send(()).ok();
2250        }
2251
2252        let edits: Vec<_> = indent_sizes
2253            .into_iter()
2254            .filter_map(|(row, indent_size)| {
2255                let current_size = indent_size_for_line(self, row);
2256                Self::edit_for_indent_size_adjustment(row, current_size, indent_size)
2257            })
2258            .collect();
2259
2260        let preserve_preview = self.preserve_preview();
2261        self.edit(edits, None, cx);
2262        if preserve_preview {
2263            self.refresh_preview();
2264        }
2265    }
2266
2267    /// Create a minimal edit that will cause the given row to be indented
2268    /// with the given size. After applying this edit, the length of the line
2269    /// will always be at least `new_size.len`.
2270    pub fn edit_for_indent_size_adjustment(
2271        row: u32,
2272        current_size: IndentSize,
2273        new_size: IndentSize,
2274    ) -> Option<(Range<Point>, String)> {
2275        if new_size.kind == current_size.kind {
2276            match new_size.len.cmp(&current_size.len) {
2277                Ordering::Greater => {
2278                    let point = Point::new(row, 0);
2279                    Some((
2280                        point..point,
2281                        iter::repeat(new_size.char())
2282                            .take((new_size.len - current_size.len) as usize)
2283                            .collect::<String>(),
2284                    ))
2285                }
2286
2287                Ordering::Less => Some((
2288                    Point::new(row, 0)..Point::new(row, current_size.len - new_size.len),
2289                    String::new(),
2290                )),
2291
2292                Ordering::Equal => None,
2293            }
2294        } else {
2295            Some((
2296                Point::new(row, 0)..Point::new(row, current_size.len),
2297                iter::repeat(new_size.char())
2298                    .take(new_size.len as usize)
2299                    .collect::<String>(),
2300            ))
2301        }
2302    }
2303
2304    /// Spawns a background task that asynchronously computes a `Diff` between the buffer's text
2305    /// and the given new text.
2306    pub fn diff<T>(&self, new_text: T, cx: &App) -> Task<Diff>
2307    where
2308        T: AsRef<str> + Send + 'static,
2309    {
2310        let old_text = self.as_rope().clone();
2311        let base_version = self.version();
2312        cx.background_spawn(async move {
2313            let old_text = old_text.to_string();
2314            let mut new_text = new_text.as_ref().to_owned();
2315            let line_ending = LineEnding::detect(&new_text);
2316            LineEnding::normalize(&mut new_text);
2317            let edits = text_diff(&old_text, &new_text);
2318            Diff {
2319                base_version,
2320                line_ending,
2321                edits,
2322            }
2323        })
2324    }
2325
2326    /// Spawns a background task that returns a `Diff` removing trailing whitespace from line ends.
2327    ///
2328    /// When `modified_rows` is `Some`, only lines whose row falls within one of the given ranges
2329    /// are trimmed; when it is `None`, the whole buffer is scanned.
2330    pub fn remove_trailing_whitespace(
2331        &self,
2332        modified_rows: Option<&[Range<u32>]>,
2333        cx: &App,
2334    ) -> Task<Diff> {
2335        let old_text = self.as_rope().clone();
2336        let line_ending = self.line_ending();
2337        let base_version = self.version();
2338        let modified_rows = modified_rows.map(|rows| rows.to_vec());
2339        cx.background_spawn(async move {
2340            let ranges = trailing_whitespace_ranges(&old_text, modified_rows.as_deref());
2341            let empty = Arc::<str>::from("");
2342            Diff {
2343                base_version,
2344                line_ending,
2345                edits: ranges
2346                    .into_iter()
2347                    .map(|range| (range, empty.clone()))
2348                    .collect(),
2349            }
2350        })
2351    }
2352
2353    /// Returns a `Diff` ensuring the buffer ends with a trailing newline.
2354    ///
2355    /// When `modified_rows` is `None`, the whole buffer is considered: trailing whitespace and
2356    /// blank lines at the end of the file are collapsed into a single newline.
2357    ///
2358    /// When `modified_rows` is `Some`, the operation is scoped to a "Format Selection": a single
2359    /// newline is appended only when the last line is non-empty and its row falls within one of
2360    /// the ranges. Trailing blank lines are left intact so that formatting a selection cannot
2361    /// delete unselected rows.
2362    pub fn ensure_final_newline(&self, modified_rows: Option<&[Range<u32>]>) -> Diff {
2363        let len = self.len();
2364        let line_ending = self.line_ending();
2365        let base_version = self.version();
2366        let newline = Arc::<str>::from("\n");
2367
2368        let edits = if len == 0 {
2369            Vec::new()
2370        } else if let Some(modified_rows) = modified_rows {
2371            let max_point = self.max_point();
2372            let last_line_is_empty = max_point.column == 0;
2373            let last_row_is_modified = modified_rows
2374                .iter()
2375                .any(|range| range.contains(&max_point.row));
2376            if last_line_is_empty || !last_row_is_modified {
2377                Vec::new()
2378            } else {
2379                Vec::from([(len..len, newline)])
2380            }
2381        } else {
2382            let mut offset = len;
2383            let mut already_normalized = false;
2384            for chunk in self.as_rope().reversed_chunks_in_range(0..len) {
2385                let non_whitespace_len = chunk
2386                    .trim_end_matches(|c: char| c.is_ascii_whitespace())
2387                    .len();
2388                offset -= chunk.len();
2389                offset += non_whitespace_len;
2390                if non_whitespace_len != 0 {
2391                    already_normalized =
2392                        offset == len - 1 && chunk.get(non_whitespace_len..) == Some("\n");
2393                    break;
2394                }
2395            }
2396            if already_normalized {
2397                Vec::new()
2398            } else {
2399                Vec::from([(offset..len, newline)])
2400            }
2401        };
2402        Diff {
2403            base_version,
2404            line_ending,
2405            edits,
2406        }
2407    }
2408
2409    /// Applies a diff to the buffer. If the buffer has changed since the given diff was
2410    /// calculated, then adjust the diff to account for those changes, and discard any
2411    /// parts of the diff that conflict with those changes.
2412    pub fn apply_diff(&mut self, diff: Diff, cx: &mut Context<Self>) -> Option<TransactionId> {
2413        let snapshot = self.snapshot();
2414        let mut edits_since = snapshot.edits_since::<usize>(&diff.base_version).peekable();
2415        let mut delta = 0;
2416        let adjusted_edits = diff.edits.into_iter().filter_map(|(range, new_text)| {
2417            while let Some(edit_since) = edits_since.peek() {
2418                // If the edit occurs after a diff hunk, then it does not
2419                // affect that hunk.
2420                if edit_since.old.start > range.end {
2421                    break;
2422                }
2423                // If the edit precedes the diff hunk, then adjust the hunk
2424                // to reflect the edit.
2425                else if edit_since.old.end < range.start {
2426                    delta += edit_since.new_len() as i64 - edit_since.old_len() as i64;
2427                    edits_since.next();
2428                }
2429                // If the edit intersects a diff hunk, then discard that hunk.
2430                else {
2431                    return None;
2432                }
2433            }
2434
2435            let start = (range.start as i64 + delta) as usize;
2436            let end = (range.end as i64 + delta) as usize;
2437            Some((start..end, new_text))
2438        });
2439
2440        self.start_transaction();
2441        self.text.set_line_ending(diff.line_ending);
2442        self.edit(adjusted_edits, None, cx);
2443        self.end_transaction(cx)
2444    }
2445
2446    pub fn has_unsaved_edits(&self) -> bool {
2447        let (last_version, has_unsaved_edits) = self.has_unsaved_edits.take();
2448
2449        if last_version == self.version {
2450            self.has_unsaved_edits
2451                .set((last_version, has_unsaved_edits));
2452            return has_unsaved_edits;
2453        }
2454
2455        let has_edits = self.has_edits_since(&self.saved_version);
2456        self.has_unsaved_edits
2457            .set((self.version.clone(), has_edits));
2458        has_edits
2459    }
2460
2461    /// Checks if the buffer has unsaved changes.
2462    pub fn is_dirty(&self) -> bool {
2463        if self.capability == Capability::ReadOnly {
2464            return false;
2465        }
2466        if self.has_conflict {
2467            return true;
2468        }
2469        match self.file.as_ref().map(|f| f.disk_state()) {
2470            Some(DiskState::New) | Some(DiskState::Deleted) => {
2471                !self.is_empty() && self.has_unsaved_edits()
2472            }
2473            _ => self.has_unsaved_edits(),
2474        }
2475    }
2476
2477    /// Marks the buffer as having a conflict regardless of current buffer state.
2478    pub fn set_conflict(&mut self) {
2479        self.has_conflict = true;
2480    }
2481
2482    /// Checks if the buffer and its file have both changed since the buffer
2483    /// was last saved or reloaded.
2484    pub fn has_conflict(&self) -> bool {
2485        if self.has_conflict {
2486            return true;
2487        }
2488        let Some(file) = self.file.as_ref() else {
2489            return false;
2490        };
2491        match file.disk_state() {
2492            DiskState::New => false,
2493            DiskState::Present { mtime, .. } => match self.saved_mtime {
2494                Some(saved_mtime) => {
2495                    mtime.bad_is_greater_than(saved_mtime) && self.has_unsaved_edits()
2496                }
2497                None => true,
2498            },
2499            DiskState::Deleted => false,
2500            DiskState::Historic { .. } => false,
2501        }
2502    }
2503
2504    /// Gets a [`Subscription`] that tracks all of the changes to the buffer's text.
2505    pub fn subscribe(&mut self) -> Subscription<usize> {
2506        self.text.subscribe()
2507    }
2508
2509    /// Adds a bit to the list of bits that are set when the buffer's text changes.
2510    ///
2511    /// This allows downstream code to check if the buffer's text has changed without
2512    /// waiting for an effect cycle, which would be required if using eents.
2513    pub fn record_changes(&mut self, bit: rc::Weak<Cell<bool>>) {
2514        if let Err(ix) = self
2515            .change_bits
2516            .binary_search_by_key(&rc::Weak::as_ptr(&bit), rc::Weak::as_ptr)
2517        {
2518            self.change_bits.insert(ix, bit);
2519        }
2520    }
2521
2522    /// Set the change bit for all "listeners".
2523    fn was_changed(&mut self) {
2524        self.change_bits.retain(|change_bit| {
2525            change_bit
2526                .upgrade()
2527                .inspect(|bit| {
2528                    _ = bit.replace(true);
2529                })
2530                .is_some()
2531        });
2532    }
2533
2534    /// Starts a transaction, if one is not already in-progress. When undoing or
2535    /// redoing edits, all of the edits performed within a transaction are undone
2536    /// or redone together.
2537    pub fn start_transaction(&mut self) -> Option<TransactionId> {
2538        self.start_transaction_at(Instant::now())
2539    }
2540
2541    /// Starts a transaction, providing the current time. Subsequent transactions
2542    /// that occur within a short period of time will be grouped together. This
2543    /// is controlled by the buffer's undo grouping duration.
2544    pub fn start_transaction_at(&mut self, now: Instant) -> Option<TransactionId> {
2545        self.transaction_depth += 1;
2546        if self.was_dirty_before_starting_transaction.is_none() {
2547            self.was_dirty_before_starting_transaction = Some(self.is_dirty());
2548        }
2549        self.text.start_transaction_at(now)
2550    }
2551
2552    /// Terminates the current transaction, if this is the outermost transaction.
2553    pub fn end_transaction(&mut self, cx: &mut Context<Self>) -> Option<TransactionId> {
2554        self.end_transaction_at(Instant::now(), cx)
2555    }
2556
2557    pub fn end_transaction_with_source(
2558        &mut self,
2559        source: BufferEditSource,
2560        cx: &mut Context<Self>,
2561    ) -> Option<TransactionId> {
2562        self.end_transaction_at_internal(Instant::now(), source, cx)
2563    }
2564
2565    /// Terminates the current transaction, providing the current time. Subsequent transactions
2566    /// that occur within a short period of time will be grouped together. This
2567    /// is controlled by the buffer's undo grouping duration.
2568    pub fn end_transaction_at(
2569        &mut self,
2570        now: Instant,
2571        cx: &mut Context<Self>,
2572    ) -> Option<TransactionId> {
2573        self.end_transaction_at_internal(now, BufferEditSource::User, cx)
2574    }
2575
2576    fn end_transaction_at_internal(
2577        &mut self,
2578        now: Instant,
2579        source: BufferEditSource,
2580        cx: &mut Context<Self>,
2581    ) -> Option<TransactionId> {
2582        assert!(self.transaction_depth > 0);
2583        self.transaction_depth -= 1;
2584        let was_dirty = if self.transaction_depth == 0 {
2585            self.was_dirty_before_starting_transaction.take().unwrap()
2586        } else {
2587            false
2588        };
2589        if let Some((transaction_id, start_version)) = self.text.end_transaction_at(now) {
2590            self.did_edit(&start_version, was_dirty, source, cx);
2591            Some(transaction_id)
2592        } else {
2593            None
2594        }
2595    }
2596
2597    /// Manually add a transaction to the buffer's undo history.
2598    pub fn push_transaction(&mut self, transaction: Transaction, now: Instant) {
2599        self.text.push_transaction(transaction, now);
2600    }
2601
2602    /// Differs from `push_transaction` in that it does not clear the redo
2603    /// stack. Intended to be used to create a parent transaction to merge
2604    /// potential child transactions into.
2605    ///
2606    /// The caller is responsible for removing it from the undo history using
2607    /// `forget_transaction` if no edits are merged into it. Otherwise, if edits
2608    /// are merged into this transaction, the caller is responsible for ensuring
2609    /// the redo stack is cleared. The easiest way to ensure the redo stack is
2610    /// cleared is to create transactions with the usual `start_transaction` and
2611    /// `end_transaction` methods and merging the resulting transactions into
2612    /// the transaction created by this method
2613    pub fn push_empty_transaction(&mut self, now: Instant) -> TransactionId {
2614        self.text.push_empty_transaction(now)
2615    }
2616
2617    /// Prevent the last transaction from being grouped with any subsequent transactions,
2618    /// even if they occur with the buffer's undo grouping duration.
2619    pub fn finalize_last_transaction(&mut self) -> Option<&Transaction> {
2620        self.text.finalize_last_transaction()
2621    }
2622
2623    /// Manually group all changes since a given transaction.
2624    pub fn group_until_transaction(&mut self, transaction_id: TransactionId) {
2625        self.text.group_until_transaction(transaction_id);
2626    }
2627
2628    /// Manually remove a transaction from the buffer's undo history
2629    pub fn forget_transaction(&mut self, transaction_id: TransactionId) -> Option<Transaction> {
2630        self.text.forget_transaction(transaction_id)
2631    }
2632
2633    /// Retrieve a transaction from the buffer's undo history
2634    pub fn get_transaction(&self, transaction_id: TransactionId) -> Option<&Transaction> {
2635        self.text.get_transaction(transaction_id)
2636    }
2637
2638    /// Manually merge two transactions in the buffer's undo history.
2639    pub fn merge_transactions(&mut self, transaction: TransactionId, destination: TransactionId) {
2640        self.text.merge_transactions(transaction, destination);
2641    }
2642
2643    /// Waits for the buffer to receive operations with the given timestamps.
2644    pub fn wait_for_edits<It: IntoIterator<Item = clock::Lamport>>(
2645        &mut self,
2646        edit_ids: It,
2647    ) -> impl Future<Output = Result<()>> + use<It> {
2648        self.text.wait_for_edits(edit_ids)
2649    }
2650
2651    /// Waits for the buffer to receive the operations necessary for resolving the given anchors.
2652    pub fn wait_for_anchors<It: IntoIterator<Item = Anchor>>(
2653        &mut self,
2654        anchors: It,
2655    ) -> impl 'static + Future<Output = Result<()>> + use<It> {
2656        self.text.wait_for_anchors(anchors)
2657    }
2658
2659    /// Waits for the buffer to receive operations up to the given version.
2660    pub fn wait_for_version(
2661        &mut self,
2662        version: clock::Global,
2663    ) -> impl Future<Output = Result<()>> + use<> {
2664        self.text.wait_for_version(version)
2665    }
2666
2667    /// Forces all futures returned by [`Buffer::wait_for_version`], [`Buffer::wait_for_edits`], or
2668    /// [`Buffer::wait_for_version`] to resolve with an error.
2669    pub fn give_up_waiting(&mut self) {
2670        self.text.give_up_waiting();
2671    }
2672
2673    pub fn wait_for_autoindent_applied(&mut self) -> Option<oneshot::Receiver<()>> {
2674        let mut rx = None;
2675        if !self.autoindent_requests.is_empty() {
2676            let channel = oneshot::channel();
2677            self.wait_for_autoindent_txs.push(channel.0);
2678            rx = Some(channel.1);
2679        }
2680        rx
2681    }
2682
2683    /// Stores a set of selections that should be broadcasted to all of the buffer's replicas.
2684    pub fn set_active_selections(
2685        &mut self,
2686        selections: Arc<[Selection<Anchor>]>,
2687        line_mode: bool,
2688        cursor_shape: CursorShape,
2689        cx: &mut Context<Self>,
2690    ) {
2691        let lamport_timestamp = self.text.lamport_clock.tick();
2692        self.remote_selections.insert(
2693            self.text.replica_id(),
2694            SelectionSet {
2695                selections: selections.clone(),
2696                lamport_timestamp,
2697                line_mode,
2698                cursor_shape,
2699            },
2700        );
2701        self.send_operation(
2702            Operation::UpdateSelections {
2703                selections,
2704                line_mode,
2705                lamport_timestamp,
2706                cursor_shape,
2707            },
2708            true,
2709            cx,
2710        );
2711        self.non_text_state_update_count += 1;
2712        cx.notify();
2713    }
2714
2715    /// Clears the selections, so that other replicas of the buffer do not see any selections for
2716    /// this replica.
2717    pub fn remove_active_selections(&mut self, cx: &mut Context<Self>) {
2718        if self
2719            .remote_selections
2720            .get(&self.text.replica_id())
2721            .is_none_or(|set| !set.selections.is_empty())
2722        {
2723            self.set_active_selections(Arc::default(), false, Default::default(), cx);
2724        }
2725    }
2726
2727    pub fn set_agent_selections(
2728        &mut self,
2729        selections: Arc<[Selection<Anchor>]>,
2730        line_mode: bool,
2731        cursor_shape: CursorShape,
2732        cx: &mut Context<Self>,
2733    ) {
2734        let lamport_timestamp = self.text.lamport_clock.tick();
2735        self.remote_selections.insert(
2736            ReplicaId::AGENT,
2737            SelectionSet {
2738                selections,
2739                lamport_timestamp,
2740                line_mode,
2741                cursor_shape,
2742            },
2743        );
2744        self.non_text_state_update_count += 1;
2745        cx.notify();
2746    }
2747
2748    pub fn remove_agent_selections(&mut self, cx: &mut Context<Self>) {
2749        self.set_agent_selections(Arc::default(), false, Default::default(), cx);
2750    }
2751
2752    /// Replaces the buffer's entire text.
2753    pub fn set_text<T>(&mut self, text: T, cx: &mut Context<Self>) -> Option<clock::Lamport>
2754    where
2755        T: Into<Arc<str>>,
2756    {
2757        self.autoindent_requests.clear();
2758        self.edit([(0..self.len(), text)], None, cx)
2759    }
2760
2761    /// Appends the given text to the end of the buffer.
2762    pub fn append<T>(&mut self, text: T, cx: &mut Context<Self>) -> Option<clock::Lamport>
2763    where
2764        T: Into<Arc<str>>,
2765    {
2766        self.edit([(self.len()..self.len(), text)], None, cx)
2767    }
2768
2769    /// Applies the given edits to the buffer. Each edit is specified as a range of text to
2770    /// delete, and a string of text to insert at that location. Adjacent edits are coalesced.
2771    /// Inserted text is normalized to LF line endings before being applied.
2772    ///
2773    /// If an [`AutoindentMode`] is provided, then the buffer will enqueue an auto-indent
2774    /// request for the edited ranges, which will be processed when the buffer finishes
2775    /// parsing.
2776    ///
2777    /// Parsing takes place at the end of a transaction, and may compute synchronously
2778    /// or asynchronously, depending on the changes.
2779    pub fn edit<I, S, T>(
2780        &mut self,
2781        edits_iter: I,
2782        autoindent_mode: Option<AutoindentMode>,
2783        cx: &mut Context<Self>,
2784    ) -> Option<clock::Lamport>
2785    where
2786        I: IntoIterator<Item = (Range<S>, T)>,
2787        S: ToOffset,
2788        T: Into<Arc<str>>,
2789    {
2790        self.edit_internal(edits_iter, autoindent_mode, true, cx)
2791    }
2792
2793    /// Like [`edit`](Self::edit), but does not coalesce adjacent edits.
2794    pub fn edit_non_coalesce<I, S, T>(
2795        &mut self,
2796        edits_iter: I,
2797        autoindent_mode: Option<AutoindentMode>,
2798        cx: &mut Context<Self>,
2799    ) -> Option<clock::Lamport>
2800    where
2801        I: IntoIterator<Item = (Range<S>, T)>,
2802        S: ToOffset,
2803        T: Into<Arc<str>>,
2804    {
2805        self.edit_internal(edits_iter, autoindent_mode, false, cx)
2806    }
2807
2808    fn edit_internal<I, S, T>(
2809        &mut self,
2810        edits_iter: I,
2811        autoindent_mode: Option<AutoindentMode>,
2812        coalesce_adjacent: bool,
2813        cx: &mut Context<Self>,
2814    ) -> Option<clock::Lamport>
2815    where
2816        I: IntoIterator<Item = (Range<S>, T)>,
2817        S: ToOffset,
2818        T: Into<Arc<str>>,
2819    {
2820        // Skip invalid edits and coalesce contiguous ones.
2821        let mut edits: Vec<(Range<usize>, Arc<str>)> = Vec::new();
2822
2823        for (range, new_text) in edits_iter {
2824            let mut range = range.start.to_offset(self)..range.end.to_offset(self);
2825
2826            if range.start > range.end {
2827                mem::swap(&mut range.start, &mut range.end);
2828            }
2829            let new_text = new_text.into();
2830            if !new_text.is_empty() || !range.is_empty() {
2831                let prev_edit = edits.last_mut();
2832                let should_coalesce = prev_edit.as_ref().is_some_and(|(prev_range, _)| {
2833                    if coalesce_adjacent {
2834                        prev_range.end >= range.start
2835                    } else {
2836                        prev_range.end > range.start
2837                    }
2838                });
2839
2840                if let Some((prev_range, prev_text)) = prev_edit
2841                    && should_coalesce
2842                {
2843                    prev_range.end = cmp::max(prev_range.end, range.end);
2844                    *prev_text = format!("{prev_text}{new_text}").into();
2845                } else {
2846                    edits.push((range, new_text));
2847                }
2848            }
2849        }
2850        if edits.is_empty() {
2851            return None;
2852        }
2853
2854        self.start_transaction();
2855        self.pending_autoindent.take();
2856        let autoindent_request = autoindent_mode
2857            .and_then(|mode| self.language.as_ref().map(|_| (self.snapshot(), mode)));
2858
2859        let edit_operation = self.text.edit(edits.iter().cloned());
2860        let edit_id = edit_operation.timestamp();
2861
2862        if let Some((before_edit, mode)) = autoindent_request {
2863            let mut delta = 0isize;
2864            let mut previous_setting = None;
2865            let entries: Vec<_> = edits
2866                .into_iter()
2867                .enumerate()
2868                .zip(&edit_operation.as_edit().unwrap().new_text)
2869                .filter(|((_, (range, _)), _)| {
2870                    let language = before_edit.language_at(range.start);
2871                    let language_id = language.map(|l| l.id());
2872                    if let Some((cached_language_id, apply_syntax_indent)) = previous_setting
2873                        && cached_language_id == language_id
2874                    {
2875                        apply_syntax_indent
2876                    } else {
2877                        // The auto-indent setting is not present in editorconfigs, hence
2878                        // we can avoid passing the file here.
2879                        let auto_indent_mode = LanguageSettings::resolve(
2880                            None,
2881                            language.map(|l| l.name()).as_ref(),
2882                            cx,
2883                        )
2884                        .auto_indent;
2885                        let apply_syntax_indent = auto_indent_mode == AutoIndentMode::SyntaxAware;
2886                        previous_setting = Some((language_id, apply_syntax_indent));
2887                        apply_syntax_indent
2888                    }
2889                })
2890                .map(|((ix, (range, _)), new_text)| {
2891                    let new_text_length = new_text.len();
2892                    let old_start = range.start.to_point(&before_edit);
2893                    let new_start = (delta + range.start as isize) as usize;
2894                    let range_len = range.end - range.start;
2895                    delta += new_text_length as isize - range_len as isize;
2896
2897                    // Decide what range of the insertion to auto-indent, and whether
2898                    // the first line of the insertion should be considered a newly-inserted line
2899                    // or an edit to an existing line.
2900                    let mut range_of_insertion_to_indent = 0..new_text_length;
2901                    let mut first_line_is_new = true;
2902
2903                    let old_line_start = before_edit.indent_size_for_line(old_start.row).len;
2904                    let old_line_end = before_edit.line_len(old_start.row);
2905
2906                    if old_start.column > old_line_start {
2907                        first_line_is_new = false;
2908                    }
2909
2910                    if !new_text.contains('\n')
2911                        && (old_start.column + (range_len as u32) < old_line_end
2912                            || old_line_end == old_line_start)
2913                    {
2914                        first_line_is_new = false;
2915                    }
2916
2917                    // When inserting text starting with a newline, avoid auto-indenting the
2918                    // previous line.
2919                    if new_text.starts_with('\n') {
2920                        range_of_insertion_to_indent.start += 1;
2921                        first_line_is_new = true;
2922                    }
2923
2924                    let mut original_indent_column = None;
2925                    if let AutoindentMode::Block {
2926                        original_indent_columns,
2927                    } = &mode
2928                    {
2929                        original_indent_column = Some(if new_text.starts_with('\n') {
2930                            indent_size_for_text(
2931                                new_text[range_of_insertion_to_indent.clone()].chars(),
2932                            )
2933                            .len
2934                        } else {
2935                            original_indent_columns
2936                                .get(ix)
2937                                .copied()
2938                                .flatten()
2939                                .unwrap_or_else(|| {
2940                                    indent_size_for_text(
2941                                        new_text[range_of_insertion_to_indent.clone()].chars(),
2942                                    )
2943                                    .len
2944                                })
2945                        });
2946
2947                        // Avoid auto-indenting the line after the edit.
2948                        if new_text[range_of_insertion_to_indent.clone()].ends_with('\n') {
2949                            range_of_insertion_to_indent.end -= 1;
2950                        }
2951                    }
2952
2953                    AutoindentRequestEntry {
2954                        original_indent_column,
2955                        old_row: if first_line_is_new {
2956                            None
2957                        } else {
2958                            Some(old_start.row)
2959                        },
2960                        indent_size: before_edit.language_indent_size_at(range.start, cx),
2961                        range: self.anchor_before(new_start + range_of_insertion_to_indent.start)
2962                            ..self.anchor_after(new_start + range_of_insertion_to_indent.end),
2963                    }
2964                })
2965                .collect();
2966
2967            if !entries.is_empty() {
2968                self.autoindent_requests.push(Arc::new(AutoindentRequest {
2969                    before_edit,
2970                    entries,
2971                    is_block_mode: matches!(mode, AutoindentMode::Block { .. }),
2972                    ignore_empty_lines: false,
2973                }));
2974            }
2975        }
2976
2977        self.end_transaction(cx);
2978        self.send_operation(Operation::Buffer(edit_operation), true, cx);
2979        Some(edit_id)
2980    }
2981
2982    fn did_edit(
2983        &mut self,
2984        old_version: &clock::Global,
2985        was_dirty: bool,
2986        source: BufferEditSource,
2987        cx: &mut Context<Self>,
2988    ) {
2989        self.was_changed();
2990
2991        if self.edits_since::<usize>(old_version).next().is_none() {
2992            return;
2993        }
2994
2995        self.reparse(cx, true);
2996        cx.emit(BufferEvent::Edited { source });
2997        let is_dirty = self.is_dirty();
2998        if was_dirty != is_dirty {
2999            cx.emit(BufferEvent::DirtyChanged);
3000        }
3001        if was_dirty && !is_dirty {
3002            if let Some(file) = self.file.as_ref() {
3003                if matches!(file.disk_state(), DiskState::Present { .. })
3004                    && file.disk_state().mtime() != self.saved_mtime
3005                {
3006                    cx.emit(BufferEvent::ReloadNeeded);
3007                }
3008            }
3009        }
3010        cx.notify();
3011    }
3012
3013    pub fn autoindent_ranges<I, T>(&mut self, ranges: I, cx: &mut Context<Self>)
3014    where
3015        I: IntoIterator<Item = Range<T>>,
3016        T: ToOffset + Copy,
3017    {
3018        let before_edit = self.snapshot();
3019        let entries = ranges
3020            .into_iter()
3021            .map(|range| AutoindentRequestEntry {
3022                range: before_edit.anchor_before(range.start)..before_edit.anchor_after(range.end),
3023                old_row: None,
3024                indent_size: before_edit.language_indent_size_at(range.start, cx),
3025                original_indent_column: None,
3026            })
3027            .collect();
3028        self.autoindent_requests.push(Arc::new(AutoindentRequest {
3029            before_edit,
3030            entries,
3031            is_block_mode: false,
3032            ignore_empty_lines: true,
3033        }));
3034        self.request_autoindent(cx, Some(Duration::from_micros(300)));
3035    }
3036
3037    // Inserts newlines at the given position to create an empty line, returning the start of the new line.
3038    // You can also request the insertion of empty lines above and below the line starting at the returned point.
3039    pub fn insert_empty_line(
3040        &mut self,
3041        position: impl ToPoint,
3042        space_above: bool,
3043        space_below: bool,
3044        cx: &mut Context<Self>,
3045    ) -> Point {
3046        let mut position = position.to_point(self);
3047
3048        self.start_transaction();
3049
3050        self.edit(
3051            [(position..position, "\n")],
3052            Some(AutoindentMode::EachLine),
3053            cx,
3054        );
3055
3056        if position.column > 0 {
3057            position += Point::new(1, 0);
3058        }
3059
3060        if !self.is_line_blank(position.row) {
3061            self.edit(
3062                [(position..position, "\n")],
3063                Some(AutoindentMode::EachLine),
3064                cx,
3065            );
3066        }
3067
3068        if space_above && position.row > 0 && !self.is_line_blank(position.row - 1) {
3069            self.edit(
3070                [(position..position, "\n")],
3071                Some(AutoindentMode::EachLine),
3072                cx,
3073            );
3074            position.row += 1;
3075        }
3076
3077        if space_below
3078            && (position.row == self.max_point().row || !self.is_line_blank(position.row + 1))
3079        {
3080            self.edit(
3081                [(position..position, "\n")],
3082                Some(AutoindentMode::EachLine),
3083                cx,
3084            );
3085        }
3086
3087        self.end_transaction(cx);
3088
3089        position
3090    }
3091
3092    /// Applies the given remote operations to the buffer.
3093    pub fn apply_ops<I: IntoIterator<Item = Operation>>(&mut self, ops: I, cx: &mut Context<Self>) {
3094        self.pending_autoindent.take();
3095        let was_dirty = self.is_dirty();
3096        let old_version = self.version.clone();
3097        let mut deferred_ops = Vec::new();
3098        let buffer_ops = ops
3099            .into_iter()
3100            .filter_map(|op| match op {
3101                Operation::Buffer(op) => Some(op),
3102                _ => {
3103                    if self.can_apply_op(&op) {
3104                        self.apply_op(op, cx);
3105                    } else {
3106                        deferred_ops.push(op);
3107                    }
3108                    None
3109                }
3110            })
3111            .collect::<Vec<_>>();
3112        for operation in buffer_ops.iter() {
3113            self.send_operation(Operation::Buffer(operation.clone()), false, cx);
3114        }
3115        self.text.apply_ops(buffer_ops);
3116        self.deferred_ops.insert(deferred_ops);
3117        self.flush_deferred_ops(cx);
3118        self.did_edit(&old_version, was_dirty, BufferEditSource::Remote, cx);
3119        // Notify independently of whether the buffer was edited as the operations could include a
3120        // selection update.
3121        cx.notify();
3122    }
3123
3124    fn flush_deferred_ops(&mut self, cx: &mut Context<Self>) {
3125        let mut deferred_ops = Vec::new();
3126        for op in self.deferred_ops.drain().iter().cloned() {
3127            if self.can_apply_op(&op) {
3128                self.apply_op(op, cx);
3129            } else {
3130                deferred_ops.push(op);
3131            }
3132        }
3133        self.deferred_ops.insert(deferred_ops);
3134    }
3135
3136    pub fn has_deferred_ops(&self) -> bool {
3137        !self.deferred_ops.is_empty() || self.text.has_deferred_ops()
3138    }
3139
3140    fn can_apply_op(&self, operation: &Operation) -> bool {
3141        match operation {
3142            Operation::Buffer(_) => {
3143                unreachable!("buffer operations should never be applied at this layer")
3144            }
3145            Operation::UpdateDiagnostics {
3146                diagnostics: diagnostic_set,
3147                ..
3148            } => diagnostic_set.iter().all(|diagnostic| {
3149                self.text.can_resolve(&diagnostic.range.start)
3150                    && self.text.can_resolve(&diagnostic.range.end)
3151            }),
3152            Operation::UpdateSelections { selections, .. } => selections
3153                .iter()
3154                .all(|s| self.can_resolve(&s.start) && self.can_resolve(&s.end)),
3155            Operation::UpdateCompletionTriggers { .. } | Operation::UpdateLineEnding { .. } => true,
3156        }
3157    }
3158
3159    fn apply_op(&mut self, operation: Operation, cx: &mut Context<Self>) {
3160        match operation {
3161            Operation::Buffer(_) => {
3162                unreachable!("buffer operations should never be applied at this layer")
3163            }
3164            Operation::UpdateDiagnostics {
3165                server_id,
3166                diagnostics: diagnostic_set,
3167                lamport_timestamp,
3168            } => {
3169                let snapshot = self.snapshot();
3170                self.apply_diagnostic_update(
3171                    server_id,
3172                    DiagnosticSet::from_sorted_entries(diagnostic_set.iter().cloned(), &snapshot),
3173                    lamport_timestamp,
3174                    cx,
3175                );
3176            }
3177            Operation::UpdateSelections {
3178                selections,
3179                lamport_timestamp,
3180                line_mode,
3181                cursor_shape,
3182            } => {
3183                if let Some(set) = self.remote_selections.get(&lamport_timestamp.replica_id)
3184                    && set.lamport_timestamp > lamport_timestamp
3185                {
3186                    return;
3187                }
3188
3189                self.remote_selections.insert(
3190                    lamport_timestamp.replica_id,
3191                    SelectionSet {
3192                        selections,
3193                        lamport_timestamp,
3194                        line_mode,
3195                        cursor_shape,
3196                    },
3197                );
3198                self.text.lamport_clock.observe(lamport_timestamp);
3199                self.non_text_state_update_count += 1;
3200            }
3201            Operation::UpdateCompletionTriggers {
3202                triggers,
3203                lamport_timestamp,
3204                server_id,
3205            } => {
3206                if triggers.is_empty() {
3207                    self.completion_triggers_per_language_server
3208                        .remove(&server_id);
3209                } else {
3210                    self.completion_triggers_per_language_server
3211                        .insert(server_id, triggers.into_iter().collect());
3212                }
3213                self.completion_triggers = self
3214                    .completion_triggers_per_language_server
3215                    .values()
3216                    .flat_map(|triggers| triggers.iter().cloned())
3217                    .collect();
3218                self.text.lamport_clock.observe(lamport_timestamp);
3219            }
3220            Operation::UpdateLineEnding {
3221                line_ending,
3222                lamport_timestamp,
3223            } => {
3224                self.text.set_line_ending(line_ending);
3225                self.text.lamport_clock.observe(lamport_timestamp);
3226            }
3227        }
3228    }
3229
3230    fn apply_diagnostic_update(
3231        &mut self,
3232        server_id: LanguageServerId,
3233        diagnostics: DiagnosticSet,
3234        lamport_timestamp: clock::Lamport,
3235        cx: &mut Context<Self>,
3236    ) {
3237        if lamport_timestamp > self.diagnostics_timestamp {
3238            if diagnostics.is_empty() {
3239                self.diagnostics.remove(&server_id);
3240            } else {
3241                self.diagnostics.insert(server_id, diagnostics);
3242            }
3243            self.diagnostics_timestamp = lamport_timestamp;
3244            self.non_text_state_update_count += 1;
3245            self.text.lamport_clock.observe(lamport_timestamp);
3246            cx.notify();
3247            cx.emit(BufferEvent::DiagnosticsUpdated);
3248        }
3249    }
3250
3251    fn send_operation(&mut self, operation: Operation, is_local: bool, cx: &mut Context<Self>) {
3252        self.was_changed();
3253        cx.emit(BufferEvent::Operation {
3254            operation,
3255            is_local,
3256        });
3257    }
3258
3259    /// Removes the selections for a given peer.
3260    pub fn remove_peer(&mut self, replica_id: ReplicaId, cx: &mut Context<Self>) {
3261        self.remote_selections.remove(&replica_id);
3262        cx.notify();
3263    }
3264
3265    /// Undoes the most recent transaction.
3266    pub fn undo(&mut self, cx: &mut Context<Self>) -> Option<TransactionId> {
3267        let was_dirty = self.is_dirty();
3268        let old_version = self.version.clone();
3269
3270        if let Some((transaction_id, operation)) = self.text.undo() {
3271            self.send_operation(Operation::Buffer(operation), true, cx);
3272            self.did_edit(&old_version, was_dirty, BufferEditSource::User, cx);
3273            self.restore_encoding_for_transaction(transaction_id, was_dirty);
3274            Some(transaction_id)
3275        } else {
3276            None
3277        }
3278    }
3279
3280    /// Manually undoes a specific transaction in the buffer's undo history.
3281    pub fn undo_transaction(
3282        &mut self,
3283        transaction_id: TransactionId,
3284        cx: &mut Context<Self>,
3285    ) -> bool {
3286        let was_dirty = self.is_dirty();
3287        let old_version = self.version.clone();
3288        if let Some(operation) = self.text.undo_transaction(transaction_id) {
3289            self.send_operation(Operation::Buffer(operation), true, cx);
3290            self.did_edit(&old_version, was_dirty, BufferEditSource::User, cx);
3291            true
3292        } else {
3293            false
3294        }
3295    }
3296
3297    /// Manually undoes all changes after a given transaction in the buffer's undo history.
3298    pub fn undo_to_transaction(
3299        &mut self,
3300        transaction_id: TransactionId,
3301        cx: &mut Context<Self>,
3302    ) -> bool {
3303        let was_dirty = self.is_dirty();
3304        let old_version = self.version.clone();
3305
3306        let operations = self.text.undo_to_transaction(transaction_id);
3307        let undone = !operations.is_empty();
3308        for operation in operations {
3309            self.send_operation(Operation::Buffer(operation), true, cx);
3310        }
3311        if undone {
3312            self.did_edit(&old_version, was_dirty, BufferEditSource::User, cx)
3313        }
3314        undone
3315    }
3316
3317    pub fn undo_operations(&mut self, counts: HashMap<Lamport, u32>, cx: &mut Context<Buffer>) {
3318        let was_dirty = self.is_dirty();
3319        let operation = self.text.undo_operations(counts);
3320        let old_version = self.version.clone();
3321        self.send_operation(Operation::Buffer(operation), true, cx);
3322        self.did_edit(&old_version, was_dirty, BufferEditSource::User, cx);
3323    }
3324
3325    /// Manually redoes a specific transaction in the buffer's redo history.
3326    pub fn redo(&mut self, cx: &mut Context<Self>) -> Option<TransactionId> {
3327        let was_dirty = self.is_dirty();
3328        let old_version = self.version.clone();
3329
3330        if let Some((transaction_id, operation)) = self.text.redo() {
3331            self.send_operation(Operation::Buffer(operation), true, cx);
3332            self.did_edit(&old_version, was_dirty, BufferEditSource::User, cx);
3333            self.restore_encoding_for_transaction(transaction_id, was_dirty);
3334            Some(transaction_id)
3335        } else {
3336            None
3337        }
3338    }
3339
3340    fn restore_encoding_for_transaction(&mut self, transaction_id: TransactionId, was_dirty: bool) {
3341        if let Some((old_encoding, old_has_bom)) =
3342            self.reload_with_encoding_txns.get(&transaction_id)
3343        {
3344            let current_encoding = self.encoding;
3345            let current_has_bom = self.has_bom;
3346            self.encoding = *old_encoding;
3347            self.has_bom = *old_has_bom;
3348            if !was_dirty {
3349                self.saved_version = self.version.clone();
3350                self.has_unsaved_edits
3351                    .set((self.saved_version.clone(), false));
3352            }
3353            self.reload_with_encoding_txns
3354                .insert(transaction_id, (current_encoding, current_has_bom));
3355        }
3356    }
3357
3358    /// Manually undoes all changes until a given transaction in the buffer's redo history.
3359    pub fn redo_to_transaction(
3360        &mut self,
3361        transaction_id: TransactionId,
3362        cx: &mut Context<Self>,
3363    ) -> bool {
3364        let was_dirty = self.is_dirty();
3365        let old_version = self.version.clone();
3366
3367        let operations = self.text.redo_to_transaction(transaction_id);
3368        let redone = !operations.is_empty();
3369        for operation in operations {
3370            self.send_operation(Operation::Buffer(operation), true, cx);
3371        }
3372        if redone {
3373            self.did_edit(&old_version, was_dirty, BufferEditSource::User, cx)
3374        }
3375        redone
3376    }
3377
3378    /// Override current completion triggers with the user-provided completion triggers.
3379    pub fn set_completion_triggers(
3380        &mut self,
3381        server_id: LanguageServerId,
3382        triggers: BTreeSet<String>,
3383        cx: &mut Context<Self>,
3384    ) {
3385        self.completion_triggers_timestamp = self.text.lamport_clock.tick();
3386        if triggers.is_empty() {
3387            self.completion_triggers_per_language_server
3388                .remove(&server_id);
3389        } else {
3390            self.completion_triggers_per_language_server
3391                .insert(server_id, triggers.clone());
3392        }
3393        self.completion_triggers = self
3394            .completion_triggers_per_language_server
3395            .values()
3396            .flat_map(|triggers| triggers.iter().cloned())
3397            .collect();
3398        self.send_operation(
3399            Operation::UpdateCompletionTriggers {
3400                triggers: triggers.into_iter().collect(),
3401                lamport_timestamp: self.completion_triggers_timestamp,
3402                server_id,
3403            },
3404            true,
3405            cx,
3406        );
3407        cx.notify();
3408    }
3409
3410    /// Returns a list of strings which trigger a completion menu for this language.
3411    /// Usually this is driven by LSP server which returns a list of trigger characters for completions.
3412    pub fn completion_triggers(&self) -> &BTreeSet<String> {
3413        &self.completion_triggers
3414    }
3415
3416    /// Call this directly after performing edits to prevent the preview tab
3417    /// from being dismissed by those edits. It causes `should_dismiss_preview`
3418    /// to return false until there are additional edits.
3419    pub fn refresh_preview(&mut self) {
3420        self.preview_version = self.version.clone();
3421    }
3422
3423    /// Whether we should preserve the preview status of a tab containing this buffer.
3424    pub fn preserve_preview(&self) -> bool {
3425        !self.has_edits_since(&self.preview_version)
3426    }
3427
3428    pub fn set_group_interval(&mut self, group_interval: Duration) {
3429        self.text.set_group_interval(group_interval);
3430    }
3431
3432    // TODO: see if ep can use this instead of Buffer::branch
3433    pub fn snapshot_with_edits<I, S, T>(
3434        &mut self,
3435        edits: I,
3436        cx: &mut Context<Self>,
3437    ) -> Task<EditedBufferSnapshot>
3438    where
3439        I: IntoIterator<Item = (Range<S>, T)>,
3440        S: ToOffset,
3441        T: Into<Arc<str>>,
3442    {
3443        let mut snapshot = self.snapshot();
3444        let text = snapshot.text.clone();
3445        let mut syntax = snapshot.syntax.clone();
3446        let language = self.language().cloned();
3447        let registry = self.language_registry();
3448        let new_text = self.text.snapshot_with_edits(edits);
3449        cx.background_spawn(async move {
3450            if let Some(language) = language.clone() {
3451                syntax.reparse(&text, registry.clone(), language);
3452            }
3453
3454            syntax.interpolate(&new_text.snapshot);
3455
3456            if let Some(language) = language {
3457                syntax.reparse(&new_text.snapshot, registry, language);
3458            }
3459
3460            snapshot.text = new_text.snapshot.clone();
3461            snapshot.syntax = syntax;
3462
3463            EditedBufferSnapshot {
3464                text: new_text,
3465                snapshot,
3466            }
3467        })
3468    }
3469
3470    pub fn fast_forward(&mut self, edited: EditedBufferSnapshot, cx: &mut Context<Self>) {
3471        let base_version = edited.text.base_version.clone();
3472        let did_edit = edited.text.did_edit;
3473        self.text.fast_forward(edited.text);
3474        if edited.snapshot.language == self.language {
3475            self.reparse = None;
3476            self.did_finish_parsing(edited.snapshot.syntax, None, cx);
3477            if did_edit {
3478                cx.emit(BufferEvent::Edited {
3479                    source: BufferEditSource::User,
3480                });
3481            }
3482        } else {
3483            self.did_edit(&base_version, false, BufferEditSource::User, cx);
3484        }
3485    }
3486}
3487
3488pub struct EditedBufferSnapshot {
3489    text: text::EditedBufferSnapshot,
3490    snapshot: BufferSnapshot,
3491}
3492
3493impl EditedBufferSnapshot {
3494    pub fn snapshot(&self) -> &BufferSnapshot {
3495        &self.snapshot
3496    }
3497
3498    pub fn base_version(&self) -> &clock::Global {
3499        &self.text.base_version
3500    }
3501}
3502
3503#[doc(hidden)]
3504#[cfg(any(test, feature = "test-support"))]
3505impl Buffer {
3506    pub fn edit_via_marked_text(
3507        &mut self,
3508        marked_string: &str,
3509        autoindent_mode: Option<AutoindentMode>,
3510        cx: &mut Context<Self>,
3511    ) {
3512        let edits = self.edits_for_marked_text(marked_string);
3513        self.edit(edits, autoindent_mode, cx);
3514    }
3515
3516    pub fn randomly_edit<T>(&mut self, rng: &mut T, old_range_count: usize, cx: &mut Context<Self>)
3517    where
3518        T: rand::Rng,
3519    {
3520        let mut edits: Vec<(Range<usize>, String)> = Vec::new();
3521        let mut last_end = None;
3522        for _ in 0..old_range_count {
3523            if last_end.is_some_and(|last_end| last_end >= self.len()) {
3524                break;
3525            }
3526
3527            let new_start = last_end.map_or(0, |last_end| last_end + 1);
3528            let mut range = self.random_byte_range(new_start, rng);
3529            if rng.random_bool(0.2) {
3530                mem::swap(&mut range.start, &mut range.end);
3531            }
3532            last_end = Some(range.end);
3533
3534            let new_text_len = rng.random_range(0..10);
3535            let mut new_text: String = RandomCharIter::new(&mut *rng).take(new_text_len).collect();
3536            new_text = new_text.to_uppercase();
3537
3538            edits.push((range, new_text));
3539        }
3540        log::info!("mutating buffer {:?} with {:?}", self.replica_id(), edits);
3541        self.edit(edits, None, cx);
3542    }
3543
3544    pub fn randomly_undo_redo(&mut self, rng: &mut impl rand::Rng, cx: &mut Context<Self>) {
3545        let was_dirty = self.is_dirty();
3546        let old_version = self.version.clone();
3547
3548        let ops = self.text.randomly_undo_redo(rng);
3549        if !ops.is_empty() {
3550            for op in ops {
3551                self.send_operation(Operation::Buffer(op), true, cx);
3552                self.did_edit(&old_version, was_dirty, BufferEditSource::User, cx);
3553            }
3554        }
3555    }
3556}
3557
3558impl EventEmitter<BufferEvent> for Buffer {}
3559
3560fn offset_in_sub_ranges(
3561    sub_ranges: &[Range<Anchor>],
3562    offset: usize,
3563    snapshot: &TextBufferSnapshot,
3564) -> bool {
3565    let start_anchor = snapshot.anchor_before(offset);
3566    let end_anchor = snapshot.anchor_after(offset);
3567
3568    sub_ranges.iter().any(|sub_range| {
3569        let is_before_start = sub_range.end.cmp(&start_anchor, snapshot).is_lt();
3570        let is_after_end = sub_range.start.cmp(&end_anchor, snapshot).is_gt();
3571        !is_before_start && !is_after_end
3572    })
3573}
3574
3575impl Deref for Buffer {
3576    type Target = TextBuffer;
3577
3578    fn deref(&self) -> &Self::Target {
3579        &self.text
3580    }
3581}
3582
3583impl BufferSnapshot {
3584    /// Returns [`IndentSize`] for a given line that respects user settings and
3585    /// language preferences.
3586    pub fn indent_size_for_line(&self, row: u32) -> IndentSize {
3587        indent_size_for_line(self, row)
3588    }
3589
3590    /// Returns [`IndentSize`] for a given position that respects user settings
3591    /// and language preferences.
3592    pub fn language_indent_size_at<T: ToOffset>(&self, position: T, cx: &App) -> IndentSize {
3593        let settings = self.settings_at(position, cx);
3594        if settings.hard_tabs {
3595            IndentSize::tab()
3596        } else {
3597            IndentSize::spaces(settings.tab_size.get())
3598        }
3599    }
3600
3601    /// Retrieve the suggested indent size for all of the given rows. The unit of indentation
3602    /// is passed in as `single_indent_size`.
3603    pub fn suggested_indents(
3604        &self,
3605        rows: impl Iterator<Item = u32>,
3606        single_indent_size: IndentSize,
3607    ) -> BTreeMap<u32, IndentSize> {
3608        let mut result = BTreeMap::new();
3609
3610        for row_range in contiguous_ranges(rows, 10) {
3611            let suggestions = match self.suggest_autoindents(row_range.clone()) {
3612                Some(suggestions) => suggestions,
3613                _ => break,
3614            };
3615
3616            for (row, suggestion) in row_range.zip(suggestions) {
3617                let indent_size = if let Some(suggestion) = suggestion {
3618                    result
3619                        .get(&suggestion.basis_row)
3620                        .copied()
3621                        .unwrap_or_else(|| self.indent_size_for_line(suggestion.basis_row))
3622                        .with_delta(suggestion.delta, single_indent_size)
3623                } else {
3624                    self.indent_size_for_line(row)
3625                };
3626
3627                result.insert(row, indent_size);
3628            }
3629        }
3630
3631        result
3632    }
3633
3634    fn suggest_autoindents(
3635        &self,
3636        row_range: Range<u32>,
3637    ) -> Option<impl Iterator<Item = Option<IndentSuggestion>> + '_> {
3638        let config = &self.language.as_ref()?.config;
3639        let prev_non_blank_row = self.prev_non_blank_row(row_range.start);
3640
3641        #[derive(Debug, Clone)]
3642        struct StartPosition {
3643            start: Point,
3644            suffix: SharedString,
3645            language: Arc<Language>,
3646        }
3647
3648        // Find the suggested indentation ranges based on the syntax tree.
3649        let start = Point::new(prev_non_blank_row.unwrap_or(row_range.start), 0);
3650        let end = Point::new(row_range.end, 0);
3651        let range = (start..end).to_offset(&self.text);
3652        let mut matches = self.syntax.matches_with_options(
3653            range.clone(),
3654            &self.text,
3655            TreeSitterOptions {
3656                max_bytes_to_query: Some(MAX_BYTES_TO_QUERY),
3657                max_start_depth: None,
3658            },
3659            |grammar| Some(&grammar.indents_config.as_ref()?.query),
3660        );
3661        let indent_configs = matches
3662            .grammars()
3663            .iter()
3664            .map(|grammar| {
3665                grammar
3666                    .indents_config
3667                    .as_ref()
3668                    .expect("grammar in indent match set has indents_config")
3669            })
3670            .collect::<Vec<_>>();
3671
3672        let mut indent_ranges = Vec::<Range<Point>>::new();
3673        let mut start_positions = Vec::<StartPosition>::new();
3674        let mut outdent_positions = Vec::<Point>::new();
3675        while let Some(mat) = matches.peek() {
3676            let mut start: Option<Point> = None;
3677            let mut end: Option<Point> = None;
3678
3679            let config = indent_configs[mat.grammar_index];
3680            for capture in mat.captures {
3681                if capture.index == config.indent_capture_ix {
3682                    start.get_or_insert(Point::from_ts_point(capture.node.start_position()));
3683                    end.get_or_insert(Point::from_ts_point(capture.node.end_position()));
3684                } else if Some(capture.index) == config.start_capture_ix {
3685                    start = Some(Point::from_ts_point(capture.node.end_position()));
3686                } else if Some(capture.index) == config.end_capture_ix {
3687                    end = Some(Point::from_ts_point(capture.node.start_position()));
3688                } else if Some(capture.index) == config.outdent_capture_ix {
3689                    outdent_positions.push(Point::from_ts_point(capture.node.start_position()));
3690                } else if let Some(suffix) = config.suffixed_start_captures.get(&capture.index) {
3691                    start_positions.push(StartPosition {
3692                        start: Point::from_ts_point(capture.node.start_position()),
3693                        suffix: suffix.clone(),
3694                        language: mat.language.clone(),
3695                    });
3696                }
3697            }
3698
3699            matches.advance();
3700            if let Some((start, end)) = start.zip(end) {
3701                if start.row == end.row {
3702                    continue;
3703                }
3704                let range = start..end;
3705                match indent_ranges.binary_search_by_key(&range.start, |r| r.start) {
3706                    Err(ix) => indent_ranges.insert(ix, range),
3707                    Ok(ix) => {
3708                        let prev_range = &mut indent_ranges[ix];
3709                        prev_range.end = prev_range.end.max(range.end);
3710                    }
3711                }
3712            }
3713        }
3714
3715        let mut error_ranges = Vec::<Range<Point>>::new();
3716        let mut matches = self
3717            .syntax
3718            .matches(range, &self.text, |grammar| grammar.error_query.as_ref());
3719        while let Some(mat) = matches.peek() {
3720            let node = mat.captures[0].node;
3721            let start = Point::from_ts_point(node.start_position());
3722            let end = Point::from_ts_point(node.end_position());
3723            let range = start..end;
3724            let ix = match error_ranges.binary_search_by_key(&range.start, |r| r.start) {
3725                Ok(ix) | Err(ix) => ix,
3726            };
3727            let mut end_ix = ix;
3728            while let Some(existing_range) = error_ranges.get(end_ix) {
3729                if existing_range.end < end {
3730                    end_ix += 1;
3731                } else {
3732                    break;
3733                }
3734            }
3735            error_ranges.splice(ix..end_ix, [range]);
3736            matches.advance();
3737        }
3738
3739        outdent_positions.sort();
3740        for outdent_position in outdent_positions {
3741            // find the innermost indent range containing this outdent_position
3742            // set its end to the outdent position
3743            if let Some(range_to_truncate) = indent_ranges
3744                .iter_mut()
3745                .rfind(|indent_range| indent_range.contains(&outdent_position))
3746            {
3747                range_to_truncate.end = outdent_position;
3748            }
3749        }
3750
3751        start_positions.sort_by_key(|b| b.start);
3752
3753        // Find the suggested indentation increases and decreased based on regexes.
3754        let mut regex_outdent_map = HashMap::default();
3755        let mut last_seen_suffix: HashMap<String, Vec<StartPosition>> = HashMap::default();
3756        let mut start_positions_iter = start_positions.iter().peekable();
3757
3758        let mut indent_change_rows = Vec::<(u32, Ordering)>::new();
3759        self.for_each_line(
3760            Point::new(prev_non_blank_row.unwrap_or(row_range.start), 0)
3761                ..Point::new(row_range.end, 0),
3762            |row, line| {
3763                let indent_len = self.indent_size_for_line(row).len;
3764                let row_language = self.language_at(Point::new(row, indent_len)).cloned();
3765                let row_language_config = row_language
3766                    .as_ref()
3767                    .map(|lang| lang.config())
3768                    .unwrap_or(config);
3769
3770                if row_language_config
3771                    .decrease_indent_pattern
3772                    .as_ref()
3773                    .is_some_and(|regex| regex.is_match(line))
3774                {
3775                    indent_change_rows.push((row, Ordering::Less));
3776                }
3777                if row_language_config
3778                    .increase_indent_pattern
3779                    .as_ref()
3780                    .is_some_and(|regex| regex.is_match(line))
3781                {
3782                    indent_change_rows.push((row + 1, Ordering::Greater));
3783                }
3784                while let Some(pos) = start_positions_iter.peek() {
3785                    if pos.start.row < row {
3786                        let pos = start_positions_iter.next().unwrap().clone();
3787                        last_seen_suffix
3788                            .entry(pos.suffix.to_string())
3789                            .or_default()
3790                            .push(pos);
3791                    } else {
3792                        break;
3793                    }
3794                }
3795                for rule in &row_language_config.decrease_indent_patterns {
3796                    if rule.pattern.as_ref().is_some_and(|r| r.is_match(line)) {
3797                        let row_start_column = self.indent_size_for_line(row).len;
3798                        let basis_row = rule
3799                            .valid_after
3800                            .iter()
3801                            .filter_map(|valid_suffix| last_seen_suffix.get(valid_suffix))
3802                            .flatten()
3803                            .filter(|pos| {
3804                                row_language
3805                                    .as_ref()
3806                                    .or(self.language.as_ref())
3807                                    .is_some_and(|lang| Arc::ptr_eq(lang, &pos.language))
3808                            })
3809                            .filter(|pos| pos.start.column <= row_start_column)
3810                            .max_by_key(|pos| pos.start.row);
3811                        if let Some(outdent_to) = basis_row {
3812                            regex_outdent_map.insert(row, outdent_to.start.row);
3813                        }
3814                        break;
3815                    }
3816                }
3817            },
3818        );
3819
3820        let mut indent_changes = indent_change_rows.into_iter().peekable();
3821        let mut prev_row = if config.auto_indent_using_last_non_empty_line {
3822            prev_non_blank_row.unwrap_or(0)
3823        } else {
3824            row_range.start.saturating_sub(1)
3825        };
3826
3827        let mut prev_row_start = Point::new(prev_row, self.indent_size_for_line(prev_row).len);
3828        Some(row_range.map(move |row| {
3829            let row_start = Point::new(row, self.indent_size_for_line(row).len);
3830
3831            let mut indent_from_prev_row = false;
3832            let mut outdent_from_prev_row = false;
3833            let mut outdent_to_row = u32::MAX;
3834            let mut from_regex = false;
3835
3836            while let Some((indent_row, delta)) = indent_changes.peek() {
3837                match indent_row.cmp(&row) {
3838                    Ordering::Equal => match delta {
3839                        Ordering::Less => {
3840                            from_regex = true;
3841                            outdent_from_prev_row = true
3842                        }
3843                        Ordering::Greater => {
3844                            indent_from_prev_row = true;
3845                            from_regex = true
3846                        }
3847                        _ => {}
3848                    },
3849
3850                    Ordering::Greater => break,
3851                    Ordering::Less => {}
3852                }
3853
3854                indent_changes.next();
3855            }
3856
3857            for range in &indent_ranges {
3858                if range.start.row >= row {
3859                    break;
3860                }
3861                if range.start.row == prev_row && range.end > row_start {
3862                    indent_from_prev_row = true;
3863                }
3864                if range.end > prev_row_start && range.end <= row_start {
3865                    outdent_to_row = outdent_to_row.min(range.start.row);
3866                }
3867            }
3868
3869            if let Some(basis_row) = regex_outdent_map.get(&row) {
3870                indent_from_prev_row = false;
3871                outdent_to_row = *basis_row;
3872                from_regex = true;
3873            }
3874
3875            let within_error = error_ranges
3876                .iter()
3877                .any(|e| e.start.row < row && e.end > row_start);
3878
3879            let suggestion = if outdent_to_row == prev_row
3880                || (outdent_from_prev_row && indent_from_prev_row)
3881            {
3882                Some(IndentSuggestion {
3883                    basis_row: prev_row,
3884                    delta: Ordering::Equal,
3885                    within_error: within_error && !from_regex,
3886                })
3887            } else if indent_from_prev_row {
3888                Some(IndentSuggestion {
3889                    basis_row: prev_row,
3890                    delta: Ordering::Greater,
3891                    within_error: within_error && !from_regex,
3892                })
3893            } else if outdent_to_row < prev_row {
3894                Some(IndentSuggestion {
3895                    basis_row: outdent_to_row,
3896                    delta: Ordering::Equal,
3897                    within_error: within_error && !from_regex,
3898                })
3899            } else if outdent_from_prev_row {
3900                Some(IndentSuggestion {
3901                    basis_row: prev_row,
3902                    delta: Ordering::Less,
3903                    within_error: within_error && !from_regex,
3904                })
3905            } else if config.auto_indent_using_last_non_empty_line || !self.is_line_blank(prev_row)
3906            {
3907                Some(IndentSuggestion {
3908                    basis_row: prev_row,
3909                    delta: Ordering::Equal,
3910                    within_error: within_error && !from_regex,
3911                })
3912            } else {
3913                None
3914            };
3915
3916            prev_row = row;
3917            prev_row_start = row_start;
3918            suggestion
3919        }))
3920    }
3921
3922    fn prev_non_blank_row(&self, mut row: u32) -> Option<u32> {
3923        while row > 0 {
3924            row -= 1;
3925            if !self.is_line_blank(row) {
3926                return Some(row);
3927            }
3928        }
3929        None
3930    }
3931
3932    pub fn captures(
3933        &self,
3934        range: Range<usize>,
3935        query: fn(&Grammar) -> Option<&tree_sitter::Query>,
3936    ) -> SyntaxMapCaptures<'_> {
3937        self.syntax.captures(range, &self.text, query)
3938    }
3939
3940    #[ztracing::instrument(skip_all)]
3941    fn get_highlights(&self, range: Range<usize>) -> (SyntaxMapCaptures<'_>, Vec<HighlightMap>) {
3942        let captures = self.syntax.captures(range, &self.text, |grammar| {
3943            grammar
3944                .highlights_config
3945                .as_ref()
3946                .map(|config| &config.query)
3947        });
3948        let highlight_maps = captures
3949            .grammars()
3950            .iter()
3951            .map(|grammar| grammar.highlight_map())
3952            .collect();
3953        (captures, highlight_maps)
3954    }
3955
3956    /// Iterates over chunks of text in the given range of the buffer. Text is chunked
3957    /// in an arbitrary way due to being stored in a [`Rope`](text::Rope). The text is also
3958    /// returned in chunks where each chunk has a single syntax highlighting style and
3959    /// diagnostic status.
3960    #[ztracing::instrument(skip_all)]
3961    pub fn chunks<T: ToOffset>(
3962        &self,
3963        range: Range<T>,
3964        language_aware: LanguageAwareStyling,
3965    ) -> BufferChunks<'_> {
3966        let range = range.start.to_offset(self)..range.end.to_offset(self);
3967
3968        let mut syntax = None;
3969        if language_aware.tree_sitter {
3970            syntax = Some(self.get_highlights(range.clone()));
3971        }
3972        BufferChunks::new(
3973            self.text.as_rope(),
3974            range,
3975            syntax,
3976            language_aware.diagnostics,
3977            Some(self),
3978        )
3979    }
3980
3981    pub fn highlighted_text_for_range<T: ToOffset>(
3982        &self,
3983        range: Range<T>,
3984        override_style: Option<HighlightStyle>,
3985        syntax_theme: &SyntaxTheme,
3986    ) -> HighlightedText {
3987        HighlightedText::from_buffer_range(
3988            range,
3989            &self.text,
3990            &self.syntax,
3991            override_style,
3992            syntax_theme,
3993        )
3994    }
3995
3996    /// Invokes the given callback for each line of text in the given range of the buffer.
3997    /// Uses callback to avoid allocating a string for each line.
3998    fn for_each_line(&self, range: Range<Point>, mut callback: impl FnMut(u32, &str)) {
3999        let mut line = String::new();
4000        let mut row = range.start.row;
4001        for chunk in self
4002            .as_rope()
4003            .chunks_in_range(range.to_offset(self))
4004            .chain(["\n"])
4005        {
4006            for (newline_ix, text) in chunk.split('\n').enumerate() {
4007                if newline_ix > 0 {
4008                    callback(row, &line);
4009                    row += 1;
4010                    line.clear();
4011                }
4012                line.push_str(text);
4013            }
4014        }
4015    }
4016
4017    /// Iterates over every [`SyntaxLayer`] in the buffer.
4018    pub fn syntax_layers(&self) -> impl Iterator<Item = SyntaxLayer<'_>> + '_ {
4019        self.syntax_layers_for_range(0..self.len(), true)
4020    }
4021
4022    pub fn syntax_layer_at<D: ToOffset>(&self, position: D) -> Option<SyntaxLayer<'_>> {
4023        let offset = position.to_offset(self);
4024        self.syntax_layers_for_range(offset..offset, false)
4025            .filter(|l| {
4026                if let Some(ranges) = l.included_sub_ranges {
4027                    ranges.iter().any(|range| {
4028                        let start = range.start.to_offset(self);
4029                        start <= offset && {
4030                            let end = range.end.to_offset(self);
4031                            offset < end
4032                        }
4033                    })
4034                } else {
4035                    l.node().start_byte() <= offset && l.node().end_byte() > offset
4036                }
4037            })
4038            .last()
4039    }
4040
4041    pub fn syntax_layers_for_range<D: ToOffset>(
4042        &self,
4043        range: Range<D>,
4044        include_hidden: bool,
4045    ) -> impl Iterator<Item = SyntaxLayer<'_>> + '_ {
4046        self.syntax
4047            .layers_for_range(range, &self.text, include_hidden)
4048    }
4049
4050    pub fn syntax_layers_languages(&self) -> impl Iterator<Item = &Arc<Language>> {
4051        self.syntax.languages(&self, true)
4052    }
4053
4054    pub fn smallest_syntax_layer_containing<D: ToOffset>(
4055        &self,
4056        range: Range<D>,
4057    ) -> Option<SyntaxLayer<'_>> {
4058        let range = range.to_offset(self);
4059        self.syntax
4060            .layers_for_range(range, &self.text, false)
4061            .max_by(|a, b| {
4062                if a.depth != b.depth {
4063                    a.depth.cmp(&b.depth)
4064                } else if a.offset.0 != b.offset.0 {
4065                    a.offset.0.cmp(&b.offset.0)
4066                } else {
4067                    a.node().end_byte().cmp(&b.node().end_byte()).reverse()
4068                }
4069            })
4070    }
4071
4072    /// Returns the [`ModelineSettings`].
4073    pub fn modeline(&self) -> Option<&Arc<ModelineSettings>> {
4074        self.modeline.as_ref()
4075    }
4076
4077    /// Returns the main [`Language`].
4078    pub fn language(&self) -> Option<&Arc<Language>> {
4079        self.language.as_ref()
4080    }
4081
4082    /// Returns the [`Language`] at the given location.
4083    pub fn language_at<D: ToOffset>(&self, position: D) -> Option<&Arc<Language>> {
4084        self.syntax_layer_at(position)
4085            .map(|info| info.language)
4086            .or(self.language.as_ref())
4087    }
4088
4089    /// Returns the settings for the language at the given location.
4090    pub fn settings_at<'a, D: ToOffset>(
4091        &'a self,
4092        position: D,
4093        cx: &'a App,
4094    ) -> Cow<'a, LanguageSettings> {
4095        LanguageSettings::for_buffer_snapshot(self, Some(position.to_offset(self)), cx)
4096    }
4097
4098    pub fn char_classifier_at<T: ToOffset>(&self, point: T) -> CharClassifier {
4099        CharClassifier::new(self.language_scope_at(point))
4100    }
4101
4102    /// Returns the [`LanguageScope`] at the given location.
4103    pub fn language_scope_at<D: ToOffset>(&self, position: D) -> Option<LanguageScope> {
4104        let offset = position.to_offset(self);
4105        let mut scope = None;
4106        let mut smallest_range_and_depth: Option<(Range<usize>, usize)> = None;
4107        let text: &TextBufferSnapshot = self;
4108
4109        // Use the layer that has the smallest node intersecting the given point.
4110        for layer in self
4111            .syntax
4112            .layers_for_range(offset..offset, &self.text, false)
4113        {
4114            if let Some(ranges) = layer.included_sub_ranges
4115                && !offset_in_sub_ranges(ranges, offset, text)
4116            {
4117                continue;
4118            }
4119
4120            let mut cursor = layer.node().walk();
4121
4122            let mut range = None;
4123            loop {
4124                let child_range = cursor.node().byte_range();
4125                if !child_range.contains(&offset) {
4126                    break;
4127                }
4128
4129                range = Some(child_range);
4130                if cursor.goto_first_child_for_byte(offset).is_none() {
4131                    break;
4132                }
4133            }
4134
4135            if let Some(range) = range
4136                && smallest_range_and_depth.as_ref().is_none_or(
4137                    |(smallest_range, smallest_range_depth)| {
4138                        if layer.depth > *smallest_range_depth {
4139                            true
4140                        } else if layer.depth == *smallest_range_depth {
4141                            range.len() < smallest_range.len()
4142                        } else {
4143                            false
4144                        }
4145                    },
4146                )
4147            {
4148                smallest_range_and_depth = Some((range, layer.depth));
4149                scope = Some(LanguageScope {
4150                    language: layer.language.clone(),
4151                    override_id: layer.override_id(offset, &self.text),
4152                });
4153            }
4154        }
4155
4156        scope.or_else(|| {
4157            self.language.clone().map(|language| LanguageScope {
4158                language,
4159                override_id: None,
4160            })
4161        })
4162    }
4163
4164    /// Returns a tuple of the range and character kind of the word
4165    /// surrounding the given position.
4166    pub fn surrounding_word<T: ToOffset>(
4167        &self,
4168        start: T,
4169        scope_context: Option<CharScopeContext>,
4170    ) -> (Range<usize>, Option<CharKind>) {
4171        let mut start = start.to_offset(self);
4172        let mut end = start;
4173        let mut next_chars = self.chars_at(start).take(128).peekable();
4174        let mut prev_chars = self.reversed_chars_at(start).take(128).peekable();
4175
4176        let classifier = self.char_classifier_at(start).scope_context(scope_context);
4177        let word_kind = cmp::max(
4178            prev_chars.peek().copied().map(|c| classifier.kind(c)),
4179            next_chars.peek().copied().map(|c| classifier.kind(c)),
4180        );
4181
4182        for ch in prev_chars {
4183            if Some(classifier.kind(ch)) == word_kind && ch != '\n' {
4184                start -= ch.len_utf8();
4185            } else {
4186                break;
4187            }
4188        }
4189
4190        for ch in next_chars {
4191            if Some(classifier.kind(ch)) == word_kind && ch != '\n' {
4192                end += ch.len_utf8();
4193            } else {
4194                break;
4195            }
4196        }
4197
4198        (start..end, word_kind)
4199    }
4200
4201    /// Moves the TreeCursor to the smallest descendant or ancestor syntax node enclosing the given
4202    /// range. When `require_larger` is true, the node found must be larger than the query range.
4203    ///
4204    /// Returns true if a node was found, and false otherwise. In the `false` case the cursor will
4205    /// be moved to the root of the tree.
4206    fn goto_node_enclosing_range(
4207        cursor: &mut tree_sitter::TreeCursor,
4208        query_range: &Range<usize>,
4209        require_larger: bool,
4210    ) -> bool {
4211        let mut ascending = false;
4212        loop {
4213            let mut range = cursor.node().byte_range();
4214            if query_range.is_empty() {
4215                // When the query range is empty and the current node starts after it, move to the
4216                // previous sibling to find the node the containing node.
4217                if range.start > query_range.start {
4218                    cursor.goto_previous_sibling();
4219                    range = cursor.node().byte_range();
4220                }
4221            } else {
4222                // When the query range is non-empty and the current node ends exactly at the start,
4223                // move to the next sibling to find a node that extends beyond the start.
4224                if range.end == query_range.start {
4225                    cursor.goto_next_sibling();
4226                    range = cursor.node().byte_range();
4227                }
4228            }
4229
4230            let encloses = range.contains_inclusive(query_range)
4231                && (!require_larger || range.len() > query_range.len());
4232            if !encloses {
4233                ascending = true;
4234                if !cursor.goto_parent() {
4235                    return false;
4236                }
4237                continue;
4238            } else if ascending {
4239                return true;
4240            }
4241
4242            // Descend into the current node.
4243            if cursor
4244                .goto_first_child_for_byte(query_range.start)
4245                .is_none()
4246            {
4247                return true;
4248            }
4249        }
4250    }
4251
4252    pub fn syntax_ancestor<'a, T: ToOffset>(
4253        &'a self,
4254        range: Range<T>,
4255    ) -> Option<tree_sitter::Node<'a>> {
4256        let range = range.start.to_offset(self)..range.end.to_offset(self);
4257        let mut result: Option<tree_sitter::Node<'a>> = None;
4258        for layer in self
4259            .syntax
4260            .layers_for_range(range.clone(), &self.text, true)
4261        {
4262            let mut cursor = layer.node().walk();
4263
4264            // Find the node that both contains the range and is larger than it.
4265            if !Self::goto_node_enclosing_range(&mut cursor, &range, true) {
4266                continue;
4267            }
4268
4269            let left_node = cursor.node();
4270            let mut layer_result = left_node;
4271
4272            // For an empty range, try to find another node immediately to the right of the range.
4273            if left_node.end_byte() == range.start {
4274                let mut right_node = None;
4275                while !cursor.goto_next_sibling() {
4276                    if !cursor.goto_parent() {
4277                        break;
4278                    }
4279                }
4280
4281                while cursor.node().start_byte() == range.start {
4282                    right_node = Some(cursor.node());
4283                    if !cursor.goto_first_child() {
4284                        break;
4285                    }
4286                }
4287
4288                // If there is a candidate node on both sides of the (empty) range, then
4289                // decide between the two by favoring a named node over an anonymous token.
4290                // If both nodes are the same in that regard, favor the right one.
4291                if let Some(right_node) = right_node
4292                    && (right_node.is_named() || !left_node.is_named())
4293                {
4294                    layer_result = right_node;
4295                }
4296            }
4297
4298            if let Some(previous_result) = &result
4299                && previous_result.byte_range().len() < layer_result.byte_range().len()
4300            {
4301                continue;
4302            }
4303            result = Some(layer_result);
4304        }
4305
4306        result
4307    }
4308
4309    /// Find the previous sibling syntax node at the given range.
4310    ///
4311    /// This function locates the syntax node that precedes the node containing
4312    /// the given range. It searches hierarchically by:
4313    /// 1. Finding the node that contains the given range
4314    /// 2. Looking for the previous sibling at the same tree level
4315    /// 3. If no sibling is found, moving up to parent levels and searching for siblings
4316    ///
4317    /// Returns `None` if there is no previous sibling at any ancestor level.
4318    pub fn syntax_prev_sibling<'a, T: ToOffset>(
4319        &'a self,
4320        range: Range<T>,
4321    ) -> Option<tree_sitter::Node<'a>> {
4322        let range = range.start.to_offset(self)..range.end.to_offset(self);
4323        let mut result: Option<tree_sitter::Node<'a>> = None;
4324
4325        for layer in self
4326            .syntax
4327            .layers_for_range(range.clone(), &self.text, true)
4328        {
4329            let mut cursor = layer.node().walk();
4330
4331            // Find the node that contains the range
4332            if !Self::goto_node_enclosing_range(&mut cursor, &range, false) {
4333                continue;
4334            }
4335
4336            // Look for the previous sibling, moving up ancestor levels if needed
4337            loop {
4338                if cursor.goto_previous_sibling() {
4339                    let layer_result = cursor.node();
4340
4341                    if let Some(previous_result) = &result {
4342                        if previous_result.byte_range().end < layer_result.byte_range().end {
4343                            continue;
4344                        }
4345                    }
4346                    result = Some(layer_result);
4347                    break;
4348                }
4349
4350                // No sibling found at this level, try moving up to parent
4351                if !cursor.goto_parent() {
4352                    break;
4353                }
4354            }
4355        }
4356
4357        result
4358    }
4359
4360    /// Find the next sibling syntax node at the given range.
4361    ///
4362    /// This function locates the syntax node that follows the node containing
4363    /// the given range. It searches hierarchically by:
4364    /// 1. Finding the node that contains the given range
4365    /// 2. Looking for the next sibling at the same tree level
4366    /// 3. If no sibling is found, moving up to parent levels and searching for siblings
4367    ///
4368    /// Returns `None` if there is no next sibling at any ancestor level.
4369    pub fn syntax_next_sibling<'a, T: ToOffset>(
4370        &'a self,
4371        range: Range<T>,
4372    ) -> Option<tree_sitter::Node<'a>> {
4373        let range = range.start.to_offset(self)..range.end.to_offset(self);
4374        let mut result: Option<tree_sitter::Node<'a>> = None;
4375
4376        for layer in self
4377            .syntax
4378            .layers_for_range(range.clone(), &self.text, true)
4379        {
4380            let mut cursor = layer.node().walk();
4381
4382            // Find the node that contains the range
4383            if !Self::goto_node_enclosing_range(&mut cursor, &range, false) {
4384                continue;
4385            }
4386
4387            // Look for the next sibling, moving up ancestor levels if needed
4388            loop {
4389                if cursor.goto_next_sibling() {
4390                    let layer_result = cursor.node();
4391
4392                    if let Some(previous_result) = &result {
4393                        if previous_result.byte_range().start > layer_result.byte_range().start {
4394                            continue;
4395                        }
4396                    }
4397                    result = Some(layer_result);
4398                    break;
4399                }
4400
4401                // No sibling found at this level, try moving up to parent
4402                if !cursor.goto_parent() {
4403                    break;
4404                }
4405            }
4406        }
4407
4408        result
4409    }
4410
4411    /// Returns the root syntax node within the given row
4412    pub fn syntax_root_ancestor(&self, position: Anchor) -> Option<tree_sitter::Node<'_>> {
4413        let start_offset = position.to_offset(self);
4414
4415        let row = self.summary_for_anchor::<text::PointUtf16>(&position).row as usize;
4416
4417        let layer = self
4418            .syntax
4419            .layers_for_range(start_offset..start_offset, &self.text, true)
4420            .next()?;
4421
4422        let mut cursor = layer.node().walk();
4423
4424        // Descend to the first leaf that touches the start of the range.
4425        while cursor.goto_first_child_for_byte(start_offset).is_some() {
4426            if cursor.node().end_byte() == start_offset {
4427                cursor.goto_next_sibling();
4428            }
4429        }
4430
4431        // Ascend to the root node within the same row.
4432        while cursor.goto_parent() {
4433            if cursor.node().start_position().row != row {
4434                break;
4435            }
4436        }
4437
4438        Some(cursor.node())
4439    }
4440
4441    /// Returns the outline for the buffer.
4442    ///
4443    /// This method allows passing an optional [`SyntaxTheme`] to
4444    /// syntax-highlight the returned symbols.
4445    pub fn outline(&self, theme: Option<&SyntaxTheme>) -> Outline<Anchor> {
4446        Outline::new(self.outline_items_containing(0..self.len(), true, theme))
4447    }
4448
4449    /// Returns all the symbols that contain the given position.
4450    ///
4451    /// This method allows passing an optional [`SyntaxTheme`] to
4452    /// syntax-highlight the returned symbols.
4453    pub fn symbols_containing<T: ToOffset>(
4454        &self,
4455        position: T,
4456        theme: Option<&SyntaxTheme>,
4457    ) -> Vec<OutlineItem<Anchor>> {
4458        let position = position.to_offset(self);
4459        let start = self.clip_offset(position.saturating_sub(1), Bias::Left);
4460        let end = self.clip_offset(position + 1, Bias::Right);
4461        let mut items = self.outline_items_containing(start..end, false, theme);
4462        let mut prev_depth = None;
4463        items.retain(|item| {
4464            let result = prev_depth.is_none_or(|prev_depth| item.depth > prev_depth);
4465            prev_depth = Some(item.depth);
4466            result
4467        });
4468        items
4469    }
4470
4471    pub fn outline_ranges_containing<T: ToOffset>(
4472        &self,
4473        range: Range<T>,
4474    ) -> impl Iterator<Item = Range<Point>> + '_ {
4475        let range = range.to_offset(self);
4476        let mut matches = self.syntax.matches(range.clone(), &self.text, |grammar| {
4477            grammar.outline_config.as_ref().map(|c| &c.query)
4478        });
4479        let configs = matches
4480            .grammars()
4481            .iter()
4482            .map(|g| g.outline_config.as_ref().unwrap())
4483            .collect::<Vec<_>>();
4484
4485        std::iter::from_fn(move || {
4486            while let Some(mat) = matches.peek() {
4487                let config = &configs[mat.grammar_index];
4488                let containing_item_node = maybe!({
4489                    let item_node = mat.captures.iter().find_map(|cap| {
4490                        if cap.index == config.item_capture_ix {
4491                            Some(cap.node)
4492                        } else {
4493                            None
4494                        }
4495                    })?;
4496
4497                    let item_byte_range = item_node.byte_range();
4498                    if item_byte_range.end < range.start || item_byte_range.start > range.end {
4499                        None
4500                    } else {
4501                        Some(item_node)
4502                    }
4503                });
4504
4505                let range = containing_item_node.as_ref().map(|item_node| {
4506                    Point::from_ts_point(item_node.start_position())
4507                        ..Point::from_ts_point(item_node.end_position())
4508                });
4509                matches.advance();
4510                if range.is_some() {
4511                    return range;
4512                }
4513            }
4514            None
4515        })
4516    }
4517
4518    pub fn outline_range_containing<T: ToOffset>(&self, range: Range<T>) -> Option<Range<Point>> {
4519        self.outline_ranges_containing(range).next()
4520    }
4521
4522    pub fn outline_items_containing<T: ToOffset>(
4523        &self,
4524        range: Range<T>,
4525        include_extra_context: bool,
4526        theme: Option<&SyntaxTheme>,
4527    ) -> Vec<OutlineItem<Anchor>> {
4528        self.outline_items_containing_internal(
4529            range,
4530            include_extra_context,
4531            theme,
4532            |this, range| this.anchor_after(range.start)..this.anchor_before(range.end),
4533        )
4534    }
4535
4536    pub fn outline_items_as_points_containing<T: ToOffset>(
4537        &self,
4538        range: Range<T>,
4539        include_extra_context: bool,
4540        theme: Option<&SyntaxTheme>,
4541    ) -> Vec<OutlineItem<Point>> {
4542        self.outline_items_containing_internal(range, include_extra_context, theme, |_, range| {
4543            range
4544        })
4545    }
4546
4547    pub fn outline_items_as_offsets_containing<T: ToOffset>(
4548        &self,
4549        range: Range<T>,
4550        include_extra_context: bool,
4551        theme: Option<&SyntaxTheme>,
4552    ) -> Vec<OutlineItem<usize>> {
4553        self.outline_items_containing_internal(
4554            range,
4555            include_extra_context,
4556            theme,
4557            |buffer, range| range.to_offset(buffer),
4558        )
4559    }
4560
4561    fn outline_items_containing_internal<T: ToOffset, U>(
4562        &self,
4563        range: Range<T>,
4564        include_extra_context: bool,
4565        theme: Option<&SyntaxTheme>,
4566        range_callback: fn(&Self, Range<Point>) -> Range<U>,
4567    ) -> Vec<OutlineItem<U>> {
4568        let range = range.to_offset(self);
4569        let mut matches = self.syntax.matches(range.clone(), &self.text, |grammar| {
4570            grammar.outline_config.as_ref().map(|c| &c.query)
4571        });
4572
4573        let mut items = Vec::new();
4574        let mut annotation_row_ranges: Vec<Range<u32>> = Vec::new();
4575        while let Some(mat) = matches.peek() {
4576            let config = matches.grammars()[mat.grammar_index]
4577                .outline_config
4578                .as_ref()
4579                .unwrap();
4580            if let Some(item) =
4581                self.next_outline_item(config, &mat, &range, include_extra_context, theme)
4582            {
4583                items.push(item);
4584            } else if let Some(capture) = mat
4585                .captures
4586                .iter()
4587                .find(|capture| Some(capture.index) == config.annotation_capture_ix)
4588            {
4589                let capture_range = capture.node.start_position()..capture.node.end_position();
4590                let mut capture_row_range =
4591                    capture_range.start.row as u32..capture_range.end.row as u32;
4592                if capture_range.end.row > capture_range.start.row && capture_range.end.column == 0
4593                {
4594                    capture_row_range.end -= 1;
4595                }
4596                if let Some(last_row_range) = annotation_row_ranges.last_mut() {
4597                    if last_row_range.end >= capture_row_range.start.saturating_sub(1) {
4598                        last_row_range.end = capture_row_range.end;
4599                    } else {
4600                        annotation_row_ranges.push(capture_row_range);
4601                    }
4602                } else {
4603                    annotation_row_ranges.push(capture_row_range);
4604                }
4605            }
4606            matches.advance();
4607        }
4608
4609        items.sort_by_key(|item| (item.range.start, Reverse(item.range.end)));
4610
4611        // Assign depths based on containment relationships and convert to anchors.
4612        let mut item_ends_stack = Vec::<Point>::new();
4613        let mut anchor_items = Vec::new();
4614        let mut annotation_row_ranges = annotation_row_ranges.into_iter().peekable();
4615        for item in items {
4616            while let Some(last_end) = item_ends_stack.last().copied() {
4617                if last_end < item.range.end {
4618                    item_ends_stack.pop();
4619                } else {
4620                    break;
4621                }
4622            }
4623
4624            let mut annotation_row_range = None;
4625            while let Some(next_annotation_row_range) = annotation_row_ranges.peek() {
4626                let row_preceding_item = item.range.start.row.saturating_sub(1);
4627                if next_annotation_row_range.end < row_preceding_item {
4628                    annotation_row_ranges.next();
4629                } else {
4630                    if next_annotation_row_range.end == row_preceding_item {
4631                        annotation_row_range = Some(next_annotation_row_range.clone());
4632                        annotation_row_ranges.next();
4633                    }
4634                    break;
4635                }
4636            }
4637
4638            anchor_items.push(OutlineItem {
4639                depth: item_ends_stack.len(),
4640                range: range_callback(self, item.range.clone()),
4641                selection_range: range_callback(self, item.selection_range.clone()),
4642                source_range_for_text: range_callback(self, item.source_range_for_text.clone()),
4643                text: item.text,
4644                highlight_ranges: item.highlight_ranges,
4645                name_ranges: item.name_ranges,
4646                body_range: item.body_range.map(|r| range_callback(self, r)),
4647                annotation_range: annotation_row_range.map(|annotation_range| {
4648                    let point_range = Point::new(annotation_range.start, 0)
4649                        ..Point::new(annotation_range.end, self.line_len(annotation_range.end));
4650                    range_callback(self, point_range)
4651                }),
4652            });
4653            item_ends_stack.push(item.range.end);
4654        }
4655
4656        anchor_items
4657    }
4658
4659    fn next_outline_item(
4660        &self,
4661        config: &OutlineConfig,
4662        mat: &SyntaxMapMatch,
4663        range: &Range<usize>,
4664        include_extra_context: bool,
4665        theme: Option<&SyntaxTheme>,
4666    ) -> Option<OutlineItem<Point>> {
4667        let item_node = mat.captures.iter().find_map(|cap| {
4668            if cap.index == config.item_capture_ix {
4669                Some(cap.node)
4670            } else {
4671                None
4672            }
4673        })?;
4674
4675        let item_byte_range = item_node.byte_range();
4676        if item_byte_range.end < range.start || item_byte_range.start > range.end {
4677            return None;
4678        }
4679        let item_point_range = Point::from_ts_point(item_node.start_position())
4680            ..Point::from_ts_point(item_node.end_position());
4681
4682        let mut open_point = None;
4683        let mut close_point = None;
4684
4685        let mut buffer_ranges = Vec::new();
4686        let mut add_to_buffer_ranges = |node: tree_sitter::Node, node_is_name| {
4687            let mut range = node.start_byte()..node.end_byte();
4688            let start = node.start_position();
4689            if node.end_position().row > start.row {
4690                range.end = range.start + self.line_len(start.row as u32) as usize - start.column;
4691            }
4692
4693            if !range.is_empty() {
4694                buffer_ranges.push((range, node_is_name));
4695            }
4696        };
4697
4698        for capture in mat.captures {
4699            if capture.index == config.name_capture_ix {
4700                add_to_buffer_ranges(capture.node, true);
4701            } else if Some(capture.index) == config.context_capture_ix
4702                || (Some(capture.index) == config.extra_context_capture_ix && include_extra_context)
4703            {
4704                add_to_buffer_ranges(capture.node, false);
4705            } else {
4706                if Some(capture.index) == config.open_capture_ix {
4707                    open_point = Some(Point::from_ts_point(capture.node.end_position()));
4708                } else if Some(capture.index) == config.close_capture_ix {
4709                    close_point = Some(Point::from_ts_point(capture.node.start_position()));
4710                }
4711            }
4712        }
4713
4714        if buffer_ranges.is_empty() {
4715            return None;
4716        }
4717        let source_range_for_text =
4718            buffer_ranges.first().unwrap().0.start..buffer_ranges.last().unwrap().0.end;
4719        let selection_range = buffer_ranges
4720            .iter()
4721            .filter(|(_, node_is_name)| *node_is_name)
4722            .map(|(buffer_range, _)| buffer_range.clone())
4723            .reduce(|mut combined_range, next_range| {
4724                combined_range.end = next_range.end;
4725                combined_range
4726            })?;
4727
4728        let mut text = String::new();
4729        let mut highlight_ranges = Vec::new();
4730        let mut name_ranges = Vec::new();
4731        let mut chunks = self.chunks(
4732            source_range_for_text.clone(),
4733            LanguageAwareStyling {
4734                tree_sitter: true,
4735                diagnostics: true,
4736            },
4737        );
4738        let mut last_buffer_range_end = 0;
4739        for (buffer_range, is_name) in buffer_ranges {
4740            let space_added = !text.is_empty() && buffer_range.start > last_buffer_range_end;
4741            if space_added {
4742                text.push(' ');
4743            }
4744            let before_append_len = text.len();
4745            let mut offset = buffer_range.start;
4746            chunks.seek(buffer_range.clone());
4747            for mut chunk in chunks.by_ref() {
4748                if chunk.text.len() > buffer_range.end - offset {
4749                    chunk.text = &chunk.text[0..(buffer_range.end - offset)];
4750                    offset = buffer_range.end;
4751                } else {
4752                    offset += chunk.text.len();
4753                }
4754                let style = chunk
4755                    .syntax_highlight_id
4756                    .zip(theme)
4757                    .and_then(|(highlight, theme)| theme.get(highlight).cloned());
4758
4759                if let Some(style) = style {
4760                    let start = text.len();
4761                    let end = start + chunk.text.len();
4762                    highlight_ranges.push((start..end, style));
4763                }
4764                text.push_str(chunk.text);
4765                if offset >= buffer_range.end {
4766                    break;
4767                }
4768            }
4769            if is_name {
4770                let after_append_len = text.len();
4771                let start = if space_added && !name_ranges.is_empty() {
4772                    before_append_len - 1
4773                } else {
4774                    before_append_len
4775                };
4776                name_ranges.push(start..after_append_len);
4777            }
4778            last_buffer_range_end = buffer_range.end;
4779        }
4780
4781        Some(OutlineItem {
4782            depth: 0, // We'll calculate the depth later
4783            range: item_point_range,
4784            selection_range: selection_range.to_point(self),
4785            source_range_for_text: source_range_for_text.to_point(self),
4786            text: text.into(),
4787            highlight_ranges,
4788            name_ranges,
4789            body_range: open_point.zip(close_point).map(|(start, end)| start..end),
4790            annotation_range: None,
4791        })
4792    }
4793
4794    pub fn function_body_fold_ranges<T: ToOffset>(
4795        &self,
4796        within: Range<T>,
4797    ) -> impl Iterator<Item = Range<usize>> + '_ {
4798        self.text_object_ranges(within, TreeSitterOptions::default())
4799            .filter_map(|(range, obj)| (obj == TextObject::InsideFunction).then_some(range))
4800    }
4801
4802    /// For each grammar in the language, runs the provided
4803    /// [`tree_sitter::Query`] against the given range.
4804    pub fn matches(
4805        &self,
4806        range: Range<usize>,
4807        query: fn(&Grammar) -> Option<&tree_sitter::Query>,
4808    ) -> SyntaxMapMatches<'_> {
4809        self.syntax.matches(range, self, query)
4810    }
4811
4812    /// Finds all [`RowChunks`] applicable to the given range, then returns all bracket pairs that intersect with those chunks.
4813    /// Hence, may return more bracket pairs than the range contains.
4814    ///
4815    /// Will omit known chunks.
4816    /// The resulting bracket match collections are not ordered.
4817    pub fn fetch_bracket_ranges(
4818        &self,
4819        range: Range<usize>,
4820        known_chunks: Option<&HashSet<Range<BufferRow>>>,
4821    ) -> HashMap<Range<BufferRow>, Vec<BracketMatch<usize>>> {
4822        let mut all_bracket_matches = HashMap::default();
4823        if self
4824            .language
4825            .as_ref()
4826            .is_none_or(|language| language.grammar().is_none())
4827        {
4828            return all_bracket_matches;
4829        }
4830
4831        for chunk in self
4832            .tree_sitter_data
4833            .chunks
4834            .applicable_chunks(&[range.to_point(self)])
4835        {
4836            if known_chunks.is_some_and(|chunks| chunks.contains(&chunk.row_range())) {
4837                continue;
4838            }
4839            let chunk_range = chunk.anchor_range();
4840            let chunk_range = chunk_range.to_offset(&self);
4841
4842            if let Some(cached_brackets) = self
4843                .tree_sitter_data
4844                .brackets_by_chunks
4845                .lock()
4846                .get(&chunk.id)
4847            {
4848                all_bracket_matches.insert(chunk.row_range(), cached_brackets.clone());
4849                continue;
4850            }
4851
4852            let mut all_brackets = Vec::new();
4853            let mut opens = Vec::new();
4854            let mut color_pairs = Vec::new();
4855
4856            let bounded_query = (
4857                chunk_range.clone(),
4858                TreeSitterOptions {
4859                    max_bytes_to_query: Some(MAX_BYTES_TO_QUERY),
4860                    max_start_depth: None,
4861                },
4862            );
4863            // The bounded query drops any pair spanning more than `MAX_BYTES_TO_QUERY`
4864            // (tree-sitter's containing byte range requires full containment), which
4865            // resets bracket depth at chunk boundaries. Every such pair encloses a
4866            // chunk edge, so recover them with two point-sized unbounded queries that
4867            // only traverse the syntax tree spine around each edge.
4868            let boundary_queries = [chunk_range.start, chunk_range.end].map(|offset| {
4869                (
4870                    self.clip_offset(offset.saturating_sub(1), Bias::Left)
4871                        ..self.clip_offset(offset.saturating_add(1), Bias::Right),
4872                    TreeSitterOptions::default(),
4873                )
4874            });
4875
4876            let mut grammar_ids = Vec::new();
4877            let mut configs = Vec::new();
4878            let mut seen_delimiters = HashSet::default();
4879            // Group matches by open delimiter so we can either trust grammar output
4880            // or repair it by picking a single closest close per open.
4881            let mut close_delimiters_by_open = BTreeMap::new();
4882            let mut bogus_patterns = HashSet::default();
4883            for (query_range, options) in iter::once(bounded_query).chain(boundary_queries) {
4884                let mut matches =
4885                    self.syntax
4886                        .matches_with_options(query_range, &self.text, options, |grammar| {
4887                            grammar.brackets_config.as_ref().map(|c| &c.query)
4888                        });
4889                let grammar_indices = matches
4890                    .grammars()
4891                    .iter()
4892                    .map(|grammar| {
4893                        grammar_ids
4894                            .iter()
4895                            .position(|&id| id == grammar.id())
4896                            .unwrap_or_else(|| {
4897                                grammar_ids.push(grammar.id());
4898                                configs.push(grammar.brackets_config.as_ref().unwrap());
4899                                grammar_ids.len() - 1
4900                            })
4901                    })
4902                    .collect::<Vec<_>>();
4903
4904                while let Some(mat) = matches.peek() {
4905                    let mut open = None;
4906                    let mut close = None;
4907                    let syntax_layer_depth = mat.depth;
4908                    let grammar_index = grammar_indices[mat.grammar_index];
4909                    let pattern_key = BracketPatternKey {
4910                        grammar_index,
4911                        pattern_index: mat.pattern_index,
4912                    };
4913                    let config = configs[grammar_index];
4914                    let pattern = &config.patterns[mat.pattern_index];
4915                    for capture in mat.captures {
4916                        if capture.index == config.open_capture_ix {
4917                            open = Some(capture.node.byte_range());
4918                        } else if capture.index == config.close_capture_ix {
4919                            close = Some(capture.node.byte_range());
4920                        }
4921                    }
4922
4923                    matches.advance();
4924
4925                    let Some((open_range, close_range)) = open.zip(close) else {
4926                        continue;
4927                    };
4928
4929                    let bracket_range = open_range.start..=close_range.end;
4930                    if !bracket_range.overlaps(&chunk_range) {
4931                        continue;
4932                    }
4933
4934                    let candidate = BracketMatchCandidate {
4935                        bracket_match: BracketMatch {
4936                            open_range,
4937                            close_range,
4938                            syntax_layer_depth,
4939                            newline_only: pattern.newline_only,
4940                            color_index: None,
4941                        },
4942                        pattern: pattern_key,
4943                        rainbow_exclude: pattern.rainbow_exclude,
4944                    };
4945
4946                    if !seen_delimiters
4947                        .insert((candidate.open_delimiter(), candidate.close_delimiter()))
4948                    {
4949                        continue;
4950                    }
4951
4952                    let close_delimiters = close_delimiters_by_open
4953                        .entry(candidate.open_delimiter())
4954                        .or_insert_with(BTreeSet::new);
4955                    close_delimiters.insert(candidate.close_delimiter());
4956                    if close_delimiters.len() > 1 {
4957                        bogus_patterns.insert(pattern_key);
4958                    }
4959
4960                    all_brackets.push(candidate);
4961                }
4962            }
4963
4964            if !bogus_patterns.is_empty() {
4965                // Certain patterns produce bogus matches where one open is paired with multiple
4966                // closes (e.g. same-character delimiters inside a single parent node).
4967                // Repair only those patterns, keeping trustworthy grammar output intact:
4968                // clean patterns may legitimately pair an open in one chunk with a close in
4969                // another, and must not be dropped by the chunk-local repair below.
4970                // For each close, we know the expected open_len from tree-sitter matches.
4971                let is_bogus =
4972                    |candidate: &BracketMatchCandidate| bogus_patterns.contains(&candidate.pattern);
4973
4974                // Map each close to its expected open length (for inferring opens)
4975                let close_to_open_len = all_brackets
4976                    .iter()
4977                    .filter(|candidate| is_bogus(candidate))
4978                    .map(|candidate| {
4979                        (
4980                            candidate.close_delimiter(),
4981                            candidate.bracket_match.open_range.len(),
4982                        )
4983                    })
4984                    .collect::<HashMap<_, _>>();
4985
4986                // Collect unique opens and closes within this chunk
4987                let unique_opens = all_brackets
4988                    .iter()
4989                    .filter(|candidate| is_bogus(candidate))
4990                    .map(|candidate| candidate.open_delimiter())
4991                    .filter(|open| chunk_range.contains(&open.start))
4992                    .collect::<HashSet<_>>();
4993
4994                let mut unique_closes = all_brackets
4995                    .iter()
4996                    .filter(|candidate| is_bogus(candidate))
4997                    .map(|candidate| candidate.close_delimiter())
4998                    .filter(|close| chunk_range.contains(&close.start))
4999                    .collect::<Vec<_>>();
5000                unique_closes.sort_unstable();
5001                unique_closes.dedup();
5002
5003                // Build valid pairs by walking through closes in order
5004                let mut sorted_opens = unique_opens.into_iter().collect::<Vec<_>>();
5005                sorted_opens.sort_unstable();
5006
5007                let mut valid_pairs = HashSet::default();
5008                let mut open_stacks = HashMap::default();
5009                let mut open_idx = 0;
5010
5011                for close in &unique_closes {
5012                    // Push all opens before this close onto stack
5013                    while open_idx < sorted_opens.len()
5014                        && sorted_opens[open_idx].start < close.start
5015                    {
5016                        let open = sorted_opens[open_idx];
5017                        open_stacks
5018                            .entry(open.pattern)
5019                            .or_insert_with(Vec::new)
5020                            .push(open);
5021                        open_idx += 1;
5022                    }
5023
5024                    // Try to match with most recent open
5025                    if let Some(open) = open_stacks
5026                        .get_mut(&close.pattern)
5027                        .and_then(|open_stack| open_stack.pop())
5028                    {
5029                        valid_pairs.insert((open, *close));
5030                    } else if let Some(&open_len) = close_to_open_len.get(close) {
5031                        // No open on stack - infer one based on expected open_len
5032                        if close.start >= open_len {
5033                            let inferred = BracketDelimiter {
5034                                start: close.start - open_len,
5035                                end: close.start,
5036                                pattern: close.pattern,
5037                            };
5038                            valid_pairs.insert((inferred, *close));
5039                            let pattern = &configs[close.pattern.grammar_index].patterns
5040                                [close.pattern.pattern_index];
5041                            all_brackets.push(BracketMatchCandidate {
5042                                bracket_match: BracketMatch {
5043                                    open_range: inferred.start..inferred.end,
5044                                    close_range: close.start..close.end,
5045                                    newline_only: pattern.newline_only,
5046                                    syntax_layer_depth: 0,
5047                                    color_index: None,
5048                                },
5049                                pattern: close.pattern,
5050                                rainbow_exclude: pattern.rainbow_exclude,
5051                            });
5052                        }
5053                    }
5054                }
5055
5056                all_brackets.retain(|candidate| {
5057                    !is_bogus(candidate)
5058                        || valid_pairs
5059                            .contains(&(candidate.open_delimiter(), candidate.close_delimiter()))
5060                });
5061            }
5062
5063            let mut all_brackets = all_brackets
5064                .into_iter()
5065                .enumerate()
5066                .map(|(index, candidate)| {
5067                    let bracket_match = candidate.bracket_match;
5068                    // Certain languages have "brackets" that are not brackets, e.g. tags. and such
5069                    // bracket will match the entire tag with all text inside.
5070                    // For now, avoid highlighting any pair that has more than single char in each bracket.
5071                    // We need to  colorize `<Element/>` bracket pairs, so cannot make this check stricter.
5072                    let should_color = !candidate.rainbow_exclude
5073                        && (bracket_match.open_range.len() == 1
5074                            || bracket_match.close_range.len() == 1);
5075                    if should_color {
5076                        opens.push(bracket_match.open_range.clone());
5077                        color_pairs.push((
5078                            bracket_match.open_range.clone(),
5079                            bracket_match.close_range.clone(),
5080                            index,
5081                        ));
5082                    }
5083                    bracket_match
5084                })
5085                .collect::<Vec<_>>();
5086
5087            opens.sort_by_key(|r| (r.start, r.end));
5088            opens.dedup_by(|a, b| a.start == b.start && a.end == b.end);
5089            color_pairs.sort_by_key(|(_, close, _)| close.end);
5090
5091            let mut open_stack = Vec::new();
5092            let mut open_index = 0;
5093            for (open, close, index) in color_pairs {
5094                while open_index < opens.len() && opens[open_index].start < close.start {
5095                    open_stack.push(opens[open_index].clone());
5096                    open_index += 1;
5097                }
5098
5099                if open_stack.last() == Some(&open) {
5100                    let depth_index = open_stack.len() - 1;
5101                    all_brackets[index].color_index = Some(depth_index);
5102                    open_stack.pop();
5103                }
5104            }
5105
5106            all_brackets.sort_by_key(|bracket_match| {
5107                (bracket_match.open_range.start, bracket_match.open_range.end)
5108            });
5109
5110            self.tree_sitter_data
5111                .brackets_by_chunks
5112                .lock()
5113                .entry(chunk.id)
5114                .or_insert_with(|| all_brackets.clone());
5115            all_bracket_matches.insert(chunk.row_range(), all_brackets);
5116        }
5117
5118        all_bracket_matches
5119    }
5120
5121    pub fn all_bracket_ranges(
5122        &self,
5123        range: Range<usize>,
5124    ) -> impl Iterator<Item = BracketMatch<usize>> {
5125        self.fetch_bracket_ranges(range.clone(), None)
5126            .into_values()
5127            .flatten()
5128            .filter(move |bracket_match| {
5129                let bracket_range = bracket_match.open_range.start..bracket_match.close_range.end;
5130                bracket_range.overlaps(&range)
5131            })
5132    }
5133
5134    /// Returns bracket range pairs overlapping or adjacent to `range`
5135    pub fn bracket_ranges<T: ToOffset>(
5136        &self,
5137        range: Range<T>,
5138    ) -> impl Iterator<Item = BracketMatch<usize>> + '_ {
5139        // Find bracket pairs that *inclusively* contain the given range.
5140        let range = range.start.to_previous_offset(self)..range.end.to_next_offset(self);
5141        self.all_bracket_ranges(range)
5142            .filter(|pair| !pair.newline_only)
5143    }
5144
5145    pub fn debug_variables_query<T: ToOffset>(
5146        &self,
5147        range: Range<T>,
5148    ) -> impl Iterator<Item = (Range<usize>, DebuggerTextObject)> + '_ {
5149        let range = range.start.to_previous_offset(self)..range.end.to_next_offset(self);
5150
5151        let mut matches = self.syntax.matches_with_options(
5152            range.clone(),
5153            &self.text,
5154            TreeSitterOptions::default(),
5155            |grammar| grammar.debug_variables_config.as_ref().map(|c| &c.query),
5156        );
5157
5158        let configs = matches
5159            .grammars()
5160            .iter()
5161            .map(|grammar| grammar.debug_variables_config.as_ref())
5162            .collect::<Vec<_>>();
5163
5164        let mut captures = Vec::<(Range<usize>, DebuggerTextObject)>::new();
5165
5166        iter::from_fn(move || {
5167            loop {
5168                while let Some(capture) = captures.pop() {
5169                    if capture.0.overlaps(&range) {
5170                        return Some(capture);
5171                    }
5172                }
5173
5174                let mat = matches.peek()?;
5175
5176                let Some(config) = configs[mat.grammar_index].as_ref() else {
5177                    matches.advance();
5178                    continue;
5179                };
5180
5181                for capture in mat.captures {
5182                    let Some(ix) = config
5183                        .objects_by_capture_ix
5184                        .binary_search_by_key(&capture.index, |e| e.0)
5185                        .ok()
5186                    else {
5187                        continue;
5188                    };
5189                    let text_object = config.objects_by_capture_ix[ix].1;
5190                    let byte_range = capture.node.byte_range();
5191
5192                    let mut found = false;
5193                    for (range, existing) in captures.iter_mut() {
5194                        if existing == &text_object {
5195                            range.start = range.start.min(byte_range.start);
5196                            range.end = range.end.max(byte_range.end);
5197                            found = true;
5198                            break;
5199                        }
5200                    }
5201
5202                    if !found {
5203                        captures.push((byte_range, text_object));
5204                    }
5205                }
5206
5207                matches.advance();
5208            }
5209        })
5210    }
5211
5212    pub fn text_object_ranges<T: ToOffset>(
5213        &self,
5214        range: Range<T>,
5215        options: TreeSitterOptions,
5216    ) -> impl Iterator<Item = (Range<usize>, TextObject)> + '_ {
5217        let range =
5218            range.start.to_previous_offset(self)..self.len().min(range.end.to_next_offset(self));
5219
5220        let mut matches =
5221            self.syntax
5222                .matches_with_options(range.clone(), &self.text, options, |grammar| {
5223                    grammar.text_object_config.as_ref().map(|c| &c.query)
5224                });
5225
5226        let configs = matches
5227            .grammars()
5228            .iter()
5229            .map(|grammar| grammar.text_object_config.as_ref())
5230            .collect::<Vec<_>>();
5231
5232        let mut captures = Vec::<(Range<usize>, TextObject)>::new();
5233
5234        iter::from_fn(move || {
5235            loop {
5236                while let Some(capture) = captures.pop() {
5237                    if capture.0.overlaps(&range) {
5238                        return Some(capture);
5239                    }
5240                }
5241
5242                let mat = matches.peek()?;
5243
5244                let Some(config) = configs[mat.grammar_index].as_ref() else {
5245                    matches.advance();
5246                    continue;
5247                };
5248
5249                for capture in mat.captures {
5250                    let Some(ix) = config
5251                        .text_objects_by_capture_ix
5252                        .binary_search_by_key(&capture.index, |e| e.0)
5253                        .ok()
5254                    else {
5255                        continue;
5256                    };
5257                    let text_object = config.text_objects_by_capture_ix[ix].1;
5258                    let byte_range = capture.node.byte_range();
5259
5260                    let mut found = false;
5261                    for (range, existing) in captures.iter_mut() {
5262                        if existing == &text_object {
5263                            range.start = range.start.min(byte_range.start);
5264                            range.end = range.end.max(byte_range.end);
5265                            found = true;
5266                            break;
5267                        }
5268                    }
5269
5270                    if !found {
5271                        captures.push((byte_range, text_object));
5272                    }
5273                }
5274
5275                matches.advance();
5276            }
5277        })
5278    }
5279
5280    /// Returns enclosing bracket ranges containing the given range
5281    pub fn enclosing_bracket_ranges<T: ToOffset>(
5282        &self,
5283        range: Range<T>,
5284    ) -> impl Iterator<Item = BracketMatch<usize>> + '_ {
5285        let range = range.start.to_offset(self)..range.end.to_offset(self);
5286
5287        let result: Vec<_> = self.bracket_ranges(range.clone()).collect();
5288        let max_depth = result
5289            .iter()
5290            .map(|mat| mat.syntax_layer_depth)
5291            .max()
5292            .unwrap_or(0);
5293        result.into_iter().filter(move |pair| {
5294            pair.open_range.start <= range.start
5295                && pair.close_range.end >= range.end
5296                && pair.syntax_layer_depth == max_depth
5297        })
5298    }
5299
5300    /// Returns the smallest enclosing bracket ranges containing the given range or None if no brackets contain range
5301    ///
5302    /// Can optionally pass a range_filter to filter the ranges of brackets to consider
5303    pub fn innermost_enclosing_bracket_ranges<T: ToOffset>(
5304        &self,
5305        range: Range<T>,
5306        range_filter: Option<&dyn Fn(Range<usize>, Range<usize>) -> bool>,
5307    ) -> Option<(Range<usize>, Range<usize>)> {
5308        let range = range.start.to_offset(self)..range.end.to_offset(self);
5309
5310        // Get the ranges of the innermost pair of brackets.
5311        let mut result: Option<(Range<usize>, Range<usize>)> = None;
5312
5313        for pair in self.enclosing_bracket_ranges(range) {
5314            if let Some(range_filter) = range_filter
5315                && !range_filter(pair.open_range.clone(), pair.close_range.clone())
5316            {
5317                continue;
5318            }
5319
5320            let len = pair.close_range.end - pair.open_range.start;
5321
5322            if let Some((existing_open, existing_close)) = &result {
5323                let existing_len = existing_close.end - existing_open.start;
5324                if len > existing_len {
5325                    continue;
5326                }
5327            }
5328
5329            result = Some((pair.open_range, pair.close_range));
5330        }
5331
5332        result
5333    }
5334
5335    /// Returns anchor ranges for any matches of the redaction query.
5336    /// The buffer can be associated with multiple languages, and the redaction query associated with each
5337    /// will be run on the relevant section of the buffer.
5338    pub fn redacted_ranges<T: ToOffset>(
5339        &self,
5340        range: Range<T>,
5341    ) -> impl Iterator<Item = Range<usize>> + '_ {
5342        let offset_range = range.start.to_offset(self)..range.end.to_offset(self);
5343        let mut syntax_matches = self.syntax.matches(offset_range, self, |grammar| {
5344            grammar
5345                .redactions_config
5346                .as_ref()
5347                .map(|config| &config.query)
5348        });
5349
5350        let configs = syntax_matches
5351            .grammars()
5352            .iter()
5353            .map(|grammar| grammar.redactions_config.as_ref())
5354            .collect::<Vec<_>>();
5355
5356        iter::from_fn(move || {
5357            let redacted_range = syntax_matches
5358                .peek()
5359                .and_then(|mat| {
5360                    configs[mat.grammar_index].and_then(|config| {
5361                        mat.captures
5362                            .iter()
5363                            .find(|capture| capture.index == config.redaction_capture_ix)
5364                    })
5365                })
5366                .map(|mat| mat.node.byte_range());
5367            syntax_matches.advance();
5368            redacted_range
5369        })
5370    }
5371
5372    pub fn injections_intersecting_range<T: ToOffset>(
5373        &self,
5374        range: Range<T>,
5375    ) -> impl Iterator<Item = (Range<usize>, &Arc<Language>)> + '_ {
5376        let offset_range = range.start.to_offset(self)..range.end.to_offset(self);
5377
5378        let mut syntax_matches = self.syntax.matches(offset_range, self, |grammar| {
5379            grammar
5380                .injection_config
5381                .as_ref()
5382                .map(|config| &config.query)
5383        });
5384
5385        let configs = syntax_matches
5386            .grammars()
5387            .iter()
5388            .map(|grammar| grammar.injection_config.as_ref())
5389            .collect::<Vec<_>>();
5390
5391        iter::from_fn(move || {
5392            let ranges = syntax_matches.peek().and_then(|mat| {
5393                let config = &configs[mat.grammar_index]?;
5394                let content_capture_range = mat.captures.iter().find_map(|capture| {
5395                    if capture.index == config.content_capture_ix {
5396                        Some(capture.node.byte_range())
5397                    } else {
5398                        None
5399                    }
5400                })?;
5401                let language = self.language_at(content_capture_range.start)?;
5402                Some((content_capture_range, language))
5403            });
5404            syntax_matches.advance();
5405            ranges
5406        })
5407    }
5408
5409    pub fn runnable_ranges(
5410        &self,
5411        offset_range: Range<usize>,
5412    ) -> impl Iterator<Item = RunnableRange> + '_ {
5413        runnable::runnable_ranges(self, offset_range)
5414    }
5415
5416    /// Returns selections for remote peers intersecting the given range.
5417    #[allow(clippy::type_complexity)]
5418    pub fn selections_in_range(
5419        &self,
5420        range: Range<Anchor>,
5421        include_local: bool,
5422    ) -> impl Iterator<
5423        Item = (
5424            ReplicaId,
5425            bool,
5426            CursorShape,
5427            impl Iterator<Item = &Selection<Anchor>> + '_,
5428        ),
5429    > + '_ {
5430        self.remote_selections
5431            .iter()
5432            .filter(move |(replica_id, set)| {
5433                (include_local || **replica_id != self.text.replica_id())
5434                    && !set.selections.is_empty()
5435            })
5436            .map(move |(replica_id, set)| {
5437                let start_ix = match set.selections.binary_search_by(|probe| {
5438                    probe.end.cmp(&range.start, self).then(Ordering::Greater)
5439                }) {
5440                    Ok(ix) | Err(ix) => ix,
5441                };
5442                let end_ix = match set.selections.binary_search_by(|probe| {
5443                    probe.start.cmp(&range.end, self).then(Ordering::Less)
5444                }) {
5445                    Ok(ix) | Err(ix) => ix,
5446                };
5447
5448                (
5449                    *replica_id,
5450                    set.line_mode,
5451                    set.cursor_shape,
5452                    set.selections[start_ix..end_ix].iter(),
5453                )
5454            })
5455    }
5456
5457    /// Returns if the buffer contains any diagnostics.
5458    pub fn has_diagnostics(&self) -> bool {
5459        !self.diagnostics.is_empty()
5460    }
5461
5462    /// Returns all the diagnostics intersecting the given range.
5463    pub fn diagnostics_in_range<'a, T, O>(
5464        &'a self,
5465        search_range: Range<T>,
5466        reversed: bool,
5467    ) -> impl 'a + Iterator<Item = DiagnosticEntryRef<'a, O>>
5468    where
5469        T: 'a + Clone + ToOffset,
5470        O: 'a + FromAnchor,
5471    {
5472        let mut iterators: Vec<_> = self
5473            .diagnostics
5474            .iter()
5475            .map(|(_, collection)| {
5476                collection
5477                    .range::<T, text::Anchor>(search_range.clone(), self, true, reversed)
5478                    .peekable()
5479            })
5480            .collect();
5481
5482        std::iter::from_fn(move || {
5483            let (next_ix, _) = iterators
5484                .iter_mut()
5485                .enumerate()
5486                .flat_map(|(ix, iter)| Some((ix, iter.peek()?)))
5487                .min_by(|(_, a), (_, b)| {
5488                    let cmp = a
5489                        .range
5490                        .start
5491                        .cmp(&b.range.start, self)
5492                        // when range is equal, sort by diagnostic severity
5493                        .then(a.diagnostic.severity.cmp(&b.diagnostic.severity))
5494                        // and stabilize order with group_id
5495                        .then(a.diagnostic.group_id.cmp(&b.diagnostic.group_id));
5496                    if reversed { cmp.reverse() } else { cmp }
5497                })?;
5498            iterators[next_ix]
5499                .next()
5500                .map(
5501                    |DiagnosticEntryRef { range, diagnostic }| DiagnosticEntryRef {
5502                        diagnostic,
5503                        range: FromAnchor::from_anchor(&range.start, self)
5504                            ..FromAnchor::from_anchor(&range.end, self),
5505                    },
5506                )
5507        })
5508    }
5509
5510    /// Returns all the diagnostic groups associated with the given
5511    /// language server ID. If no language server ID is provided,
5512    /// all diagnostics groups are returned.
5513    pub fn diagnostic_groups(
5514        &self,
5515        language_server_id: Option<LanguageServerId>,
5516    ) -> Vec<(LanguageServerId, DiagnosticGroup<'_, Anchor>)> {
5517        let mut groups = Vec::new();
5518
5519        if let Some(language_server_id) = language_server_id {
5520            if let Some(set) = self.diagnostics.get(&language_server_id) {
5521                set.groups(language_server_id, &mut groups, self);
5522            }
5523        } else {
5524            for (language_server_id, diagnostics) in self.diagnostics.iter() {
5525                diagnostics.groups(*language_server_id, &mut groups, self);
5526            }
5527        }
5528
5529        groups.sort_by(|(id_a, group_a), (id_b, group_b)| {
5530            let a_start = &group_a.entries[group_a.primary_ix].range.start;
5531            let b_start = &group_b.entries[group_b.primary_ix].range.start;
5532            a_start.cmp(b_start, self).then_with(|| id_a.cmp(id_b))
5533        });
5534
5535        groups
5536    }
5537
5538    /// Returns an iterator over the diagnostics for the given group.
5539    pub fn diagnostic_group<O>(
5540        &self,
5541        group_id: usize,
5542    ) -> impl Iterator<Item = DiagnosticEntryRef<'_, O>> + use<'_, O>
5543    where
5544        O: FromAnchor + 'static,
5545    {
5546        self.diagnostics
5547            .iter()
5548            .flat_map(move |(_, set)| set.group(group_id, self))
5549    }
5550
5551    /// An integer version number that accounts for all updates besides
5552    /// the buffer's text itself (which is versioned via a version vector).
5553    pub fn non_text_state_update_count(&self) -> usize {
5554        self.non_text_state_update_count
5555    }
5556
5557    /// An integer version that changes when the buffer's syntax changes.
5558    pub fn syntax_update_count(&self) -> usize {
5559        self.syntax.update_count()
5560    }
5561
5562    /// Returns a snapshot of underlying file.
5563    pub fn file(&self) -> Option<&Arc<dyn File>> {
5564        self.file.as_ref()
5565    }
5566
5567    pub fn resolve_file_path(&self, include_root: bool, cx: &App) -> Option<String> {
5568        if let Some(file) = self.file() {
5569            if file.path().file_name().is_none() || include_root {
5570                Some(file.full_path(cx).to_string_lossy().into_owned())
5571            } else {
5572                Some(file.path().display(file.path_style(cx)).to_string())
5573            }
5574        } else {
5575            None
5576        }
5577    }
5578
5579    pub fn words_in_range(&self, query: WordsQuery) -> BTreeMap<String, Range<Anchor>> {
5580        let query_str = query.fuzzy_contents;
5581        if query_str.is_some_and(|query| query.is_empty()) {
5582            return BTreeMap::default();
5583        }
5584
5585        let classifier = CharClassifier::new(self.language.clone().map(|language| LanguageScope {
5586            language,
5587            override_id: None,
5588        }));
5589
5590        let mut query_ix = 0;
5591        let query_chars = query_str.map(|query| query.chars().collect::<Vec<_>>());
5592        let query_len = query_chars.as_ref().map_or(0, |query| query.len());
5593
5594        let mut words = BTreeMap::default();
5595        let mut current_word_start_ix = None;
5596        let mut chunk_ix = query.range.start;
5597        for chunk in self.chunks(
5598            query.range,
5599            LanguageAwareStyling {
5600                tree_sitter: false,
5601                diagnostics: false,
5602            },
5603        ) {
5604            for (i, c) in chunk.text.char_indices() {
5605                let ix = chunk_ix + i;
5606                if classifier.is_word(c) {
5607                    if current_word_start_ix.is_none() {
5608                        current_word_start_ix = Some(ix);
5609                    }
5610
5611                    if let Some(query_chars) = &query_chars
5612                        && query_ix < query_len
5613                        && c.to_lowercase().eq(query_chars[query_ix].to_lowercase())
5614                    {
5615                        query_ix += 1;
5616                    }
5617                    continue;
5618                } else if let Some(word_start) = current_word_start_ix.take()
5619                    && query_ix == query_len
5620                {
5621                    let word_range = self.anchor_before(word_start)..self.anchor_after(ix);
5622                    let mut word_text = self.text_for_range(word_start..ix).peekable();
5623                    let first_char = word_text
5624                        .peek()
5625                        .and_then(|first_chunk| first_chunk.chars().next());
5626                    // Skip empty and "words" starting with digits as a heuristic to reduce useless completions
5627                    if !query.skip_digits
5628                        || first_char.is_none_or(|first_char| !first_char.is_digit(10))
5629                    {
5630                        words.insert(word_text.collect(), word_range);
5631                    }
5632                }
5633                query_ix = 0;
5634            }
5635            chunk_ix += chunk.text.len();
5636        }
5637
5638        words
5639    }
5640}
5641
5642/// A configuration to use when producing styled text chunks.
5643#[derive(Clone, Copy)]
5644pub struct LanguageAwareStyling {
5645    /// Whether to highlight text chunks using tree-sitter.
5646    pub tree_sitter: bool,
5647    /// Whether to highlight text chunks based on the diagnostics data.
5648    pub diagnostics: bool,
5649}
5650
5651pub struct WordsQuery<'a> {
5652    /// Only returns words with all chars from the fuzzy string in them.
5653    pub fuzzy_contents: Option<&'a str>,
5654    /// Skips words that start with a digit.
5655    pub skip_digits: bool,
5656    /// Buffer offset range, to look for words.
5657    pub range: Range<usize>,
5658}
5659
5660fn indent_size_for_line(text: &text::BufferSnapshot, row: u32) -> IndentSize {
5661    indent_size_for_text(text.chars_at(Point::new(row, 0)))
5662}
5663
5664fn indent_size_for_text(text: impl Iterator<Item = char>) -> IndentSize {
5665    let mut result = IndentSize::spaces(0);
5666    for c in text {
5667        let kind = match c {
5668            ' ' => IndentKind::Space,
5669            '\t' => IndentKind::Tab,
5670            _ => break,
5671        };
5672        if result.len == 0 {
5673            result.kind = kind;
5674        }
5675        result.len += 1;
5676    }
5677    result
5678}
5679
5680impl Clone for BufferSnapshot {
5681    fn clone(&self) -> Self {
5682        Self {
5683            text: self.text.clone(),
5684            syntax: self.syntax.clone(),
5685            file: self.file.clone(),
5686            remote_selections: self.remote_selections.clone(),
5687            diagnostics: self.diagnostics.clone(),
5688            language: self.language.clone(),
5689            tree_sitter_data: self.tree_sitter_data.clone(),
5690            non_text_state_update_count: self.non_text_state_update_count,
5691            capability: self.capability,
5692            modeline: self.modeline.clone(),
5693        }
5694    }
5695}
5696
5697impl Deref for BufferSnapshot {
5698    type Target = text::BufferSnapshot;
5699
5700    fn deref(&self) -> &Self::Target {
5701        &self.text
5702    }
5703}
5704
5705unsafe impl Send for BufferChunks<'_> {}
5706
5707impl<'a> BufferChunks<'a> {
5708    pub(crate) fn new(
5709        text: &'a Rope,
5710        range: Range<usize>,
5711        syntax: Option<(SyntaxMapCaptures<'a>, Vec<HighlightMap>)>,
5712        diagnostics: bool,
5713        buffer_snapshot: Option<&'a BufferSnapshot>,
5714    ) -> Self {
5715        let mut highlights = None;
5716        if let Some((captures, highlight_maps)) = syntax {
5717            highlights = Some(BufferChunkHighlights {
5718                captures,
5719                next_capture: None,
5720                stack: Default::default(),
5721                highlight_maps,
5722            })
5723        }
5724
5725        let diagnostic_endpoints = diagnostics.then(|| Vec::new().into_iter().peekable());
5726        let chunks = text.chunks_in_range(range.clone());
5727
5728        let mut this = BufferChunks {
5729            range,
5730            buffer_snapshot,
5731            chunks,
5732            diagnostic_endpoints,
5733            error_depth: 0,
5734            warning_depth: 0,
5735            information_depth: 0,
5736            hint_depth: 0,
5737            unnecessary_depth: 0,
5738            underline: true,
5739            highlights,
5740        };
5741        this.initialize_diagnostic_endpoints();
5742        this
5743    }
5744
5745    /// Seeks to the given byte offset in the buffer.
5746    pub fn seek(&mut self, range: Range<usize>) {
5747        let old_range = std::mem::replace(&mut self.range, range.clone());
5748        self.chunks.set_range(self.range.clone());
5749        if let Some(highlights) = self.highlights.as_mut() {
5750            if old_range.start <= self.range.start && old_range.end >= self.range.end {
5751                // Reuse existing highlights stack, as the new range is a subrange of the old one.
5752                highlights
5753                    .stack
5754                    .retain(|(end_offset, _)| *end_offset > range.start);
5755                if let Some(capture) = &highlights.next_capture
5756                    && range.start >= capture.node.start_byte()
5757                {
5758                    let next_capture_end = capture.node.end_byte();
5759                    if range.start < next_capture_end
5760                        && let Some(capture_id) =
5761                            highlights.highlight_maps[capture.grammar_index].get(capture.index)
5762                    {
5763                        highlights.stack.push((next_capture_end, capture_id));
5764                    }
5765                    highlights.next_capture.take();
5766                }
5767            } else if let Some(snapshot) = self.buffer_snapshot {
5768                let (captures, highlight_maps) = snapshot.get_highlights(self.range.clone());
5769                *highlights = BufferChunkHighlights {
5770                    captures,
5771                    next_capture: None,
5772                    stack: Default::default(),
5773                    highlight_maps,
5774                };
5775            } else {
5776                // We cannot obtain new highlights for a language-aware buffer iterator, as we don't have a buffer snapshot.
5777                // Seeking such BufferChunks is not supported.
5778                debug_assert!(
5779                    false,
5780                    "Attempted to seek on a language-aware buffer iterator without associated buffer snapshot"
5781                );
5782            }
5783
5784            highlights.captures.set_byte_range(self.range.clone());
5785            self.initialize_diagnostic_endpoints();
5786        }
5787    }
5788
5789    fn initialize_diagnostic_endpoints(&mut self) {
5790        if let Some(diagnostics) = self.diagnostic_endpoints.as_mut()
5791            && let Some(buffer) = self.buffer_snapshot
5792        {
5793            let mut diagnostic_endpoints = Vec::new();
5794            for entry in buffer.diagnostics_in_range::<_, usize>(self.range.clone(), false) {
5795                diagnostic_endpoints.push(DiagnosticEndpoint {
5796                    offset: entry.range.start,
5797                    is_start: true,
5798                    severity: entry.diagnostic.severity,
5799                    is_unnecessary: entry.diagnostic.is_unnecessary,
5800                    underline: entry.diagnostic.underline,
5801                });
5802                diagnostic_endpoints.push(DiagnosticEndpoint {
5803                    offset: entry.range.end,
5804                    is_start: false,
5805                    severity: entry.diagnostic.severity,
5806                    is_unnecessary: entry.diagnostic.is_unnecessary,
5807                    underline: entry.diagnostic.underline,
5808                });
5809            }
5810            diagnostic_endpoints
5811                .sort_unstable_by_key(|endpoint| (endpoint.offset, !endpoint.is_start));
5812            *diagnostics = diagnostic_endpoints.into_iter().peekable();
5813            self.hint_depth = 0;
5814            self.error_depth = 0;
5815            self.warning_depth = 0;
5816            self.information_depth = 0;
5817        }
5818    }
5819
5820    /// The current byte offset in the buffer.
5821    pub fn offset(&self) -> usize {
5822        self.range.start
5823    }
5824
5825    pub fn range(&self) -> Range<usize> {
5826        self.range.clone()
5827    }
5828
5829    fn update_diagnostic_depths(&mut self, endpoint: DiagnosticEndpoint) {
5830        let depth = match endpoint.severity {
5831            DiagnosticSeverity::ERROR => &mut self.error_depth,
5832            DiagnosticSeverity::WARNING => &mut self.warning_depth,
5833            DiagnosticSeverity::INFORMATION => &mut self.information_depth,
5834            DiagnosticSeverity::HINT => &mut self.hint_depth,
5835            _ => return,
5836        };
5837        if endpoint.is_start {
5838            *depth += 1;
5839        } else {
5840            *depth -= 1;
5841        }
5842
5843        if endpoint.is_unnecessary {
5844            if endpoint.is_start {
5845                self.unnecessary_depth += 1;
5846            } else {
5847                self.unnecessary_depth -= 1;
5848            }
5849        }
5850    }
5851
5852    fn current_diagnostic_severity(&self) -> Option<DiagnosticSeverity> {
5853        if self.error_depth > 0 {
5854            Some(DiagnosticSeverity::ERROR)
5855        } else if self.warning_depth > 0 {
5856            Some(DiagnosticSeverity::WARNING)
5857        } else if self.information_depth > 0 {
5858            Some(DiagnosticSeverity::INFORMATION)
5859        } else if self.hint_depth > 0 {
5860            Some(DiagnosticSeverity::HINT)
5861        } else {
5862            None
5863        }
5864    }
5865
5866    fn current_code_is_unnecessary(&self) -> bool {
5867        self.unnecessary_depth > 0
5868    }
5869}
5870
5871impl<'a> Iterator for BufferChunks<'a> {
5872    type Item = Chunk<'a>;
5873
5874    fn next(&mut self) -> Option<Self::Item> {
5875        let mut next_capture_start = usize::MAX;
5876        let mut next_diagnostic_endpoint = usize::MAX;
5877
5878        if let Some(highlights) = self.highlights.as_mut() {
5879            while let Some((parent_capture_end, _)) = highlights.stack.last() {
5880                if *parent_capture_end <= self.range.start {
5881                    highlights.stack.pop();
5882                } else {
5883                    break;
5884                }
5885            }
5886
5887            if highlights.next_capture.is_none() {
5888                highlights.next_capture = highlights.captures.next();
5889            }
5890
5891            while let Some(capture) = highlights.next_capture.as_ref() {
5892                if self.range.start < capture.node.start_byte() {
5893                    next_capture_start = capture.node.start_byte();
5894                    break;
5895                } else {
5896                    let highlight_id =
5897                        highlights.highlight_maps[capture.grammar_index].get(capture.index);
5898                    if let Some(highlight_id) = highlight_id {
5899                        highlights
5900                            .stack
5901                            .push((capture.node.end_byte(), highlight_id));
5902                    }
5903                    highlights.next_capture = highlights.captures.next();
5904                }
5905            }
5906        }
5907
5908        let mut diagnostic_endpoints = std::mem::take(&mut self.diagnostic_endpoints);
5909        if let Some(diagnostic_endpoints) = diagnostic_endpoints.as_mut() {
5910            while let Some(endpoint) = diagnostic_endpoints.peek().copied() {
5911                if endpoint.offset <= self.range.start {
5912                    self.update_diagnostic_depths(endpoint);
5913                    diagnostic_endpoints.next();
5914                    self.underline = endpoint.underline;
5915                } else {
5916                    next_diagnostic_endpoint = endpoint.offset;
5917                    break;
5918                }
5919            }
5920        }
5921        self.diagnostic_endpoints = diagnostic_endpoints;
5922
5923        if let Some(ChunkBitmaps {
5924            text: chunk,
5925            chars: chars_map,
5926            tabs,
5927            newlines,
5928        }) = self.chunks.peek_with_bitmaps()
5929        {
5930            let chunk_start = self.range.start;
5931            let mut chunk_end = (self.chunks.offset() + chunk.len())
5932                .min(next_capture_start)
5933                .min(next_diagnostic_endpoint);
5934            let mut highlight_id = None;
5935            if let Some(highlights) = self.highlights.as_ref()
5936                && let Some((parent_capture_end, parent_highlight_id)) = highlights.stack.last()
5937            {
5938                chunk_end = chunk_end.min(*parent_capture_end);
5939                highlight_id = Some(*parent_highlight_id);
5940            }
5941            let bit_start = chunk_start - self.chunks.offset();
5942            let bit_end = chunk_end - self.chunks.offset();
5943
5944            let slice = &chunk[bit_start..bit_end];
5945
5946            let mask = 1u128
5947                .unbounded_shl((bit_end - bit_start) as u32)
5948                .wrapping_sub(1);
5949            let tabs = (tabs >> bit_start) & mask;
5950            let chars = (chars_map >> bit_start) & mask;
5951            let newlines = (newlines >> bit_start) & mask;
5952
5953            self.range.start = chunk_end;
5954            if self.range.start == self.chunks.offset() + chunk.len() {
5955                self.chunks.next().unwrap();
5956            }
5957
5958            Some(Chunk {
5959                text: slice,
5960                syntax_highlight_id: highlight_id,
5961                underline: self.underline,
5962                diagnostic_severity: self.current_diagnostic_severity(),
5963                is_unnecessary: self.current_code_is_unnecessary(),
5964                tabs,
5965                chars,
5966                newlines,
5967                ..Chunk::default()
5968            })
5969        } else {
5970            None
5971        }
5972    }
5973}
5974
5975impl operation_queue::Operation for Operation {
5976    fn lamport_timestamp(&self) -> clock::Lamport {
5977        match self {
5978            Operation::Buffer(_) => {
5979                unreachable!("buffer operations should never be deferred at this layer")
5980            }
5981            Operation::UpdateDiagnostics {
5982                lamport_timestamp, ..
5983            }
5984            | Operation::UpdateSelections {
5985                lamport_timestamp, ..
5986            }
5987            | Operation::UpdateCompletionTriggers {
5988                lamport_timestamp, ..
5989            }
5990            | Operation::UpdateLineEnding {
5991                lamport_timestamp, ..
5992            } => *lamport_timestamp,
5993        }
5994    }
5995}
5996
5997impl IndentSize {
5998    /// Returns an [`IndentSize`] representing the given spaces.
5999    pub fn spaces(len: u32) -> Self {
6000        Self {
6001            len,
6002            kind: IndentKind::Space,
6003        }
6004    }
6005
6006    /// Returns an [`IndentSize`] representing a tab.
6007    pub fn tab() -> Self {
6008        Self {
6009            len: 1,
6010            kind: IndentKind::Tab,
6011        }
6012    }
6013
6014    /// An iterator over the characters represented by this [`IndentSize`].
6015    pub fn chars(&self) -> impl Iterator<Item = char> {
6016        iter::repeat(self.char()).take(self.len as usize)
6017    }
6018
6019    /// The character representation of this [`IndentSize`].
6020    pub fn char(&self) -> char {
6021        match self.kind {
6022            IndentKind::Space => ' ',
6023            IndentKind::Tab => '\t',
6024        }
6025    }
6026
6027    /// Consumes the current [`IndentSize`] and returns a new one that has
6028    /// been shrunk or enlarged by the given size along the given direction.
6029    pub fn with_delta(mut self, direction: Ordering, size: IndentSize) -> Self {
6030        match direction {
6031            Ordering::Less => {
6032                if self.kind == size.kind && self.len >= size.len {
6033                    self.len -= size.len;
6034                }
6035            }
6036            Ordering::Equal => {}
6037            Ordering::Greater => {
6038                if self.len == 0 {
6039                    self = size;
6040                } else if self.kind == size.kind {
6041                    self.len += size.len;
6042                }
6043            }
6044        }
6045        self
6046    }
6047
6048    /// Returns the number of indentation characters to remove when outdenting to the
6049    /// previous editor tab stop.
6050    pub fn outdent_len(self, tab_size: NonZeroU32) -> u32 {
6051        if self.len == 0 {
6052            return 0;
6053        }
6054
6055        match self.kind {
6056            IndentKind::Space => {
6057                let tab_size = tab_size.get();
6058                let columns_to_prev_tab_stop = self.len % tab_size;
6059                if columns_to_prev_tab_stop == 0 {
6060                    tab_size
6061                } else {
6062                    columns_to_prev_tab_stop
6063                }
6064            }
6065            IndentKind::Tab => 1,
6066        }
6067    }
6068
6069    pub fn len_with_expanded_tabs(&self, tab_size: NonZeroU32) -> usize {
6070        match self.kind {
6071            IndentKind::Space => self.len as usize,
6072            IndentKind::Tab => self.len as usize * tab_size.get() as usize,
6073        }
6074    }
6075}
6076
6077#[cfg(any(test, feature = "test-support"))]
6078pub struct TestFile {
6079    pub path: Arc<RelPath>,
6080    pub root_name: String,
6081    pub local_root: Option<PathBuf>,
6082}
6083
6084#[cfg(any(test, feature = "test-support"))]
6085impl File for TestFile {
6086    fn path(&self) -> &Arc<RelPath> {
6087        &self.path
6088    }
6089
6090    fn full_path(&self, _: &gpui::App) -> PathBuf {
6091        PathBuf::from(self.root_name.clone()).join(self.path.as_std_path())
6092    }
6093
6094    fn as_local(&self) -> Option<&dyn LocalFile> {
6095        if self.local_root.is_some() {
6096            Some(self)
6097        } else {
6098            None
6099        }
6100    }
6101
6102    fn disk_state(&self) -> DiskState {
6103        unimplemented!()
6104    }
6105
6106    fn file_name<'a>(&'a self, _: &'a gpui::App) -> &'a str {
6107        self.path().file_name().unwrap_or(self.root_name.as_ref())
6108    }
6109
6110    fn worktree_id(&self, _: &App) -> WorktreeId {
6111        WorktreeId::from_usize(0)
6112    }
6113
6114    fn to_proto(&self, _: &App) -> rpc::proto::File {
6115        unimplemented!()
6116    }
6117
6118    fn is_private(&self) -> bool {
6119        false
6120    }
6121
6122    fn path_style(&self, _cx: &App) -> PathStyle {
6123        PathStyle::local()
6124    }
6125}
6126
6127#[cfg(any(test, feature = "test-support"))]
6128impl LocalFile for TestFile {
6129    fn abs_path(&self, _cx: &App) -> PathBuf {
6130        PathBuf::from(self.local_root.as_ref().unwrap())
6131            .join(&self.root_name)
6132            .join(self.path.as_std_path())
6133    }
6134
6135    fn load(&self, _cx: &App) -> Task<Result<String>> {
6136        unimplemented!()
6137    }
6138
6139    fn load_bytes(&self, _cx: &App) -> Task<Result<Vec<u8>>> {
6140        unimplemented!()
6141    }
6142}
6143
6144pub(crate) fn contiguous_ranges(
6145    values: impl Iterator<Item = u32>,
6146    max_len: usize,
6147) -> impl Iterator<Item = Range<u32>> {
6148    let mut values = values;
6149    let mut current_range: Option<Range<u32>> = None;
6150    std::iter::from_fn(move || {
6151        loop {
6152            if let Some(value) = values.next() {
6153                if let Some(range) = &mut current_range
6154                    && value == range.end
6155                    && range.len() < max_len
6156                {
6157                    range.end += 1;
6158                    continue;
6159                }
6160
6161                let prev_range = current_range.clone();
6162                current_range = Some(value..(value + 1));
6163                if prev_range.is_some() {
6164                    return prev_range;
6165                }
6166            } else {
6167                return current_range.take();
6168            }
6169        }
6170    })
6171}
6172
6173#[derive(Default, Debug)]
6174pub struct CharClassifier {
6175    scope: Option<LanguageScope>,
6176    scope_context: Option<CharScopeContext>,
6177    ignore_punctuation: bool,
6178}
6179
6180impl CharClassifier {
6181    pub fn new(scope: Option<LanguageScope>) -> Self {
6182        Self {
6183            scope,
6184            scope_context: None,
6185            ignore_punctuation: false,
6186        }
6187    }
6188
6189    pub fn scope_context(self, scope_context: Option<CharScopeContext>) -> Self {
6190        Self {
6191            scope_context,
6192            ..self
6193        }
6194    }
6195
6196    pub fn ignore_punctuation(self, ignore_punctuation: bool) -> Self {
6197        Self {
6198            ignore_punctuation,
6199            ..self
6200        }
6201    }
6202
6203    pub fn is_whitespace(&self, c: char) -> bool {
6204        self.kind(c) == CharKind::Whitespace
6205    }
6206
6207    pub fn is_word(&self, c: char) -> bool {
6208        self.kind(c) == CharKind::Word
6209    }
6210
6211    pub fn is_punctuation(&self, c: char) -> bool {
6212        self.kind(c) == CharKind::Punctuation
6213    }
6214
6215    pub fn kind_with(&self, c: char, ignore_punctuation: bool) -> CharKind {
6216        if c.is_alphanumeric() || c == '_' {
6217            return CharKind::Word;
6218        }
6219
6220        if let Some(scope) = &self.scope {
6221            let characters = match self.scope_context {
6222                Some(CharScopeContext::Completion) => scope.completion_query_characters(),
6223                Some(CharScopeContext::LinkedEdit) => scope.linked_edit_characters(),
6224                None => scope.word_characters(),
6225            };
6226            if let Some(characters) = characters
6227                && characters.contains(&c)
6228            {
6229                return CharKind::Word;
6230            }
6231        }
6232
6233        if c.is_whitespace() {
6234            return CharKind::Whitespace;
6235        }
6236
6237        if ignore_punctuation {
6238            CharKind::Word
6239        } else {
6240            CharKind::Punctuation
6241        }
6242    }
6243
6244    pub fn kind(&self, c: char) -> CharKind {
6245        self.kind_with(c, self.ignore_punctuation)
6246    }
6247}
6248
6249/// Find all of the ranges of whitespace that occur at the ends of lines
6250/// in the given rope.
6251///
6252/// This could also be done with a regex search, but this implementation
6253/// avoids copying text.
6254/// Returns the byte ranges of trailing whitespace at the end of each line.
6255///
6256/// When `row_ranges` is `Some`, only lines whose row falls within one of the ranges are
6257/// included. The single pass keeps filtering cheap, avoiding collecting every range up front.
6258pub(crate) fn trailing_whitespace_ranges(
6259    rope: &Rope,
6260    row_ranges: Option<&[Range<u32>]>,
6261) -> Vec<Range<usize>> {
6262    let mut ranges = Vec::new();
6263
6264    let is_row_included = |row: u32| match row_ranges {
6265        Some(row_ranges) => row_ranges.iter().any(|range| range.contains(&row)),
6266        None => true,
6267    };
6268
6269    let mut offset = 0;
6270    let mut current_row: u32 = 0;
6271    let mut prev_row: Option<u32> = None;
6272    let mut prev_chunk_trailing_whitespace_range = 0..0;
6273    for chunk in rope.chunks() {
6274        let mut prev_line_trailing_whitespace_range = 0..0;
6275        for (i, line) in chunk.split('\n').enumerate() {
6276            let line_end_offset = offset + line.len();
6277            let trimmed_line_len = line.trim_end_matches([' ', '\t']).len();
6278            let mut trailing_whitespace_range = (offset + trimmed_line_len)..line_end_offset;
6279
6280            if i == 0 && trimmed_line_len == 0 {
6281                trailing_whitespace_range.start = prev_chunk_trailing_whitespace_range.start;
6282            }
6283            if let Some(row) = prev_row {
6284                if !prev_line_trailing_whitespace_range.is_empty() && is_row_included(row) {
6285                    ranges.push(prev_line_trailing_whitespace_range);
6286                }
6287            }
6288
6289            prev_row = Some(current_row);
6290            offset = line_end_offset + 1;
6291            current_row += 1;
6292            prev_line_trailing_whitespace_range = trailing_whitespace_range;
6293        }
6294
6295        offset -= 1;
6296        current_row -= 1;
6297        prev_chunk_trailing_whitespace_range = prev_line_trailing_whitespace_range;
6298    }
6299
6300    if !prev_chunk_trailing_whitespace_range.is_empty() && is_row_included(current_row) {
6301        ranges.push(prev_chunk_trailing_whitespace_range);
6302    }
6303
6304    ranges
6305}
6306
Served at tenant.openagents/omega Member data and write actions are omitted.