lib.rs

   1mod highlight_map;
   2mod language;
   3#[cfg(test)]
   4mod tests;
   5
   6pub use self::{
   7    highlight_map::{HighlightId, HighlightMap},
   8    language::{BracketPair, Language, LanguageConfig, LanguageRegistry},
   9};
  10use anyhow::{anyhow, Result};
  11pub use buffer::*;
  12use clock::ReplicaId;
  13use gpui::{AppContext, Entity, ModelContext, MutableAppContext, Task};
  14use lazy_static::lazy_static;
  15use parking_lot::Mutex;
  16use rpc::proto;
  17use similar::{ChangeTag, TextDiff};
  18use smol::future::yield_now;
  19use std::{
  20    any::Any,
  21    cell::RefCell,
  22    cmp,
  23    collections::{BTreeMap, HashMap, HashSet},
  24    ffi::OsString,
  25    future::Future,
  26    iter::Iterator,
  27    ops::{Deref, DerefMut, Range},
  28    path::{Path, PathBuf},
  29    str,
  30    sync::Arc,
  31    time::{Duration, Instant, SystemTime, UNIX_EPOCH},
  32};
  33use tree_sitter::{InputEdit, Parser, QueryCursor, Tree};
  34
  35thread_local! {
  36    static PARSER: RefCell<Parser> = RefCell::new(Parser::new());
  37}
  38
  39lazy_static! {
  40    static ref QUERY_CURSORS: Mutex<Vec<QueryCursor>> = Default::default();
  41}
  42
  43// TODO - Make this configurable
  44const INDENT_SIZE: u32 = 4;
  45
  46pub struct Buffer {
  47    buffer: TextBuffer,
  48    file: Option<Box<dyn File>>,
  49    saved_version: clock::Global,
  50    saved_mtime: SystemTime,
  51    language: Option<Arc<Language>>,
  52    autoindent_requests: Vec<Arc<AutoindentRequest>>,
  53    pending_autoindent: Option<Task<()>>,
  54    sync_parse_timeout: Duration,
  55    syntax_tree: Mutex<Option<SyntaxTree>>,
  56    parsing_in_background: bool,
  57    parse_count: usize,
  58    #[cfg(test)]
  59    operations: Vec<Operation>,
  60}
  61
  62pub struct Snapshot {
  63    text: buffer::Snapshot,
  64    tree: Option<Tree>,
  65    is_parsing: bool,
  66    language: Option<Arc<Language>>,
  67    query_cursor: QueryCursorHandle,
  68}
  69
  70#[derive(Clone, Debug, Eq, PartialEq)]
  71pub enum Event {
  72    Edited,
  73    Dirtied,
  74    Saved,
  75    FileHandleChanged,
  76    Reloaded,
  77    Reparsed,
  78    Closed,
  79}
  80
  81pub trait File {
  82    fn worktree_id(&self) -> usize;
  83
  84    fn entry_id(&self) -> Option<usize>;
  85
  86    fn set_entry_id(&mut self, entry_id: Option<usize>);
  87
  88    fn mtime(&self) -> SystemTime;
  89
  90    fn set_mtime(&mut self, mtime: SystemTime);
  91
  92    fn path(&self) -> &Arc<Path>;
  93
  94    fn set_path(&mut self, path: Arc<Path>);
  95
  96    fn full_path(&self, cx: &AppContext) -> PathBuf;
  97
  98    /// Returns the last component of this handle's absolute path. If this handle refers to the root
  99    /// of its worktree, then this method will return the name of the worktree itself.
 100    fn file_name<'a>(&'a self, cx: &'a AppContext) -> Option<OsString>;
 101
 102    fn is_deleted(&self) -> bool;
 103
 104    fn save(
 105        &self,
 106        buffer_id: u64,
 107        text: Rope,
 108        version: clock::Global,
 109        cx: &mut MutableAppContext,
 110    ) -> Task<Result<(clock::Global, SystemTime)>>;
 111
 112    fn buffer_updated(&self, buffer_id: u64, operation: Operation, cx: &mut MutableAppContext);
 113
 114    fn buffer_removed(&self, buffer_id: u64, cx: &mut MutableAppContext);
 115
 116    fn boxed_clone(&self) -> Box<dyn File>;
 117
 118    fn as_any(&self) -> &dyn Any;
 119}
 120
 121struct QueryCursorHandle(Option<QueryCursor>);
 122
 123#[derive(Clone)]
 124struct SyntaxTree {
 125    tree: Tree,
 126    version: clock::Global,
 127}
 128
 129#[derive(Clone)]
 130struct AutoindentRequest {
 131    selection_set_ids: HashSet<SelectionSetId>,
 132    before_edit: Snapshot,
 133    edited: AnchorSet,
 134    inserted: Option<AnchorRangeSet>,
 135}
 136
 137#[derive(Debug)]
 138struct IndentSuggestion {
 139    basis_row: u32,
 140    indent: bool,
 141}
 142
 143struct TextProvider<'a>(&'a Rope);
 144
 145struct Highlights<'a> {
 146    captures: tree_sitter::QueryCaptures<'a, 'a, TextProvider<'a>>,
 147    next_capture: Option<(tree_sitter::QueryMatch<'a, 'a>, usize)>,
 148    stack: Vec<(usize, HighlightId)>,
 149    highlight_map: HighlightMap,
 150}
 151
 152pub struct HighlightedChunks<'a> {
 153    range: Range<usize>,
 154    chunks: Chunks<'a>,
 155    highlights: Option<Highlights<'a>>,
 156}
 157
 158struct Diff {
 159    base_version: clock::Global,
 160    new_text: Arc<str>,
 161    changes: Vec<(ChangeTag, usize)>,
 162}
 163
 164impl Buffer {
 165    pub fn new<T: Into<Arc<str>>>(
 166        replica_id: ReplicaId,
 167        base_text: T,
 168        cx: &mut ModelContext<Self>,
 169    ) -> Self {
 170        Self::build(
 171            TextBuffer::new(
 172                replica_id,
 173                cx.model_id() as u64,
 174                History::new(base_text.into()),
 175            ),
 176            None,
 177            None,
 178            cx,
 179        )
 180    }
 181
 182    pub fn from_history(
 183        replica_id: ReplicaId,
 184        history: History,
 185        file: Option<Box<dyn File>>,
 186        language: Option<Arc<Language>>,
 187        cx: &mut ModelContext<Self>,
 188    ) -> Self {
 189        Self::build(
 190            TextBuffer::new(replica_id, cx.model_id() as u64, history),
 191            file,
 192            language,
 193            cx,
 194        )
 195    }
 196
 197    pub fn from_proto(
 198        replica_id: ReplicaId,
 199        message: proto::Buffer,
 200        file: Option<Box<dyn File>>,
 201        language: Option<Arc<Language>>,
 202        cx: &mut ModelContext<Self>,
 203    ) -> Result<Self> {
 204        Ok(Self::build(
 205            TextBuffer::from_proto(replica_id, message)?,
 206            file,
 207            language,
 208            cx,
 209        ))
 210    }
 211
 212    fn build(
 213        buffer: TextBuffer,
 214        file: Option<Box<dyn File>>,
 215        language: Option<Arc<Language>>,
 216        cx: &mut ModelContext<Self>,
 217    ) -> Self {
 218        let saved_mtime;
 219        if let Some(file) = file.as_ref() {
 220            saved_mtime = file.mtime();
 221        } else {
 222            saved_mtime = UNIX_EPOCH;
 223        }
 224
 225        let mut result = Self {
 226            buffer,
 227            saved_mtime,
 228            saved_version: clock::Global::new(),
 229            file,
 230            syntax_tree: Mutex::new(None),
 231            parsing_in_background: false,
 232            parse_count: 0,
 233            sync_parse_timeout: Duration::from_millis(1),
 234            autoindent_requests: Default::default(),
 235            pending_autoindent: Default::default(),
 236            language,
 237
 238            #[cfg(test)]
 239            operations: Default::default(),
 240        };
 241        result.reparse(cx);
 242        result
 243    }
 244
 245    pub fn snapshot(&self) -> Snapshot {
 246        Snapshot {
 247            text: self.buffer.snapshot(),
 248            tree: self.syntax_tree(),
 249            is_parsing: self.parsing_in_background,
 250            language: self.language.clone(),
 251            query_cursor: QueryCursorHandle::new(),
 252        }
 253    }
 254
 255    pub fn file(&self) -> Option<&dyn File> {
 256        self.file.as_deref()
 257    }
 258
 259    pub fn file_mut(&mut self) -> Option<&mut dyn File> {
 260        self.file.as_mut().map(|f| f.deref_mut() as &mut dyn File)
 261    }
 262
 263    pub fn save(
 264        &mut self,
 265        cx: &mut ModelContext<Self>,
 266    ) -> Result<Task<Result<(clock::Global, SystemTime)>>> {
 267        let file = self
 268            .file
 269            .as_ref()
 270            .ok_or_else(|| anyhow!("buffer has no file"))?;
 271        let text = self.as_rope().clone();
 272        let version = self.version.clone();
 273        let save = file.save(self.remote_id(), text, version, cx.as_mut());
 274        Ok(cx.spawn(|this, mut cx| async move {
 275            let (version, mtime) = save.await?;
 276            this.update(&mut cx, |this, cx| {
 277                this.did_save(version.clone(), mtime, None, cx);
 278            });
 279            Ok((version, mtime))
 280        }))
 281    }
 282
 283    pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut ModelContext<Self>) {
 284        self.language = language;
 285        self.reparse(cx);
 286    }
 287
 288    pub fn did_save(
 289        &mut self,
 290        version: clock::Global,
 291        mtime: SystemTime,
 292        new_file: Option<Box<dyn File>>,
 293        cx: &mut ModelContext<Self>,
 294    ) {
 295        self.saved_mtime = mtime;
 296        self.saved_version = version;
 297        if let Some(new_file) = new_file {
 298            self.file = Some(new_file);
 299        }
 300        cx.emit(Event::Saved);
 301    }
 302
 303    pub fn file_updated(
 304        &mut self,
 305        path: Arc<Path>,
 306        mtime: SystemTime,
 307        new_text: Option<String>,
 308        cx: &mut ModelContext<Self>,
 309    ) {
 310        let file = self.file.as_mut().unwrap();
 311        let mut changed = false;
 312        if path != *file.path() {
 313            file.set_path(path);
 314            changed = true;
 315        }
 316
 317        if mtime != file.mtime() {
 318            file.set_mtime(mtime);
 319            changed = true;
 320            if let Some(new_text) = new_text {
 321                if self.version == self.saved_version {
 322                    cx.spawn(|this, mut cx| async move {
 323                        let diff = this
 324                            .read_with(&cx, |this, cx| this.diff(new_text.into(), cx))
 325                            .await;
 326                        this.update(&mut cx, |this, cx| {
 327                            if this.apply_diff(diff, cx) {
 328                                this.saved_version = this.version.clone();
 329                                this.saved_mtime = mtime;
 330                                cx.emit(Event::Reloaded);
 331                            }
 332                        });
 333                    })
 334                    .detach();
 335                }
 336            }
 337        }
 338
 339        if changed {
 340            cx.emit(Event::FileHandleChanged);
 341        }
 342    }
 343
 344    pub fn file_deleted(&mut self, cx: &mut ModelContext<Self>) {
 345        if self.version == self.saved_version {
 346            cx.emit(Event::Dirtied);
 347        }
 348        cx.emit(Event::FileHandleChanged);
 349    }
 350
 351    pub fn close(&mut self, cx: &mut ModelContext<Self>) {
 352        cx.emit(Event::Closed);
 353    }
 354
 355    pub fn language(&self) -> Option<&Arc<Language>> {
 356        self.language.as_ref()
 357    }
 358
 359    pub fn parse_count(&self) -> usize {
 360        self.parse_count
 361    }
 362
 363    fn syntax_tree(&self) -> Option<Tree> {
 364        if let Some(syntax_tree) = self.syntax_tree.lock().as_mut() {
 365            self.interpolate_tree(syntax_tree);
 366            Some(syntax_tree.tree.clone())
 367        } else {
 368            None
 369        }
 370    }
 371
 372    #[cfg(any(test, feature = "test-support"))]
 373    pub fn is_parsing(&self) -> bool {
 374        self.parsing_in_background
 375    }
 376
 377    #[cfg(test)]
 378    pub fn set_sync_parse_timeout(&mut self, timeout: Duration) {
 379        self.sync_parse_timeout = timeout;
 380    }
 381
 382    fn reparse(&mut self, cx: &mut ModelContext<Self>) -> bool {
 383        if self.parsing_in_background {
 384            return false;
 385        }
 386
 387        if let Some(language) = self.language.clone() {
 388            let old_tree = self.syntax_tree();
 389            let text = self.as_rope().clone();
 390            let parsed_version = self.version();
 391            let parse_task = cx.background().spawn({
 392                let language = language.clone();
 393                async move { Self::parse_text(&text, old_tree, &language) }
 394            });
 395
 396            match cx
 397                .background()
 398                .block_with_timeout(self.sync_parse_timeout, parse_task)
 399            {
 400                Ok(new_tree) => {
 401                    self.did_finish_parsing(new_tree, parsed_version, cx);
 402                    return true;
 403                }
 404                Err(parse_task) => {
 405                    self.parsing_in_background = true;
 406                    cx.spawn(move |this, mut cx| async move {
 407                        let new_tree = parse_task.await;
 408                        this.update(&mut cx, move |this, cx| {
 409                            let language_changed =
 410                                this.language.as_ref().map_or(true, |curr_language| {
 411                                    !Arc::ptr_eq(curr_language, &language)
 412                                });
 413                            let parse_again = this.version > parsed_version || language_changed;
 414                            this.parsing_in_background = false;
 415                            this.did_finish_parsing(new_tree, parsed_version, cx);
 416
 417                            if parse_again && this.reparse(cx) {
 418                                return;
 419                            }
 420                        });
 421                    })
 422                    .detach();
 423                }
 424            }
 425        }
 426        false
 427    }
 428
 429    fn parse_text(text: &Rope, old_tree: Option<Tree>, language: &Language) -> Tree {
 430        PARSER.with(|parser| {
 431            let mut parser = parser.borrow_mut();
 432            parser
 433                .set_language(language.grammar)
 434                .expect("incompatible grammar");
 435            let mut chunks = text.chunks_in_range(0..text.len());
 436            let tree = parser
 437                .parse_with(
 438                    &mut move |offset, _| {
 439                        chunks.seek(offset);
 440                        chunks.next().unwrap_or("").as_bytes()
 441                    },
 442                    old_tree.as_ref(),
 443                )
 444                .unwrap();
 445            tree
 446        })
 447    }
 448
 449    fn interpolate_tree(&self, tree: &mut SyntaxTree) {
 450        let mut delta = 0_isize;
 451        for edit in self.edits_since(tree.version.clone()) {
 452            let start_offset = (edit.old_bytes.start as isize + delta) as usize;
 453            let start_point = self.as_rope().to_point(start_offset);
 454            tree.tree.edit(&InputEdit {
 455                start_byte: start_offset,
 456                old_end_byte: start_offset + edit.deleted_bytes(),
 457                new_end_byte: start_offset + edit.inserted_bytes(),
 458                start_position: start_point.to_ts_point(),
 459                old_end_position: (start_point + edit.deleted_lines()).to_ts_point(),
 460                new_end_position: self
 461                    .as_rope()
 462                    .to_point(start_offset + edit.inserted_bytes())
 463                    .to_ts_point(),
 464            });
 465            delta += edit.inserted_bytes() as isize - edit.deleted_bytes() as isize;
 466        }
 467        tree.version = self.version();
 468    }
 469
 470    fn did_finish_parsing(
 471        &mut self,
 472        tree: Tree,
 473        version: clock::Global,
 474        cx: &mut ModelContext<Self>,
 475    ) {
 476        self.parse_count += 1;
 477        *self.syntax_tree.lock() = Some(SyntaxTree { tree, version });
 478        self.request_autoindent(cx);
 479        cx.emit(Event::Reparsed);
 480        cx.notify();
 481    }
 482
 483    fn request_autoindent(&mut self, cx: &mut ModelContext<Self>) {
 484        if let Some(indent_columns) = self.compute_autoindents() {
 485            let indent_columns = cx.background().spawn(indent_columns);
 486            match cx
 487                .background()
 488                .block_with_timeout(Duration::from_micros(500), indent_columns)
 489            {
 490                Ok(indent_columns) => self.apply_autoindents(indent_columns, cx),
 491                Err(indent_columns) => {
 492                    self.pending_autoindent = Some(cx.spawn(|this, mut cx| async move {
 493                        let indent_columns = indent_columns.await;
 494                        this.update(&mut cx, |this, cx| {
 495                            this.apply_autoindents(indent_columns, cx);
 496                        });
 497                    }));
 498                }
 499            }
 500        }
 501    }
 502
 503    fn compute_autoindents(&self) -> Option<impl Future<Output = BTreeMap<u32, u32>>> {
 504        let max_rows_between_yields = 100;
 505        let snapshot = self.snapshot();
 506        if snapshot.language.is_none()
 507            || snapshot.tree.is_none()
 508            || self.autoindent_requests.is_empty()
 509        {
 510            return None;
 511        }
 512
 513        let autoindent_requests = self.autoindent_requests.clone();
 514        Some(async move {
 515            let mut indent_columns = BTreeMap::new();
 516            for request in autoindent_requests {
 517                let old_to_new_rows = request
 518                    .edited
 519                    .to_points(&request.before_edit)
 520                    .map(|point| point.row)
 521                    .zip(request.edited.to_points(&snapshot).map(|point| point.row))
 522                    .collect::<BTreeMap<u32, u32>>();
 523
 524                let mut old_suggestions = HashMap::<u32, u32>::default();
 525                let old_edited_ranges =
 526                    contiguous_ranges(old_to_new_rows.keys().copied(), max_rows_between_yields);
 527                for old_edited_range in old_edited_ranges {
 528                    let suggestions = request
 529                        .before_edit
 530                        .suggest_autoindents(old_edited_range.clone())
 531                        .into_iter()
 532                        .flatten();
 533                    for (old_row, suggestion) in old_edited_range.zip(suggestions) {
 534                        let indentation_basis = old_to_new_rows
 535                            .get(&suggestion.basis_row)
 536                            .and_then(|from_row| old_suggestions.get(from_row).copied())
 537                            .unwrap_or_else(|| {
 538                                request
 539                                    .before_edit
 540                                    .indent_column_for_line(suggestion.basis_row)
 541                            });
 542                        let delta = if suggestion.indent { INDENT_SIZE } else { 0 };
 543                        old_suggestions.insert(
 544                            *old_to_new_rows.get(&old_row).unwrap(),
 545                            indentation_basis + delta,
 546                        );
 547                    }
 548                    yield_now().await;
 549                }
 550
 551                // At this point, old_suggestions contains the suggested indentation for all edited lines with respect to the state of the
 552                // buffer before the edit, but keyed by the row for these lines after the edits were applied.
 553                let new_edited_row_ranges =
 554                    contiguous_ranges(old_to_new_rows.values().copied(), max_rows_between_yields);
 555                for new_edited_row_range in new_edited_row_ranges {
 556                    let suggestions = snapshot
 557                        .suggest_autoindents(new_edited_row_range.clone())
 558                        .into_iter()
 559                        .flatten();
 560                    for (new_row, suggestion) in new_edited_row_range.zip(suggestions) {
 561                        let delta = if suggestion.indent { INDENT_SIZE } else { 0 };
 562                        let new_indentation = indent_columns
 563                            .get(&suggestion.basis_row)
 564                            .copied()
 565                            .unwrap_or_else(|| {
 566                                snapshot.indent_column_for_line(suggestion.basis_row)
 567                            })
 568                            + delta;
 569                        if old_suggestions
 570                            .get(&new_row)
 571                            .map_or(true, |old_indentation| new_indentation != *old_indentation)
 572                        {
 573                            indent_columns.insert(new_row, new_indentation);
 574                        }
 575                    }
 576                    yield_now().await;
 577                }
 578
 579                if let Some(inserted) = request.inserted.as_ref() {
 580                    let inserted_row_ranges = contiguous_ranges(
 581                        inserted
 582                            .to_point_ranges(&snapshot)
 583                            .flat_map(|range| range.start.row..range.end.row + 1),
 584                        max_rows_between_yields,
 585                    );
 586                    for inserted_row_range in inserted_row_ranges {
 587                        let suggestions = snapshot
 588                            .suggest_autoindents(inserted_row_range.clone())
 589                            .into_iter()
 590                            .flatten();
 591                        for (row, suggestion) in inserted_row_range.zip(suggestions) {
 592                            let delta = if suggestion.indent { INDENT_SIZE } else { 0 };
 593                            let new_indentation = indent_columns
 594                                .get(&suggestion.basis_row)
 595                                .copied()
 596                                .unwrap_or_else(|| {
 597                                    snapshot.indent_column_for_line(suggestion.basis_row)
 598                                })
 599                                + delta;
 600                            indent_columns.insert(row, new_indentation);
 601                        }
 602                        yield_now().await;
 603                    }
 604                }
 605            }
 606            indent_columns
 607        })
 608    }
 609
 610    fn apply_autoindents(
 611        &mut self,
 612        indent_columns: BTreeMap<u32, u32>,
 613        cx: &mut ModelContext<Self>,
 614    ) {
 615        let selection_set_ids = self
 616            .autoindent_requests
 617            .drain(..)
 618            .flat_map(|req| req.selection_set_ids.clone())
 619            .collect::<HashSet<_>>();
 620
 621        self.start_transaction(selection_set_ids.iter().copied())
 622            .unwrap();
 623        for (row, indent_column) in &indent_columns {
 624            self.set_indent_column_for_line(*row, *indent_column, cx);
 625        }
 626
 627        for selection_set_id in &selection_set_ids {
 628            if let Ok(set) = self.selection_set(*selection_set_id) {
 629                let new_selections = set
 630                    .selections
 631                    .iter()
 632                    .map(|selection| {
 633                        let start_point = selection.start.to_point(&self.buffer);
 634                        if start_point.column == 0 {
 635                            let end_point = selection.end.to_point(&self.buffer);
 636                            let delta = Point::new(
 637                                0,
 638                                indent_columns.get(&start_point.row).copied().unwrap_or(0),
 639                            );
 640                            if delta.column > 0 {
 641                                return Selection {
 642                                    id: selection.id,
 643                                    goal: selection.goal,
 644                                    reversed: selection.reversed,
 645                                    start: self
 646                                        .anchor_at(start_point + delta, selection.start.bias),
 647                                    end: self.anchor_at(end_point + delta, selection.end.bias),
 648                                };
 649                            }
 650                        }
 651                        selection.clone()
 652                    })
 653                    .collect::<Arc<[_]>>();
 654                self.update_selection_set(*selection_set_id, new_selections, cx)
 655                    .unwrap();
 656            }
 657        }
 658
 659        self.end_transaction(selection_set_ids.iter().copied(), cx)
 660            .unwrap();
 661    }
 662
 663    pub fn indent_column_for_line(&self, row: u32) -> u32 {
 664        self.content().indent_column_for_line(row)
 665    }
 666
 667    fn set_indent_column_for_line(&mut self, row: u32, column: u32, cx: &mut ModelContext<Self>) {
 668        let current_column = self.indent_column_for_line(row);
 669        if column > current_column {
 670            let offset = Point::new(row, 0).to_offset(&*self);
 671            self.edit(
 672                [offset..offset],
 673                " ".repeat((column - current_column) as usize),
 674                cx,
 675            );
 676        } else if column < current_column {
 677            self.edit(
 678                [Point::new(row, 0)..Point::new(row, current_column - column)],
 679                "",
 680                cx,
 681            );
 682        }
 683    }
 684
 685    pub fn range_for_syntax_ancestor<T: ToOffset>(&self, range: Range<T>) -> Option<Range<usize>> {
 686        if let Some(tree) = self.syntax_tree() {
 687            let root = tree.root_node();
 688            let range = range.start.to_offset(self)..range.end.to_offset(self);
 689            let mut node = root.descendant_for_byte_range(range.start, range.end);
 690            while node.map_or(false, |n| n.byte_range() == range) {
 691                node = node.unwrap().parent();
 692            }
 693            node.map(|n| n.byte_range())
 694        } else {
 695            None
 696        }
 697    }
 698
 699    pub fn enclosing_bracket_ranges<T: ToOffset>(
 700        &self,
 701        range: Range<T>,
 702    ) -> Option<(Range<usize>, Range<usize>)> {
 703        let (lang, tree) = self.language.as_ref().zip(self.syntax_tree())?;
 704        let open_capture_ix = lang.brackets_query.capture_index_for_name("open")?;
 705        let close_capture_ix = lang.brackets_query.capture_index_for_name("close")?;
 706
 707        // Find bracket pairs that *inclusively* contain the given range.
 708        let range = range.start.to_offset(self).saturating_sub(1)..range.end.to_offset(self) + 1;
 709        let mut cursor = QueryCursorHandle::new();
 710        let matches = cursor.set_byte_range(range).matches(
 711            &lang.brackets_query,
 712            tree.root_node(),
 713            TextProvider(self.as_rope()),
 714        );
 715
 716        // Get the ranges of the innermost pair of brackets.
 717        matches
 718            .filter_map(|mat| {
 719                let open = mat.nodes_for_capture_index(open_capture_ix).next()?;
 720                let close = mat.nodes_for_capture_index(close_capture_ix).next()?;
 721                Some((open.byte_range(), close.byte_range()))
 722            })
 723            .min_by_key(|(open_range, close_range)| close_range.end - open_range.start)
 724    }
 725
 726    fn diff(&self, new_text: Arc<str>, cx: &AppContext) -> Task<Diff> {
 727        // TODO: it would be nice to not allocate here.
 728        let old_text = self.text();
 729        let base_version = self.version();
 730        cx.background().spawn(async move {
 731            let changes = TextDiff::from_lines(old_text.as_str(), new_text.as_ref())
 732                .iter_all_changes()
 733                .map(|c| (c.tag(), c.value().len()))
 734                .collect::<Vec<_>>();
 735            Diff {
 736                base_version,
 737                new_text,
 738                changes,
 739            }
 740        })
 741    }
 742
 743    pub fn set_text_from_disk(&self, new_text: Arc<str>, cx: &mut ModelContext<Self>) -> Task<()> {
 744        cx.spawn(|this, mut cx| async move {
 745            let diff = this
 746                .read_with(&cx, |this, cx| this.diff(new_text, cx))
 747                .await;
 748
 749            this.update(&mut cx, |this, cx| {
 750                if this.apply_diff(diff, cx) {
 751                    this.saved_version = this.version.clone();
 752                }
 753            });
 754        })
 755    }
 756
 757    fn apply_diff(&mut self, diff: Diff, cx: &mut ModelContext<Self>) -> bool {
 758        if self.version == diff.base_version {
 759            self.start_transaction(None).unwrap();
 760            let mut offset = 0;
 761            for (tag, len) in diff.changes {
 762                let range = offset..(offset + len);
 763                match tag {
 764                    ChangeTag::Equal => offset += len,
 765                    ChangeTag::Delete => self.edit(Some(range), "", cx),
 766                    ChangeTag::Insert => {
 767                        self.edit(Some(offset..offset), &diff.new_text[range], cx);
 768                        offset += len;
 769                    }
 770                }
 771            }
 772            self.end_transaction(None, cx).unwrap();
 773            true
 774        } else {
 775            false
 776        }
 777    }
 778
 779    pub fn is_dirty(&self) -> bool {
 780        self.version > self.saved_version
 781            || self.file.as_ref().map_or(false, |file| file.is_deleted())
 782    }
 783
 784    pub fn has_conflict(&self) -> bool {
 785        self.version > self.saved_version
 786            && self
 787                .file
 788                .as_ref()
 789                .map_or(false, |file| file.mtime() > self.saved_mtime)
 790    }
 791
 792    pub fn start_transaction(
 793        &mut self,
 794        selection_set_ids: impl IntoIterator<Item = SelectionSetId>,
 795    ) -> Result<()> {
 796        self.start_transaction_at(selection_set_ids, Instant::now())
 797    }
 798
 799    fn start_transaction_at(
 800        &mut self,
 801        selection_set_ids: impl IntoIterator<Item = SelectionSetId>,
 802        now: Instant,
 803    ) -> Result<()> {
 804        self.buffer.start_transaction_at(selection_set_ids, now)
 805    }
 806
 807    pub fn end_transaction(
 808        &mut self,
 809        selection_set_ids: impl IntoIterator<Item = SelectionSetId>,
 810        cx: &mut ModelContext<Self>,
 811    ) -> Result<()> {
 812        self.end_transaction_at(selection_set_ids, Instant::now(), cx)
 813    }
 814
 815    fn end_transaction_at(
 816        &mut self,
 817        selection_set_ids: impl IntoIterator<Item = SelectionSetId>,
 818        now: Instant,
 819        cx: &mut ModelContext<Self>,
 820    ) -> Result<()> {
 821        if let Some(start_version) = self.buffer.end_transaction_at(selection_set_ids, now) {
 822            cx.notify();
 823            let was_dirty = start_version != self.saved_version;
 824            let edited = self.edits_since(start_version).next().is_some();
 825            if edited {
 826                self.did_edit(was_dirty, cx);
 827                self.reparse(cx);
 828            }
 829        }
 830        Ok(())
 831    }
 832
 833    pub fn edit<I, S, T>(&mut self, ranges_iter: I, new_text: T, cx: &mut ModelContext<Self>)
 834    where
 835        I: IntoIterator<Item = Range<S>>,
 836        S: ToOffset,
 837        T: Into<String>,
 838    {
 839        self.edit_internal(ranges_iter, new_text, false, cx)
 840    }
 841
 842    pub fn edit_with_autoindent<I, S, T>(
 843        &mut self,
 844        ranges_iter: I,
 845        new_text: T,
 846        cx: &mut ModelContext<Self>,
 847    ) where
 848        I: IntoIterator<Item = Range<S>>,
 849        S: ToOffset,
 850        T: Into<String>,
 851    {
 852        self.edit_internal(ranges_iter, new_text, true, cx)
 853    }
 854
 855    pub fn edit_internal<I, S, T>(
 856        &mut self,
 857        ranges_iter: I,
 858        new_text: T,
 859        autoindent: bool,
 860        cx: &mut ModelContext<Self>,
 861    ) where
 862        I: IntoIterator<Item = Range<S>>,
 863        S: ToOffset,
 864        T: Into<String>,
 865    {
 866        let new_text = new_text.into();
 867
 868        // Skip invalid ranges and coalesce contiguous ones.
 869        let mut ranges: Vec<Range<usize>> = Vec::new();
 870        for range in ranges_iter {
 871            let range = range.start.to_offset(&*self)..range.end.to_offset(&*self);
 872            if !new_text.is_empty() || !range.is_empty() {
 873                if let Some(prev_range) = ranges.last_mut() {
 874                    if prev_range.end >= range.start {
 875                        prev_range.end = cmp::max(prev_range.end, range.end);
 876                    } else {
 877                        ranges.push(range);
 878                    }
 879                } else {
 880                    ranges.push(range);
 881                }
 882            }
 883        }
 884        if ranges.is_empty() {
 885            return;
 886        }
 887
 888        self.start_transaction(None).unwrap();
 889        self.pending_autoindent.take();
 890        let autoindent_request = if autoindent && self.language.is_some() {
 891            let before_edit = self.snapshot();
 892            let edited = self.content().anchor_set(ranges.iter().filter_map(|range| {
 893                let start = range.start.to_point(&*self);
 894                if new_text.starts_with('\n') && start.column == self.line_len(start.row) {
 895                    None
 896                } else {
 897                    Some((range.start, Bias::Left))
 898                }
 899            }));
 900            Some((before_edit, edited))
 901        } else {
 902            None
 903        };
 904
 905        let first_newline_ix = new_text.find('\n');
 906        let new_text_len = new_text.len();
 907
 908        let edit = self.buffer.edit(ranges.iter().cloned(), new_text);
 909
 910        if let Some((before_edit, edited)) = autoindent_request {
 911            let mut inserted = None;
 912            if let Some(first_newline_ix) = first_newline_ix {
 913                let mut delta = 0isize;
 914                inserted = Some(self.content().anchor_range_set(ranges.iter().map(|range| {
 915                    let start = (delta + range.start as isize) as usize + first_newline_ix + 1;
 916                    let end = (delta + range.start as isize) as usize + new_text_len;
 917                    delta += (range.end as isize - range.start as isize) + new_text_len as isize;
 918                    (start, Bias::Left)..(end, Bias::Right)
 919                })));
 920            }
 921
 922            let selection_set_ids = self
 923                .buffer
 924                .peek_undo_stack()
 925                .unwrap()
 926                .starting_selection_set_ids()
 927                .collect();
 928            self.autoindent_requests.push(Arc::new(AutoindentRequest {
 929                selection_set_ids,
 930                before_edit,
 931                edited,
 932                inserted,
 933            }));
 934        }
 935
 936        self.end_transaction(None, cx).unwrap();
 937        self.send_operation(Operation::Edit(edit), cx);
 938    }
 939
 940    fn did_edit(&self, was_dirty: bool, cx: &mut ModelContext<Self>) {
 941        cx.emit(Event::Edited);
 942        if !was_dirty {
 943            cx.emit(Event::Dirtied);
 944        }
 945    }
 946
 947    pub fn add_selection_set(
 948        &mut self,
 949        selections: impl Into<Arc<[Selection]>>,
 950        cx: &mut ModelContext<Self>,
 951    ) -> SelectionSetId {
 952        let operation = self.buffer.add_selection_set(selections);
 953        if let Operation::UpdateSelections { set_id, .. } = &operation {
 954            let set_id = *set_id;
 955            cx.notify();
 956            self.send_operation(operation, cx);
 957            set_id
 958        } else {
 959            unreachable!()
 960        }
 961    }
 962
 963    pub fn update_selection_set(
 964        &mut self,
 965        set_id: SelectionSetId,
 966        selections: impl Into<Arc<[Selection]>>,
 967        cx: &mut ModelContext<Self>,
 968    ) -> Result<()> {
 969        let operation = self.buffer.update_selection_set(set_id, selections)?;
 970        cx.notify();
 971        self.send_operation(operation, cx);
 972        Ok(())
 973    }
 974
 975    pub fn set_active_selection_set(
 976        &mut self,
 977        set_id: Option<SelectionSetId>,
 978        cx: &mut ModelContext<Self>,
 979    ) -> Result<()> {
 980        let operation = self.buffer.set_active_selection_set(set_id)?;
 981        self.send_operation(operation, cx);
 982        Ok(())
 983    }
 984
 985    pub fn remove_selection_set(
 986        &mut self,
 987        set_id: SelectionSetId,
 988        cx: &mut ModelContext<Self>,
 989    ) -> Result<()> {
 990        let operation = self.buffer.remove_selection_set(set_id)?;
 991        cx.notify();
 992        self.send_operation(operation, cx);
 993        Ok(())
 994    }
 995
 996    pub fn apply_ops<I: IntoIterator<Item = Operation>>(
 997        &mut self,
 998        ops: I,
 999        cx: &mut ModelContext<Self>,
1000    ) -> Result<()> {
1001        self.pending_autoindent.take();
1002
1003        let was_dirty = self.is_dirty();
1004        let old_version = self.version.clone();
1005
1006        self.buffer.apply_ops(ops)?;
1007
1008        cx.notify();
1009        if self.edits_since(old_version).next().is_some() {
1010            self.did_edit(was_dirty, cx);
1011            self.reparse(cx);
1012        }
1013
1014        Ok(())
1015    }
1016
1017    #[cfg(not(test))]
1018    pub fn send_operation(&mut self, operation: Operation, cx: &mut ModelContext<Self>) {
1019        if let Some(file) = &self.file {
1020            file.buffer_updated(self.remote_id(), operation, cx.as_mut());
1021        }
1022    }
1023
1024    #[cfg(test)]
1025    pub fn send_operation(&mut self, operation: Operation, _: &mut ModelContext<Self>) {
1026        self.operations.push(operation);
1027    }
1028
1029    pub fn remove_peer(&mut self, replica_id: ReplicaId, cx: &mut ModelContext<Self>) {
1030        self.buffer.remove_peer(replica_id);
1031        cx.notify();
1032    }
1033
1034    pub fn undo(&mut self, cx: &mut ModelContext<Self>) {
1035        let was_dirty = self.is_dirty();
1036        let old_version = self.version.clone();
1037
1038        for operation in self.buffer.undo() {
1039            self.send_operation(operation, cx);
1040        }
1041
1042        cx.notify();
1043        if self.edits_since(old_version).next().is_some() {
1044            self.did_edit(was_dirty, cx);
1045            self.reparse(cx);
1046        }
1047    }
1048
1049    pub fn redo(&mut self, cx: &mut ModelContext<Self>) {
1050        let was_dirty = self.is_dirty();
1051        let old_version = self.version.clone();
1052
1053        for operation in self.buffer.redo() {
1054            self.send_operation(operation, cx);
1055        }
1056
1057        cx.notify();
1058        if self.edits_since(old_version).next().is_some() {
1059            self.did_edit(was_dirty, cx);
1060            self.reparse(cx);
1061        }
1062    }
1063}
1064
1065#[cfg(any(test, feature = "test-support"))]
1066impl Buffer {
1067    pub fn randomly_edit<T>(&mut self, rng: &mut T, old_range_count: usize)
1068    where
1069        T: rand::Rng,
1070    {
1071        self.buffer.randomly_edit(rng, old_range_count);
1072    }
1073
1074    pub fn randomly_mutate<T>(&mut self, rng: &mut T)
1075    where
1076        T: rand::Rng,
1077    {
1078        self.buffer.randomly_mutate(rng);
1079    }
1080}
1081
1082impl Entity for Buffer {
1083    type Event = Event;
1084
1085    fn release(&mut self, cx: &mut gpui::MutableAppContext) {
1086        if let Some(file) = self.file.as_ref() {
1087            file.buffer_removed(self.remote_id(), cx);
1088        }
1089    }
1090}
1091
1092impl Clone for Buffer {
1093    fn clone(&self) -> Self {
1094        Self {
1095            buffer: self.buffer.clone(),
1096            saved_version: self.saved_version.clone(),
1097            saved_mtime: self.saved_mtime,
1098            file: self.file.as_ref().map(|f| f.boxed_clone()),
1099            language: self.language.clone(),
1100            syntax_tree: Mutex::new(self.syntax_tree.lock().clone()),
1101            parsing_in_background: false,
1102            sync_parse_timeout: self.sync_parse_timeout,
1103            parse_count: self.parse_count,
1104            autoindent_requests: Default::default(),
1105            pending_autoindent: Default::default(),
1106
1107            #[cfg(test)]
1108            operations: self.operations.clone(),
1109        }
1110    }
1111}
1112
1113impl Deref for Buffer {
1114    type Target = TextBuffer;
1115
1116    fn deref(&self) -> &Self::Target {
1117        &self.buffer
1118    }
1119}
1120
1121impl<'a> From<&'a Buffer> for Content<'a> {
1122    fn from(buffer: &'a Buffer) -> Self {
1123        Self::from(&buffer.buffer)
1124    }
1125}
1126
1127impl<'a> From<&'a mut Buffer> for Content<'a> {
1128    fn from(buffer: &'a mut Buffer) -> Self {
1129        Self::from(&buffer.buffer)
1130    }
1131}
1132
1133impl<'a> From<&'a Snapshot> for Content<'a> {
1134    fn from(snapshot: &'a Snapshot) -> Self {
1135        Self::from(&snapshot.text)
1136    }
1137}
1138
1139impl Snapshot {
1140    fn suggest_autoindents<'a>(
1141        &'a self,
1142        row_range: Range<u32>,
1143    ) -> Option<impl Iterator<Item = IndentSuggestion> + 'a> {
1144        let mut query_cursor = QueryCursorHandle::new();
1145        if let Some((language, tree)) = self.language.as_ref().zip(self.tree.as_ref()) {
1146            let prev_non_blank_row = self.prev_non_blank_row(row_range.start);
1147
1148            // Get the "indentation ranges" that intersect this row range.
1149            let indent_capture_ix = language.indents_query.capture_index_for_name("indent");
1150            let end_capture_ix = language.indents_query.capture_index_for_name("end");
1151            query_cursor.set_point_range(
1152                Point::new(prev_non_blank_row.unwrap_or(row_range.start), 0).to_ts_point()
1153                    ..Point::new(row_range.end, 0).to_ts_point(),
1154            );
1155            let mut indentation_ranges = Vec::<(Range<Point>, &'static str)>::new();
1156            for mat in query_cursor.matches(
1157                &language.indents_query,
1158                tree.root_node(),
1159                TextProvider(self.as_rope()),
1160            ) {
1161                let mut node_kind = "";
1162                let mut start: Option<Point> = None;
1163                let mut end: Option<Point> = None;
1164                for capture in mat.captures {
1165                    if Some(capture.index) == indent_capture_ix {
1166                        node_kind = capture.node.kind();
1167                        start.get_or_insert(Point::from_ts_point(capture.node.start_position()));
1168                        end.get_or_insert(Point::from_ts_point(capture.node.end_position()));
1169                    } else if Some(capture.index) == end_capture_ix {
1170                        end = Some(Point::from_ts_point(capture.node.start_position().into()));
1171                    }
1172                }
1173
1174                if let Some((start, end)) = start.zip(end) {
1175                    if start.row == end.row {
1176                        continue;
1177                    }
1178
1179                    let range = start..end;
1180                    match indentation_ranges.binary_search_by_key(&range.start, |r| r.0.start) {
1181                        Err(ix) => indentation_ranges.insert(ix, (range, node_kind)),
1182                        Ok(ix) => {
1183                            let prev_range = &mut indentation_ranges[ix];
1184                            prev_range.0.end = prev_range.0.end.max(range.end);
1185                        }
1186                    }
1187                }
1188            }
1189
1190            let mut prev_row = prev_non_blank_row.unwrap_or(0);
1191            Some(row_range.map(move |row| {
1192                let row_start = Point::new(row, self.indent_column_for_line(row));
1193
1194                let mut indent_from_prev_row = false;
1195                let mut outdent_to_row = u32::MAX;
1196                for (range, _node_kind) in &indentation_ranges {
1197                    if range.start.row >= row {
1198                        break;
1199                    }
1200
1201                    if range.start.row == prev_row && range.end > row_start {
1202                        indent_from_prev_row = true;
1203                    }
1204                    if range.end.row >= prev_row && range.end <= row_start {
1205                        outdent_to_row = outdent_to_row.min(range.start.row);
1206                    }
1207                }
1208
1209                let suggestion = if outdent_to_row == prev_row {
1210                    IndentSuggestion {
1211                        basis_row: prev_row,
1212                        indent: false,
1213                    }
1214                } else if indent_from_prev_row {
1215                    IndentSuggestion {
1216                        basis_row: prev_row,
1217                        indent: true,
1218                    }
1219                } else if outdent_to_row < prev_row {
1220                    IndentSuggestion {
1221                        basis_row: outdent_to_row,
1222                        indent: false,
1223                    }
1224                } else {
1225                    IndentSuggestion {
1226                        basis_row: prev_row,
1227                        indent: false,
1228                    }
1229                };
1230
1231                prev_row = row;
1232                suggestion
1233            }))
1234        } else {
1235            None
1236        }
1237    }
1238
1239    fn prev_non_blank_row(&self, mut row: u32) -> Option<u32> {
1240        while row > 0 {
1241            row -= 1;
1242            if !self.is_line_blank(row) {
1243                return Some(row);
1244            }
1245        }
1246        None
1247    }
1248
1249    fn is_line_blank(&self, row: u32) -> bool {
1250        self.text_for_range(Point::new(row, 0)..Point::new(row, self.line_len(row)))
1251            .all(|chunk| chunk.matches(|c: char| !c.is_whitespace()).next().is_none())
1252    }
1253
1254    pub fn highlighted_text_for_range<T: ToOffset>(
1255        &mut self,
1256        range: Range<T>,
1257    ) -> HighlightedChunks {
1258        let range = range.start.to_offset(&*self)..range.end.to_offset(&*self);
1259        let chunks = self.text.as_rope().chunks_in_range(range.clone());
1260        if let Some((language, tree)) = self.language.as_ref().zip(self.tree.as_ref()) {
1261            let captures = self.query_cursor.set_byte_range(range.clone()).captures(
1262                &language.highlights_query,
1263                tree.root_node(),
1264                TextProvider(self.text.as_rope()),
1265            );
1266
1267            HighlightedChunks {
1268                range,
1269                chunks,
1270                highlights: Some(Highlights {
1271                    captures,
1272                    next_capture: None,
1273                    stack: Default::default(),
1274                    highlight_map: language.highlight_map(),
1275                }),
1276            }
1277        } else {
1278            HighlightedChunks {
1279                range,
1280                chunks,
1281                highlights: None,
1282            }
1283        }
1284    }
1285}
1286
1287impl Clone for Snapshot {
1288    fn clone(&self) -> Self {
1289        Self {
1290            text: self.text.clone(),
1291            tree: self.tree.clone(),
1292            is_parsing: self.is_parsing,
1293            language: self.language.clone(),
1294            query_cursor: QueryCursorHandle::new(),
1295        }
1296    }
1297}
1298
1299impl Deref for Snapshot {
1300    type Target = buffer::Snapshot;
1301
1302    fn deref(&self) -> &Self::Target {
1303        &self.text
1304    }
1305}
1306
1307impl<'a> tree_sitter::TextProvider<'a> for TextProvider<'a> {
1308    type I = ByteChunks<'a>;
1309
1310    fn text(&mut self, node: tree_sitter::Node) -> Self::I {
1311        ByteChunks(self.0.chunks_in_range(node.byte_range()))
1312    }
1313}
1314
1315struct ByteChunks<'a>(rope::Chunks<'a>);
1316
1317impl<'a> Iterator for ByteChunks<'a> {
1318    type Item = &'a [u8];
1319
1320    fn next(&mut self) -> Option<Self::Item> {
1321        self.0.next().map(str::as_bytes)
1322    }
1323}
1324
1325impl<'a> HighlightedChunks<'a> {
1326    pub fn seek(&mut self, offset: usize) {
1327        self.range.start = offset;
1328        self.chunks.seek(self.range.start);
1329        if let Some(highlights) = self.highlights.as_mut() {
1330            highlights
1331                .stack
1332                .retain(|(end_offset, _)| *end_offset > offset);
1333            if let Some((mat, capture_ix)) = &highlights.next_capture {
1334                let capture = mat.captures[*capture_ix as usize];
1335                if offset >= capture.node.start_byte() {
1336                    let next_capture_end = capture.node.end_byte();
1337                    if offset < next_capture_end {
1338                        highlights.stack.push((
1339                            next_capture_end,
1340                            highlights.highlight_map.get(capture.index),
1341                        ));
1342                    }
1343                    highlights.next_capture.take();
1344                }
1345            }
1346            highlights.captures.set_byte_range(self.range.clone());
1347        }
1348    }
1349
1350    pub fn offset(&self) -> usize {
1351        self.range.start
1352    }
1353}
1354
1355impl<'a> Iterator for HighlightedChunks<'a> {
1356    type Item = (&'a str, HighlightId);
1357
1358    fn next(&mut self) -> Option<Self::Item> {
1359        let mut next_capture_start = usize::MAX;
1360
1361        if let Some(highlights) = self.highlights.as_mut() {
1362            while let Some((parent_capture_end, _)) = highlights.stack.last() {
1363                if *parent_capture_end <= self.range.start {
1364                    highlights.stack.pop();
1365                } else {
1366                    break;
1367                }
1368            }
1369
1370            if highlights.next_capture.is_none() {
1371                highlights.next_capture = highlights.captures.next();
1372            }
1373
1374            while let Some((mat, capture_ix)) = highlights.next_capture.as_ref() {
1375                let capture = mat.captures[*capture_ix as usize];
1376                if self.range.start < capture.node.start_byte() {
1377                    next_capture_start = capture.node.start_byte();
1378                    break;
1379                } else {
1380                    let style_id = highlights.highlight_map.get(capture.index);
1381                    highlights.stack.push((capture.node.end_byte(), style_id));
1382                    highlights.next_capture = highlights.captures.next();
1383                }
1384            }
1385        }
1386
1387        if let Some(chunk) = self.chunks.peek() {
1388            let chunk_start = self.range.start;
1389            let mut chunk_end = (self.chunks.offset() + chunk.len()).min(next_capture_start);
1390            let mut style_id = HighlightId::default();
1391            if let Some((parent_capture_end, parent_style_id)) =
1392                self.highlights.as_ref().and_then(|h| h.stack.last())
1393            {
1394                chunk_end = chunk_end.min(*parent_capture_end);
1395                style_id = *parent_style_id;
1396            }
1397
1398            let slice =
1399                &chunk[chunk_start - self.chunks.offset()..chunk_end - self.chunks.offset()];
1400            self.range.start = chunk_end;
1401            if self.range.start == self.chunks.offset() + chunk.len() {
1402                self.chunks.next().unwrap();
1403            }
1404
1405            Some((slice, style_id))
1406        } else {
1407            None
1408        }
1409    }
1410}
1411
1412impl QueryCursorHandle {
1413    fn new() -> Self {
1414        QueryCursorHandle(Some(
1415            QUERY_CURSORS
1416                .lock()
1417                .pop()
1418                .unwrap_or_else(|| QueryCursor::new()),
1419        ))
1420    }
1421}
1422
1423impl Deref for QueryCursorHandle {
1424    type Target = QueryCursor;
1425
1426    fn deref(&self) -> &Self::Target {
1427        self.0.as_ref().unwrap()
1428    }
1429}
1430
1431impl DerefMut for QueryCursorHandle {
1432    fn deref_mut(&mut self) -> &mut Self::Target {
1433        self.0.as_mut().unwrap()
1434    }
1435}
1436
1437impl Drop for QueryCursorHandle {
1438    fn drop(&mut self) {
1439        let mut cursor = self.0.take().unwrap();
1440        cursor.set_byte_range(0..usize::MAX);
1441        cursor.set_point_range(Point::zero().to_ts_point()..Point::MAX.to_ts_point());
1442        QUERY_CURSORS.lock().push(cursor)
1443    }
1444}
1445
1446trait ToTreeSitterPoint {
1447    fn to_ts_point(self) -> tree_sitter::Point;
1448    fn from_ts_point(point: tree_sitter::Point) -> Self;
1449}
1450
1451impl ToTreeSitterPoint for Point {
1452    fn to_ts_point(self) -> tree_sitter::Point {
1453        tree_sitter::Point::new(self.row as usize, self.column as usize)
1454    }
1455
1456    fn from_ts_point(point: tree_sitter::Point) -> Self {
1457        Point::new(point.row as u32, point.column as u32)
1458    }
1459}
1460
1461fn contiguous_ranges(
1462    values: impl IntoIterator<Item = u32>,
1463    max_len: usize,
1464) -> impl Iterator<Item = Range<u32>> {
1465    let mut values = values.into_iter();
1466    let mut current_range: Option<Range<u32>> = None;
1467    std::iter::from_fn(move || loop {
1468        if let Some(value) = values.next() {
1469            if let Some(range) = &mut current_range {
1470                if value == range.end && range.len() < max_len {
1471                    range.end += 1;
1472                    continue;
1473                }
1474            }
1475
1476            let prev_range = current_range.clone();
1477            current_range = Some(value..(value + 1));
1478            if prev_range.is_some() {
1479                return prev_range;
1480            }
1481        } else {
1482            return current_range.take();
1483        }
1484    })
1485}