lsp_store.rs

   1use crate::{
   2    buffer_store::{BufferStore, BufferStoreEvent},
   3    deserialize_code_actions,
   4    environment::ProjectEnvironment,
   5    lsp_command::{self, *},
   6    lsp_ext_command,
   7    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   8    project_settings::{LspSettings, ProjectSettings},
   9    relativize_path, resolve_path,
  10    toolchain_store::{EmptyToolchainStore, ToolchainStoreEvent},
  11    worktree_store::{WorktreeStore, WorktreeStoreEvent},
  12    yarn::YarnPathStore,
  13    CodeAction, Completion, CoreCompletion, Hover, InlayHint, ProjectItem as _, ProjectPath,
  14    ProjectTransaction, ResolveState, Symbol, ToolchainStore,
  15};
  16use anyhow::{anyhow, Context as _, Result};
  17use async_trait::async_trait;
  18use client::{proto, TypedEnvelope};
  19use collections::{btree_map, BTreeMap, HashMap, HashSet};
  20use futures::{
  21    future::{join_all, Shared},
  22    select,
  23    stream::FuturesUnordered,
  24    AsyncWriteExt, Future, FutureExt, StreamExt,
  25};
  26use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
  27use gpui::{
  28    AppContext, AsyncAppContext, Entity, EventEmitter, Model, ModelContext, PromptLevel, Task,
  29    WeakModel,
  30};
  31use http_client::HttpClient;
  32use itertools::Itertools as _;
  33use language::{
  34    language_settings::{
  35        language_settings, FormatOnSave, Formatter, LanguageSettings, SelectedFormatter,
  36    },
  37    markdown, point_to_lsp, prepare_completion_documentation,
  38    proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
  39    range_from_lsp, Bias, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
  40    DiagnosticEntry, DiagnosticSet, Diff, Documentation, File as _, Language, LanguageName,
  41    LanguageRegistry, LanguageServerBinaryStatus, LanguageToolchainStore, LocalFile, LspAdapter,
  42    LspAdapterDelegate, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction,
  43    Unclipped,
  44};
  45use lsp::{
  46    notification::DidRenameFiles, CodeActionKind, CompletionContext, DiagnosticSeverity,
  47    DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter,
  48    FileOperationPatternKind, FileOperationRegistrationOptions, FileRename, FileSystemWatcher,
  49    InsertTextFormat, LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions,
  50    LanguageServerId, LanguageServerName, LspRequestFuture, MessageActionItem, MessageType, OneOf,
  51    RenameFilesParams, ServerHealthStatus, ServerStatus, SymbolKind, TextEdit, Url,
  52    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder,
  53};
  54use node_runtime::read_package_installed_version;
  55use parking_lot::{Mutex, RwLock};
  56use postage::watch;
  57use rand::prelude::*;
  58
  59use rpc::AnyProtoClient;
  60use serde::Serialize;
  61use settings::{Settings, SettingsLocation, SettingsStore};
  62use sha2::{Digest, Sha256};
  63use similar::{ChangeTag, TextDiff};
  64use smol::channel::Sender;
  65use snippet::Snippet;
  66use std::{
  67    any::Any,
  68    cmp::Ordering,
  69    convert::TryInto,
  70    ffi::OsStr,
  71    iter, mem,
  72    ops::{ControlFlow, Range},
  73    path::{self, Path, PathBuf},
  74    str,
  75    sync::Arc,
  76    time::{Duration, Instant},
  77};
  78use text::{Anchor, BufferId, LineEnding, Point, Selection};
  79use util::{
  80    debug_panic, defer, maybe, merge_json_value_into, post_inc, ResultExt, TryFutureExt as _,
  81};
  82
  83pub use fs::*;
  84pub use language::Location;
  85#[cfg(any(test, feature = "test-support"))]
  86pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  87pub use worktree::{
  88    Entry, EntryKind, File, LocalWorktree, PathChange, ProjectEntryId, RepositoryEntry,
  89    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  90    FS_WATCH_LATENCY,
  91};
  92
  93const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  94pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  95
  96#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  97pub enum FormatTrigger {
  98    Save,
  99    Manual,
 100}
 101
 102pub enum FormatTarget {
 103    Buffer,
 104    Ranges(Vec<Selection<Point>>),
 105}
 106
 107impl FormatTarget {
 108    pub fn as_selections(&self) -> Option<&[Selection<Point>]> {
 109        match self {
 110            FormatTarget::Buffer => None,
 111            FormatTarget::Ranges(selections) => Some(selections.as_slice()),
 112        }
 113    }
 114}
 115
 116// Currently, formatting operations are represented differently depending on
 117// whether they come from a language server or an external command.
 118#[derive(Debug)]
 119pub enum FormatOperation {
 120    Lsp(Vec<(Range<Anchor>, String)>),
 121    External(Diff),
 122    Prettier(Diff),
 123}
 124
 125impl FormatTrigger {
 126    fn from_proto(value: i32) -> FormatTrigger {
 127        match value {
 128            0 => FormatTrigger::Save,
 129            1 => FormatTrigger::Manual,
 130            _ => FormatTrigger::Save,
 131        }
 132    }
 133}
 134
 135pub struct LocalLspStore {
 136    http_client: Arc<dyn HttpClient>,
 137    environment: Model<ProjectEnvironment>,
 138    fs: Arc<dyn Fs>,
 139    yarn: Model<YarnPathStore>,
 140    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
 141    buffers_being_formatted: HashSet<BufferId>,
 142    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
 143    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
 144    language_server_paths_watched_for_rename:
 145        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
 146    language_server_watcher_registrations:
 147        HashMap<LanguageServerId, HashMap<String, Vec<FileSystemWatcher>>>,
 148    supplementary_language_servers:
 149        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
 150    prettier_store: Model<PrettierStore>,
 151    current_lsp_settings: HashMap<LanguageServerName, LspSettings>,
 152    _subscription: gpui::Subscription,
 153}
 154
 155impl LocalLspStore {
 156    fn shutdown_language_servers(
 157        &mut self,
 158        _cx: &mut ModelContext<LspStore>,
 159    ) -> impl Future<Output = ()> {
 160        let shutdown_futures = self
 161            .language_servers
 162            .drain()
 163            .map(|(_, server_state)| async {
 164                use LanguageServerState::*;
 165                match server_state {
 166                    Running { server, .. } => server.shutdown()?.await,
 167                    Starting(task) => task.await?.shutdown()?.await,
 168                }
 169            })
 170            .collect::<Vec<_>>();
 171
 172        async move {
 173            futures::future::join_all(shutdown_futures).await;
 174        }
 175    }
 176
 177    async fn format_locally(
 178        lsp_store: WeakModel<LspStore>,
 179        mut buffers: Vec<FormattableBuffer>,
 180        push_to_history: bool,
 181        trigger: FormatTrigger,
 182        target: FormatTarget,
 183        mut cx: AsyncAppContext,
 184    ) -> anyhow::Result<ProjectTransaction> {
 185        // Do not allow multiple concurrent formatting requests for the
 186        // same buffer.
 187        lsp_store.update(&mut cx, |this, cx| {
 188            let this = this.as_local_mut().unwrap();
 189            buffers.retain(|buffer| {
 190                this.buffers_being_formatted
 191                    .insert(buffer.handle.read(cx).remote_id())
 192            });
 193        })?;
 194
 195        let _cleanup = defer({
 196            let this = lsp_store.clone();
 197            let mut cx = cx.clone();
 198            let buffers = &buffers;
 199            move || {
 200                this.update(&mut cx, |this, cx| {
 201                    let this = this.as_local_mut().unwrap();
 202                    for buffer in buffers {
 203                        this.buffers_being_formatted
 204                            .remove(&buffer.handle.read(cx).remote_id());
 205                    }
 206                })
 207                .ok();
 208            }
 209        });
 210
 211        let mut project_transaction = ProjectTransaction::default();
 212        for buffer in &buffers {
 213            let (primary_adapter_and_server, adapters_and_servers) =
 214                lsp_store.update(&mut cx, |lsp_store, cx| {
 215                    let buffer = buffer.handle.read(cx);
 216
 217                    let adapters_and_servers = lsp_store
 218                        .language_servers_for_buffer(buffer, cx)
 219                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 220                        .collect::<Vec<_>>();
 221
 222                    let primary_adapter = lsp_store
 223                        .primary_language_server_for_buffer(buffer, cx)
 224                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()));
 225
 226                    (primary_adapter, adapters_and_servers)
 227                })?;
 228
 229            let settings = buffer.handle.update(&mut cx, |buffer, cx| {
 230                language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 231                    .into_owned()
 232            })?;
 233
 234            let remove_trailing_whitespace = settings.remove_trailing_whitespace_on_save;
 235            let ensure_final_newline = settings.ensure_final_newline_on_save;
 236
 237            // First, format buffer's whitespace according to the settings.
 238            let trailing_whitespace_diff = if remove_trailing_whitespace {
 239                Some(
 240                    buffer
 241                        .handle
 242                        .update(&mut cx, |b, cx| b.remove_trailing_whitespace(cx))?
 243                        .await,
 244                )
 245            } else {
 246                None
 247            };
 248            let whitespace_transaction_id = buffer.handle.update(&mut cx, |buffer, cx| {
 249                buffer.finalize_last_transaction();
 250                buffer.start_transaction();
 251                if let Some(diff) = trailing_whitespace_diff {
 252                    buffer.apply_diff(diff, cx);
 253                }
 254                if ensure_final_newline {
 255                    buffer.ensure_final_newline(cx);
 256                }
 257                buffer.end_transaction(cx)
 258            })?;
 259
 260            // Apply the `code_actions_on_format` before we run the formatter.
 261            let code_actions = deserialize_code_actions(&settings.code_actions_on_format);
 262            #[allow(clippy::nonminimal_bool)]
 263            if !code_actions.is_empty()
 264                && !(trigger == FormatTrigger::Save && settings.format_on_save == FormatOnSave::Off)
 265            {
 266                LspStore::execute_code_actions_on_servers(
 267                    &lsp_store,
 268                    &adapters_and_servers,
 269                    code_actions,
 270                    &buffer.handle,
 271                    push_to_history,
 272                    &mut project_transaction,
 273                    &mut cx,
 274                )
 275                .await?;
 276            }
 277
 278            // Apply language-specific formatting using either the primary language server
 279            // or external command.
 280            // Except for code actions, which are applied with all connected language servers.
 281            let primary_language_server =
 282                primary_adapter_and_server.map(|(_adapter, server)| server.clone());
 283            let server_and_buffer = primary_language_server
 284                .as_ref()
 285                .zip(buffer.abs_path.as_ref());
 286
 287            let prettier_settings = buffer.handle.read_with(&cx, |buffer, cx| {
 288                language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 289                    .prettier
 290                    .clone()
 291            })?;
 292
 293            let mut format_operations: Vec<FormatOperation> = vec![];
 294            {
 295                match trigger {
 296                    FormatTrigger::Save => {
 297                        match &settings.format_on_save {
 298                            FormatOnSave::Off => {
 299                                // nothing
 300                            }
 301                            FormatOnSave::On => {
 302                                match &settings.formatter {
 303                                    SelectedFormatter::Auto => {
 304                                        // do the auto-format: prefer prettier, fallback to primary language server
 305                                        let diff = {
 306                                            if prettier_settings.allowed {
 307                                                Self::perform_format(
 308                                                    &Formatter::Prettier,
 309                                                    &target,
 310                                                    server_and_buffer,
 311                                                    lsp_store.clone(),
 312                                                    buffer,
 313                                                    &settings,
 314                                                    &adapters_and_servers,
 315                                                    push_to_history,
 316                                                    &mut project_transaction,
 317                                                    &mut cx,
 318                                                )
 319                                                .await
 320                                            } else {
 321                                                Self::perform_format(
 322                                                    &Formatter::LanguageServer { name: None },
 323                                                    &target,
 324                                                    server_and_buffer,
 325                                                    lsp_store.clone(),
 326                                                    buffer,
 327                                                    &settings,
 328                                                    &adapters_and_servers,
 329                                                    push_to_history,
 330                                                    &mut project_transaction,
 331                                                    &mut cx,
 332                                                )
 333                                                .await
 334                                            }
 335                                        }?;
 336
 337                                        if let Some(op) = diff {
 338                                            format_operations.push(op);
 339                                        }
 340                                    }
 341                                    SelectedFormatter::List(formatters) => {
 342                                        for formatter in formatters.as_ref() {
 343                                            let diff = Self::perform_format(
 344                                                formatter,
 345                                                &target,
 346                                                server_and_buffer,
 347                                                lsp_store.clone(),
 348                                                buffer,
 349                                                &settings,
 350                                                &adapters_and_servers,
 351                                                push_to_history,
 352                                                &mut project_transaction,
 353                                                &mut cx,
 354                                            )
 355                                            .await?;
 356                                            if let Some(op) = diff {
 357                                                format_operations.push(op);
 358                                            }
 359
 360                                            // format with formatter
 361                                        }
 362                                    }
 363                                }
 364                            }
 365                            FormatOnSave::List(formatters) => {
 366                                for formatter in formatters.as_ref() {
 367                                    let diff = Self::perform_format(
 368                                        formatter,
 369                                        &target,
 370                                        server_and_buffer,
 371                                        lsp_store.clone(),
 372                                        buffer,
 373                                        &settings,
 374                                        &adapters_and_servers,
 375                                        push_to_history,
 376                                        &mut project_transaction,
 377                                        &mut cx,
 378                                    )
 379                                    .await?;
 380                                    if let Some(op) = diff {
 381                                        format_operations.push(op);
 382                                    }
 383                                }
 384                            }
 385                        }
 386                    }
 387                    FormatTrigger::Manual => {
 388                        match &settings.formatter {
 389                            SelectedFormatter::Auto => {
 390                                // do the auto-format: prefer prettier, fallback to primary language server
 391                                let diff = {
 392                                    if prettier_settings.allowed {
 393                                        Self::perform_format(
 394                                            &Formatter::Prettier,
 395                                            &target,
 396                                            server_and_buffer,
 397                                            lsp_store.clone(),
 398                                            buffer,
 399                                            &settings,
 400                                            &adapters_and_servers,
 401                                            push_to_history,
 402                                            &mut project_transaction,
 403                                            &mut cx,
 404                                        )
 405                                        .await
 406                                    } else {
 407                                        let formatter = Formatter::LanguageServer {
 408                                            name: primary_language_server
 409                                                .as_ref()
 410                                                .map(|server| server.name().to_string()),
 411                                        };
 412                                        Self::perform_format(
 413                                            &formatter,
 414                                            &target,
 415                                            server_and_buffer,
 416                                            lsp_store.clone(),
 417                                            buffer,
 418                                            &settings,
 419                                            &adapters_and_servers,
 420                                            push_to_history,
 421                                            &mut project_transaction,
 422                                            &mut cx,
 423                                        )
 424                                        .await
 425                                    }
 426                                }?;
 427
 428                                if let Some(op) = diff {
 429                                    format_operations.push(op)
 430                                }
 431                            }
 432                            SelectedFormatter::List(formatters) => {
 433                                for formatter in formatters.as_ref() {
 434                                    // format with formatter
 435                                    let diff = Self::perform_format(
 436                                        formatter,
 437                                        &target,
 438                                        server_and_buffer,
 439                                        lsp_store.clone(),
 440                                        buffer,
 441                                        &settings,
 442                                        &adapters_and_servers,
 443                                        push_to_history,
 444                                        &mut project_transaction,
 445                                        &mut cx,
 446                                    )
 447                                    .await?;
 448                                    if let Some(op) = diff {
 449                                        format_operations.push(op);
 450                                    }
 451                                }
 452                            }
 453                        }
 454                    }
 455                }
 456            }
 457
 458            buffer.handle.update(&mut cx, |b, cx| {
 459                // If the buffer had its whitespace formatted and was edited while the language-specific
 460                // formatting was being computed, avoid applying the language-specific formatting, because
 461                // it can't be grouped with the whitespace formatting in the undo history.
 462                if let Some(transaction_id) = whitespace_transaction_id {
 463                    if b.peek_undo_stack()
 464                        .map_or(true, |e| e.transaction_id() != transaction_id)
 465                    {
 466                        format_operations.clear();
 467                    }
 468                }
 469
 470                // Apply any language-specific formatting, and group the two formatting operations
 471                // in the buffer's undo history.
 472                for operation in format_operations {
 473                    match operation {
 474                        FormatOperation::Lsp(edits) => {
 475                            b.edit(edits, None, cx);
 476                        }
 477                        FormatOperation::External(diff) => {
 478                            b.apply_diff(diff, cx);
 479                        }
 480                        FormatOperation::Prettier(diff) => {
 481                            b.apply_diff(diff, cx);
 482                        }
 483                    }
 484
 485                    if let Some(transaction_id) = whitespace_transaction_id {
 486                        b.group_until_transaction(transaction_id);
 487                    } else if let Some(transaction) = project_transaction.0.get(&buffer.handle) {
 488                        b.group_until_transaction(transaction.id)
 489                    }
 490                }
 491
 492                if let Some(transaction) = b.finalize_last_transaction().cloned() {
 493                    if !push_to_history {
 494                        b.forget_transaction(transaction.id);
 495                    }
 496                    project_transaction
 497                        .0
 498                        .insert(buffer.handle.clone(), transaction);
 499                }
 500            })?;
 501        }
 502
 503        Ok(project_transaction)
 504    }
 505
 506    #[allow(clippy::too_many_arguments)]
 507    async fn perform_format(
 508        formatter: &Formatter,
 509        format_target: &FormatTarget,
 510        primary_server_and_buffer: Option<(&Arc<LanguageServer>, &PathBuf)>,
 511        lsp_store: WeakModel<LspStore>,
 512        buffer: &FormattableBuffer,
 513        settings: &LanguageSettings,
 514        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 515        push_to_history: bool,
 516        transaction: &mut ProjectTransaction,
 517        cx: &mut AsyncAppContext,
 518    ) -> Result<Option<FormatOperation>, anyhow::Error> {
 519        let result = match formatter {
 520            Formatter::LanguageServer { name } => {
 521                if let Some((language_server, buffer_abs_path)) = primary_server_and_buffer {
 522                    let language_server = if let Some(name) = name {
 523                        adapters_and_servers
 524                            .iter()
 525                            .find_map(|(adapter, server)| {
 526                                adapter.name.0.as_ref().eq(name.as_str()).then_some(server)
 527                            })
 528                            .unwrap_or(language_server)
 529                    } else {
 530                        language_server
 531                    };
 532
 533                    match format_target {
 534                        FormatTarget::Buffer => Some(FormatOperation::Lsp(
 535                            LspStore::format_via_lsp(
 536                                &lsp_store,
 537                                &buffer.handle,
 538                                buffer_abs_path,
 539                                language_server,
 540                                settings,
 541                                cx,
 542                            )
 543                            .await
 544                            .context("failed to format via language server")?,
 545                        )),
 546                        FormatTarget::Ranges(selections) => Some(FormatOperation::Lsp(
 547                            LspStore::format_range_via_lsp(
 548                                &lsp_store,
 549                                &buffer.handle,
 550                                selections.as_slice(),
 551                                buffer_abs_path,
 552                                language_server,
 553                                settings,
 554                                cx,
 555                            )
 556                            .await
 557                            .context("failed to format ranges via language server")?,
 558                        )),
 559                    }
 560                } else {
 561                    None
 562                }
 563            }
 564            Formatter::Prettier => {
 565                let prettier = lsp_store.update(cx, |lsp_store, _cx| {
 566                    lsp_store.prettier_store().unwrap().downgrade()
 567                })?;
 568                prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 569                    .await
 570                    .transpose()?
 571            }
 572            Formatter::External { command, arguments } => {
 573                Self::format_via_external_command(buffer, command, arguments.as_deref(), cx)
 574                    .await
 575                    .context(format!(
 576                        "failed to format via external command {:?}",
 577                        command
 578                    ))?
 579                    .map(FormatOperation::External)
 580            }
 581            Formatter::CodeActions(code_actions) => {
 582                let code_actions = deserialize_code_actions(code_actions);
 583                if !code_actions.is_empty() {
 584                    LspStore::execute_code_actions_on_servers(
 585                        &lsp_store,
 586                        adapters_and_servers,
 587                        code_actions,
 588                        &buffer.handle,
 589                        push_to_history,
 590                        transaction,
 591                        cx,
 592                    )
 593                    .await?;
 594                }
 595                None
 596            }
 597        };
 598        anyhow::Ok(result)
 599    }
 600
 601    async fn format_via_external_command(
 602        buffer: &FormattableBuffer,
 603        command: &str,
 604        arguments: Option<&[String]>,
 605        cx: &mut AsyncAppContext,
 606    ) -> Result<Option<Diff>> {
 607        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 608            let file = File::from_dyn(buffer.file())?;
 609            let worktree = file.worktree.read(cx);
 610            let mut worktree_path = worktree.abs_path().to_path_buf();
 611            if worktree.root_entry()?.is_file() {
 612                worktree_path.pop();
 613            }
 614            Some(worktree_path)
 615        })?;
 616
 617        let mut child = util::command::new_smol_command(command);
 618
 619        if let Some(buffer_env) = buffer.env.as_ref() {
 620            child.envs(buffer_env);
 621        }
 622
 623        if let Some(working_dir_path) = working_dir_path {
 624            child.current_dir(working_dir_path);
 625        }
 626
 627        if let Some(arguments) = arguments {
 628            child.args(arguments.iter().map(|arg| {
 629                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 630                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 631                } else {
 632                    arg.replace("{buffer_path}", "Untitled")
 633                }
 634            }));
 635        }
 636
 637        let mut child = child
 638            .stdin(smol::process::Stdio::piped())
 639            .stdout(smol::process::Stdio::piped())
 640            .stderr(smol::process::Stdio::piped())
 641            .spawn()?;
 642
 643        let stdin = child
 644            .stdin
 645            .as_mut()
 646            .ok_or_else(|| anyhow!("failed to acquire stdin"))?;
 647        let text = buffer
 648            .handle
 649            .update(cx, |buffer, _| buffer.as_rope().clone())?;
 650        for chunk in text.chunks() {
 651            stdin.write_all(chunk.as_bytes()).await?;
 652        }
 653        stdin.flush().await?;
 654
 655        let output = child.output().await?;
 656        if !output.status.success() {
 657            return Err(anyhow!(
 658                "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 659                output.status.code(),
 660                String::from_utf8_lossy(&output.stdout),
 661                String::from_utf8_lossy(&output.stderr),
 662            ));
 663        }
 664
 665        let stdout = String::from_utf8(output.stdout)?;
 666        Ok(Some(
 667            buffer
 668                .handle
 669                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 670                .await,
 671        ))
 672    }
 673}
 674
 675#[derive(Debug)]
 676pub struct FormattableBuffer {
 677    handle: Model<Buffer>,
 678    abs_path: Option<PathBuf>,
 679    env: Option<HashMap<String, String>>,
 680}
 681
 682pub struct RemoteLspStore {
 683    upstream_client: Option<AnyProtoClient>,
 684    upstream_project_id: u64,
 685}
 686
 687#[allow(clippy::large_enum_variant)]
 688pub enum LspStoreMode {
 689    Local(LocalLspStore),   // ssh host and collab host
 690    Remote(RemoteLspStore), // collab guest
 691}
 692
 693impl LspStoreMode {
 694    fn is_local(&self) -> bool {
 695        matches!(self, LspStoreMode::Local(_))
 696    }
 697
 698    fn is_remote(&self) -> bool {
 699        matches!(self, LspStoreMode::Remote(_))
 700    }
 701}
 702
 703pub struct LspStore {
 704    mode: LspStoreMode,
 705    last_formatting_failure: Option<String>,
 706    downstream_client: Option<(AnyProtoClient, u64)>,
 707    nonce: u128,
 708    buffer_store: Model<BufferStore>,
 709    worktree_store: Model<WorktreeStore>,
 710    toolchain_store: Option<Model<ToolchainStore>>,
 711    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
 712    pub languages: Arc<LanguageRegistry>,
 713    language_server_ids: HashMap<(WorktreeId, LanguageServerName), LanguageServerId>,
 714    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 715    active_entry: Option<ProjectEntryId>,
 716    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 717    _maintain_buffer_languages: Task<()>,
 718    next_diagnostic_group_id: usize,
 719    diagnostic_summaries:
 720        HashMap<WorktreeId, HashMap<Arc<Path>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 721    diagnostics: HashMap<
 722        WorktreeId,
 723        HashMap<
 724            Arc<Path>,
 725            Vec<(
 726                LanguageServerId,
 727                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 728            )>,
 729        >,
 730    >,
 731}
 732
 733pub enum LspStoreEvent {
 734    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 735    LanguageServerRemoved(LanguageServerId),
 736    LanguageServerUpdate {
 737        language_server_id: LanguageServerId,
 738        message: proto::update_language_server::Variant,
 739    },
 740    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 741    LanguageServerPrompt(LanguageServerPromptRequest),
 742    LanguageDetected {
 743        buffer: Model<Buffer>,
 744        new_language: Option<Arc<Language>>,
 745    },
 746    Notification(String),
 747    RefreshInlayHints,
 748    DiagnosticsUpdated {
 749        language_server_id: LanguageServerId,
 750        path: ProjectPath,
 751    },
 752    DiskBasedDiagnosticsStarted {
 753        language_server_id: LanguageServerId,
 754    },
 755    DiskBasedDiagnosticsFinished {
 756        language_server_id: LanguageServerId,
 757    },
 758    SnippetEdit {
 759        buffer_id: BufferId,
 760        edits: Vec<(lsp::Range, Snippet)>,
 761        most_recent_edit: clock::Lamport,
 762    },
 763}
 764
 765#[derive(Clone, Debug, Serialize)]
 766pub struct LanguageServerStatus {
 767    pub name: String,
 768    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 769    pub has_pending_diagnostic_updates: bool,
 770    progress_tokens: HashSet<String>,
 771}
 772
 773#[derive(Clone, Debug)]
 774struct CoreSymbol {
 775    pub language_server_name: LanguageServerName,
 776    pub source_worktree_id: WorktreeId,
 777    pub path: ProjectPath,
 778    pub name: String,
 779    pub kind: lsp::SymbolKind,
 780    pub range: Range<Unclipped<PointUtf16>>,
 781    pub signature: [u8; 32],
 782}
 783
 784impl LspStore {
 785    pub fn init(client: &AnyProtoClient) {
 786        client.add_model_request_handler(Self::handle_multi_lsp_query);
 787        client.add_model_request_handler(Self::handle_restart_language_servers);
 788        client.add_model_request_handler(Self::handle_cancel_language_server_work);
 789        client.add_model_message_handler(Self::handle_start_language_server);
 790        client.add_model_message_handler(Self::handle_update_language_server);
 791        client.add_model_message_handler(Self::handle_language_server_log);
 792        client.add_model_message_handler(Self::handle_update_diagnostic_summary);
 793        client.add_model_request_handler(Self::handle_format_buffers);
 794        client.add_model_request_handler(Self::handle_resolve_completion_documentation);
 795        client.add_model_request_handler(Self::handle_apply_code_action);
 796        client.add_model_request_handler(Self::handle_inlay_hints);
 797        client.add_model_request_handler(Self::handle_get_project_symbols);
 798        client.add_model_request_handler(Self::handle_resolve_inlay_hint);
 799        client.add_model_request_handler(Self::handle_open_buffer_for_symbol);
 800        client.add_model_request_handler(Self::handle_refresh_inlay_hints);
 801        client.add_model_request_handler(Self::handle_on_type_formatting);
 802        client.add_model_request_handler(Self::handle_apply_additional_edits_for_completion);
 803        client.add_model_request_handler(Self::handle_lsp_command::<GetCodeActions>);
 804        client.add_model_request_handler(Self::handle_lsp_command::<GetCompletions>);
 805        client.add_model_request_handler(Self::handle_lsp_command::<GetHover>);
 806        client.add_model_request_handler(Self::handle_lsp_command::<GetDefinition>);
 807        client.add_model_request_handler(Self::handle_lsp_command::<GetDeclaration>);
 808        client.add_model_request_handler(Self::handle_lsp_command::<GetTypeDefinition>);
 809        client.add_model_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 810        client.add_model_request_handler(Self::handle_lsp_command::<GetReferences>);
 811        client.add_model_request_handler(Self::handle_lsp_command::<PrepareRename>);
 812        client.add_model_request_handler(Self::handle_lsp_command::<PerformRename>);
 813        client.add_model_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 814        client.add_model_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 815    }
 816
 817    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 818        match &self.mode {
 819            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 820            _ => None,
 821        }
 822    }
 823
 824    pub fn as_local(&self) -> Option<&LocalLspStore> {
 825        match &self.mode {
 826            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 827            _ => None,
 828        }
 829    }
 830
 831    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 832        match &mut self.mode {
 833            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 834            _ => None,
 835        }
 836    }
 837
 838    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 839        match &self.mode {
 840            LspStoreMode::Remote(RemoteLspStore {
 841                upstream_client: Some(upstream_client),
 842                upstream_project_id,
 843                ..
 844            }) => Some((upstream_client.clone(), *upstream_project_id)),
 845
 846            LspStoreMode::Remote(RemoteLspStore {
 847                upstream_client: None,
 848                ..
 849            }) => None,
 850            LspStoreMode::Local(_) => None,
 851        }
 852    }
 853
 854    pub fn swap_current_lsp_settings(
 855        &mut self,
 856        new_settings: HashMap<LanguageServerName, LspSettings>,
 857    ) -> Option<HashMap<LanguageServerName, LspSettings>> {
 858        match &mut self.mode {
 859            LspStoreMode::Local(LocalLspStore {
 860                current_lsp_settings,
 861                ..
 862            }) => {
 863                let ret = mem::take(current_lsp_settings);
 864                *current_lsp_settings = new_settings;
 865                Some(ret)
 866            }
 867            LspStoreMode::Remote(_) => None,
 868        }
 869    }
 870
 871    #[allow(clippy::too_many_arguments)]
 872    pub fn new_local(
 873        buffer_store: Model<BufferStore>,
 874        worktree_store: Model<WorktreeStore>,
 875        prettier_store: Model<PrettierStore>,
 876        toolchain_store: Model<ToolchainStore>,
 877        environment: Model<ProjectEnvironment>,
 878        languages: Arc<LanguageRegistry>,
 879        http_client: Arc<dyn HttpClient>,
 880        fs: Arc<dyn Fs>,
 881        cx: &mut ModelContext<Self>,
 882    ) -> Self {
 883        let yarn = YarnPathStore::new(fs.clone(), cx);
 884        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 885            .detach();
 886        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 887            .detach();
 888        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 889            .detach();
 890        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 891            .detach();
 892        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 893            .detach();
 894
 895        let _maintain_workspace_config = {
 896            let (sender, receiver) = watch::channel();
 897            (Self::maintain_workspace_config(receiver, cx), sender)
 898        };
 899        Self {
 900            mode: LspStoreMode::Local(LocalLspStore {
 901                supplementary_language_servers: Default::default(),
 902                language_servers: Default::default(),
 903                last_workspace_edits_by_language_server: Default::default(),
 904                language_server_watched_paths: Default::default(),
 905                language_server_paths_watched_for_rename: Default::default(),
 906                language_server_watcher_registrations: Default::default(),
 907                current_lsp_settings: ProjectSettings::get_global(cx).lsp.clone(),
 908                buffers_being_formatted: Default::default(),
 909                prettier_store,
 910                environment,
 911                http_client,
 912                fs,
 913                yarn,
 914                _subscription: cx.on_app_quit(|this, cx| {
 915                    this.as_local_mut().unwrap().shutdown_language_servers(cx)
 916                }),
 917            }),
 918            last_formatting_failure: None,
 919            downstream_client: None,
 920            buffer_store,
 921            worktree_store,
 922            toolchain_store: Some(toolchain_store),
 923            languages: languages.clone(),
 924            language_server_ids: Default::default(),
 925            language_server_statuses: Default::default(),
 926            nonce: StdRng::from_entropy().gen(),
 927            buffer_snapshots: Default::default(),
 928            next_diagnostic_group_id: Default::default(),
 929            diagnostic_summaries: Default::default(),
 930            diagnostics: Default::default(),
 931            active_entry: None,
 932
 933            _maintain_workspace_config,
 934            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 935        }
 936    }
 937
 938    fn send_lsp_proto_request<R: LspCommand>(
 939        &self,
 940        buffer: Model<Buffer>,
 941        client: AnyProtoClient,
 942        upstream_project_id: u64,
 943        request: R,
 944        cx: &mut ModelContext<'_, LspStore>,
 945    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 946        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 947        cx.spawn(move |this, cx| async move {
 948            let response = client.request(message).await?;
 949            let this = this.upgrade().context("project dropped")?;
 950            request
 951                .response_from_proto(response, this, buffer, cx)
 952                .await
 953        })
 954    }
 955
 956    pub(super) fn new_remote(
 957        buffer_store: Model<BufferStore>,
 958        worktree_store: Model<WorktreeStore>,
 959        toolchain_store: Option<Model<ToolchainStore>>,
 960        languages: Arc<LanguageRegistry>,
 961        upstream_client: AnyProtoClient,
 962        project_id: u64,
 963        cx: &mut ModelContext<Self>,
 964    ) -> Self {
 965        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 966            .detach();
 967        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 968            .detach();
 969        let _maintain_workspace_config = {
 970            let (sender, receiver) = watch::channel();
 971            (Self::maintain_workspace_config(receiver, cx), sender)
 972        };
 973        Self {
 974            mode: LspStoreMode::Remote(RemoteLspStore {
 975                upstream_client: Some(upstream_client),
 976                upstream_project_id: project_id,
 977            }),
 978            downstream_client: None,
 979            last_formatting_failure: None,
 980            buffer_store,
 981            worktree_store,
 982            languages: languages.clone(),
 983            language_server_ids: Default::default(),
 984            language_server_statuses: Default::default(),
 985            nonce: StdRng::from_entropy().gen(),
 986            buffer_snapshots: Default::default(),
 987            next_diagnostic_group_id: Default::default(),
 988            diagnostic_summaries: Default::default(),
 989            diagnostics: Default::default(),
 990            active_entry: None,
 991            toolchain_store,
 992            _maintain_workspace_config,
 993            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 994        }
 995    }
 996
 997    fn worktree_for_id(
 998        &self,
 999        worktree_id: WorktreeId,
1000        cx: &ModelContext<Self>,
1001    ) -> Result<Model<Worktree>> {
1002        self.worktree_store
1003            .read(cx)
1004            .worktree_for_id(worktree_id, cx)
1005            .ok_or_else(|| anyhow!("worktree not found"))
1006    }
1007
1008    fn on_buffer_store_event(
1009        &mut self,
1010        _: Model<BufferStore>,
1011        event: &BufferStoreEvent,
1012        cx: &mut ModelContext<Self>,
1013    ) {
1014        match event {
1015            BufferStoreEvent::BufferAdded(buffer) => {
1016                self.register_buffer(buffer, cx).log_err();
1017            }
1018            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
1019                if let Some(old_file) = File::from_dyn(old_file.as_ref()) {
1020                    self.unregister_buffer_from_language_servers(buffer, old_file, cx);
1021                }
1022
1023                self.register_buffer_with_language_servers(buffer, cx);
1024            }
1025            BufferStoreEvent::BufferDropped(_) => {}
1026        }
1027    }
1028
1029    fn on_worktree_store_event(
1030        &mut self,
1031        _: Model<WorktreeStore>,
1032        event: &WorktreeStoreEvent,
1033        cx: &mut ModelContext<Self>,
1034    ) {
1035        match event {
1036            WorktreeStoreEvent::WorktreeAdded(worktree) => {
1037                if !worktree.read(cx).is_local() {
1038                    return;
1039                }
1040                cx.subscribe(worktree, |this, worktree, event, cx| match event {
1041                    worktree::Event::UpdatedEntries(changes) => {
1042                        this.update_local_worktree_language_servers(&worktree, changes, cx);
1043                    }
1044                    worktree::Event::UpdatedGitRepositories(_)
1045                    | worktree::Event::DeletedEntry(_) => {}
1046                })
1047                .detach()
1048            }
1049            WorktreeStoreEvent::WorktreeReleased(..) => {}
1050            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
1051            WorktreeStoreEvent::WorktreeOrderChanged => {}
1052            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
1053                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
1054            }
1055        }
1056    }
1057
1058    fn on_prettier_store_event(
1059        &mut self,
1060        _: Model<PrettierStore>,
1061        event: &PrettierStoreEvent,
1062        cx: &mut ModelContext<Self>,
1063    ) {
1064        match event {
1065            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
1066                self.unregister_supplementary_language_server(*prettier_server_id, cx);
1067            }
1068            PrettierStoreEvent::LanguageServerAdded {
1069                new_server_id,
1070                name,
1071                prettier_server,
1072            } => {
1073                self.register_supplementary_language_server(
1074                    *new_server_id,
1075                    name.clone(),
1076                    prettier_server.clone(),
1077                    cx,
1078                );
1079            }
1080        }
1081    }
1082
1083    fn on_toolchain_store_event(
1084        &mut self,
1085        _: Model<ToolchainStore>,
1086        event: &ToolchainStoreEvent,
1087        _: &mut ModelContext<Self>,
1088    ) {
1089        match event {
1090            ToolchainStoreEvent::ToolchainActivated { .. } => {
1091                self.request_workspace_config_refresh()
1092            }
1093        }
1094    }
1095
1096    fn request_workspace_config_refresh(&mut self) {
1097        *self._maintain_workspace_config.1.borrow_mut() = ();
1098    }
1099    // todo!
1100    pub fn prettier_store(&self) -> Option<Model<PrettierStore>> {
1101        self.as_local().map(|local| local.prettier_store.clone())
1102    }
1103
1104    fn on_buffer_event(
1105        &mut self,
1106        buffer: Model<Buffer>,
1107        event: &language::BufferEvent,
1108        cx: &mut ModelContext<Self>,
1109    ) {
1110        match event {
1111            language::BufferEvent::Edited { .. } => {
1112                self.on_buffer_edited(buffer, cx);
1113            }
1114
1115            language::BufferEvent::Saved => {
1116                self.on_buffer_saved(buffer, cx);
1117            }
1118
1119            _ => {}
1120        }
1121    }
1122
1123    fn register_buffer(
1124        &mut self,
1125        buffer: &Model<Buffer>,
1126        cx: &mut ModelContext<Self>,
1127    ) -> Result<()> {
1128        buffer.update(cx, |buffer, _| {
1129            buffer.set_language_registry(self.languages.clone())
1130        });
1131
1132        cx.subscribe(buffer, |this, buffer, event, cx| {
1133            this.on_buffer_event(buffer, event, cx);
1134        })
1135        .detach();
1136
1137        self.register_buffer_with_language_servers(buffer, cx);
1138        cx.observe_release(buffer, |this, buffer, cx| {
1139            if let Some(file) = File::from_dyn(buffer.file()) {
1140                if file.is_local() {
1141                    let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
1142                    for server in this.language_servers_for_buffer(buffer, cx) {
1143                        server
1144                            .1
1145                            .notify::<lsp::notification::DidCloseTextDocument>(
1146                                lsp::DidCloseTextDocumentParams {
1147                                    text_document: lsp::TextDocumentIdentifier::new(uri.clone()),
1148                                },
1149                            )
1150                            .log_err();
1151                    }
1152                }
1153            }
1154        })
1155        .detach();
1156
1157        Ok(())
1158    }
1159
1160    fn maintain_buffer_languages(
1161        languages: Arc<LanguageRegistry>,
1162        cx: &mut ModelContext<Self>,
1163    ) -> Task<()> {
1164        let mut subscription = languages.subscribe();
1165        let mut prev_reload_count = languages.reload_count();
1166        cx.spawn(move |this, mut cx| async move {
1167            while let Some(()) = subscription.next().await {
1168                if let Some(this) = this.upgrade() {
1169                    // If the language registry has been reloaded, then remove and
1170                    // re-assign the languages on all open buffers.
1171                    let reload_count = languages.reload_count();
1172                    if reload_count > prev_reload_count {
1173                        prev_reload_count = reload_count;
1174                        this.update(&mut cx, |this, cx| {
1175                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
1176                                for buffer in buffer_store.buffers() {
1177                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
1178                                    {
1179                                        this.unregister_buffer_from_language_servers(
1180                                            &buffer, &f, cx,
1181                                        );
1182                                        buffer
1183                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
1184                                    }
1185                                }
1186                            });
1187                        })
1188                        .ok();
1189                    }
1190
1191                    this.update(&mut cx, |this, cx| {
1192                        let mut plain_text_buffers = Vec::new();
1193                        let mut buffers_with_unknown_injections = Vec::new();
1194                        for handle in this.buffer_store.read(cx).buffers() {
1195                            let buffer = handle.read(cx);
1196                            if buffer.language().is_none()
1197                                || buffer.language() == Some(&*language::PLAIN_TEXT)
1198                            {
1199                                plain_text_buffers.push(handle);
1200                            } else if buffer.contains_unknown_injections() {
1201                                buffers_with_unknown_injections.push(handle);
1202                            }
1203                        }
1204                        for buffer in plain_text_buffers {
1205                            this.register_buffer_with_language_servers(&buffer, cx);
1206                        }
1207
1208                        for buffer in buffers_with_unknown_injections {
1209                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
1210                        }
1211                    })
1212                    .ok();
1213                }
1214            }
1215        })
1216    }
1217
1218    fn detect_language_for_buffer(
1219        &mut self,
1220        buffer_handle: &Model<Buffer>,
1221        cx: &mut ModelContext<Self>,
1222    ) -> Option<language::AvailableLanguage> {
1223        // If the buffer has a language, set it and start the language server if we haven't already.
1224        let buffer = buffer_handle.read(cx);
1225        let file = buffer.file()?;
1226
1227        let content = buffer.as_rope();
1228        let available_language = self.languages.language_for_file(file, Some(content), cx);
1229        if let Some(available_language) = &available_language {
1230            if let Some(Ok(Ok(new_language))) = self
1231                .languages
1232                .load_language(available_language)
1233                .now_or_never()
1234            {
1235                self.set_language_for_buffer(buffer_handle, new_language, cx);
1236            }
1237        } else {
1238            cx.emit(LspStoreEvent::LanguageDetected {
1239                buffer: buffer_handle.clone(),
1240                new_language: None,
1241            });
1242        }
1243
1244        available_language
1245    }
1246
1247    pub fn set_language_for_buffer(
1248        &mut self,
1249        buffer: &Model<Buffer>,
1250        new_language: Arc<Language>,
1251        cx: &mut ModelContext<Self>,
1252    ) {
1253        buffer.update(cx, |buffer, cx| {
1254            if buffer.language().map_or(true, |old_language| {
1255                !Arc::ptr_eq(old_language, &new_language)
1256            }) {
1257                buffer.set_language(Some(new_language.clone()), cx);
1258            }
1259        });
1260
1261        let buffer_file = buffer.read(cx).file().cloned();
1262        let settings =
1263            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
1264        let buffer_file = File::from_dyn(buffer_file.as_ref());
1265
1266        let worktree_id = if let Some(file) = buffer_file {
1267            let worktree = file.worktree.clone();
1268            self.start_language_servers(&worktree, new_language.name(), cx);
1269
1270            Some(worktree.read(cx).id())
1271        } else {
1272            None
1273        };
1274
1275        if settings.prettier.allowed {
1276            if let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
1277            {
1278                let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
1279                if let Some(prettier_store) = prettier_store {
1280                    prettier_store.update(cx, |prettier_store, cx| {
1281                        prettier_store.install_default_prettier(
1282                            worktree_id,
1283                            prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
1284                            cx,
1285                        )
1286                    })
1287                }
1288            }
1289        }
1290
1291        cx.emit(LspStoreEvent::LanguageDetected {
1292            buffer: buffer.clone(),
1293            new_language: Some(new_language),
1294        })
1295    }
1296
1297    pub fn buffer_store(&self) -> Model<BufferStore> {
1298        self.buffer_store.clone()
1299    }
1300
1301    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
1302        self.active_entry = active_entry;
1303    }
1304
1305    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
1306        if let Some((client, downstream_project_id)) = self.downstream_client.clone() {
1307            if let Some(summaries) = self.diagnostic_summaries.get(&worktree.id()) {
1308                for (path, summaries) in summaries {
1309                    for (&server_id, summary) in summaries {
1310                        client
1311                            .send(proto::UpdateDiagnosticSummary {
1312                                project_id: downstream_project_id,
1313                                worktree_id: worktree.id().to_proto(),
1314                                summary: Some(summary.to_proto(server_id, path)),
1315                            })
1316                            .log_err();
1317                    }
1318                }
1319            }
1320        }
1321    }
1322
1323    pub fn request_lsp<R: LspCommand>(
1324        &self,
1325        buffer_handle: Model<Buffer>,
1326        server: LanguageServerToQuery,
1327        request: R,
1328        cx: &mut ModelContext<Self>,
1329    ) -> Task<Result<R::Response>>
1330    where
1331        <R::LspRequest as lsp::request::Request>::Result: Send,
1332        <R::LspRequest as lsp::request::Request>::Params: Send,
1333    {
1334        let buffer = buffer_handle.read(cx);
1335
1336        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
1337            return self.send_lsp_proto_request(
1338                buffer_handle,
1339                upstream_client,
1340                upstream_project_id,
1341                request,
1342                cx,
1343            );
1344        }
1345
1346        let language_server = match server {
1347            LanguageServerToQuery::Primary => {
1348                match self.primary_language_server_for_buffer(buffer, cx) {
1349                    Some((_, server)) => Some(Arc::clone(server)),
1350                    None => return Task::ready(Ok(Default::default())),
1351                }
1352            }
1353            LanguageServerToQuery::Other(id) => self
1354                .language_server_for_buffer(buffer, id, cx)
1355                .map(|(_, server)| Arc::clone(server)),
1356        };
1357        let file = File::from_dyn(buffer.file()).and_then(File::as_local);
1358        if let (Some(file), Some(language_server)) = (file, language_server) {
1359            let lsp_params = request.to_lsp(&file.abs_path(cx), buffer, &language_server, cx);
1360            let status = request.status();
1361            return cx.spawn(move |this, cx| async move {
1362                if !request.check_capabilities(language_server.adapter_server_capabilities()) {
1363                    return Ok(Default::default());
1364                }
1365
1366                let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
1367
1368                let id = lsp_request.id();
1369                let _cleanup = if status.is_some() {
1370                    cx.update(|cx| {
1371                        this.update(cx, |this, cx| {
1372                            this.on_lsp_work_start(
1373                                language_server.server_id(),
1374                                id.to_string(),
1375                                LanguageServerProgress {
1376                                    is_disk_based_diagnostics_progress: false,
1377                                    is_cancellable: false,
1378                                    title: None,
1379                                    message: status.clone(),
1380                                    percentage: None,
1381                                    last_update_at: cx.background_executor().now(),
1382                                },
1383                                cx,
1384                            );
1385                        })
1386                    })
1387                    .log_err();
1388
1389                    Some(defer(|| {
1390                        cx.update(|cx| {
1391                            this.update(cx, |this, cx| {
1392                                this.on_lsp_work_end(
1393                                    language_server.server_id(),
1394                                    id.to_string(),
1395                                    cx,
1396                                );
1397                            })
1398                        })
1399                        .log_err();
1400                    }))
1401                } else {
1402                    None
1403                };
1404
1405                let result = lsp_request.await;
1406
1407                let response = result.map_err(|err| {
1408                    log::warn!(
1409                        "Generic lsp request to {} failed: {}",
1410                        language_server.name(),
1411                        err
1412                    );
1413                    err
1414                })?;
1415
1416                request
1417                    .response_from_lsp(
1418                        response,
1419                        this.upgrade().ok_or_else(|| anyhow!("no app context"))?,
1420                        buffer_handle,
1421                        language_server.server_id(),
1422                        cx.clone(),
1423                    )
1424                    .await
1425            });
1426        }
1427
1428        Task::ready(Ok(Default::default()))
1429    }
1430
1431    fn on_settings_changed(&mut self, cx: &mut ModelContext<Self>) {
1432        let mut language_servers_to_start = Vec::new();
1433        let mut language_formatters_to_check = Vec::new();
1434        for buffer in self.buffer_store.read(cx).buffers() {
1435            let buffer = buffer.read(cx);
1436            let buffer_file = File::from_dyn(buffer.file());
1437            let buffer_language = buffer.language();
1438            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
1439            if let Some(language) = buffer_language {
1440                if settings.enable_language_server {
1441                    if let Some(file) = buffer_file {
1442                        language_servers_to_start.push((file.worktree.clone(), language.name()));
1443                    }
1444                }
1445                language_formatters_to_check.push((
1446                    buffer_file.map(|f| f.worktree_id(cx)),
1447                    settings.into_owned(),
1448                ));
1449            }
1450        }
1451
1452        let mut language_servers_to_stop = Vec::new();
1453        let mut language_servers_to_restart = Vec::new();
1454        let languages = self.languages.to_vec();
1455
1456        let new_lsp_settings = ProjectSettings::get_global(cx).lsp.clone();
1457        let Some(current_lsp_settings) = self.swap_current_lsp_settings(new_lsp_settings.clone())
1458        else {
1459            return;
1460        };
1461        for (worktree_id, started_lsp_name) in self.started_language_servers() {
1462            let language = languages.iter().find_map(|l| {
1463                let adapter = self
1464                    .languages
1465                    .lsp_adapters(&l.name())
1466                    .iter()
1467                    .find(|adapter| adapter.name == started_lsp_name)?
1468                    .clone();
1469                Some((l, adapter))
1470            });
1471            if let Some((language, adapter)) = language {
1472                let worktree = self.worktree_for_id(worktree_id, cx).ok();
1473                let root_file = worktree.as_ref().and_then(|worktree| {
1474                    worktree
1475                        .update(cx, |tree, cx| tree.root_file(cx))
1476                        .map(|f| f as _)
1477                });
1478                let settings = language_settings(Some(language.name()), root_file.as_ref(), cx);
1479                if !settings.enable_language_server {
1480                    language_servers_to_stop.push((worktree_id, started_lsp_name.clone()));
1481                } else if let Some(worktree) = worktree {
1482                    let server_name = &adapter.name;
1483                    match (
1484                        current_lsp_settings.get(server_name),
1485                        new_lsp_settings.get(server_name),
1486                    ) {
1487                        (None, None) => {}
1488                        (Some(_), None) | (None, Some(_)) => {
1489                            language_servers_to_restart.push((worktree, language.name()));
1490                        }
1491                        (Some(current_lsp_settings), Some(new_lsp_settings)) => {
1492                            if current_lsp_settings != new_lsp_settings {
1493                                language_servers_to_restart.push((worktree, language.name()));
1494                            }
1495                        }
1496                    }
1497                }
1498            }
1499        }
1500
1501        for (worktree_id, adapter_name) in language_servers_to_stop {
1502            self.stop_local_language_server(worktree_id, adapter_name, cx)
1503                .detach();
1504        }
1505
1506        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
1507            prettier_store.update(cx, |prettier_store, cx| {
1508                prettier_store.on_settings_changed(language_formatters_to_check, cx)
1509            })
1510        }
1511
1512        // Start all the newly-enabled language servers.
1513        for (worktree, language) in language_servers_to_start {
1514            self.start_language_servers(&worktree, language, cx);
1515        }
1516
1517        // Restart all language servers with changed initialization options.
1518        for (worktree, language) in language_servers_to_restart {
1519            self.restart_local_language_servers(worktree, language, cx);
1520        }
1521
1522        cx.notify();
1523    }
1524
1525    pub async fn execute_code_actions_on_servers(
1526        this: &WeakModel<LspStore>,
1527        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
1528        code_actions: Vec<lsp::CodeActionKind>,
1529        buffer: &Model<Buffer>,
1530        push_to_history: bool,
1531        project_transaction: &mut ProjectTransaction,
1532        cx: &mut AsyncAppContext,
1533    ) -> Result<(), anyhow::Error> {
1534        for (lsp_adapter, language_server) in adapters_and_servers.iter() {
1535            let code_actions = code_actions.clone();
1536
1537            let actions = this
1538                .update(cx, move |this, cx| {
1539                    let request = GetCodeActions {
1540                        range: text::Anchor::MIN..text::Anchor::MAX,
1541                        kinds: Some(code_actions),
1542                    };
1543                    let server = LanguageServerToQuery::Other(language_server.server_id());
1544                    this.request_lsp(buffer.clone(), server, request, cx)
1545                })?
1546                .await?;
1547
1548            for mut action in actions {
1549                Self::try_resolve_code_action(language_server, &mut action)
1550                    .await
1551                    .context("resolving a formatting code action")?;
1552
1553                if let Some(edit) = action.lsp_action.edit {
1554                    if edit.changes.is_none() && edit.document_changes.is_none() {
1555                        continue;
1556                    }
1557
1558                    let new = Self::deserialize_workspace_edit(
1559                        this.upgrade().ok_or_else(|| anyhow!("project dropped"))?,
1560                        edit,
1561                        push_to_history,
1562                        lsp_adapter.clone(),
1563                        language_server.clone(),
1564                        cx,
1565                    )
1566                    .await?;
1567                    project_transaction.0.extend(new.0);
1568                }
1569
1570                if let Some(command) = action.lsp_action.command {
1571                    this.update(cx, |this, _| {
1572                        if let LspStoreMode::Local(mode) = &mut this.mode {
1573                            mode.last_workspace_edits_by_language_server
1574                                .remove(&language_server.server_id());
1575                        }
1576                    })?;
1577
1578                    language_server
1579                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
1580                            command: command.command,
1581                            arguments: command.arguments.unwrap_or_default(),
1582                            ..Default::default()
1583                        })
1584                        .await?;
1585
1586                    this.update(cx, |this, _| {
1587                        if let LspStoreMode::Local(mode) = &mut this.mode {
1588                            project_transaction.0.extend(
1589                                mode.last_workspace_edits_by_language_server
1590                                    .remove(&language_server.server_id())
1591                                    .unwrap_or_default()
1592                                    .0,
1593                            )
1594                        }
1595                    })?;
1596                }
1597            }
1598        }
1599
1600        Ok(())
1601    }
1602
1603    async fn try_resolve_code_action(
1604        lang_server: &LanguageServer,
1605        action: &mut CodeAction,
1606    ) -> anyhow::Result<()> {
1607        if GetCodeActions::can_resolve_actions(&lang_server.capabilities())
1608            && action.lsp_action.data.is_some()
1609            && (action.lsp_action.command.is_none() || action.lsp_action.edit.is_none())
1610        {
1611            action.lsp_action = lang_server
1612                .request::<lsp::request::CodeActionResolveRequest>(action.lsp_action.clone())
1613                .await?;
1614        }
1615
1616        anyhow::Ok(())
1617    }
1618
1619    pub fn apply_code_action(
1620        &self,
1621        buffer_handle: Model<Buffer>,
1622        mut action: CodeAction,
1623        push_to_history: bool,
1624        cx: &mut ModelContext<Self>,
1625    ) -> Task<Result<ProjectTransaction>> {
1626        if let Some((upstream_client, project_id)) = self.upstream_client() {
1627            let request = proto::ApplyCodeAction {
1628                project_id,
1629                buffer_id: buffer_handle.read(cx).remote_id().into(),
1630                action: Some(Self::serialize_code_action(&action)),
1631            };
1632            let buffer_store = self.buffer_store();
1633            cx.spawn(move |_, mut cx| async move {
1634                let response = upstream_client
1635                    .request(request)
1636                    .await?
1637                    .transaction
1638                    .ok_or_else(|| anyhow!("missing transaction"))?;
1639
1640                buffer_store
1641                    .update(&mut cx, |buffer_store, cx| {
1642                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
1643                    })?
1644                    .await
1645            })
1646        } else {
1647            let buffer = buffer_handle.read(cx);
1648            let (lsp_adapter, lang_server) = if let Some((adapter, server)) =
1649                self.language_server_for_buffer(buffer, action.server_id, cx)
1650            {
1651                (adapter.clone(), server.clone())
1652            } else {
1653                return Task::ready(Ok(Default::default()));
1654            };
1655            cx.spawn(move |this, mut cx| async move {
1656                Self::try_resolve_code_action(&lang_server, &mut action)
1657                    .await
1658                    .context("resolving a code action")?;
1659                if let Some(edit) = action.lsp_action.edit {
1660                    if edit.changes.is_some() || edit.document_changes.is_some() {
1661                        return Self::deserialize_workspace_edit(
1662                            this.upgrade().ok_or_else(|| anyhow!("no app present"))?,
1663                            edit,
1664                            push_to_history,
1665                            lsp_adapter.clone(),
1666                            lang_server.clone(),
1667                            &mut cx,
1668                        )
1669                        .await;
1670                    }
1671                }
1672
1673                if let Some(command) = action.lsp_action.command {
1674                    this.update(&mut cx, |this, _| {
1675                        this.as_local_mut()
1676                            .unwrap()
1677                            .last_workspace_edits_by_language_server
1678                            .remove(&lang_server.server_id());
1679                    })?;
1680
1681                    let result = lang_server
1682                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
1683                            command: command.command,
1684                            arguments: command.arguments.unwrap_or_default(),
1685                            ..Default::default()
1686                        })
1687                        .await;
1688
1689                    result?;
1690
1691                    return this.update(&mut cx, |this, _| {
1692                        this.as_local_mut()
1693                            .unwrap()
1694                            .last_workspace_edits_by_language_server
1695                            .remove(&lang_server.server_id())
1696                            .unwrap_or_default()
1697                    });
1698                }
1699
1700                Ok(ProjectTransaction::default())
1701            })
1702        }
1703    }
1704
1705    pub fn resolve_inlay_hint(
1706        &self,
1707        hint: InlayHint,
1708        buffer_handle: Model<Buffer>,
1709        server_id: LanguageServerId,
1710        cx: &mut ModelContext<Self>,
1711    ) -> Task<anyhow::Result<InlayHint>> {
1712        if let Some((upstream_client, project_id)) = self.upstream_client() {
1713            let request = proto::ResolveInlayHint {
1714                project_id,
1715                buffer_id: buffer_handle.read(cx).remote_id().into(),
1716                language_server_id: server_id.0 as u64,
1717                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
1718            };
1719            cx.spawn(move |_, _| async move {
1720                let response = upstream_client
1721                    .request(request)
1722                    .await
1723                    .context("inlay hints proto request")?;
1724                match response.hint {
1725                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
1726                        .context("inlay hints proto resolve response conversion"),
1727                    None => Ok(hint),
1728                }
1729            })
1730        } else {
1731            let buffer = buffer_handle.read(cx);
1732            let (_, lang_server) = if let Some((adapter, server)) =
1733                self.language_server_for_buffer(buffer, server_id, cx)
1734            {
1735                (adapter.clone(), server.clone())
1736            } else {
1737                return Task::ready(Ok(hint));
1738            };
1739            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
1740                return Task::ready(Ok(hint));
1741            }
1742
1743            let buffer_snapshot = buffer.snapshot();
1744            cx.spawn(move |_, mut cx| async move {
1745                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
1746                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
1747                );
1748                let resolved_hint = resolve_task
1749                    .await
1750                    .context("inlay hint resolve LSP request")?;
1751                let resolved_hint = InlayHints::lsp_to_project_hint(
1752                    resolved_hint,
1753                    &buffer_handle,
1754                    server_id,
1755                    ResolveState::Resolved,
1756                    false,
1757                    &mut cx,
1758                )
1759                .await?;
1760                Ok(resolved_hint)
1761            })
1762        }
1763    }
1764
1765    pub(crate) fn linked_edit(
1766        &self,
1767        buffer: &Model<Buffer>,
1768        position: Anchor,
1769        cx: &mut ModelContext<Self>,
1770    ) -> Task<Result<Vec<Range<Anchor>>>> {
1771        let snapshot = buffer.read(cx).snapshot();
1772        let scope = snapshot.language_scope_at(position);
1773        let Some(server_id) = self
1774            .language_servers_for_buffer(buffer.read(cx), cx)
1775            .filter(|(_, server)| {
1776                server
1777                    .capabilities()
1778                    .linked_editing_range_provider
1779                    .is_some()
1780            })
1781            .filter(|(adapter, _)| {
1782                scope
1783                    .as_ref()
1784                    .map(|scope| scope.language_allowed(&adapter.name))
1785                    .unwrap_or(true)
1786            })
1787            .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
1788            .next()
1789            .or_else(|| {
1790                self.upstream_client()
1791                    .is_some()
1792                    .then_some(LanguageServerToQuery::Primary)
1793            })
1794            .filter(|_| {
1795                maybe!({
1796                    let language = buffer.read(cx).language_at(position)?;
1797                    Some(
1798                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
1799                            .linked_edits,
1800                    )
1801                }) == Some(true)
1802            })
1803        else {
1804            return Task::ready(Ok(vec![]));
1805        };
1806
1807        self.request_lsp(
1808            buffer.clone(),
1809            server_id,
1810            LinkedEditingRange { position },
1811            cx,
1812        )
1813    }
1814
1815    fn apply_on_type_formatting(
1816        &mut self,
1817        buffer: Model<Buffer>,
1818        position: Anchor,
1819        trigger: String,
1820        cx: &mut ModelContext<Self>,
1821    ) -> Task<Result<Option<Transaction>>> {
1822        if let Some((client, project_id)) = self.upstream_client() {
1823            let request = proto::OnTypeFormatting {
1824                project_id,
1825                buffer_id: buffer.read(cx).remote_id().into(),
1826                position: Some(serialize_anchor(&position)),
1827                trigger,
1828                version: serialize_version(&buffer.read(cx).version()),
1829            };
1830            cx.spawn(move |_, _| async move {
1831                client
1832                    .request(request)
1833                    .await?
1834                    .transaction
1835                    .map(language::proto::deserialize_transaction)
1836                    .transpose()
1837            })
1838        } else if let Some(local) = self.as_local_mut() {
1839            let buffer_id = buffer.read(cx).remote_id();
1840            local.buffers_being_formatted.insert(buffer_id);
1841            cx.spawn(move |this, mut cx| async move {
1842                let _cleanup = defer({
1843                    let this = this.clone();
1844                    let mut cx = cx.clone();
1845                    move || {
1846                        this.update(&mut cx, |this, _| {
1847                            if let Some(local) = this.as_local_mut() {
1848                                local.buffers_being_formatted.remove(&buffer_id);
1849                            }
1850                        })
1851                        .ok();
1852                    }
1853                });
1854
1855                buffer
1856                    .update(&mut cx, |buffer, _| {
1857                        buffer.wait_for_edits(Some(position.timestamp))
1858                    })?
1859                    .await?;
1860                this.update(&mut cx, |this, cx| {
1861                    let position = position.to_point_utf16(buffer.read(cx));
1862                    this.on_type_format(buffer, position, trigger, false, cx)
1863                })?
1864                .await
1865            })
1866        } else {
1867            Task::ready(Err(anyhow!("No upstream client or local language server")))
1868        }
1869    }
1870
1871    pub fn on_type_format<T: ToPointUtf16>(
1872        &mut self,
1873        buffer: Model<Buffer>,
1874        position: T,
1875        trigger: String,
1876        push_to_history: bool,
1877        cx: &mut ModelContext<Self>,
1878    ) -> Task<Result<Option<Transaction>>> {
1879        let position = position.to_point_utf16(buffer.read(cx));
1880        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
1881    }
1882
1883    fn on_type_format_impl(
1884        &mut self,
1885        buffer: Model<Buffer>,
1886        position: PointUtf16,
1887        trigger: String,
1888        push_to_history: bool,
1889        cx: &mut ModelContext<Self>,
1890    ) -> Task<Result<Option<Transaction>>> {
1891        let options = buffer.update(cx, |buffer, cx| {
1892            lsp_command::lsp_formatting_options(
1893                language_settings(
1894                    buffer.language_at(position).map(|l| l.name()),
1895                    buffer.file(),
1896                    cx,
1897                )
1898                .as_ref(),
1899            )
1900        });
1901        self.request_lsp(
1902            buffer.clone(),
1903            LanguageServerToQuery::Primary,
1904            OnTypeFormatting {
1905                position,
1906                trigger,
1907                options,
1908                push_to_history,
1909            },
1910            cx,
1911        )
1912    }
1913
1914    pub async fn format_via_lsp(
1915        this: &WeakModel<Self>,
1916        buffer: &Model<Buffer>,
1917        abs_path: &Path,
1918        language_server: &Arc<LanguageServer>,
1919        settings: &LanguageSettings,
1920        cx: &mut AsyncAppContext,
1921    ) -> Result<Vec<(Range<Anchor>, String)>> {
1922        let uri = lsp::Url::from_file_path(abs_path)
1923            .map_err(|_| anyhow!("failed to convert abs path to uri"))?;
1924        let text_document = lsp::TextDocumentIdentifier::new(uri);
1925        let capabilities = &language_server.capabilities();
1926
1927        let formatting_provider = capabilities.document_formatting_provider.as_ref();
1928        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
1929
1930        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
1931            language_server
1932                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
1933                    text_document,
1934                    options: lsp_command::lsp_formatting_options(settings),
1935                    work_done_progress_params: Default::default(),
1936                })
1937                .await?
1938        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
1939            let buffer_start = lsp::Position::new(0, 0);
1940            let buffer_end = buffer.update(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
1941            language_server
1942                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
1943                    text_document: text_document.clone(),
1944                    range: lsp::Range::new(buffer_start, buffer_end),
1945                    options: lsp_command::lsp_formatting_options(settings),
1946                    work_done_progress_params: Default::default(),
1947                })
1948                .await?
1949        } else {
1950            None
1951        };
1952
1953        if let Some(lsp_edits) = lsp_edits {
1954            this.update(cx, |this, cx| {
1955                this.edits_from_lsp(buffer, lsp_edits, language_server.server_id(), None, cx)
1956            })?
1957            .await
1958        } else {
1959            Ok(Vec::with_capacity(0))
1960        }
1961    }
1962    pub async fn format_range_via_lsp(
1963        this: &WeakModel<Self>,
1964        buffer: &Model<Buffer>,
1965        selections: &[Selection<Point>],
1966        abs_path: &Path,
1967        language_server: &Arc<LanguageServer>,
1968        settings: &LanguageSettings,
1969        cx: &mut AsyncAppContext,
1970    ) -> Result<Vec<(Range<Anchor>, String)>> {
1971        let capabilities = &language_server.capabilities();
1972        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
1973        if range_formatting_provider.map_or(false, |provider| provider == &OneOf::Left(false)) {
1974            return Err(anyhow!(
1975                "{} language server does not support range formatting",
1976                language_server.name()
1977            ));
1978        }
1979
1980        let uri = lsp::Url::from_file_path(abs_path)
1981            .map_err(|_| anyhow!("failed to convert abs path to uri"))?;
1982        let text_document = lsp::TextDocumentIdentifier::new(uri);
1983
1984        let lsp_edits = {
1985            let ranges = selections.into_iter().map(|s| {
1986                let start = lsp::Position::new(s.start.row, s.start.column);
1987                let end = lsp::Position::new(s.end.row, s.end.column);
1988                lsp::Range::new(start, end)
1989            });
1990
1991            let mut edits = None;
1992            for range in ranges {
1993                if let Some(mut edit) = language_server
1994                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
1995                        text_document: text_document.clone(),
1996                        range,
1997                        options: lsp_command::lsp_formatting_options(settings),
1998                        work_done_progress_params: Default::default(),
1999                    })
2000                    .await?
2001                {
2002                    edits.get_or_insert_with(Vec::new).append(&mut edit);
2003                }
2004            }
2005            edits
2006        };
2007
2008        if let Some(lsp_edits) = lsp_edits {
2009            this.update(cx, |this, cx| {
2010                this.edits_from_lsp(buffer, lsp_edits, language_server.server_id(), None, cx)
2011            })?
2012            .await
2013        } else {
2014            Ok(Vec::with_capacity(0))
2015        }
2016    }
2017
2018    pub fn code_actions(
2019        &mut self,
2020        buffer_handle: &Model<Buffer>,
2021        range: Range<Anchor>,
2022        kinds: Option<Vec<CodeActionKind>>,
2023        cx: &mut ModelContext<Self>,
2024    ) -> Task<Result<Vec<CodeAction>>> {
2025        if let Some((upstream_client, project_id)) = self.upstream_client() {
2026            let request_task = upstream_client.request(proto::MultiLspQuery {
2027                buffer_id: buffer_handle.read(cx).remote_id().into(),
2028                version: serialize_version(&buffer_handle.read(cx).version()),
2029                project_id,
2030                strategy: Some(proto::multi_lsp_query::Strategy::All(
2031                    proto::AllLanguageServers {},
2032                )),
2033                request: Some(proto::multi_lsp_query::Request::GetCodeActions(
2034                    GetCodeActions {
2035                        range: range.clone(),
2036                        kinds: kinds.clone(),
2037                    }
2038                    .to_proto(project_id, buffer_handle.read(cx)),
2039                )),
2040            });
2041            let buffer = buffer_handle.clone();
2042            cx.spawn(|weak_project, cx| async move {
2043                let Some(project) = weak_project.upgrade() else {
2044                    return Ok(Vec::new());
2045                };
2046                let responses = request_task.await?.responses;
2047                let actions = join_all(
2048                    responses
2049                        .into_iter()
2050                        .filter_map(|lsp_response| match lsp_response.response? {
2051                            proto::lsp_response::Response::GetCodeActionsResponse(response) => {
2052                                Some(response)
2053                            }
2054                            unexpected => {
2055                                debug_panic!("Unexpected response: {unexpected:?}");
2056                                None
2057                            }
2058                        })
2059                        .map(|code_actions_response| {
2060                            GetCodeActions {
2061                                range: range.clone(),
2062                                kinds: kinds.clone(),
2063                            }
2064                            .response_from_proto(
2065                                code_actions_response,
2066                                project.clone(),
2067                                buffer.clone(),
2068                                cx.clone(),
2069                            )
2070                        }),
2071                )
2072                .await;
2073
2074                Ok(actions
2075                    .into_iter()
2076                    .collect::<Result<Vec<Vec<_>>>>()?
2077                    .into_iter()
2078                    .flatten()
2079                    .collect())
2080            })
2081        } else {
2082            let all_actions_task = self.request_multiple_lsp_locally(
2083                buffer_handle,
2084                Some(range.start),
2085                GetCodeActions {
2086                    range: range.clone(),
2087                    kinds: kinds.clone(),
2088                },
2089                cx,
2090            );
2091            cx.spawn(
2092                |_, _| async move { Ok(all_actions_task.await.into_iter().flatten().collect()) },
2093            )
2094        }
2095    }
2096
2097    #[inline(never)]
2098    pub fn completions(
2099        &self,
2100        buffer: &Model<Buffer>,
2101        position: PointUtf16,
2102        context: CompletionContext,
2103        cx: &mut ModelContext<Self>,
2104    ) -> Task<Result<Vec<Completion>>> {
2105        let language_registry = self.languages.clone();
2106
2107        if let Some((upstream_client, project_id)) = self.upstream_client() {
2108            let task = self.send_lsp_proto_request(
2109                buffer.clone(),
2110                upstream_client,
2111                project_id,
2112                GetCompletions { position, context },
2113                cx,
2114            );
2115            let language = buffer.read(cx).language().cloned();
2116
2117            // In the future, we should provide project guests with the names of LSP adapters,
2118            // so that they can use the correct LSP adapter when computing labels. For now,
2119            // guests just use the first LSP adapter associated with the buffer's language.
2120            let lsp_adapter = language.as_ref().and_then(|language| {
2121                language_registry
2122                    .lsp_adapters(&language.name())
2123                    .first()
2124                    .cloned()
2125            });
2126
2127            cx.foreground_executor().spawn(async move {
2128                let completions = task.await?;
2129                let mut result = Vec::new();
2130                populate_labels_for_completions(
2131                    completions,
2132                    &language_registry,
2133                    language,
2134                    lsp_adapter,
2135                    &mut result,
2136                )
2137                .await;
2138                Ok(result)
2139            })
2140        } else {
2141            let snapshot = buffer.read(cx).snapshot();
2142            let offset = position.to_offset(&snapshot);
2143            let scope = snapshot.language_scope_at(offset);
2144            let language = snapshot.language().cloned();
2145
2146            let server_ids: Vec<_> = self
2147                .language_servers_for_buffer(buffer.read(cx), cx)
2148                .filter(|(_, server)| server.capabilities().completion_provider.is_some())
2149                .filter(|(adapter, _)| {
2150                    scope
2151                        .as_ref()
2152                        .map(|scope| scope.language_allowed(&adapter.name))
2153                        .unwrap_or(true)
2154                })
2155                .map(|(_, server)| server.server_id())
2156                .collect();
2157
2158            let buffer = buffer.clone();
2159            cx.spawn(move |this, mut cx| async move {
2160                let mut tasks = Vec::with_capacity(server_ids.len());
2161                this.update(&mut cx, |this, cx| {
2162                    for server_id in server_ids {
2163                        let lsp_adapter = this.language_server_adapter_for_id(server_id);
2164                        tasks.push((
2165                            lsp_adapter,
2166                            this.request_lsp(
2167                                buffer.clone(),
2168                                LanguageServerToQuery::Other(server_id),
2169                                GetCompletions {
2170                                    position,
2171                                    context: context.clone(),
2172                                },
2173                                cx,
2174                            ),
2175                        ));
2176                    }
2177                })?;
2178
2179                let mut completions = Vec::new();
2180                for (lsp_adapter, task) in tasks {
2181                    if let Ok(new_completions) = task.await {
2182                        populate_labels_for_completions(
2183                            new_completions,
2184                            &language_registry,
2185                            language.clone(),
2186                            lsp_adapter,
2187                            &mut completions,
2188                        )
2189                        .await;
2190                    }
2191                }
2192
2193                Ok(completions)
2194            })
2195        }
2196    }
2197
2198    pub fn resolve_completions(
2199        &self,
2200        buffer: Model<Buffer>,
2201        completion_indices: Vec<usize>,
2202        completions: Arc<RwLock<Box<[Completion]>>>,
2203        cx: &mut ModelContext<Self>,
2204    ) -> Task<Result<bool>> {
2205        let client = self.upstream_client();
2206        let language_registry = self.languages.clone();
2207
2208        let buffer_id = buffer.read(cx).remote_id();
2209        let buffer_snapshot = buffer.read(cx).snapshot();
2210
2211        cx.spawn(move |this, cx| async move {
2212            let mut did_resolve = false;
2213            if let Some((client, project_id)) = client {
2214                for completion_index in completion_indices {
2215                    let (server_id, completion) = {
2216                        let completions_guard = completions.read();
2217                        let completion = &completions_guard[completion_index];
2218                        did_resolve = true;
2219                        let server_id = completion.server_id;
2220                        let completion = completion.lsp_completion.clone();
2221
2222                        (server_id, completion)
2223                    };
2224
2225                    Self::resolve_completion_remote(
2226                        project_id,
2227                        server_id,
2228                        buffer_id,
2229                        completions.clone(),
2230                        completion_index,
2231                        completion,
2232                        client.clone(),
2233                        language_registry.clone(),
2234                    )
2235                    .await;
2236                }
2237            } else {
2238                for completion_index in completion_indices {
2239                    let (server_id, completion) = {
2240                        let completions_guard = completions.read();
2241                        let completion = &completions_guard[completion_index];
2242                        let server_id = completion.server_id;
2243                        let completion = completion.lsp_completion.clone();
2244
2245                        (server_id, completion)
2246                    };
2247
2248                    let server_and_adapter = this
2249                        .read_with(&cx, |lsp_store, _| {
2250                            let server = lsp_store.language_server_for_id(server_id)?;
2251                            let adapter =
2252                                lsp_store.language_server_adapter_for_id(server.server_id())?;
2253                            Some((server, adapter))
2254                        })
2255                        .ok()
2256                        .flatten();
2257                    let Some((server, adapter)) = server_and_adapter else {
2258                        continue;
2259                    };
2260
2261                    did_resolve = true;
2262                    Self::resolve_completion_local(
2263                        server,
2264                        adapter,
2265                        &buffer_snapshot,
2266                        completions.clone(),
2267                        completion_index,
2268                        completion,
2269                        language_registry.clone(),
2270                    )
2271                    .await;
2272                }
2273            }
2274
2275            Ok(did_resolve)
2276        })
2277    }
2278
2279    async fn resolve_completion_local(
2280        server: Arc<lsp::LanguageServer>,
2281        adapter: Arc<CachedLspAdapter>,
2282        snapshot: &BufferSnapshot,
2283        completions: Arc<RwLock<Box<[Completion]>>>,
2284        completion_index: usize,
2285        completion: lsp::CompletionItem,
2286        language_registry: Arc<LanguageRegistry>,
2287    ) {
2288        let can_resolve = server
2289            .capabilities()
2290            .completion_provider
2291            .as_ref()
2292            .and_then(|options| options.resolve_provider)
2293            .unwrap_or(false);
2294        if !can_resolve {
2295            return;
2296        }
2297
2298        let request = server.request::<lsp::request::ResolveCompletionItem>(completion);
2299        let Some(completion_item) = request.await.log_err() else {
2300            return;
2301        };
2302
2303        if let Some(lsp_documentation) = completion_item.documentation.as_ref() {
2304            let documentation = language::prepare_completion_documentation(
2305                lsp_documentation,
2306                &language_registry,
2307                snapshot.language().cloned(),
2308            )
2309            .await;
2310
2311            let mut completions = completions.write();
2312            let completion = &mut completions[completion_index];
2313            completion.documentation = Some(documentation);
2314        } else {
2315            let mut completions = completions.write();
2316            let completion = &mut completions[completion_index];
2317            completion.documentation = Some(Documentation::Undocumented);
2318        }
2319
2320        if let Some(text_edit) = completion_item.text_edit.as_ref() {
2321            // Technically we don't have to parse the whole `text_edit`, since the only
2322            // language server we currently use that does update `text_edit` in `completionItem/resolve`
2323            // is `typescript-language-server` and they only update `text_edit.new_text`.
2324            // But we should not rely on that.
2325            let edit = parse_completion_text_edit(text_edit, snapshot);
2326
2327            if let Some((old_range, mut new_text)) = edit {
2328                LineEnding::normalize(&mut new_text);
2329
2330                let mut completions = completions.write();
2331                let completion = &mut completions[completion_index];
2332
2333                completion.new_text = new_text;
2334                completion.old_range = old_range;
2335            }
2336        }
2337        if completion_item.insert_text_format == Some(InsertTextFormat::SNIPPET) {
2338            // vtsls might change the type of completion after resolution.
2339            let mut completions = completions.write();
2340            let completion = &mut completions[completion_index];
2341            if completion_item.insert_text_format != completion.lsp_completion.insert_text_format {
2342                completion.lsp_completion.insert_text_format = completion_item.insert_text_format;
2343            }
2344        }
2345
2346        // NB: Zed does not have `details` inside the completion resolve capabilities, but certain language servers violate the spec and do not return `details` immediately, e.g. https://github.com/yioneko/vtsls/issues/213
2347        // So we have to update the label here anyway...
2348        let new_label = match snapshot.language() {
2349            Some(language) => adapter
2350                .labels_for_completions(&[completion_item.clone()], language)
2351                .await
2352                .log_err()
2353                .unwrap_or_default(),
2354            None => Vec::new(),
2355        }
2356        .pop()
2357        .flatten()
2358        .unwrap_or_else(|| {
2359            CodeLabel::plain(
2360                completion_item.label.clone(),
2361                completion_item.filter_text.as_deref(),
2362            )
2363        });
2364
2365        let mut completions = completions.write();
2366        let completion = &mut completions[completion_index];
2367        completion.lsp_completion = completion_item;
2368        completion.label = new_label;
2369    }
2370
2371    #[allow(clippy::too_many_arguments)]
2372    async fn resolve_completion_remote(
2373        project_id: u64,
2374        server_id: LanguageServerId,
2375        buffer_id: BufferId,
2376        completions: Arc<RwLock<Box<[Completion]>>>,
2377        completion_index: usize,
2378        completion: lsp::CompletionItem,
2379        client: AnyProtoClient,
2380        language_registry: Arc<LanguageRegistry>,
2381    ) {
2382        let request = proto::ResolveCompletionDocumentation {
2383            project_id,
2384            language_server_id: server_id.0 as u64,
2385            lsp_completion: serde_json::to_string(&completion).unwrap().into_bytes(),
2386            buffer_id: buffer_id.into(),
2387        };
2388
2389        let Some(response) = client
2390            .request(request)
2391            .await
2392            .context("completion documentation resolve proto request")
2393            .log_err()
2394        else {
2395            return;
2396        };
2397        let Some(lsp_completion) = serde_json::from_slice(&response.lsp_completion).log_err()
2398        else {
2399            return;
2400        };
2401
2402        let documentation = if response.documentation.is_empty() {
2403            Documentation::Undocumented
2404        } else if response.documentation_is_markdown {
2405            Documentation::MultiLineMarkdown(
2406                markdown::parse_markdown(&response.documentation, &language_registry, None).await,
2407            )
2408        } else if response.documentation.lines().count() <= 1 {
2409            Documentation::SingleLine(response.documentation)
2410        } else {
2411            Documentation::MultiLinePlainText(response.documentation)
2412        };
2413
2414        let mut completions = completions.write();
2415        let completion = &mut completions[completion_index];
2416        completion.documentation = Some(documentation);
2417        completion.lsp_completion = lsp_completion;
2418
2419        let old_range = response
2420            .old_start
2421            .and_then(deserialize_anchor)
2422            .zip(response.old_end.and_then(deserialize_anchor));
2423        if let Some((old_start, old_end)) = old_range {
2424            if !response.new_text.is_empty() {
2425                completion.new_text = response.new_text;
2426                completion.old_range = old_start..old_end;
2427            }
2428        }
2429    }
2430
2431    pub fn apply_additional_edits_for_completion(
2432        &self,
2433        buffer_handle: Model<Buffer>,
2434        completion: Completion,
2435        push_to_history: bool,
2436        cx: &mut ModelContext<Self>,
2437    ) -> Task<Result<Option<Transaction>>> {
2438        let buffer = buffer_handle.read(cx);
2439        let buffer_id = buffer.remote_id();
2440
2441        if let Some((client, project_id)) = self.upstream_client() {
2442            cx.spawn(move |_, mut cx| async move {
2443                let response = client
2444                    .request(proto::ApplyCompletionAdditionalEdits {
2445                        project_id,
2446                        buffer_id: buffer_id.into(),
2447                        completion: Some(Self::serialize_completion(&CoreCompletion {
2448                            old_range: completion.old_range,
2449                            new_text: completion.new_text,
2450                            server_id: completion.server_id,
2451                            lsp_completion: completion.lsp_completion,
2452                        })),
2453                    })
2454                    .await?;
2455
2456                if let Some(transaction) = response.transaction {
2457                    let transaction = language::proto::deserialize_transaction(transaction)?;
2458                    buffer_handle
2459                        .update(&mut cx, |buffer, _| {
2460                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
2461                        })?
2462                        .await?;
2463                    if push_to_history {
2464                        buffer_handle.update(&mut cx, |buffer, _| {
2465                            buffer.push_transaction(transaction.clone(), Instant::now());
2466                        })?;
2467                    }
2468                    Ok(Some(transaction))
2469                } else {
2470                    Ok(None)
2471                }
2472            })
2473        } else {
2474            let server_id = completion.server_id;
2475            let lang_server = match self.language_server_for_buffer(buffer, server_id, cx) {
2476                Some((_, server)) => server.clone(),
2477                _ => return Task::ready(Ok(Default::default())),
2478            };
2479
2480            cx.spawn(move |this, mut cx| async move {
2481                let can_resolve = lang_server
2482                    .capabilities()
2483                    .completion_provider
2484                    .as_ref()
2485                    .and_then(|options| options.resolve_provider)
2486                    .unwrap_or(false);
2487                let additional_text_edits = if can_resolve {
2488                    lang_server
2489                        .request::<lsp::request::ResolveCompletionItem>(completion.lsp_completion)
2490                        .await?
2491                        .additional_text_edits
2492                } else {
2493                    completion.lsp_completion.additional_text_edits
2494                };
2495                if let Some(edits) = additional_text_edits {
2496                    let edits = this
2497                        .update(&mut cx, |this, cx| {
2498                            this.edits_from_lsp(
2499                                &buffer_handle,
2500                                edits,
2501                                lang_server.server_id(),
2502                                None,
2503                                cx,
2504                            )
2505                        })?
2506                        .await?;
2507
2508                    buffer_handle.update(&mut cx, |buffer, cx| {
2509                        buffer.finalize_last_transaction();
2510                        buffer.start_transaction();
2511
2512                        for (range, text) in edits {
2513                            let primary = &completion.old_range;
2514                            let start_within = primary.start.cmp(&range.start, buffer).is_le()
2515                                && primary.end.cmp(&range.start, buffer).is_ge();
2516                            let end_within = range.start.cmp(&primary.end, buffer).is_le()
2517                                && range.end.cmp(&primary.end, buffer).is_ge();
2518
2519                            //Skip additional edits which overlap with the primary completion edit
2520                            //https://github.com/zed-industries/zed/pull/1871
2521                            if !start_within && !end_within {
2522                                buffer.edit([(range, text)], None, cx);
2523                            }
2524                        }
2525
2526                        let transaction = if buffer.end_transaction(cx).is_some() {
2527                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
2528                            if !push_to_history {
2529                                buffer.forget_transaction(transaction.id);
2530                            }
2531                            Some(transaction)
2532                        } else {
2533                            None
2534                        };
2535                        Ok(transaction)
2536                    })?
2537                } else {
2538                    Ok(None)
2539                }
2540            })
2541        }
2542    }
2543
2544    pub fn inlay_hints(
2545        &mut self,
2546        buffer_handle: Model<Buffer>,
2547        range: Range<Anchor>,
2548        cx: &mut ModelContext<Self>,
2549    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
2550        let buffer = buffer_handle.read(cx);
2551        let range_start = range.start;
2552        let range_end = range.end;
2553        let buffer_id = buffer.remote_id().into();
2554        let lsp_request = InlayHints { range };
2555
2556        if let Some((client, project_id)) = self.upstream_client() {
2557            let request = proto::InlayHints {
2558                project_id,
2559                buffer_id,
2560                start: Some(serialize_anchor(&range_start)),
2561                end: Some(serialize_anchor(&range_end)),
2562                version: serialize_version(&buffer_handle.read(cx).version()),
2563            };
2564            cx.spawn(move |project, cx| async move {
2565                let response = client
2566                    .request(request)
2567                    .await
2568                    .context("inlay hints proto request")?;
2569                LspCommand::response_from_proto(
2570                    lsp_request,
2571                    response,
2572                    project.upgrade().ok_or_else(|| anyhow!("No project"))?,
2573                    buffer_handle.clone(),
2574                    cx.clone(),
2575                )
2576                .await
2577                .context("inlay hints proto response conversion")
2578            })
2579        } else {
2580            let lsp_request_task = self.request_lsp(
2581                buffer_handle.clone(),
2582                LanguageServerToQuery::Primary,
2583                lsp_request,
2584                cx,
2585            );
2586            cx.spawn(move |_, mut cx| async move {
2587                buffer_handle
2588                    .update(&mut cx, |buffer, _| {
2589                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
2590                    })?
2591                    .await
2592                    .context("waiting for inlay hint request range edits")?;
2593                lsp_request_task.await.context("inlay hints LSP request")
2594            })
2595        }
2596    }
2597
2598    pub fn signature_help<T: ToPointUtf16>(
2599        &self,
2600        buffer: &Model<Buffer>,
2601        position: T,
2602        cx: &mut ModelContext<Self>,
2603    ) -> Task<Vec<SignatureHelp>> {
2604        let position = position.to_point_utf16(buffer.read(cx));
2605
2606        if let Some((client, upstream_project_id)) = self.upstream_client() {
2607            let request_task = client.request(proto::MultiLspQuery {
2608                buffer_id: buffer.read(cx).remote_id().into(),
2609                version: serialize_version(&buffer.read(cx).version()),
2610                project_id: upstream_project_id,
2611                strategy: Some(proto::multi_lsp_query::Strategy::All(
2612                    proto::AllLanguageServers {},
2613                )),
2614                request: Some(proto::multi_lsp_query::Request::GetSignatureHelp(
2615                    GetSignatureHelp { position }.to_proto(upstream_project_id, buffer.read(cx)),
2616                )),
2617            });
2618            let buffer = buffer.clone();
2619            cx.spawn(|weak_project, cx| async move {
2620                let Some(project) = weak_project.upgrade() else {
2621                    return Vec::new();
2622                };
2623                join_all(
2624                    request_task
2625                        .await
2626                        .log_err()
2627                        .map(|response| response.responses)
2628                        .unwrap_or_default()
2629                        .into_iter()
2630                        .filter_map(|lsp_response| match lsp_response.response? {
2631                            proto::lsp_response::Response::GetSignatureHelpResponse(response) => {
2632                                Some(response)
2633                            }
2634                            unexpected => {
2635                                debug_panic!("Unexpected response: {unexpected:?}");
2636                                None
2637                            }
2638                        })
2639                        .map(|signature_response| {
2640                            let response = GetSignatureHelp { position }.response_from_proto(
2641                                signature_response,
2642                                project.clone(),
2643                                buffer.clone(),
2644                                cx.clone(),
2645                            );
2646                            async move { response.await.log_err().flatten() }
2647                        }),
2648                )
2649                .await
2650                .into_iter()
2651                .flatten()
2652                .collect()
2653            })
2654        } else {
2655            let all_actions_task = self.request_multiple_lsp_locally(
2656                buffer,
2657                Some(position),
2658                GetSignatureHelp { position },
2659                cx,
2660            );
2661            cx.spawn(|_, _| async move {
2662                all_actions_task
2663                    .await
2664                    .into_iter()
2665                    .flatten()
2666                    .filter(|help| !help.markdown.is_empty())
2667                    .collect::<Vec<_>>()
2668            })
2669        }
2670    }
2671
2672    pub fn hover(
2673        &self,
2674        buffer: &Model<Buffer>,
2675        position: PointUtf16,
2676        cx: &mut ModelContext<Self>,
2677    ) -> Task<Vec<Hover>> {
2678        if let Some((client, upstream_project_id)) = self.upstream_client() {
2679            let request_task = client.request(proto::MultiLspQuery {
2680                buffer_id: buffer.read(cx).remote_id().into(),
2681                version: serialize_version(&buffer.read(cx).version()),
2682                project_id: upstream_project_id,
2683                strategy: Some(proto::multi_lsp_query::Strategy::All(
2684                    proto::AllLanguageServers {},
2685                )),
2686                request: Some(proto::multi_lsp_query::Request::GetHover(
2687                    GetHover { position }.to_proto(upstream_project_id, buffer.read(cx)),
2688                )),
2689            });
2690            let buffer = buffer.clone();
2691            cx.spawn(|weak_project, cx| async move {
2692                let Some(project) = weak_project.upgrade() else {
2693                    return Vec::new();
2694                };
2695                join_all(
2696                    request_task
2697                        .await
2698                        .log_err()
2699                        .map(|response| response.responses)
2700                        .unwrap_or_default()
2701                        .into_iter()
2702                        .filter_map(|lsp_response| match lsp_response.response? {
2703                            proto::lsp_response::Response::GetHoverResponse(response) => {
2704                                Some(response)
2705                            }
2706                            unexpected => {
2707                                debug_panic!("Unexpected response: {unexpected:?}");
2708                                None
2709                            }
2710                        })
2711                        .map(|hover_response| {
2712                            let response = GetHover { position }.response_from_proto(
2713                                hover_response,
2714                                project.clone(),
2715                                buffer.clone(),
2716                                cx.clone(),
2717                            );
2718                            async move {
2719                                response
2720                                    .await
2721                                    .log_err()
2722                                    .flatten()
2723                                    .and_then(remove_empty_hover_blocks)
2724                            }
2725                        }),
2726                )
2727                .await
2728                .into_iter()
2729                .flatten()
2730                .collect()
2731            })
2732        } else {
2733            let all_actions_task = self.request_multiple_lsp_locally(
2734                buffer,
2735                Some(position),
2736                GetHover { position },
2737                cx,
2738            );
2739            cx.spawn(|_, _| async move {
2740                all_actions_task
2741                    .await
2742                    .into_iter()
2743                    .filter_map(|hover| remove_empty_hover_blocks(hover?))
2744                    .collect::<Vec<Hover>>()
2745            })
2746        }
2747    }
2748
2749    pub fn symbols(&self, query: &str, cx: &mut ModelContext<Self>) -> Task<Result<Vec<Symbol>>> {
2750        let language_registry = self.languages.clone();
2751
2752        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
2753            let request = upstream_client.request(proto::GetProjectSymbols {
2754                project_id: *project_id,
2755                query: query.to_string(),
2756            });
2757            cx.foreground_executor().spawn(async move {
2758                let response = request.await?;
2759                let mut symbols = Vec::new();
2760                let core_symbols = response
2761                    .symbols
2762                    .into_iter()
2763                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
2764                    .collect::<Vec<_>>();
2765                populate_labels_for_symbols(
2766                    core_symbols,
2767                    &language_registry,
2768                    None,
2769                    None,
2770                    &mut symbols,
2771                )
2772                .await;
2773                Ok(symbols)
2774            })
2775        } else {
2776            struct WorkspaceSymbolsResult {
2777                lsp_adapter: Arc<CachedLspAdapter>,
2778                language: LanguageName,
2779                worktree: WeakModel<Worktree>,
2780                worktree_abs_path: Arc<Path>,
2781                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
2782            }
2783
2784            let mut requests = Vec::new();
2785            for ((worktree_id, _), server_id) in self.language_server_ids.iter() {
2786                let Some(worktree_handle) = self
2787                    .worktree_store
2788                    .read(cx)
2789                    .worktree_for_id(*worktree_id, cx)
2790                else {
2791                    continue;
2792                };
2793                let worktree = worktree_handle.read(cx);
2794                if !worktree.is_visible() {
2795                    continue;
2796                }
2797                let worktree_abs_path = worktree.abs_path().clone();
2798
2799                let (lsp_adapter, language, server) =
2800                    match self.as_local().unwrap().language_servers.get(server_id) {
2801                        Some(LanguageServerState::Running {
2802                            adapter,
2803                            language,
2804                            server,
2805                            ..
2806                        }) => (adapter.clone(), language.clone(), server),
2807
2808                        _ => continue,
2809                    };
2810
2811                requests.push(
2812                        server
2813                            .request::<lsp::request::WorkspaceSymbolRequest>(
2814                                lsp::WorkspaceSymbolParams {
2815                                    query: query.to_string(),
2816                                    ..Default::default()
2817                                },
2818                            )
2819                            .log_err()
2820                            .map(move |response| {
2821                                let lsp_symbols = response.flatten().map(|symbol_response| match symbol_response {
2822                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
2823                                        flat_responses.into_iter().map(|lsp_symbol| {
2824                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
2825                                        }).collect::<Vec<_>>()
2826                                    }
2827                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
2828                                        nested_responses.into_iter().filter_map(|lsp_symbol| {
2829                                            let location = match lsp_symbol.location {
2830                                                OneOf::Left(location) => location,
2831                                                OneOf::Right(_) => {
2832                                                    log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
2833                                                    return None
2834                                                }
2835                                            };
2836                                            Some((lsp_symbol.name, lsp_symbol.kind, location))
2837                                        }).collect::<Vec<_>>()
2838                                    }
2839                                }).unwrap_or_default();
2840
2841                                WorkspaceSymbolsResult {
2842                                    lsp_adapter,
2843                                    language,
2844                                    worktree: worktree_handle.downgrade(),
2845                                    worktree_abs_path,
2846                                    lsp_symbols,
2847                                }
2848                            }),
2849                    );
2850            }
2851
2852            cx.spawn(move |this, mut cx| async move {
2853                let responses = futures::future::join_all(requests).await;
2854                let this = match this.upgrade() {
2855                    Some(this) => this,
2856                    None => return Ok(Vec::new()),
2857                };
2858
2859                let mut symbols = Vec::new();
2860                for result in responses {
2861                    let core_symbols = this.update(&mut cx, |this, cx| {
2862                        result
2863                            .lsp_symbols
2864                            .into_iter()
2865                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
2866                                let abs_path = symbol_location.uri.to_file_path().ok()?;
2867                                let source_worktree = result.worktree.upgrade()?;
2868                                let source_worktree_id = source_worktree.read(cx).id();
2869
2870                                let path;
2871                                let worktree;
2872                                if let Some((tree, rel_path)) =
2873                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
2874                                {
2875                                    worktree = tree;
2876                                    path = rel_path;
2877                                } else {
2878                                    worktree = source_worktree.clone();
2879                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
2880                                }
2881
2882                                let worktree_id = worktree.read(cx).id();
2883                                let project_path = ProjectPath {
2884                                    worktree_id,
2885                                    path: path.into(),
2886                                };
2887                                let signature = this.symbol_signature(&project_path);
2888                                Some(CoreSymbol {
2889                                    language_server_name: result.lsp_adapter.name.clone(),
2890                                    source_worktree_id,
2891                                    path: project_path,
2892                                    kind: symbol_kind,
2893                                    name: symbol_name,
2894                                    range: range_from_lsp(symbol_location.range),
2895                                    signature,
2896                                })
2897                            })
2898                            .collect()
2899                    })?;
2900
2901                    populate_labels_for_symbols(
2902                        core_symbols,
2903                        &language_registry,
2904                        Some(result.language),
2905                        Some(result.lsp_adapter),
2906                        &mut symbols,
2907                    )
2908                    .await;
2909                }
2910
2911                Ok(symbols)
2912            })
2913        }
2914    }
2915
2916    pub fn diagnostic_summaries<'a>(
2917        &'a self,
2918        include_ignored: bool,
2919        cx: &'a AppContext,
2920    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
2921        self.worktree_store
2922            .read(cx)
2923            .visible_worktrees(cx)
2924            .filter_map(|worktree| {
2925                let worktree = worktree.read(cx);
2926                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
2927            })
2928            .flat_map(move |(worktree, summaries)| {
2929                let worktree_id = worktree.id();
2930                summaries
2931                    .iter()
2932                    .filter(move |(path, _)| {
2933                        include_ignored
2934                            || worktree
2935                                .entry_for_path(path.as_ref())
2936                                .map_or(false, |entry| !entry.is_ignored)
2937                    })
2938                    .flat_map(move |(path, summaries)| {
2939                        summaries.iter().map(move |(server_id, summary)| {
2940                            (
2941                                ProjectPath {
2942                                    worktree_id,
2943                                    path: path.clone(),
2944                                },
2945                                *server_id,
2946                                *summary,
2947                            )
2948                        })
2949                    })
2950            })
2951    }
2952
2953    pub fn diagnostics_for_buffer(
2954        &self,
2955        path: &ProjectPath,
2956    ) -> Option<
2957        &[(
2958            LanguageServerId,
2959            Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
2960        )],
2961    > {
2962        self.diagnostics
2963            .get(&path.worktree_id)?
2964            .get(&path.path)
2965            .map(|diagnostics| diagnostics.as_slice())
2966    }
2967
2968    pub fn started_language_servers(&self) -> Vec<(WorktreeId, LanguageServerName)> {
2969        self.language_server_ids.keys().cloned().collect()
2970    }
2971
2972    pub fn on_buffer_edited(
2973        &mut self,
2974        buffer: Model<Buffer>,
2975        cx: &mut ModelContext<Self>,
2976    ) -> Option<()> {
2977        let buffer = buffer.read(cx);
2978        let file = File::from_dyn(buffer.file())?;
2979        let abs_path = file.as_local()?.abs_path(cx);
2980        let uri = lsp::Url::from_file_path(abs_path).unwrap();
2981        let next_snapshot = buffer.text_snapshot();
2982
2983        let language_servers: Vec<_> = self
2984            .language_servers_for_buffer(buffer, cx)
2985            .map(|i| i.1.clone())
2986            .collect();
2987
2988        for language_server in language_servers {
2989            let language_server = language_server.clone();
2990
2991            let buffer_snapshots = self
2992                .buffer_snapshots
2993                .get_mut(&buffer.remote_id())
2994                .and_then(|m| m.get_mut(&language_server.server_id()))?;
2995            let previous_snapshot = buffer_snapshots.last()?;
2996
2997            let build_incremental_change = || {
2998                buffer
2999                    .edits_since::<(PointUtf16, usize)>(previous_snapshot.snapshot.version())
3000                    .map(|edit| {
3001                        let edit_start = edit.new.start.0;
3002                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
3003                        let new_text = next_snapshot
3004                            .text_for_range(edit.new.start.1..edit.new.end.1)
3005                            .collect();
3006                        lsp::TextDocumentContentChangeEvent {
3007                            range: Some(lsp::Range::new(
3008                                point_to_lsp(edit_start),
3009                                point_to_lsp(edit_end),
3010                            )),
3011                            range_length: None,
3012                            text: new_text,
3013                        }
3014                    })
3015                    .collect()
3016            };
3017
3018            let document_sync_kind = language_server
3019                .capabilities()
3020                .text_document_sync
3021                .as_ref()
3022                .and_then(|sync| match sync {
3023                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
3024                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
3025                });
3026
3027            let content_changes: Vec<_> = match document_sync_kind {
3028                Some(lsp::TextDocumentSyncKind::FULL) => {
3029                    vec![lsp::TextDocumentContentChangeEvent {
3030                        range: None,
3031                        range_length: None,
3032                        text: next_snapshot.text(),
3033                    }]
3034                }
3035                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
3036                _ => {
3037                    #[cfg(any(test, feature = "test-support"))]
3038                    {
3039                        build_incremental_change()
3040                    }
3041
3042                    #[cfg(not(any(test, feature = "test-support")))]
3043                    {
3044                        continue;
3045                    }
3046                }
3047            };
3048
3049            let next_version = previous_snapshot.version + 1;
3050            buffer_snapshots.push(LspBufferSnapshot {
3051                version: next_version,
3052                snapshot: next_snapshot.clone(),
3053            });
3054
3055            language_server
3056                .notify::<lsp::notification::DidChangeTextDocument>(
3057                    lsp::DidChangeTextDocumentParams {
3058                        text_document: lsp::VersionedTextDocumentIdentifier::new(
3059                            uri.clone(),
3060                            next_version,
3061                        ),
3062                        content_changes,
3063                    },
3064                )
3065                .log_err();
3066        }
3067
3068        None
3069    }
3070
3071    pub fn on_buffer_saved(
3072        &mut self,
3073        buffer: Model<Buffer>,
3074        cx: &mut ModelContext<Self>,
3075    ) -> Option<()> {
3076        let file = File::from_dyn(buffer.read(cx).file())?;
3077        let worktree_id = file.worktree_id(cx);
3078        let abs_path = file.as_local()?.abs_path(cx);
3079        let text_document = lsp::TextDocumentIdentifier {
3080            uri: lsp::Url::from_file_path(abs_path).log_err()?,
3081        };
3082
3083        for server in self.language_servers_for_worktree(worktree_id) {
3084            if let Some(include_text) = include_text(server.as_ref()) {
3085                let text = if include_text {
3086                    Some(buffer.read(cx).text())
3087                } else {
3088                    None
3089                };
3090                server
3091                    .notify::<lsp::notification::DidSaveTextDocument>(
3092                        lsp::DidSaveTextDocumentParams {
3093                            text_document: text_document.clone(),
3094                            text,
3095                        },
3096                    )
3097                    .log_err();
3098            }
3099        }
3100
3101        for language_server_id in self.language_server_ids_for_buffer(buffer.read(cx), cx) {
3102            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
3103        }
3104
3105        None
3106    }
3107
3108    pub(crate) async fn refresh_workspace_configurations(
3109        this: &WeakModel<Self>,
3110        mut cx: AsyncAppContext,
3111    ) {
3112        maybe!(async move {
3113            let servers = this
3114                .update(&mut cx, |this, cx| {
3115                    this.language_server_ids
3116                        .iter()
3117                        .filter_map(|((worktree_id, _), server_id)| {
3118                            let worktree = this
3119                                .worktree_store
3120                                .read(cx)
3121                                .worktree_for_id(*worktree_id, cx)?;
3122                            let state = this.as_local()?.language_servers.get(server_id)?;
3123                            let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
3124                            match state {
3125                                LanguageServerState::Starting(_) => None,
3126                                LanguageServerState::Running {
3127                                    adapter, server, ..
3128                                } => Some((
3129                                    adapter.adapter.clone(),
3130                                    server.clone(),
3131                                    delegate as Arc<dyn LspAdapterDelegate>,
3132                                )),
3133                            }
3134                        })
3135                        .collect::<Vec<_>>()
3136                })
3137                .ok()?;
3138
3139            let toolchain_store = this
3140                .update(&mut cx, |this, cx| this.toolchain_store(cx))
3141                .ok()?;
3142            for (adapter, server, delegate) in servers {
3143                let settings = adapter
3144                    .workspace_configuration(&delegate, toolchain_store.clone(), &mut cx)
3145                    .await
3146                    .ok()?;
3147
3148                server
3149                    .notify::<lsp::notification::DidChangeConfiguration>(
3150                        lsp::DidChangeConfigurationParams { settings },
3151                    )
3152                    .ok();
3153            }
3154            Some(())
3155        })
3156        .await;
3157    }
3158
3159    fn toolchain_store(&self, cx: &AppContext) -> Arc<dyn LanguageToolchainStore> {
3160        if let Some(toolchain_store) = self.toolchain_store.as_ref() {
3161            toolchain_store.read(cx).as_language_toolchain_store()
3162        } else {
3163            Arc::new(EmptyToolchainStore)
3164        }
3165    }
3166    fn maintain_workspace_config(
3167        external_refresh_requests: watch::Receiver<()>,
3168        cx: &mut ModelContext<Self>,
3169    ) -> Task<Result<()>> {
3170        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
3171        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
3172
3173        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
3174            *settings_changed_tx.borrow_mut() = ();
3175        });
3176
3177        let mut joint_future =
3178            futures::stream::select(settings_changed_rx, external_refresh_requests);
3179        cx.spawn(move |this, cx| async move {
3180            while let Some(()) = joint_future.next().await {
3181                Self::refresh_workspace_configurations(&this, cx.clone()).await;
3182            }
3183
3184            drop(settings_observation);
3185            anyhow::Ok(())
3186        })
3187    }
3188
3189    fn primary_language_server_for_buffer<'a>(
3190        &'a self,
3191        buffer: &'a Buffer,
3192        cx: &'a AppContext,
3193    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
3194        // The list of language servers is ordered based on the `language_servers` setting
3195        // for each language, thus we can consider the first one in the list to be the
3196        // primary one.
3197        self.language_servers_for_buffer(buffer, cx).next()
3198    }
3199
3200    pub fn language_server_for_buffer<'a>(
3201        &'a self,
3202        buffer: &'a Buffer,
3203        server_id: LanguageServerId,
3204        cx: &'a AppContext,
3205    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
3206        self.language_servers_for_buffer(buffer, cx)
3207            .find(|(_, s)| s.server_id() == server_id)
3208    }
3209
3210    fn language_servers_for_worktree(
3211        &self,
3212        worktree_id: WorktreeId,
3213    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
3214        self.language_server_ids
3215            .iter()
3216            .filter_map(move |((language_server_worktree_id, _), id)| {
3217                if *language_server_worktree_id == worktree_id {
3218                    if let Some(LanguageServerState::Running { server, .. }) =
3219                        self.as_local()?.language_servers.get(id)
3220                    {
3221                        return Some(server);
3222                    }
3223                }
3224                None
3225            })
3226    }
3227
3228    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut ModelContext<Self>) {
3229        self.diagnostics.remove(&id_to_remove);
3230        self.diagnostic_summaries.remove(&id_to_remove);
3231
3232        let mut servers_to_remove = HashMap::default();
3233        let mut servers_to_preserve = HashSet::default();
3234        for ((worktree_id, server_name), &server_id) in &self.language_server_ids {
3235            if worktree_id == &id_to_remove {
3236                servers_to_remove.insert(server_id, server_name.clone());
3237            } else {
3238                servers_to_preserve.insert(server_id);
3239            }
3240        }
3241        servers_to_remove.retain(|server_id, _| !servers_to_preserve.contains(server_id));
3242        for (server_id_to_remove, server_name) in servers_to_remove {
3243            self.language_server_ids
3244                .remove(&(id_to_remove, server_name));
3245            self.language_server_statuses.remove(&server_id_to_remove);
3246            if let Some(local_lsp_store) = self.as_local_mut() {
3247                local_lsp_store
3248                    .language_server_watched_paths
3249                    .remove(&server_id_to_remove);
3250                local_lsp_store
3251                    .last_workspace_edits_by_language_server
3252                    .remove(&server_id_to_remove);
3253                local_lsp_store
3254                    .language_servers
3255                    .remove(&server_id_to_remove);
3256            }
3257            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id_to_remove));
3258        }
3259
3260        if let Some(local) = self.as_local() {
3261            local.prettier_store.update(cx, |prettier_store, cx| {
3262                prettier_store.remove_worktree(id_to_remove, cx);
3263            })
3264        }
3265    }
3266
3267    pub fn shared(
3268        &mut self,
3269        project_id: u64,
3270        downstream_client: AnyProtoClient,
3271        _: &mut ModelContext<Self>,
3272    ) {
3273        self.downstream_client = Some((downstream_client.clone(), project_id));
3274
3275        for (server_id, status) in &self.language_server_statuses {
3276            downstream_client
3277                .send(proto::StartLanguageServer {
3278                    project_id,
3279                    server: Some(proto::LanguageServer {
3280                        id: server_id.0 as u64,
3281                        name: status.name.clone(),
3282                        worktree_id: None,
3283                    }),
3284                })
3285                .log_err();
3286        }
3287    }
3288
3289    pub fn disconnected_from_host(&mut self) {
3290        self.downstream_client.take();
3291    }
3292
3293    pub fn disconnected_from_ssh_remote(&mut self) {
3294        if let LspStoreMode::Remote(RemoteLspStore {
3295            upstream_client, ..
3296        }) = &mut self.mode
3297        {
3298            upstream_client.take();
3299        }
3300    }
3301
3302    pub(crate) fn set_language_server_statuses_from_proto(
3303        &mut self,
3304        language_servers: Vec<proto::LanguageServer>,
3305    ) {
3306        self.language_server_statuses = language_servers
3307            .into_iter()
3308            .map(|server| {
3309                (
3310                    LanguageServerId(server.id as usize),
3311                    LanguageServerStatus {
3312                        name: server.name,
3313                        pending_work: Default::default(),
3314                        has_pending_diagnostic_updates: false,
3315                        progress_tokens: Default::default(),
3316                    },
3317                )
3318            })
3319            .collect();
3320    }
3321
3322    pub(crate) fn register_language_server(
3323        &mut self,
3324        worktree_id: WorktreeId,
3325        language_server_name: LanguageServerName,
3326        language_server_id: LanguageServerId,
3327    ) {
3328        self.language_server_ids
3329            .insert((worktree_id, language_server_name), language_server_id);
3330    }
3331
3332    #[track_caller]
3333    pub(crate) fn register_buffer_with_language_servers(
3334        &mut self,
3335        buffer_handle: &Model<Buffer>,
3336        cx: &mut ModelContext<Self>,
3337    ) {
3338        let available_language = self.detect_language_for_buffer(buffer_handle, cx);
3339
3340        let buffer = buffer_handle.read(cx);
3341        let buffer_id = buffer.remote_id();
3342
3343        if let Some(file) = File::from_dyn(buffer.file()) {
3344            if !file.is_local() {
3345                return;
3346            }
3347
3348            let abs_path = file.abs_path(cx);
3349            let Some(uri) = lsp::Url::from_file_path(&abs_path).log_err() else {
3350                return;
3351            };
3352            let initial_snapshot = buffer.text_snapshot();
3353            let worktree_id = file.worktree_id(cx);
3354
3355            if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
3356                for (server_id, diagnostics) in
3357                    diagnostics.get(file.path()).cloned().unwrap_or_default()
3358                {
3359                    self.update_buffer_diagnostics(buffer_handle, server_id, None, diagnostics, cx)
3360                        .log_err();
3361                }
3362            }
3363
3364            if let Some(language) = available_language {
3365                for adapter in self.languages.lsp_adapters(&language.name()) {
3366                    let server = self
3367                        .language_server_ids
3368                        .get(&(worktree_id, adapter.name.clone()))
3369                        .and_then(|id| self.as_local()?.language_servers.get(id))
3370                        .and_then(|server_state| {
3371                            if let LanguageServerState::Running { server, .. } = server_state {
3372                                Some(server.clone())
3373                            } else {
3374                                None
3375                            }
3376                        });
3377                    let server = match server {
3378                        Some(server) => server,
3379                        None => continue,
3380                    };
3381
3382                    server
3383                        .notify::<lsp::notification::DidOpenTextDocument>(
3384                            lsp::DidOpenTextDocumentParams {
3385                                text_document: lsp::TextDocumentItem::new(
3386                                    uri.clone(),
3387                                    adapter.language_id(&language.name()),
3388                                    0,
3389                                    initial_snapshot.text(),
3390                                ),
3391                            },
3392                        )
3393                        .log_err();
3394
3395                    buffer_handle.update(cx, |buffer, cx| {
3396                        buffer.set_completion_triggers(
3397                            server.server_id(),
3398                            server
3399                                .capabilities()
3400                                .completion_provider
3401                                .as_ref()
3402                                .and_then(|provider| {
3403                                    provider
3404                                        .trigger_characters
3405                                        .as_ref()
3406                                        .map(|characters| characters.iter().cloned().collect())
3407                                })
3408                                .unwrap_or_default(),
3409                            cx,
3410                        );
3411                    });
3412
3413                    let snapshot = LspBufferSnapshot {
3414                        version: 0,
3415                        snapshot: initial_snapshot.clone(),
3416                    };
3417                    self.buffer_snapshots
3418                        .entry(buffer_id)
3419                        .or_default()
3420                        .insert(server.server_id(), vec![snapshot]);
3421                }
3422            }
3423        }
3424    }
3425
3426    pub(crate) fn unregister_buffer_from_language_servers(
3427        &mut self,
3428        buffer: &Model<Buffer>,
3429        old_file: &File,
3430        cx: &mut AppContext,
3431    ) {
3432        let old_path = match old_file.as_local() {
3433            Some(local) => local.abs_path(cx),
3434            None => return,
3435        };
3436
3437        buffer.update(cx, |buffer, cx| {
3438            let worktree_id = old_file.worktree_id(cx);
3439
3440            let ids = &self.language_server_ids;
3441
3442            if let Some(language) = buffer.language().cloned() {
3443                for adapter in self.languages.lsp_adapters(&language.name()) {
3444                    if let Some(server_id) = ids.get(&(worktree_id, adapter.name.clone())) {
3445                        buffer.update_diagnostics(*server_id, DiagnosticSet::new([], buffer), cx);
3446                        buffer.set_completion_triggers(*server_id, Default::default(), cx);
3447                    }
3448                }
3449            }
3450
3451            self.buffer_snapshots.remove(&buffer.remote_id());
3452            let file_url = lsp::Url::from_file_path(old_path).unwrap();
3453            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
3454                language_server
3455                    .notify::<lsp::notification::DidCloseTextDocument>(
3456                        lsp::DidCloseTextDocumentParams {
3457                            text_document: lsp::TextDocumentIdentifier::new(file_url.clone()),
3458                        },
3459                    )
3460                    .log_err();
3461            }
3462        });
3463    }
3464
3465    pub fn update_diagnostic_entries(
3466        &mut self,
3467        server_id: LanguageServerId,
3468        abs_path: PathBuf,
3469        version: Option<i32>,
3470        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
3471        cx: &mut ModelContext<Self>,
3472    ) -> Result<(), anyhow::Error> {
3473        let Some((worktree, relative_path)) =
3474            self.worktree_store.read(cx).find_worktree(&abs_path, cx)
3475        else {
3476            log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
3477            return Ok(());
3478        };
3479
3480        let project_path = ProjectPath {
3481            worktree_id: worktree.read(cx).id(),
3482            path: relative_path.into(),
3483        };
3484
3485        if let Some(buffer) = self.buffer_store.read(cx).get_by_path(&project_path, cx) {
3486            self.update_buffer_diagnostics(&buffer, server_id, version, diagnostics.clone(), cx)?;
3487        }
3488
3489        let updated = worktree.update(cx, |worktree, cx| {
3490            self.update_worktree_diagnostics(
3491                worktree.id(),
3492                server_id,
3493                project_path.path.clone(),
3494                diagnostics,
3495                cx,
3496            )
3497        })?;
3498        if updated {
3499            cx.emit(LspStoreEvent::DiagnosticsUpdated {
3500                language_server_id: server_id,
3501                path: project_path,
3502            })
3503        }
3504        Ok(())
3505    }
3506
3507    fn update_worktree_diagnostics(
3508        &mut self,
3509        worktree_id: WorktreeId,
3510        server_id: LanguageServerId,
3511        worktree_path: Arc<Path>,
3512        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
3513        _: &mut ModelContext<Worktree>,
3514    ) -> Result<bool> {
3515        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
3516        let diagnostics_for_tree = self.diagnostics.entry(worktree_id).or_default();
3517        let summaries_by_server_id = summaries_for_tree.entry(worktree_path.clone()).or_default();
3518
3519        let old_summary = summaries_by_server_id
3520            .remove(&server_id)
3521            .unwrap_or_default();
3522
3523        let new_summary = DiagnosticSummary::new(&diagnostics);
3524        if new_summary.is_empty() {
3525            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&worktree_path) {
3526                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
3527                    diagnostics_by_server_id.remove(ix);
3528                }
3529                if diagnostics_by_server_id.is_empty() {
3530                    diagnostics_for_tree.remove(&worktree_path);
3531                }
3532            }
3533        } else {
3534            summaries_by_server_id.insert(server_id, new_summary);
3535            let diagnostics_by_server_id = diagnostics_for_tree
3536                .entry(worktree_path.clone())
3537                .or_default();
3538            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
3539                Ok(ix) => {
3540                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
3541                }
3542                Err(ix) => {
3543                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
3544                }
3545            }
3546        }
3547
3548        if !old_summary.is_empty() || !new_summary.is_empty() {
3549            if let Some((downstream_client, project_id)) = &self.downstream_client {
3550                downstream_client
3551                    .send(proto::UpdateDiagnosticSummary {
3552                        project_id: *project_id,
3553                        worktree_id: worktree_id.to_proto(),
3554                        summary: Some(proto::DiagnosticSummary {
3555                            path: worktree_path.to_string_lossy().to_string(),
3556                            language_server_id: server_id.0 as u64,
3557                            error_count: new_summary.error_count as u32,
3558                            warning_count: new_summary.warning_count as u32,
3559                        }),
3560                    })
3561                    .log_err();
3562            }
3563        }
3564
3565        Ok(!old_summary.is_empty() || !new_summary.is_empty())
3566    }
3567
3568    pub fn open_buffer_for_symbol(
3569        &mut self,
3570        symbol: &Symbol,
3571        cx: &mut ModelContext<Self>,
3572    ) -> Task<Result<Model<Buffer>>> {
3573        if let Some((client, project_id)) = self.upstream_client() {
3574            let request = client.request(proto::OpenBufferForSymbol {
3575                project_id,
3576                symbol: Some(Self::serialize_symbol(symbol)),
3577            });
3578            cx.spawn(move |this, mut cx| async move {
3579                let response = request.await?;
3580                let buffer_id = BufferId::new(response.buffer_id)?;
3581                this.update(&mut cx, |this, cx| {
3582                    this.wait_for_remote_buffer(buffer_id, cx)
3583                })?
3584                .await
3585            })
3586        } else {
3587            let Some(&language_server_id) = self.language_server_ids.get(&(
3588                symbol.source_worktree_id,
3589                symbol.language_server_name.clone(),
3590            )) else {
3591                return Task::ready(Err(anyhow!(
3592                    "language server for worktree and language not found"
3593                )));
3594            };
3595
3596            let worktree_abs_path = if let Some(worktree_abs_path) = self
3597                .worktree_store
3598                .read(cx)
3599                .worktree_for_id(symbol.path.worktree_id, cx)
3600                .map(|worktree| worktree.read(cx).abs_path())
3601            {
3602                worktree_abs_path
3603            } else {
3604                return Task::ready(Err(anyhow!("worktree not found for symbol")));
3605            };
3606
3607            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
3608            let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
3609                uri
3610            } else {
3611                return Task::ready(Err(anyhow!("invalid symbol path")));
3612            };
3613
3614            self.open_local_buffer_via_lsp(
3615                symbol_uri,
3616                language_server_id,
3617                symbol.language_server_name.clone(),
3618                cx,
3619            )
3620        }
3621    }
3622
3623    pub fn open_local_buffer_via_lsp(
3624        &mut self,
3625        mut abs_path: lsp::Url,
3626        language_server_id: LanguageServerId,
3627        language_server_name: LanguageServerName,
3628        cx: &mut ModelContext<Self>,
3629    ) -> Task<Result<Model<Buffer>>> {
3630        cx.spawn(move |lsp_store, mut cx| async move {
3631            // Escape percent-encoded string.
3632            let current_scheme = abs_path.scheme().to_owned();
3633            let _ = abs_path.set_scheme("file");
3634
3635            let abs_path = abs_path
3636                .to_file_path()
3637                .map_err(|_| anyhow!("can't convert URI to path"))?;
3638            let p = abs_path.clone();
3639            let yarn_worktree = lsp_store
3640                .update(&mut cx, move |lsp_store, cx| match lsp_store.as_local() {
3641                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
3642                        cx.spawn(|this, mut cx| async move {
3643                            let t = this
3644                                .update(&mut cx, |this, cx| {
3645                                    this.process_path(&p, &current_scheme, cx)
3646                                })
3647                                .ok()?;
3648                            t.await
3649                        })
3650                    }),
3651                    None => Task::ready(None),
3652                })?
3653                .await;
3654            let (worktree_root_target, known_relative_path) =
3655                if let Some((zip_root, relative_path)) = yarn_worktree {
3656                    (zip_root, Some(relative_path))
3657                } else {
3658                    (Arc::<Path>::from(abs_path.as_path()), None)
3659                };
3660            let (worktree, relative_path) = if let Some(result) =
3661                lsp_store.update(&mut cx, |lsp_store, cx| {
3662                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
3663                        worktree_store.find_worktree(&worktree_root_target, cx)
3664                    })
3665                })? {
3666                let relative_path =
3667                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
3668                (result.0, relative_path)
3669            } else {
3670                let worktree = lsp_store
3671                    .update(&mut cx, |lsp_store, cx| {
3672                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
3673                            worktree_store.create_worktree(&worktree_root_target, false, cx)
3674                        })
3675                    })?
3676                    .await?;
3677                if worktree.update(&mut cx, |worktree, _| worktree.is_local())? {
3678                    lsp_store
3679                        .update(&mut cx, |lsp_store, cx| {
3680                            lsp_store.register_language_server(
3681                                worktree.read(cx).id(),
3682                                language_server_name,
3683                                language_server_id,
3684                            )
3685                        })
3686                        .ok();
3687                }
3688                let worktree_root = worktree.update(&mut cx, |worktree, _| worktree.abs_path())?;
3689                let relative_path = if let Some(known_path) = known_relative_path {
3690                    known_path
3691                } else {
3692                    abs_path.strip_prefix(worktree_root)?.into()
3693                };
3694                (worktree, relative_path)
3695            };
3696            let project_path = ProjectPath {
3697                worktree_id: worktree.update(&mut cx, |worktree, _| worktree.id())?,
3698                path: relative_path,
3699            };
3700            lsp_store
3701                .update(&mut cx, |lsp_store, cx| {
3702                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
3703                        buffer_store.open_buffer(project_path, cx)
3704                    })
3705                })?
3706                .await
3707        })
3708    }
3709
3710    pub(crate) fn update_buffer_diagnostics(
3711        &mut self,
3712        buffer: &Model<Buffer>,
3713        server_id: LanguageServerId,
3714        version: Option<i32>,
3715        mut diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
3716        cx: &mut ModelContext<Self>,
3717    ) -> Result<()> {
3718        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
3719            Ordering::Equal
3720                .then_with(|| b.is_primary.cmp(&a.is_primary))
3721                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
3722                .then_with(|| a.severity.cmp(&b.severity))
3723                .then_with(|| a.message.cmp(&b.message))
3724        }
3725
3726        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
3727
3728        diagnostics.sort_unstable_by(|a, b| {
3729            Ordering::Equal
3730                .then_with(|| a.range.start.cmp(&b.range.start))
3731                .then_with(|| b.range.end.cmp(&a.range.end))
3732                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
3733        });
3734
3735        let mut sanitized_diagnostics = Vec::new();
3736        let edits_since_save = Patch::new(
3737            snapshot
3738                .edits_since::<Unclipped<PointUtf16>>(buffer.read(cx).saved_version())
3739                .collect(),
3740        );
3741        for entry in diagnostics {
3742            let start;
3743            let end;
3744            if entry.diagnostic.is_disk_based {
3745                // Some diagnostics are based on files on disk instead of buffers'
3746                // current contents. Adjust these diagnostics' ranges to reflect
3747                // any unsaved edits.
3748                start = edits_since_save.old_to_new(entry.range.start);
3749                end = edits_since_save.old_to_new(entry.range.end);
3750            } else {
3751                start = entry.range.start;
3752                end = entry.range.end;
3753            }
3754
3755            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
3756                ..snapshot.clip_point_utf16(end, Bias::Right);
3757
3758            // Expand empty ranges by one codepoint
3759            if range.start == range.end {
3760                // This will be go to the next boundary when being clipped
3761                range.end.column += 1;
3762                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
3763                if range.start == range.end && range.end.column > 0 {
3764                    range.start.column -= 1;
3765                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
3766                }
3767            }
3768
3769            sanitized_diagnostics.push(DiagnosticEntry {
3770                range,
3771                diagnostic: entry.diagnostic,
3772            });
3773        }
3774        drop(edits_since_save);
3775
3776        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
3777        buffer.update(cx, |buffer, cx| {
3778            buffer.update_diagnostics(server_id, set, cx)
3779        });
3780        Ok(())
3781    }
3782
3783    fn request_multiple_lsp_locally<P, R>(
3784        &self,
3785        buffer: &Model<Buffer>,
3786        position: Option<P>,
3787        request: R,
3788        cx: &mut ModelContext<'_, Self>,
3789    ) -> Task<Vec<R::Response>>
3790    where
3791        P: ToOffset,
3792        R: LspCommand + Clone,
3793        <R::LspRequest as lsp::request::Request>::Result: Send,
3794        <R::LspRequest as lsp::request::Request>::Params: Send,
3795    {
3796        debug_assert!(self.upstream_client().is_none());
3797
3798        let snapshot = buffer.read(cx).snapshot();
3799        let scope = position.and_then(|position| snapshot.language_scope_at(position));
3800        let server_ids = self
3801            .language_servers_for_buffer(buffer.read(cx), cx)
3802            .filter(|(adapter, _)| {
3803                scope
3804                    .as_ref()
3805                    .map(|scope| scope.language_allowed(&adapter.name))
3806                    .unwrap_or(true)
3807            })
3808            .map(|(_, server)| server.server_id())
3809            .collect::<Vec<_>>();
3810
3811        let mut response_results = server_ids
3812            .into_iter()
3813            .map(|server_id| {
3814                self.request_lsp(
3815                    buffer.clone(),
3816                    LanguageServerToQuery::Other(server_id),
3817                    request.clone(),
3818                    cx,
3819                )
3820            })
3821            .collect::<FuturesUnordered<_>>();
3822
3823        cx.spawn(|_, _| async move {
3824            let mut responses = Vec::with_capacity(response_results.len());
3825            while let Some(response_result) = response_results.next().await {
3826                if let Some(response) = response_result.log_err() {
3827                    responses.push(response);
3828                }
3829            }
3830            responses
3831        })
3832    }
3833
3834    async fn handle_lsp_command<T: LspCommand>(
3835        this: Model<Self>,
3836        envelope: TypedEnvelope<T::ProtoRequest>,
3837        mut cx: AsyncAppContext,
3838    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
3839    where
3840        <T::LspRequest as lsp::request::Request>::Params: Send,
3841        <T::LspRequest as lsp::request::Request>::Result: Send,
3842    {
3843        let sender_id = envelope.original_sender_id().unwrap_or_default();
3844        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
3845        let buffer_handle = this.update(&mut cx, |this, cx| {
3846            this.buffer_store.read(cx).get_existing(buffer_id)
3847        })??;
3848        let request = T::from_proto(
3849            envelope.payload,
3850            this.clone(),
3851            buffer_handle.clone(),
3852            cx.clone(),
3853        )
3854        .await?;
3855        let response = this
3856            .update(&mut cx, |this, cx| {
3857                this.request_lsp(
3858                    buffer_handle.clone(),
3859                    LanguageServerToQuery::Primary,
3860                    request,
3861                    cx,
3862                )
3863            })?
3864            .await?;
3865        this.update(&mut cx, |this, cx| {
3866            Ok(T::response_to_proto(
3867                response,
3868                this,
3869                sender_id,
3870                &buffer_handle.read(cx).version(),
3871                cx,
3872            ))
3873        })?
3874    }
3875
3876    async fn handle_multi_lsp_query(
3877        this: Model<Self>,
3878        envelope: TypedEnvelope<proto::MultiLspQuery>,
3879        mut cx: AsyncAppContext,
3880    ) -> Result<proto::MultiLspQueryResponse> {
3881        let response_from_ssh = this.update(&mut cx, |this, _| {
3882            let (upstream_client, project_id) = this.upstream_client()?;
3883            let mut payload = envelope.payload.clone();
3884            payload.project_id = project_id;
3885
3886            Some(upstream_client.request(payload))
3887        })?;
3888        if let Some(response_from_ssh) = response_from_ssh {
3889            return response_from_ssh.await;
3890        }
3891
3892        let sender_id = envelope.original_sender_id().unwrap_or_default();
3893        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
3894        let version = deserialize_version(&envelope.payload.version);
3895        let buffer = this.update(&mut cx, |this, cx| {
3896            this.buffer_store.read(cx).get_existing(buffer_id)
3897        })??;
3898        buffer
3899            .update(&mut cx, |buffer, _| {
3900                buffer.wait_for_version(version.clone())
3901            })?
3902            .await?;
3903        let buffer_version = buffer.update(&mut cx, |buffer, _| buffer.version())?;
3904        match envelope
3905            .payload
3906            .strategy
3907            .context("invalid request without the strategy")?
3908        {
3909            proto::multi_lsp_query::Strategy::All(_) => {
3910                // currently, there's only one multiple language servers query strategy,
3911                // so just ensure it's specified correctly
3912            }
3913        }
3914        match envelope.payload.request {
3915            Some(proto::multi_lsp_query::Request::GetHover(get_hover)) => {
3916                let get_hover =
3917                    GetHover::from_proto(get_hover, this.clone(), buffer.clone(), cx.clone())
3918                        .await?;
3919                let all_hovers = this
3920                    .update(&mut cx, |this, cx| {
3921                        this.request_multiple_lsp_locally(
3922                            &buffer,
3923                            Some(get_hover.position),
3924                            get_hover,
3925                            cx,
3926                        )
3927                    })?
3928                    .await
3929                    .into_iter()
3930                    .filter_map(|hover| remove_empty_hover_blocks(hover?));
3931                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
3932                    responses: all_hovers
3933                        .map(|hover| proto::LspResponse {
3934                            response: Some(proto::lsp_response::Response::GetHoverResponse(
3935                                GetHover::response_to_proto(
3936                                    Some(hover),
3937                                    project,
3938                                    sender_id,
3939                                    &buffer_version,
3940                                    cx,
3941                                ),
3942                            )),
3943                        })
3944                        .collect(),
3945                })
3946            }
3947            Some(proto::multi_lsp_query::Request::GetCodeActions(get_code_actions)) => {
3948                let get_code_actions = GetCodeActions::from_proto(
3949                    get_code_actions,
3950                    this.clone(),
3951                    buffer.clone(),
3952                    cx.clone(),
3953                )
3954                .await?;
3955
3956                let all_actions = this
3957                    .update(&mut cx, |project, cx| {
3958                        project.request_multiple_lsp_locally(
3959                            &buffer,
3960                            Some(get_code_actions.range.start),
3961                            get_code_actions,
3962                            cx,
3963                        )
3964                    })?
3965                    .await
3966                    .into_iter();
3967
3968                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
3969                    responses: all_actions
3970                        .map(|code_actions| proto::LspResponse {
3971                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
3972                                GetCodeActions::response_to_proto(
3973                                    code_actions,
3974                                    project,
3975                                    sender_id,
3976                                    &buffer_version,
3977                                    cx,
3978                                ),
3979                            )),
3980                        })
3981                        .collect(),
3982                })
3983            }
3984            Some(proto::multi_lsp_query::Request::GetSignatureHelp(get_signature_help)) => {
3985                let get_signature_help = GetSignatureHelp::from_proto(
3986                    get_signature_help,
3987                    this.clone(),
3988                    buffer.clone(),
3989                    cx.clone(),
3990                )
3991                .await?;
3992
3993                let all_signatures = this
3994                    .update(&mut cx, |project, cx| {
3995                        project.request_multiple_lsp_locally(
3996                            &buffer,
3997                            Some(get_signature_help.position),
3998                            get_signature_help,
3999                            cx,
4000                        )
4001                    })?
4002                    .await
4003                    .into_iter();
4004
4005                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
4006                    responses: all_signatures
4007                        .map(|signature_help| proto::LspResponse {
4008                            response: Some(
4009                                proto::lsp_response::Response::GetSignatureHelpResponse(
4010                                    GetSignatureHelp::response_to_proto(
4011                                        signature_help,
4012                                        project,
4013                                        sender_id,
4014                                        &buffer_version,
4015                                        cx,
4016                                    ),
4017                                ),
4018                            ),
4019                        })
4020                        .collect(),
4021                })
4022            }
4023            None => anyhow::bail!("empty multi lsp query request"),
4024        }
4025    }
4026
4027    async fn handle_apply_code_action(
4028        this: Model<Self>,
4029        envelope: TypedEnvelope<proto::ApplyCodeAction>,
4030        mut cx: AsyncAppContext,
4031    ) -> Result<proto::ApplyCodeActionResponse> {
4032        let sender_id = envelope.original_sender_id().unwrap_or_default();
4033        let action = Self::deserialize_code_action(
4034            envelope
4035                .payload
4036                .action
4037                .ok_or_else(|| anyhow!("invalid action"))?,
4038        )?;
4039        let apply_code_action = this.update(&mut cx, |this, cx| {
4040            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
4041            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
4042            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
4043        })??;
4044
4045        let project_transaction = apply_code_action.await?;
4046        let project_transaction = this.update(&mut cx, |this, cx| {
4047            this.buffer_store.update(cx, |buffer_store, cx| {
4048                buffer_store.serialize_project_transaction_for_peer(
4049                    project_transaction,
4050                    sender_id,
4051                    cx,
4052                )
4053            })
4054        })?;
4055        Ok(proto::ApplyCodeActionResponse {
4056            transaction: Some(project_transaction),
4057        })
4058    }
4059
4060    async fn handle_update_diagnostic_summary(
4061        this: Model<Self>,
4062        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
4063        mut cx: AsyncAppContext,
4064    ) -> Result<()> {
4065        this.update(&mut cx, |this, cx| {
4066            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
4067            if let Some(message) = envelope.payload.summary {
4068                let project_path = ProjectPath {
4069                    worktree_id,
4070                    path: Path::new(&message.path).into(),
4071                };
4072                let path = project_path.path.clone();
4073                let server_id = LanguageServerId(message.language_server_id as usize);
4074                let summary = DiagnosticSummary {
4075                    error_count: message.error_count as usize,
4076                    warning_count: message.warning_count as usize,
4077                };
4078
4079                if summary.is_empty() {
4080                    if let Some(worktree_summaries) =
4081                        this.diagnostic_summaries.get_mut(&worktree_id)
4082                    {
4083                        if let Some(summaries) = worktree_summaries.get_mut(&path) {
4084                            summaries.remove(&server_id);
4085                            if summaries.is_empty() {
4086                                worktree_summaries.remove(&path);
4087                            }
4088                        }
4089                    }
4090                } else {
4091                    this.diagnostic_summaries
4092                        .entry(worktree_id)
4093                        .or_default()
4094                        .entry(path)
4095                        .or_default()
4096                        .insert(server_id, summary);
4097                }
4098                if let Some((downstream_client, project_id)) = &this.downstream_client {
4099                    downstream_client
4100                        .send(proto::UpdateDiagnosticSummary {
4101                            project_id: *project_id,
4102                            worktree_id: worktree_id.to_proto(),
4103                            summary: Some(proto::DiagnosticSummary {
4104                                path: project_path.path.to_string_lossy().to_string(),
4105                                language_server_id: server_id.0 as u64,
4106                                error_count: summary.error_count as u32,
4107                                warning_count: summary.warning_count as u32,
4108                            }),
4109                        })
4110                        .log_err();
4111                }
4112                cx.emit(LspStoreEvent::DiagnosticsUpdated {
4113                    language_server_id: LanguageServerId(message.language_server_id as usize),
4114                    path: project_path,
4115                });
4116            }
4117            Ok(())
4118        })?
4119    }
4120
4121    async fn handle_start_language_server(
4122        this: Model<Self>,
4123        envelope: TypedEnvelope<proto::StartLanguageServer>,
4124        mut cx: AsyncAppContext,
4125    ) -> Result<()> {
4126        let server = envelope
4127            .payload
4128            .server
4129            .ok_or_else(|| anyhow!("invalid server"))?;
4130
4131        this.update(&mut cx, |this, cx| {
4132            let server_id = LanguageServerId(server.id as usize);
4133            this.language_server_statuses.insert(
4134                server_id,
4135                LanguageServerStatus {
4136                    name: server.name.clone(),
4137                    pending_work: Default::default(),
4138                    has_pending_diagnostic_updates: false,
4139                    progress_tokens: Default::default(),
4140                },
4141            );
4142            cx.emit(LspStoreEvent::LanguageServerAdded(
4143                server_id,
4144                LanguageServerName(server.name.into()),
4145                server.worktree_id.map(WorktreeId::from_proto),
4146            ));
4147            cx.notify();
4148        })?;
4149        Ok(())
4150    }
4151
4152    async fn handle_update_language_server(
4153        this: Model<Self>,
4154        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
4155        mut cx: AsyncAppContext,
4156    ) -> Result<()> {
4157        this.update(&mut cx, |this, cx| {
4158            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
4159
4160            match envelope
4161                .payload
4162                .variant
4163                .ok_or_else(|| anyhow!("invalid variant"))?
4164            {
4165                proto::update_language_server::Variant::WorkStart(payload) => {
4166                    this.on_lsp_work_start(
4167                        language_server_id,
4168                        payload.token,
4169                        LanguageServerProgress {
4170                            title: payload.title,
4171                            is_disk_based_diagnostics_progress: false,
4172                            is_cancellable: payload.is_cancellable.unwrap_or(false),
4173                            message: payload.message,
4174                            percentage: payload.percentage.map(|p| p as usize),
4175                            last_update_at: cx.background_executor().now(),
4176                        },
4177                        cx,
4178                    );
4179                }
4180
4181                proto::update_language_server::Variant::WorkProgress(payload) => {
4182                    this.on_lsp_work_progress(
4183                        language_server_id,
4184                        payload.token,
4185                        LanguageServerProgress {
4186                            title: None,
4187                            is_disk_based_diagnostics_progress: false,
4188                            is_cancellable: payload.is_cancellable.unwrap_or(false),
4189                            message: payload.message,
4190                            percentage: payload.percentage.map(|p| p as usize),
4191                            last_update_at: cx.background_executor().now(),
4192                        },
4193                        cx,
4194                    );
4195                }
4196
4197                proto::update_language_server::Variant::WorkEnd(payload) => {
4198                    this.on_lsp_work_end(language_server_id, payload.token, cx);
4199                }
4200
4201                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
4202                    this.disk_based_diagnostics_started(language_server_id, cx);
4203                }
4204
4205                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
4206                    this.disk_based_diagnostics_finished(language_server_id, cx)
4207                }
4208            }
4209
4210            Ok(())
4211        })?
4212    }
4213
4214    async fn handle_language_server_log(
4215        this: Model<Self>,
4216        envelope: TypedEnvelope<proto::LanguageServerLog>,
4217        mut cx: AsyncAppContext,
4218    ) -> Result<()> {
4219        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
4220        let log_type = envelope
4221            .payload
4222            .log_type
4223            .map(LanguageServerLogType::from_proto)
4224            .context("invalid language server log type")?;
4225
4226        let message = envelope.payload.message;
4227
4228        this.update(&mut cx, |_, cx| {
4229            cx.emit(LspStoreEvent::LanguageServerLog(
4230                language_server_id,
4231                log_type,
4232                message,
4233            ));
4234        })
4235    }
4236
4237    pub fn disk_based_diagnostics_started(
4238        &mut self,
4239        language_server_id: LanguageServerId,
4240        cx: &mut ModelContext<Self>,
4241    ) {
4242        if let Some(language_server_status) =
4243            self.language_server_statuses.get_mut(&language_server_id)
4244        {
4245            language_server_status.has_pending_diagnostic_updates = true;
4246        }
4247
4248        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
4249        cx.emit(LspStoreEvent::LanguageServerUpdate {
4250            language_server_id,
4251            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
4252                Default::default(),
4253            ),
4254        })
4255    }
4256
4257    pub fn disk_based_diagnostics_finished(
4258        &mut self,
4259        language_server_id: LanguageServerId,
4260        cx: &mut ModelContext<Self>,
4261    ) {
4262        if let Some(language_server_status) =
4263            self.language_server_statuses.get_mut(&language_server_id)
4264        {
4265            language_server_status.has_pending_diagnostic_updates = false;
4266        }
4267
4268        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
4269        cx.emit(LspStoreEvent::LanguageServerUpdate {
4270            language_server_id,
4271            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
4272                Default::default(),
4273            ),
4274        })
4275    }
4276
4277    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
4278    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
4279    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
4280    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
4281    // the language server might take some time to publish diagnostics.
4282    fn simulate_disk_based_diagnostics_events_if_needed(
4283        &mut self,
4284        language_server_id: LanguageServerId,
4285        cx: &mut ModelContext<Self>,
4286    ) {
4287        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
4288
4289        let Some(LanguageServerState::Running {
4290            simulate_disk_based_diagnostics_completion,
4291            adapter,
4292            ..
4293        }) = self
4294            .as_local_mut()
4295            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
4296        else {
4297            return;
4298        };
4299
4300        if adapter.disk_based_diagnostics_progress_token.is_some() {
4301            return;
4302        }
4303
4304        let prev_task = simulate_disk_based_diagnostics_completion.replace(cx.spawn(
4305            move |this, mut cx| async move {
4306                cx.background_executor()
4307                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
4308                    .await;
4309
4310                this.update(&mut cx, |this, cx| {
4311                    this.disk_based_diagnostics_finished(language_server_id, cx);
4312
4313                    if let Some(LanguageServerState::Running {
4314                        simulate_disk_based_diagnostics_completion,
4315                        ..
4316                    }) = this.as_local_mut().and_then(|local_store| {
4317                        local_store.language_servers.get_mut(&language_server_id)
4318                    }) {
4319                        *simulate_disk_based_diagnostics_completion = None;
4320                    }
4321                })
4322                .ok();
4323            },
4324        ));
4325
4326        if prev_task.is_none() {
4327            self.disk_based_diagnostics_started(language_server_id, cx);
4328        }
4329    }
4330
4331    pub fn language_server_statuses(
4332        &self,
4333    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
4334        self.language_server_statuses
4335            .iter()
4336            .map(|(key, value)| (*key, value))
4337    }
4338
4339    pub(super) fn did_rename_entry(
4340        &self,
4341        worktree_id: WorktreeId,
4342        old_path: &Path,
4343        new_path: &Path,
4344        is_dir: bool,
4345    ) {
4346        maybe!({
4347            let local_store = self.as_local()?;
4348
4349            let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from)?;
4350            let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from)?;
4351
4352            for language_server in self.language_servers_for_worktree(worktree_id) {
4353                let Some(filter) = local_store
4354                    .language_server_paths_watched_for_rename
4355                    .get(&language_server.server_id())
4356                else {
4357                    continue;
4358                };
4359
4360                if filter.should_send_did_rename(&old_uri, is_dir) {
4361                    language_server
4362                        .notify::<DidRenameFiles>(RenameFilesParams {
4363                            files: vec![FileRename {
4364                                old_uri: old_uri.clone(),
4365                                new_uri: new_uri.clone(),
4366                            }],
4367                        })
4368                        .log_err();
4369                }
4370            }
4371            Some(())
4372        });
4373    }
4374
4375    pub(super) fn will_rename_entry(
4376        this: WeakModel<Self>,
4377        worktree_id: WorktreeId,
4378        old_path: &Path,
4379        new_path: &Path,
4380        is_dir: bool,
4381        cx: AsyncAppContext,
4382    ) -> Task<()> {
4383        let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from);
4384        let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from);
4385        cx.spawn(move |mut cx| async move {
4386            let mut tasks = vec![];
4387            this.update(&mut cx, |this, cx| {
4388                let local_store = this.as_local()?;
4389                let old_uri = old_uri?;
4390                let new_uri = new_uri?;
4391                for language_server in this.language_servers_for_worktree(worktree_id) {
4392                    let Some(filter) = local_store
4393                        .language_server_paths_watched_for_rename
4394                        .get(&language_server.server_id())
4395                    else {
4396                        continue;
4397                    };
4398                    let Some(adapter) =
4399                        this.language_server_adapter_for_id(language_server.server_id())
4400                    else {
4401                        continue;
4402                    };
4403                    if filter.should_send_will_rename(&old_uri, is_dir) {
4404                        let apply_edit = cx.spawn({
4405                            let old_uri = old_uri.clone();
4406                            let new_uri = new_uri.clone();
4407                            let language_server = language_server.clone();
4408                            |this, mut cx| async move {
4409                                let edit = language_server
4410                                    .request::<WillRenameFiles>(RenameFilesParams {
4411                                        files: vec![FileRename { old_uri, new_uri }],
4412                                    })
4413                                    .log_err()
4414                                    .await
4415                                    .flatten()?;
4416
4417                                Self::deserialize_workspace_edit(
4418                                    this.upgrade()?,
4419                                    edit,
4420                                    false,
4421                                    adapter.clone(),
4422                                    language_server.clone(),
4423                                    &mut cx,
4424                                )
4425                                .await
4426                                .ok();
4427                                Some(())
4428                            }
4429                        });
4430                        tasks.push(apply_edit);
4431                    }
4432                }
4433                Some(())
4434            })
4435            .ok()
4436            .flatten();
4437            for task in tasks {
4438                // Await on tasks sequentially so that the order of application of edits is deterministic
4439                // (at least with regards to the order of registration of language servers)
4440                task.await;
4441            }
4442        })
4443    }
4444
4445    fn lsp_notify_abs_paths_changed(
4446        &mut self,
4447        server_id: LanguageServerId,
4448        changes: Vec<PathEvent>,
4449    ) {
4450        maybe!({
4451            let server = self.language_server_for_id(server_id)?;
4452            let changes = changes
4453                .into_iter()
4454                .filter_map(|event| {
4455                    let typ = match event.kind? {
4456                        PathEventKind::Created => lsp::FileChangeType::CREATED,
4457                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
4458                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
4459                    };
4460                    Some(lsp::FileEvent {
4461                        uri: lsp::Url::from_file_path(&event.path).ok()?,
4462                        typ,
4463                    })
4464                })
4465                .collect::<Vec<_>>();
4466            if !changes.is_empty() {
4467                server
4468                    .notify::<lsp::notification::DidChangeWatchedFiles>(
4469                        lsp::DidChangeWatchedFilesParams { changes },
4470                    )
4471                    .log_err();
4472            }
4473            Some(())
4474        });
4475    }
4476
4477    fn rebuild_watched_paths(
4478        &mut self,
4479        language_server_id: LanguageServerId,
4480        cx: &mut ModelContext<Self>,
4481    ) {
4482        let Some(watchers) = self.as_local().and_then(|local| {
4483            local
4484                .language_server_watcher_registrations
4485                .get(&language_server_id)
4486        }) else {
4487            return;
4488        };
4489
4490        let watch_builder =
4491            self.rebuild_watched_paths_inner(language_server_id, watchers.values().flatten(), cx);
4492        let Some(local_lsp_store) = self.as_local_mut() else {
4493            return;
4494        };
4495        let watcher = watch_builder.build(local_lsp_store.fs.clone(), language_server_id, cx);
4496        local_lsp_store
4497            .language_server_watched_paths
4498            .insert(language_server_id, watcher);
4499
4500        cx.notify();
4501    }
4502    fn rebuild_watched_paths_inner<'a>(
4503        &'a self,
4504        language_server_id: LanguageServerId,
4505        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
4506        cx: &mut ModelContext<Self>,
4507    ) -> LanguageServerWatchedPathsBuilder {
4508        let worktrees = self
4509            .worktree_store
4510            .read(cx)
4511            .worktrees()
4512            .filter_map(|worktree| {
4513                self.language_servers_for_worktree(worktree.read(cx).id())
4514                    .find(|server| server.server_id() == language_server_id)
4515                    .map(|_| worktree)
4516            })
4517            .collect::<Vec<_>>();
4518
4519        let mut worktree_globs = HashMap::default();
4520        let mut abs_globs = HashMap::default();
4521        log::trace!(
4522            "Processing new watcher paths for language server with id {}",
4523            language_server_id
4524        );
4525
4526        enum PathToWatch {
4527            Worktree {
4528                literal_prefix: Arc<Path>,
4529                pattern: String,
4530            },
4531            Absolute {
4532                path: Arc<Path>,
4533                pattern: String,
4534            },
4535        }
4536        for watcher in watchers {
4537            let mut found_host = false;
4538            for worktree in &worktrees {
4539                let glob_is_inside_worktree = worktree.update(cx, |tree, _| {
4540                    if let Some(worktree_root_path) = tree.abs_path().to_str() {
4541                        let path_to_watch = match &watcher.glob_pattern {
4542                            lsp::GlobPattern::String(s) => {
4543                                match s.strip_prefix(worktree_root_path) {
4544                                    Some(relative) => {
4545                                        let pattern = relative
4546                                            .strip_prefix(std::path::MAIN_SEPARATOR)
4547                                            .unwrap_or(relative)
4548                                            .to_owned();
4549                                        let literal_prefix = glob_literal_prefix(&pattern);
4550
4551                                        let literal_prefix = Arc::from(PathBuf::from(
4552                                            literal_prefix
4553                                                .strip_prefix(std::path::MAIN_SEPARATOR)
4554                                                .unwrap_or(literal_prefix),
4555                                        ));
4556                                        PathToWatch::Worktree {
4557                                            literal_prefix,
4558                                            pattern,
4559                                        }
4560                                    }
4561                                    None => {
4562                                        let path = glob_literal_prefix(s);
4563                                        let glob = &s[path.len()..];
4564                                        let pattern = glob
4565                                            .strip_prefix(std::path::MAIN_SEPARATOR)
4566                                            .unwrap_or(glob)
4567                                            .to_owned();
4568                                        let path = if Path::new(path).components().next().is_none()
4569                                        {
4570                                            Arc::from(Path::new(worktree_root_path))
4571                                        } else {
4572                                            PathBuf::from(path).into()
4573                                        };
4574
4575                                        PathToWatch::Absolute { path, pattern }
4576                                    }
4577                                }
4578                            }
4579                            lsp::GlobPattern::Relative(rp) => {
4580                                let Ok(mut base_uri) = match &rp.base_uri {
4581                                    lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
4582                                    lsp::OneOf::Right(base_uri) => base_uri,
4583                                }
4584                                .to_file_path() else {
4585                                    return false;
4586                                };
4587
4588                                match base_uri.strip_prefix(worktree_root_path) {
4589                                    Ok(relative) => {
4590                                        let mut literal_prefix = relative.to_owned();
4591                                        literal_prefix.push(glob_literal_prefix(&rp.pattern));
4592
4593                                        PathToWatch::Worktree {
4594                                            literal_prefix: literal_prefix.into(),
4595                                            pattern: rp.pattern.clone(),
4596                                        }
4597                                    }
4598                                    Err(_) => {
4599                                        let path = glob_literal_prefix(&rp.pattern);
4600                                        let glob = &rp.pattern[path.len()..];
4601                                        let pattern = glob
4602                                            .strip_prefix(std::path::MAIN_SEPARATOR)
4603                                            .unwrap_or(glob)
4604                                            .to_owned();
4605                                        base_uri.push(path);
4606
4607                                        let path = if base_uri.components().next().is_none() {
4608                                            Arc::from(Path::new("/"))
4609                                        } else {
4610                                            base_uri.into()
4611                                        };
4612                                        PathToWatch::Absolute { path, pattern }
4613                                    }
4614                                }
4615                            }
4616                        };
4617                        match path_to_watch {
4618                            PathToWatch::Worktree {
4619                                literal_prefix,
4620                                pattern,
4621                            } => {
4622                                if let Some((tree, glob)) =
4623                                    tree.as_local_mut().zip(Glob::new(&pattern).log_err())
4624                                {
4625                                    tree.add_path_prefix_to_scan(literal_prefix);
4626                                    worktree_globs
4627                                        .entry(tree.id())
4628                                        .or_insert_with(GlobSetBuilder::new)
4629                                        .add(glob);
4630                                } else {
4631                                    return false;
4632                                }
4633                            }
4634                            PathToWatch::Absolute { path, pattern } => {
4635                                if let Some(glob) = Glob::new(&pattern).log_err() {
4636                                    abs_globs
4637                                        .entry(path)
4638                                        .or_insert_with(GlobSetBuilder::new)
4639                                        .add(glob);
4640                                }
4641                            }
4642                        }
4643                        return true;
4644                    }
4645                    false
4646                });
4647                if glob_is_inside_worktree {
4648                    log::trace!(
4649                        "Watcher pattern `{}` has been attached to the worktree at `{}`",
4650                        serde_json::to_string(&watcher.glob_pattern).unwrap(),
4651                        worktree.read(cx).abs_path().display()
4652                    );
4653                    found_host = true;
4654                }
4655            }
4656            if !found_host {
4657                log::error!(
4658                    "Watcher pattern `{}` has not been attached to any worktree or absolute path",
4659                    serde_json::to_string(&watcher.glob_pattern).unwrap()
4660                )
4661            }
4662        }
4663
4664        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
4665        for (worktree_id, builder) in worktree_globs {
4666            if let Ok(globset) = builder.build() {
4667                watch_builder.watch_worktree(worktree_id, globset);
4668            }
4669        }
4670        for (abs_path, builder) in abs_globs {
4671            if let Ok(globset) = builder.build() {
4672                watch_builder.watch_abs_path(abs_path, globset);
4673            }
4674        }
4675        watch_builder
4676    }
4677
4678    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
4679        if let Some(local_lsp_store) = self.as_local() {
4680            if let Some(LanguageServerState::Running { server, .. }) =
4681                local_lsp_store.language_servers.get(&id)
4682            {
4683                Some(server.clone())
4684            } else if let Some((_, server)) =
4685                local_lsp_store.supplementary_language_servers.get(&id)
4686            {
4687                Some(Arc::clone(server))
4688            } else {
4689                None
4690            }
4691        } else {
4692            None
4693        }
4694    }
4695
4696    async fn on_lsp_workspace_edit(
4697        this: WeakModel<Self>,
4698        params: lsp::ApplyWorkspaceEditParams,
4699        server_id: LanguageServerId,
4700        adapter: Arc<CachedLspAdapter>,
4701        mut cx: AsyncAppContext,
4702    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
4703        let this = this
4704            .upgrade()
4705            .ok_or_else(|| anyhow!("project project closed"))?;
4706        let language_server = this
4707            .update(&mut cx, |this, _| this.language_server_for_id(server_id))?
4708            .ok_or_else(|| anyhow!("language server not found"))?;
4709        let transaction = Self::deserialize_workspace_edit(
4710            this.clone(),
4711            params.edit,
4712            true,
4713            adapter.clone(),
4714            language_server.clone(),
4715            &mut cx,
4716        )
4717        .await
4718        .log_err();
4719        this.update(&mut cx, |this, _| {
4720            if let Some(transaction) = transaction {
4721                this.as_local_mut()
4722                    .unwrap()
4723                    .last_workspace_edits_by_language_server
4724                    .insert(server_id, transaction);
4725            }
4726        })?;
4727        Ok(lsp::ApplyWorkspaceEditResponse {
4728            applied: true,
4729            failed_change: None,
4730            failure_reason: None,
4731        })
4732    }
4733
4734    fn on_lsp_progress(
4735        &mut self,
4736        progress: lsp::ProgressParams,
4737        language_server_id: LanguageServerId,
4738        disk_based_diagnostics_progress_token: Option<String>,
4739        cx: &mut ModelContext<Self>,
4740    ) {
4741        let token = match progress.token {
4742            lsp::NumberOrString::String(token) => token,
4743            lsp::NumberOrString::Number(token) => {
4744                log::info!("skipping numeric progress token {}", token);
4745                return;
4746            }
4747        };
4748
4749        let lsp::ProgressParamsValue::WorkDone(progress) = progress.value;
4750        let language_server_status =
4751            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
4752                status
4753            } else {
4754                return;
4755            };
4756
4757        if !language_server_status.progress_tokens.contains(&token) {
4758            return;
4759        }
4760
4761        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
4762            .as_ref()
4763            .map_or(false, |disk_based_token| {
4764                token.starts_with(disk_based_token)
4765            });
4766
4767        match progress {
4768            lsp::WorkDoneProgress::Begin(report) => {
4769                if is_disk_based_diagnostics_progress {
4770                    self.disk_based_diagnostics_started(language_server_id, cx);
4771                }
4772                self.on_lsp_work_start(
4773                    language_server_id,
4774                    token.clone(),
4775                    LanguageServerProgress {
4776                        title: Some(report.title),
4777                        is_disk_based_diagnostics_progress,
4778                        is_cancellable: report.cancellable.unwrap_or(false),
4779                        message: report.message.clone(),
4780                        percentage: report.percentage.map(|p| p as usize),
4781                        last_update_at: cx.background_executor().now(),
4782                    },
4783                    cx,
4784                );
4785            }
4786            lsp::WorkDoneProgress::Report(report) => {
4787                if self.on_lsp_work_progress(
4788                    language_server_id,
4789                    token.clone(),
4790                    LanguageServerProgress {
4791                        title: None,
4792                        is_disk_based_diagnostics_progress,
4793                        is_cancellable: report.cancellable.unwrap_or(false),
4794                        message: report.message.clone(),
4795                        percentage: report.percentage.map(|p| p as usize),
4796                        last_update_at: cx.background_executor().now(),
4797                    },
4798                    cx,
4799                ) {
4800                    cx.emit(LspStoreEvent::LanguageServerUpdate {
4801                        language_server_id,
4802                        message: proto::update_language_server::Variant::WorkProgress(
4803                            proto::LspWorkProgress {
4804                                token,
4805                                message: report.message,
4806                                percentage: report.percentage,
4807                                is_cancellable: report.cancellable,
4808                            },
4809                        ),
4810                    })
4811                }
4812            }
4813            lsp::WorkDoneProgress::End(_) => {
4814                language_server_status.progress_tokens.remove(&token);
4815                self.on_lsp_work_end(language_server_id, token.clone(), cx);
4816                if is_disk_based_diagnostics_progress {
4817                    self.disk_based_diagnostics_finished(language_server_id, cx);
4818                }
4819            }
4820        }
4821    }
4822
4823    fn on_lsp_work_start(
4824        &mut self,
4825        language_server_id: LanguageServerId,
4826        token: String,
4827        progress: LanguageServerProgress,
4828        cx: &mut ModelContext<Self>,
4829    ) {
4830        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
4831            status.pending_work.insert(token.clone(), progress.clone());
4832            cx.notify();
4833        }
4834        cx.emit(LspStoreEvent::LanguageServerUpdate {
4835            language_server_id,
4836            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
4837                token,
4838                title: progress.title,
4839                message: progress.message,
4840                percentage: progress.percentage.map(|p| p as u32),
4841                is_cancellable: Some(progress.is_cancellable),
4842            }),
4843        })
4844    }
4845
4846    fn on_lsp_work_progress(
4847        &mut self,
4848        language_server_id: LanguageServerId,
4849        token: String,
4850        progress: LanguageServerProgress,
4851        cx: &mut ModelContext<Self>,
4852    ) -> bool {
4853        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
4854            match status.pending_work.entry(token) {
4855                btree_map::Entry::Vacant(entry) => {
4856                    entry.insert(progress);
4857                    cx.notify();
4858                    return true;
4859                }
4860                btree_map::Entry::Occupied(mut entry) => {
4861                    let entry = entry.get_mut();
4862                    if (progress.last_update_at - entry.last_update_at)
4863                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
4864                    {
4865                        entry.last_update_at = progress.last_update_at;
4866                        if progress.message.is_some() {
4867                            entry.message = progress.message;
4868                        }
4869                        if progress.percentage.is_some() {
4870                            entry.percentage = progress.percentage;
4871                        }
4872                        if progress.is_cancellable != entry.is_cancellable {
4873                            entry.is_cancellable = progress.is_cancellable;
4874                        }
4875                        cx.notify();
4876                        return true;
4877                    }
4878                }
4879            }
4880        }
4881
4882        false
4883    }
4884
4885    fn on_lsp_work_end(
4886        &mut self,
4887        language_server_id: LanguageServerId,
4888        token: String,
4889        cx: &mut ModelContext<Self>,
4890    ) {
4891        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
4892            if let Some(work) = status.pending_work.remove(&token) {
4893                if !work.is_disk_based_diagnostics_progress {
4894                    cx.emit(LspStoreEvent::RefreshInlayHints);
4895                }
4896            }
4897            cx.notify();
4898        }
4899
4900        cx.emit(LspStoreEvent::LanguageServerUpdate {
4901            language_server_id,
4902            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
4903        })
4904    }
4905
4906    fn on_lsp_did_change_watched_files(
4907        &mut self,
4908        language_server_id: LanguageServerId,
4909        registration_id: &str,
4910        params: DidChangeWatchedFilesRegistrationOptions,
4911        cx: &mut ModelContext<Self>,
4912    ) {
4913        if let Some(local) = self.as_local_mut() {
4914            let registrations = local
4915                .language_server_watcher_registrations
4916                .entry(language_server_id)
4917                .or_default();
4918
4919            registrations.insert(registration_id.to_string(), params.watchers);
4920
4921            self.rebuild_watched_paths(language_server_id, cx);
4922        }
4923    }
4924
4925    fn on_lsp_unregister_did_change_watched_files(
4926        &mut self,
4927        language_server_id: LanguageServerId,
4928        registration_id: &str,
4929        cx: &mut ModelContext<Self>,
4930    ) {
4931        if let Some(local) = self.as_local_mut() {
4932            let registrations = local
4933                .language_server_watcher_registrations
4934                .entry(language_server_id)
4935                .or_default();
4936
4937            if registrations.remove(registration_id).is_some() {
4938                log::info!(
4939                    "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
4940                    language_server_id,
4941                    registration_id
4942                );
4943            } else {
4944                log::warn!(
4945                    "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
4946                    language_server_id,
4947                    registration_id
4948                );
4949            }
4950
4951            self.rebuild_watched_paths(language_server_id, cx);
4952        }
4953    }
4954
4955    #[allow(clippy::type_complexity)]
4956    pub(crate) fn edits_from_lsp(
4957        &mut self,
4958        buffer: &Model<Buffer>,
4959        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
4960        server_id: LanguageServerId,
4961        version: Option<i32>,
4962        cx: &mut ModelContext<Self>,
4963    ) -> Task<Result<Vec<(Range<Anchor>, String)>>> {
4964        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
4965        cx.background_executor().spawn(async move {
4966            let snapshot = snapshot?;
4967            let mut lsp_edits = lsp_edits
4968                .into_iter()
4969                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
4970                .collect::<Vec<_>>();
4971            lsp_edits.sort_by_key(|(range, _)| range.start);
4972
4973            let mut lsp_edits = lsp_edits.into_iter().peekable();
4974            let mut edits = Vec::new();
4975            while let Some((range, mut new_text)) = lsp_edits.next() {
4976                // Clip invalid ranges provided by the language server.
4977                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
4978                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
4979
4980                // Combine any LSP edits that are adjacent.
4981                //
4982                // Also, combine LSP edits that are separated from each other by only
4983                // a newline. This is important because for some code actions,
4984                // Rust-analyzer rewrites the entire buffer via a series of edits that
4985                // are separated by unchanged newline characters.
4986                //
4987                // In order for the diffing logic below to work properly, any edits that
4988                // cancel each other out must be combined into one.
4989                while let Some((next_range, next_text)) = lsp_edits.peek() {
4990                    if next_range.start.0 > range.end {
4991                        if next_range.start.0.row > range.end.row + 1
4992                            || next_range.start.0.column > 0
4993                            || snapshot.clip_point_utf16(
4994                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
4995                                Bias::Left,
4996                            ) > range.end
4997                        {
4998                            break;
4999                        }
5000                        new_text.push('\n');
5001                    }
5002                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
5003                    new_text.push_str(next_text);
5004                    lsp_edits.next();
5005                }
5006
5007                // For multiline edits, perform a diff of the old and new text so that
5008                // we can identify the changes more precisely, preserving the locations
5009                // of any anchors positioned in the unchanged regions.
5010                if range.end.row > range.start.row {
5011                    let mut offset = range.start.to_offset(&snapshot);
5012                    let old_text = snapshot.text_for_range(range).collect::<String>();
5013
5014                    let diff = TextDiff::from_lines(old_text.as_str(), &new_text);
5015                    let mut moved_since_edit = true;
5016                    for change in diff.iter_all_changes() {
5017                        let tag = change.tag();
5018                        let value = change.value();
5019                        match tag {
5020                            ChangeTag::Equal => {
5021                                offset += value.len();
5022                                moved_since_edit = true;
5023                            }
5024                            ChangeTag::Delete => {
5025                                let start = snapshot.anchor_after(offset);
5026                                let end = snapshot.anchor_before(offset + value.len());
5027                                if moved_since_edit {
5028                                    edits.push((start..end, String::new()));
5029                                } else {
5030                                    edits.last_mut().unwrap().0.end = end;
5031                                }
5032                                offset += value.len();
5033                                moved_since_edit = false;
5034                            }
5035                            ChangeTag::Insert => {
5036                                if moved_since_edit {
5037                                    let anchor = snapshot.anchor_after(offset);
5038                                    edits.push((anchor..anchor, value.to_string()));
5039                                } else {
5040                                    edits.last_mut().unwrap().1.push_str(value);
5041                                }
5042                                moved_since_edit = false;
5043                            }
5044                        }
5045                    }
5046                } else if range.end == range.start {
5047                    let anchor = snapshot.anchor_after(range.start);
5048                    edits.push((anchor..anchor, new_text));
5049                } else {
5050                    let edit_start = snapshot.anchor_after(range.start);
5051                    let edit_end = snapshot.anchor_before(range.end);
5052                    edits.push((edit_start..edit_end, new_text));
5053                }
5054            }
5055
5056            Ok(edits)
5057        })
5058    }
5059
5060    pub async fn handle_resolve_completion_documentation(
5061        this: Model<Self>,
5062        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
5063        mut cx: AsyncAppContext,
5064    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
5065        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
5066
5067        let completion = this
5068            .read_with(&cx, |this, cx| {
5069                let id = LanguageServerId(envelope.payload.language_server_id as usize);
5070                let Some(server) = this.language_server_for_id(id) else {
5071                    return Err(anyhow!("No language server {id}"));
5072                };
5073
5074                Ok(cx.background_executor().spawn(async move {
5075                    let can_resolve = server
5076                        .capabilities()
5077                        .completion_provider
5078                        .as_ref()
5079                        .and_then(|options| options.resolve_provider)
5080                        .unwrap_or(false);
5081                    if can_resolve {
5082                        server
5083                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
5084                            .await
5085                    } else {
5086                        anyhow::Ok(lsp_completion)
5087                    }
5088                }))
5089            })??
5090            .await?;
5091
5092        let mut documentation_is_markdown = false;
5093        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
5094        let documentation = match completion.documentation {
5095            Some(lsp::Documentation::String(text)) => text,
5096
5097            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
5098                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
5099                value
5100            }
5101
5102            _ => String::new(),
5103        };
5104
5105        // If we have a new buffer_id, that means we're talking to a new client
5106        // and want to check for new text_edits in the completion too.
5107        let mut old_start = None;
5108        let mut old_end = None;
5109        let mut new_text = String::default();
5110        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
5111            let buffer_snapshot = this.update(&mut cx, |this, cx| {
5112                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
5113                anyhow::Ok(buffer.read(cx).snapshot())
5114            })??;
5115
5116            if let Some(text_edit) = completion.text_edit.as_ref() {
5117                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
5118
5119                if let Some((old_range, mut text_edit_new_text)) = edit {
5120                    LineEnding::normalize(&mut text_edit_new_text);
5121
5122                    new_text = text_edit_new_text;
5123                    old_start = Some(serialize_anchor(&old_range.start));
5124                    old_end = Some(serialize_anchor(&old_range.end));
5125                }
5126            }
5127        }
5128
5129        Ok(proto::ResolveCompletionDocumentationResponse {
5130            documentation,
5131            documentation_is_markdown,
5132            old_start,
5133            old_end,
5134            new_text,
5135            lsp_completion,
5136        })
5137    }
5138
5139    async fn handle_on_type_formatting(
5140        this: Model<Self>,
5141        envelope: TypedEnvelope<proto::OnTypeFormatting>,
5142        mut cx: AsyncAppContext,
5143    ) -> Result<proto::OnTypeFormattingResponse> {
5144        let on_type_formatting = this.update(&mut cx, |this, cx| {
5145            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
5146            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
5147            let position = envelope
5148                .payload
5149                .position
5150                .and_then(deserialize_anchor)
5151                .ok_or_else(|| anyhow!("invalid position"))?;
5152            Ok::<_, anyhow::Error>(this.apply_on_type_formatting(
5153                buffer,
5154                position,
5155                envelope.payload.trigger.clone(),
5156                cx,
5157            ))
5158        })??;
5159
5160        let transaction = on_type_formatting
5161            .await?
5162            .as_ref()
5163            .map(language::proto::serialize_transaction);
5164        Ok(proto::OnTypeFormattingResponse { transaction })
5165    }
5166
5167    async fn handle_refresh_inlay_hints(
5168        this: Model<Self>,
5169        _: TypedEnvelope<proto::RefreshInlayHints>,
5170        mut cx: AsyncAppContext,
5171    ) -> Result<proto::Ack> {
5172        this.update(&mut cx, |_, cx| {
5173            cx.emit(LspStoreEvent::RefreshInlayHints);
5174        })?;
5175        Ok(proto::Ack {})
5176    }
5177
5178    async fn handle_inlay_hints(
5179        this: Model<Self>,
5180        envelope: TypedEnvelope<proto::InlayHints>,
5181        mut cx: AsyncAppContext,
5182    ) -> Result<proto::InlayHintsResponse> {
5183        let sender_id = envelope.original_sender_id().unwrap_or_default();
5184        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
5185        let buffer = this.update(&mut cx, |this, cx| {
5186            this.buffer_store.read(cx).get_existing(buffer_id)
5187        })??;
5188        buffer
5189            .update(&mut cx, |buffer, _| {
5190                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
5191            })?
5192            .await
5193            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
5194
5195        let start = envelope
5196            .payload
5197            .start
5198            .and_then(deserialize_anchor)
5199            .context("missing range start")?;
5200        let end = envelope
5201            .payload
5202            .end
5203            .and_then(deserialize_anchor)
5204            .context("missing range end")?;
5205        let buffer_hints = this
5206            .update(&mut cx, |lsp_store, cx| {
5207                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
5208            })?
5209            .await
5210            .context("inlay hints fetch")?;
5211
5212        this.update(&mut cx, |project, cx| {
5213            InlayHints::response_to_proto(
5214                buffer_hints,
5215                project,
5216                sender_id,
5217                &buffer.read(cx).version(),
5218                cx,
5219            )
5220        })
5221    }
5222
5223    async fn handle_resolve_inlay_hint(
5224        this: Model<Self>,
5225        envelope: TypedEnvelope<proto::ResolveInlayHint>,
5226        mut cx: AsyncAppContext,
5227    ) -> Result<proto::ResolveInlayHintResponse> {
5228        let proto_hint = envelope
5229            .payload
5230            .hint
5231            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
5232        let hint = InlayHints::proto_to_project_hint(proto_hint)
5233            .context("resolved proto inlay hint conversion")?;
5234        let buffer = this.update(&mut cx, |this, cx| {
5235            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
5236            this.buffer_store.read(cx).get_existing(buffer_id)
5237        })??;
5238        let response_hint = this
5239            .update(&mut cx, |this, cx| {
5240                this.resolve_inlay_hint(
5241                    hint,
5242                    buffer,
5243                    LanguageServerId(envelope.payload.language_server_id as usize),
5244                    cx,
5245                )
5246            })?
5247            .await
5248            .context("inlay hints fetch")?;
5249        Ok(proto::ResolveInlayHintResponse {
5250            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
5251        })
5252    }
5253
5254    async fn handle_open_buffer_for_symbol(
5255        this: Model<Self>,
5256        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
5257        mut cx: AsyncAppContext,
5258    ) -> Result<proto::OpenBufferForSymbolResponse> {
5259        let peer_id = envelope.original_sender_id().unwrap_or_default();
5260        let symbol = envelope
5261            .payload
5262            .symbol
5263            .ok_or_else(|| anyhow!("invalid symbol"))?;
5264        let symbol = Self::deserialize_symbol(symbol)?;
5265        let symbol = this.update(&mut cx, |this, _| {
5266            let signature = this.symbol_signature(&symbol.path);
5267            if signature == symbol.signature {
5268                Ok(symbol)
5269            } else {
5270                Err(anyhow!("invalid symbol signature"))
5271            }
5272        })??;
5273        let buffer = this
5274            .update(&mut cx, |this, cx| {
5275                this.open_buffer_for_symbol(
5276                    &Symbol {
5277                        language_server_name: symbol.language_server_name,
5278                        source_worktree_id: symbol.source_worktree_id,
5279                        path: symbol.path,
5280                        name: symbol.name,
5281                        kind: symbol.kind,
5282                        range: symbol.range,
5283                        signature: symbol.signature,
5284                        label: CodeLabel {
5285                            text: Default::default(),
5286                            runs: Default::default(),
5287                            filter_range: Default::default(),
5288                        },
5289                    },
5290                    cx,
5291                )
5292            })?
5293            .await?;
5294
5295        this.update(&mut cx, |this, cx| {
5296            let is_private = buffer
5297                .read(cx)
5298                .file()
5299                .map(|f| f.is_private())
5300                .unwrap_or_default();
5301            if is_private {
5302                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
5303            } else {
5304                this.buffer_store
5305                    .update(cx, |buffer_store, cx| {
5306                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
5307                    })
5308                    .detach_and_log_err(cx);
5309                let buffer_id = buffer.read(cx).remote_id().to_proto();
5310                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
5311            }
5312        })?
5313    }
5314
5315    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
5316        let mut hasher = Sha256::new();
5317        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
5318        hasher.update(project_path.path.to_string_lossy().as_bytes());
5319        hasher.update(self.nonce.to_be_bytes());
5320        hasher.finalize().as_slice().try_into().unwrap()
5321    }
5322
5323    pub async fn handle_get_project_symbols(
5324        this: Model<Self>,
5325        envelope: TypedEnvelope<proto::GetProjectSymbols>,
5326        mut cx: AsyncAppContext,
5327    ) -> Result<proto::GetProjectSymbolsResponse> {
5328        let symbols = this
5329            .update(&mut cx, |this, cx| {
5330                this.symbols(&envelope.payload.query, cx)
5331            })?
5332            .await?;
5333
5334        Ok(proto::GetProjectSymbolsResponse {
5335            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
5336        })
5337    }
5338
5339    pub async fn handle_restart_language_servers(
5340        this: Model<Self>,
5341        envelope: TypedEnvelope<proto::RestartLanguageServers>,
5342        mut cx: AsyncAppContext,
5343    ) -> Result<proto::Ack> {
5344        this.update(&mut cx, |this, cx| {
5345            let buffers = this.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
5346            this.restart_language_servers_for_buffers(buffers, cx);
5347        })?;
5348
5349        Ok(proto::Ack {})
5350    }
5351
5352    pub async fn handle_cancel_language_server_work(
5353        this: Model<Self>,
5354        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
5355        mut cx: AsyncAppContext,
5356    ) -> Result<proto::Ack> {
5357        this.update(&mut cx, |this, cx| {
5358            if let Some(work) = envelope.payload.work {
5359                match work {
5360                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
5361                        let buffers =
5362                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
5363                        this.cancel_language_server_work_for_buffers(buffers, cx);
5364                    }
5365                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
5366                        let server_id = LanguageServerId::from_proto(work.language_server_id);
5367                        this.cancel_language_server_work(server_id, work.token, cx);
5368                    }
5369                }
5370            }
5371        })?;
5372
5373        Ok(proto::Ack {})
5374    }
5375
5376    fn buffer_ids_to_buffers(
5377        &mut self,
5378        buffer_ids: impl Iterator<Item = u64>,
5379        cx: &mut ModelContext<Self>,
5380    ) -> Vec<Model<Buffer>> {
5381        buffer_ids
5382            .into_iter()
5383            .flat_map(|buffer_id| {
5384                self.buffer_store
5385                    .read(cx)
5386                    .get(BufferId::new(buffer_id).log_err()?)
5387            })
5388            .collect::<Vec<_>>()
5389    }
5390
5391    async fn handle_apply_additional_edits_for_completion(
5392        this: Model<Self>,
5393        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
5394        mut cx: AsyncAppContext,
5395    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
5396        let (buffer, completion) = this.update(&mut cx, |this, cx| {
5397            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
5398            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
5399            let completion = Self::deserialize_completion(
5400                envelope
5401                    .payload
5402                    .completion
5403                    .ok_or_else(|| anyhow!("invalid completion"))?,
5404            )?;
5405            anyhow::Ok((buffer, completion))
5406        })??;
5407
5408        let apply_additional_edits = this.update(&mut cx, |this, cx| {
5409            this.apply_additional_edits_for_completion(
5410                buffer,
5411                Completion {
5412                    old_range: completion.old_range,
5413                    new_text: completion.new_text,
5414                    lsp_completion: completion.lsp_completion,
5415                    server_id: completion.server_id,
5416                    documentation: None,
5417                    label: CodeLabel {
5418                        text: Default::default(),
5419                        runs: Default::default(),
5420                        filter_range: Default::default(),
5421                    },
5422                    confirm: None,
5423                },
5424                false,
5425                cx,
5426            )
5427        })?;
5428
5429        Ok(proto::ApplyCompletionAdditionalEditsResponse {
5430            transaction: apply_additional_edits
5431                .await?
5432                .as_ref()
5433                .map(language::proto::serialize_transaction),
5434        })
5435    }
5436
5437    pub fn last_formatting_failure(&self) -> Option<&str> {
5438        self.last_formatting_failure.as_deref()
5439    }
5440
5441    pub fn reset_last_formatting_failure(&mut self) {
5442        self.last_formatting_failure = None;
5443    }
5444
5445    pub fn environment_for_buffer(
5446        &self,
5447        buffer: &Model<Buffer>,
5448        cx: &mut ModelContext<Self>,
5449    ) -> Shared<Task<Option<HashMap<String, String>>>> {
5450        let worktree_id = buffer.read(cx).file().map(|file| file.worktree_id(cx));
5451        let worktree_abs_path = worktree_id.and_then(|worktree_id| {
5452            self.worktree_store
5453                .read(cx)
5454                .worktree_for_id(worktree_id, cx)
5455                .map(|entry| entry.read(cx).abs_path().clone())
5456        });
5457
5458        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
5459            environment.update(cx, |env, cx| {
5460                env.get_environment(worktree_id, worktree_abs_path, cx)
5461            })
5462        } else {
5463            Task::ready(None).shared()
5464        }
5465    }
5466
5467    pub fn format(
5468        &mut self,
5469        buffers: HashSet<Model<Buffer>>,
5470        push_to_history: bool,
5471        trigger: FormatTrigger,
5472        target: FormatTarget,
5473        cx: &mut ModelContext<Self>,
5474    ) -> Task<anyhow::Result<ProjectTransaction>> {
5475        if let Some(_) = self.as_local() {
5476            let buffers_with_paths = buffers
5477                .into_iter()
5478                .map(|buffer_handle| {
5479                    let buffer = buffer_handle.read(cx);
5480                    let buffer_abs_path = File::from_dyn(buffer.file())
5481                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
5482
5483                    (buffer_handle, buffer_abs_path)
5484                })
5485                .collect::<Vec<_>>();
5486
5487            cx.spawn(move |lsp_store, mut cx| async move {
5488                let mut formattable_buffers = Vec::with_capacity(buffers_with_paths.len());
5489
5490                for (handle, abs_path) in buffers_with_paths {
5491                    let env = lsp_store
5492                        .update(&mut cx, |lsp_store, cx| {
5493                            lsp_store.environment_for_buffer(&handle, cx)
5494                        })?
5495                        .await;
5496
5497                    formattable_buffers.push(FormattableBuffer {
5498                        handle,
5499                        abs_path,
5500                        env,
5501                    });
5502                }
5503
5504                let result = LocalLspStore::format_locally(
5505                    lsp_store.clone(),
5506                    formattable_buffers,
5507                    push_to_history,
5508                    trigger,
5509                    target,
5510                    cx.clone(),
5511                )
5512                .await;
5513                lsp_store.update(&mut cx, |lsp_store, _| {
5514                    lsp_store.update_last_formatting_failure(&result);
5515                })?;
5516
5517                result
5518            })
5519        } else if let Some((client, project_id)) = self.upstream_client() {
5520            let buffer_store = self.buffer_store();
5521            cx.spawn(move |lsp_store, mut cx| async move {
5522                let result = client
5523                    .request(proto::FormatBuffers {
5524                        project_id,
5525                        trigger: trigger as i32,
5526                        buffer_ids: buffers
5527                            .iter()
5528                            .map(|buffer| {
5529                                buffer.update(&mut cx, |buffer, _| buffer.remote_id().into())
5530                            })
5531                            .collect::<Result<_>>()?,
5532                    })
5533                    .await
5534                    .and_then(|result| result.transaction.context("missing transaction"));
5535
5536                lsp_store.update(&mut cx, |lsp_store, _| {
5537                    lsp_store.update_last_formatting_failure(&result);
5538                })?;
5539
5540                let transaction_response = result?;
5541                buffer_store
5542                    .update(&mut cx, |buffer_store, cx| {
5543                        buffer_store.deserialize_project_transaction(
5544                            transaction_response,
5545                            push_to_history,
5546                            cx,
5547                        )
5548                    })?
5549                    .await
5550            })
5551        } else {
5552            Task::ready(Ok(ProjectTransaction::default()))
5553        }
5554    }
5555
5556    async fn handle_format_buffers(
5557        this: Model<Self>,
5558        envelope: TypedEnvelope<proto::FormatBuffers>,
5559        mut cx: AsyncAppContext,
5560    ) -> Result<proto::FormatBuffersResponse> {
5561        let sender_id = envelope.original_sender_id().unwrap_or_default();
5562        let format = this.update(&mut cx, |this, cx| {
5563            let mut buffers = HashSet::default();
5564            for buffer_id in &envelope.payload.buffer_ids {
5565                let buffer_id = BufferId::new(*buffer_id)?;
5566                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
5567            }
5568            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
5569            anyhow::Ok(this.format(buffers, false, trigger, FormatTarget::Buffer, cx))
5570        })??;
5571
5572        let project_transaction = format.await?;
5573        let project_transaction = this.update(&mut cx, |this, cx| {
5574            this.buffer_store.update(cx, |buffer_store, cx| {
5575                buffer_store.serialize_project_transaction_for_peer(
5576                    project_transaction,
5577                    sender_id,
5578                    cx,
5579                )
5580            })
5581        })?;
5582        Ok(proto::FormatBuffersResponse {
5583            transaction: Some(project_transaction),
5584        })
5585    }
5586
5587    pub fn start_language_servers(
5588        &mut self,
5589        worktree: &Model<Worktree>,
5590        language: LanguageName,
5591        cx: &mut ModelContext<Self>,
5592    ) {
5593        let root_file = worktree
5594            .update(cx, |tree, cx| tree.root_file(cx))
5595            .map(|f| f as _);
5596        let settings = language_settings(Some(language.clone()), root_file.as_ref(), cx);
5597        if !settings.enable_language_server || self.mode.is_remote() {
5598            return;
5599        }
5600
5601        let available_lsp_adapters = self.languages.clone().lsp_adapters(&language);
5602        let available_language_servers = available_lsp_adapters
5603            .iter()
5604            .map(|lsp_adapter| lsp_adapter.name.clone())
5605            .collect::<Vec<_>>();
5606
5607        let desired_language_servers =
5608            settings.customized_language_servers(&available_language_servers);
5609
5610        let mut enabled_lsp_adapters: Vec<Arc<CachedLspAdapter>> = Vec::new();
5611        for desired_language_server in desired_language_servers {
5612            if let Some(adapter) = available_lsp_adapters
5613                .iter()
5614                .find(|adapter| adapter.name == desired_language_server)
5615            {
5616                enabled_lsp_adapters.push(adapter.clone());
5617                continue;
5618            }
5619
5620            if let Some(adapter) = self
5621                .languages
5622                .load_available_lsp_adapter(&desired_language_server)
5623            {
5624                self.languages
5625                    .register_lsp_adapter(language.clone(), adapter.adapter.clone());
5626                enabled_lsp_adapters.push(adapter);
5627                continue;
5628            }
5629
5630            log::warn!(
5631                "no language server found matching '{}'",
5632                desired_language_server.0
5633            );
5634        }
5635
5636        for adapter in &enabled_lsp_adapters {
5637            self.start_language_server(worktree, adapter.clone(), language.clone(), cx);
5638        }
5639
5640        // After starting all the language servers, reorder them to reflect the desired order
5641        // based on the settings.
5642        //
5643        // This is done, in part, to ensure that language servers loaded at different points
5644        // (e.g., native vs extension) still end up in the right order at the end, rather than
5645        // it being based on which language server happened to be loaded in first.
5646        self.languages
5647            .reorder_language_servers(&language, enabled_lsp_adapters);
5648    }
5649
5650    fn get_language_server_binary(
5651        &self,
5652        adapter: Arc<CachedLspAdapter>,
5653        delegate: Arc<dyn LspAdapterDelegate>,
5654        allow_binary_download: bool,
5655        cx: &mut ModelContext<Self>,
5656    ) -> Task<Result<LanguageServerBinary>> {
5657        let settings = ProjectSettings::get(
5658            Some(SettingsLocation {
5659                worktree_id: delegate.worktree_id(),
5660                path: Path::new(""),
5661            }),
5662            cx,
5663        )
5664        .lsp
5665        .get(&adapter.name)
5666        .and_then(|s| s.binary.clone());
5667
5668        if settings.as_ref().is_some_and(|b| b.path.is_some()) {
5669            let settings = settings.unwrap();
5670            return cx.spawn(|_, _| async move {
5671                Ok(LanguageServerBinary {
5672                    path: PathBuf::from(&settings.path.unwrap()),
5673                    env: Some(delegate.shell_env().await),
5674                    arguments: settings
5675                        .arguments
5676                        .unwrap_or_default()
5677                        .iter()
5678                        .map(Into::into)
5679                        .collect(),
5680                })
5681            });
5682        }
5683        let lsp_binary_options = LanguageServerBinaryOptions {
5684            allow_path_lookup: !settings
5685                .as_ref()
5686                .and_then(|b| b.ignore_system_version)
5687                .unwrap_or_default(),
5688            allow_binary_download,
5689        };
5690        let toolchains = self.toolchain_store(cx);
5691        cx.spawn(|_, mut cx| async move {
5692            let binary_result = adapter
5693                .clone()
5694                .get_language_server_command(
5695                    delegate.clone(),
5696                    toolchains,
5697                    lsp_binary_options,
5698                    &mut cx,
5699                )
5700                .await;
5701
5702            delegate.update_status(adapter.name.clone(), LanguageServerBinaryStatus::None);
5703
5704            let mut binary = binary_result?;
5705            if let Some(arguments) = settings.and_then(|b| b.arguments) {
5706                binary.arguments = arguments.into_iter().map(Into::into).collect();
5707            }
5708
5709            let mut shell_env = delegate.shell_env().await;
5710            shell_env.extend(binary.env.unwrap_or_default());
5711            binary.env = Some(shell_env);
5712            Ok(binary)
5713        })
5714    }
5715
5716    fn start_language_server(
5717        &mut self,
5718        worktree_handle: &Model<Worktree>,
5719        adapter: Arc<CachedLspAdapter>,
5720        language: LanguageName,
5721        cx: &mut ModelContext<Self>,
5722    ) {
5723        if self.mode.is_remote() {
5724            return;
5725        }
5726
5727        let worktree = worktree_handle.read(cx);
5728        let worktree_id = worktree.id();
5729        let root_path = worktree.abs_path();
5730        let key = (worktree_id, adapter.name.clone());
5731
5732        if self.language_server_ids.contains_key(&key) {
5733            return;
5734        }
5735
5736        let project_settings = ProjectSettings::get(
5737            Some(SettingsLocation {
5738                worktree_id,
5739                path: Path::new(""),
5740            }),
5741            cx,
5742        );
5743        let lsp = project_settings.lsp.get(&adapter.name);
5744        let override_options = lsp.and_then(|s| s.initialization_options.clone());
5745
5746        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
5747        let delegate = LocalLspAdapterDelegate::for_local(self, worktree_handle, cx)
5748            as Arc<dyn LspAdapterDelegate>;
5749
5750        let server_id = self.languages.next_language_server_id();
5751        log::info!(
5752            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
5753            adapter.name.0
5754        );
5755
5756        let binary = self.get_language_server_binary(adapter.clone(), delegate.clone(), true, cx);
5757
5758        let pending_server = cx.spawn({
5759            let adapter = adapter.clone();
5760            let server_name = adapter.name.clone();
5761            let stderr_capture = stderr_capture.clone();
5762
5763            move |_lsp_store, cx| async move {
5764                let binary = binary.await?;
5765
5766                #[cfg(any(test, feature = "test-support"))]
5767                if let Some(server) = _lsp_store
5768                    .update(&mut cx.clone(), |this, cx| {
5769                        this.languages.create_fake_language_server(
5770                            server_id,
5771                            &server_name,
5772                            binary.clone(),
5773                            cx.to_async(),
5774                        )
5775                    })
5776                    .ok()
5777                    .flatten()
5778                {
5779                    return Ok(server);
5780                }
5781
5782                lsp::LanguageServer::new(
5783                    stderr_capture,
5784                    server_id,
5785                    server_name,
5786                    binary,
5787                    &root_path,
5788                    adapter.code_action_kinds(),
5789                    cx,
5790                )
5791            }
5792        });
5793
5794        let state = LanguageServerState::Starting({
5795            let server_name = adapter.name.0.clone();
5796            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
5797            let language = language.clone();
5798            let key = key.clone();
5799            let adapter = adapter.clone();
5800
5801            cx.spawn(move |this, mut cx| async move {
5802                let result = {
5803                    let delegate = delegate.clone();
5804                    let adapter = adapter.clone();
5805                    let this = this.clone();
5806                    let toolchains = this
5807                        .update(&mut cx, |this, cx| this.toolchain_store(cx))
5808                        .ok()?;
5809                    let mut cx = cx.clone();
5810                    async move {
5811                        let language_server = pending_server.await?;
5812
5813                        let workspace_config = adapter
5814                            .adapter
5815                            .clone()
5816                            .workspace_configuration(&delegate, toolchains.clone(), &mut cx)
5817                            .await?;
5818
5819                        let mut initialization_options = adapter
5820                            .adapter
5821                            .clone()
5822                            .initialization_options(&(delegate))
5823                            .await?;
5824
5825                        match (&mut initialization_options, override_options) {
5826                            (Some(initialization_options), Some(override_options)) => {
5827                                merge_json_value_into(override_options, initialization_options);
5828                            }
5829                            (None, override_options) => initialization_options = override_options,
5830                            _ => {}
5831                        }
5832
5833                        let initialization_params = cx.update(|cx| {
5834                            let mut params = language_server.default_initialize_params(cx);
5835                            params.initialization_options = initialization_options;
5836                            adapter.adapter.prepare_initialize_params(params)
5837                        })??;
5838
5839                        Self::setup_lsp_messages(this.clone(), &language_server, delegate, adapter);
5840
5841                        let language_server = cx
5842                            .update(|cx| {
5843                                language_server.initialize(Some(initialization_params), cx)
5844                            })?
5845                            .await
5846                            .inspect_err(|_| {
5847                                if let Some(this) = this.upgrade() {
5848                                    this.update(&mut cx, |_, cx| {
5849                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
5850                                    })
5851                                    .ok();
5852                                }
5853                            })?;
5854
5855                        language_server
5856                            .notify::<lsp::notification::DidChangeConfiguration>(
5857                                lsp::DidChangeConfigurationParams {
5858                                    settings: workspace_config,
5859                                },
5860                            )
5861                            .ok();
5862
5863                        anyhow::Ok(language_server)
5864                    }
5865                }
5866                .await;
5867
5868                match result {
5869                    Ok(server) => {
5870                        this.update(&mut cx, |this, mut cx| {
5871                            this.insert_newly_running_language_server(
5872                                language,
5873                                adapter,
5874                                server.clone(),
5875                                server_id,
5876                                key,
5877                                &mut cx,
5878                            );
5879                        })
5880                        .ok();
5881                        stderr_capture.lock().take();
5882                        Some(server)
5883                    }
5884
5885                    Err(err) => {
5886                        let log = stderr_capture.lock().take().unwrap_or_default();
5887                        delegate.update_status(
5888                            adapter.name(),
5889                            LanguageServerBinaryStatus::Failed {
5890                                error: format!("{err}\n-- stderr--\n{}", log),
5891                            },
5892                        );
5893                        log::error!("Failed to start language server {server_name:?}: {err}");
5894                        log::error!("server stderr: {:?}", log);
5895                        None
5896                    }
5897                }
5898            })
5899        });
5900
5901        self.as_local_mut()
5902            .unwrap()
5903            .language_servers
5904            .insert(server_id, state);
5905        self.language_server_ids.insert(key, server_id);
5906    }
5907
5908    async fn shutdown_language_server(
5909        server_state: Option<LanguageServerState>,
5910        name: LanguageServerName,
5911        cx: AsyncAppContext,
5912    ) {
5913        let server = match server_state {
5914            Some(LanguageServerState::Starting(task)) => {
5915                let mut timer = cx
5916                    .background_executor()
5917                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
5918                    .fuse();
5919
5920                select! {
5921                    server = task.fuse() => server,
5922                    _ = timer => {
5923                        log::info!(
5924                            "timeout waiting for language server {} to finish launching before stopping",
5925                            name
5926                        );
5927                        None
5928                    },
5929                }
5930            }
5931
5932            Some(LanguageServerState::Running { server, .. }) => Some(server),
5933
5934            None => None,
5935        };
5936
5937        if let Some(server) = server {
5938            if let Some(shutdown) = server.shutdown() {
5939                shutdown.await;
5940            }
5941        }
5942    }
5943
5944    // Returns a list of all of the worktrees which no longer have a language server and the root path
5945    // for the stopped server
5946    fn stop_local_language_server(
5947        &mut self,
5948        worktree_id: WorktreeId,
5949        adapter_name: LanguageServerName,
5950        cx: &mut ModelContext<Self>,
5951    ) -> Task<Vec<WorktreeId>> {
5952        let key = (worktree_id, adapter_name);
5953        if self.mode.is_local() {
5954            if let Some(server_id) = self.language_server_ids.remove(&key) {
5955                let name = key.1;
5956                log::info!("stopping language server {name}");
5957
5958                // Remove other entries for this language server as well
5959                let mut orphaned_worktrees = vec![worktree_id];
5960                let other_keys = self.language_server_ids.keys().cloned().collect::<Vec<_>>();
5961                for other_key in other_keys {
5962                    if self.language_server_ids.get(&other_key) == Some(&server_id) {
5963                        self.language_server_ids.remove(&other_key);
5964                        orphaned_worktrees.push(other_key.0);
5965                    }
5966                }
5967
5968                self.buffer_store.update(cx, |buffer_store, cx| {
5969                    for buffer in buffer_store.buffers() {
5970                        buffer.update(cx, |buffer, cx| {
5971                            buffer.update_diagnostics(
5972                                server_id,
5973                                DiagnosticSet::new([], buffer),
5974                                cx,
5975                            );
5976                            buffer.set_completion_triggers(server_id, Default::default(), cx);
5977                        });
5978                    }
5979                });
5980
5981                for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
5982                    summaries.retain(|path, summaries_by_server_id| {
5983                        if summaries_by_server_id.remove(&server_id).is_some() {
5984                            if let Some((client, project_id)) = self.downstream_client.clone() {
5985                                client
5986                                    .send(proto::UpdateDiagnosticSummary {
5987                                        project_id,
5988                                        worktree_id: worktree_id.to_proto(),
5989                                        summary: Some(proto::DiagnosticSummary {
5990                                            path: path.to_string_lossy().to_string(),
5991                                            language_server_id: server_id.0 as u64,
5992                                            error_count: 0,
5993                                            warning_count: 0,
5994                                        }),
5995                                    })
5996                                    .log_err();
5997                            }
5998                            !summaries_by_server_id.is_empty()
5999                        } else {
6000                            true
6001                        }
6002                    });
6003                }
6004
6005                for diagnostics in self.diagnostics.values_mut() {
6006                    diagnostics.retain(|_, diagnostics_by_server_id| {
6007                        if let Ok(ix) =
6008                            diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0)
6009                        {
6010                            diagnostics_by_server_id.remove(ix);
6011                            !diagnostics_by_server_id.is_empty()
6012                        } else {
6013                            true
6014                        }
6015                    });
6016                }
6017
6018                self.as_local_mut()
6019                    .unwrap()
6020                    .language_server_watched_paths
6021                    .remove(&server_id);
6022                self.language_server_statuses.remove(&server_id);
6023                cx.notify();
6024
6025                let server_state = self
6026                    .as_local_mut()
6027                    .unwrap()
6028                    .language_servers
6029                    .remove(&server_id);
6030                cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
6031                cx.spawn(move |_, cx| async move {
6032                    Self::shutdown_language_server(server_state, name, cx).await;
6033                    orphaned_worktrees
6034                })
6035            } else {
6036                Task::ready(Vec::new())
6037            }
6038        } else {
6039            Task::ready(Vec::new())
6040        }
6041    }
6042
6043    pub fn restart_language_servers_for_buffers(
6044        &mut self,
6045        buffers: impl IntoIterator<Item = Model<Buffer>>,
6046        cx: &mut ModelContext<Self>,
6047    ) {
6048        if let Some((client, project_id)) = self.upstream_client() {
6049            let request = client.request(proto::RestartLanguageServers {
6050                project_id,
6051                buffer_ids: buffers
6052                    .into_iter()
6053                    .map(|b| b.read(cx).remote_id().to_proto())
6054                    .collect(),
6055            });
6056            cx.background_executor()
6057                .spawn(request)
6058                .detach_and_log_err(cx);
6059        } else {
6060            let language_server_lookup_info: HashSet<(Model<Worktree>, LanguageName)> = buffers
6061                .into_iter()
6062                .filter_map(|buffer| {
6063                    let buffer = buffer.read(cx);
6064                    let file = buffer.file()?;
6065                    let worktree = File::from_dyn(Some(file))?.worktree.clone();
6066                    let language =
6067                        self.languages
6068                            .language_for_file(file, Some(buffer.as_rope()), cx)?;
6069
6070                    Some((worktree, language.name()))
6071                })
6072                .collect();
6073
6074            for (worktree, language) in language_server_lookup_info {
6075                self.restart_local_language_servers(worktree, language, cx);
6076            }
6077        }
6078    }
6079
6080    fn restart_local_language_servers(
6081        &mut self,
6082        worktree: Model<Worktree>,
6083        language: LanguageName,
6084        cx: &mut ModelContext<Self>,
6085    ) {
6086        let worktree_id = worktree.read(cx).id();
6087
6088        let stop_tasks = self
6089            .languages
6090            .clone()
6091            .lsp_adapters(&language)
6092            .iter()
6093            .map(|adapter| {
6094                let stop_task =
6095                    self.stop_local_language_server(worktree_id, adapter.name.clone(), cx);
6096                (stop_task, adapter.name.clone())
6097            })
6098            .collect::<Vec<_>>();
6099        if stop_tasks.is_empty() {
6100            return;
6101        }
6102
6103        cx.spawn(move |this, mut cx| async move {
6104            // For each stopped language server, record all of the worktrees with which
6105            // it was associated.
6106            let mut affected_worktrees = Vec::new();
6107            for (stop_task, language_server_name) in stop_tasks {
6108                for affected_worktree_id in stop_task.await {
6109                    affected_worktrees.push((affected_worktree_id, language_server_name.clone()));
6110                }
6111            }
6112
6113            this.update(&mut cx, |this, cx| {
6114                // Restart the language server for the given worktree.
6115                this.start_language_servers(&worktree, language.clone(), cx);
6116
6117                // Lookup new server ids and set them for each of the orphaned worktrees
6118                for (affected_worktree_id, language_server_name) in affected_worktrees {
6119                    if let Some(new_server_id) = this
6120                        .language_server_ids
6121                        .get(&(worktree_id, language_server_name.clone()))
6122                        .cloned()
6123                    {
6124                        this.language_server_ids
6125                            .insert((affected_worktree_id, language_server_name), new_server_id);
6126                    }
6127                }
6128            })
6129            .ok();
6130        })
6131        .detach();
6132    }
6133
6134    fn setup_lsp_messages(
6135        this: WeakModel<Self>,
6136        language_server: &LanguageServer,
6137        delegate: Arc<dyn LspAdapterDelegate>,
6138        adapter: Arc<CachedLspAdapter>,
6139    ) {
6140        let name = language_server.name();
6141        let server_id = language_server.server_id();
6142        language_server
6143            .on_notification::<lsp::notification::PublishDiagnostics, _>({
6144                let adapter = adapter.clone();
6145                let this = this.clone();
6146                move |mut params, mut cx| {
6147                    let adapter = adapter.clone();
6148                    if let Some(this) = this.upgrade() {
6149                        adapter.process_diagnostics(&mut params);
6150                        this.update(&mut cx, |this, cx| {
6151                            this.update_diagnostics(
6152                                server_id,
6153                                params,
6154                                &adapter.disk_based_diagnostic_sources,
6155                                cx,
6156                            )
6157                            .log_err();
6158                        })
6159                        .ok();
6160                    }
6161                }
6162            })
6163            .detach();
6164        language_server
6165            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
6166                let adapter = adapter.adapter.clone();
6167                let delegate = delegate.clone();
6168                let this = this.clone();
6169                move |params, mut cx| {
6170                    let adapter = adapter.clone();
6171                    let delegate = delegate.clone();
6172                    let this = this.clone();
6173                    async move {
6174                        let toolchains =
6175                            this.update(&mut cx, |this, cx| this.toolchain_store(cx))?;
6176                        let workspace_config = adapter
6177                            .workspace_configuration(&delegate, toolchains, &mut cx)
6178                            .await?;
6179                        Ok(params
6180                            .items
6181                            .into_iter()
6182                            .map(|item| {
6183                                if let Some(section) = &item.section {
6184                                    workspace_config
6185                                        .get(section)
6186                                        .cloned()
6187                                        .unwrap_or(serde_json::Value::Null)
6188                                } else {
6189                                    workspace_config.clone()
6190                                }
6191                            })
6192                            .collect())
6193                    }
6194                }
6195            })
6196            .detach();
6197
6198        language_server
6199            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
6200                let this = this.clone();
6201                move |_, mut cx| {
6202                    let this = this.clone();
6203                    async move {
6204                        let Some(server) =
6205                            this.update(&mut cx, |this, _| this.language_server_for_id(server_id))?
6206                        else {
6207                            return Ok(None);
6208                        };
6209                        let root = server.root_path();
6210                        let Ok(uri) = Url::from_file_path(&root) else {
6211                            return Ok(None);
6212                        };
6213                        Ok(Some(vec![WorkspaceFolder {
6214                            uri,
6215                            name: Default::default(),
6216                        }]))
6217                    }
6218                }
6219            })
6220            .detach();
6221        // Even though we don't have handling for these requests, respond to them to
6222        // avoid stalling any language server like `gopls` which waits for a response
6223        // to these requests when initializing.
6224        language_server
6225            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
6226                let this = this.clone();
6227                move |params, mut cx| {
6228                    let this = this.clone();
6229                    async move {
6230                        this.update(&mut cx, |this, _| {
6231                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
6232                            {
6233                                if let lsp::NumberOrString::String(token) = params.token {
6234                                    status.progress_tokens.insert(token);
6235                                }
6236                            }
6237                        })?;
6238
6239                        Ok(())
6240                    }
6241                }
6242            })
6243            .detach();
6244
6245        language_server
6246            .on_request::<lsp::request::RegisterCapability, _, _>({
6247                let this = this.clone();
6248                move |params, mut cx| {
6249                    let this = this.clone();
6250                    async move {
6251                        for reg in params.registrations {
6252                            match reg.method.as_str() {
6253                                "workspace/didChangeWatchedFiles" => {
6254                                    if let Some(options) = reg.register_options {
6255                                        let options = serde_json::from_value(options)?;
6256                                        this.update(&mut cx, |this, cx| {
6257                                            this.on_lsp_did_change_watched_files(
6258                                                server_id, &reg.id, options, cx,
6259                                            );
6260                                        })?;
6261                                    }
6262                                }
6263                                "textDocument/rangeFormatting" => {
6264                                    this.update(&mut cx, |this, _| {
6265                                        if let Some(server) = this.language_server_for_id(server_id)
6266                                        {
6267                                            let options = reg
6268                                                .register_options
6269                                                .map(|options| {
6270                                                    serde_json::from_value::<
6271                                                        lsp::DocumentRangeFormattingOptions,
6272                                                    >(
6273                                                        options
6274                                                    )
6275                                                })
6276                                                .transpose()?;
6277                                            let provider = match options {
6278                                                None => OneOf::Left(true),
6279                                                Some(options) => OneOf::Right(options),
6280                                            };
6281                                            server.update_capabilities(|capabilities| {
6282                                                capabilities.document_range_formatting_provider =
6283                                                    Some(provider);
6284                                            })
6285                                        }
6286                                        anyhow::Ok(())
6287                                    })??;
6288                                }
6289                                "textDocument/onTypeFormatting" => {
6290                                    this.update(&mut cx, |this, _| {
6291                                        if let Some(server) = this.language_server_for_id(server_id)
6292                                        {
6293                                            let options = reg
6294                                                .register_options
6295                                                .map(|options| {
6296                                                    serde_json::from_value::<
6297                                                        lsp::DocumentOnTypeFormattingOptions,
6298                                                    >(
6299                                                        options
6300                                                    )
6301                                                })
6302                                                .transpose()?;
6303                                            if let Some(options) = options {
6304                                                server.update_capabilities(|capabilities| {
6305                                                    capabilities
6306                                                        .document_on_type_formatting_provider =
6307                                                        Some(options);
6308                                                })
6309                                            }
6310                                        }
6311                                        anyhow::Ok(())
6312                                    })??;
6313                                }
6314                                "textDocument/formatting" => {
6315                                    this.update(&mut cx, |this, _| {
6316                                        if let Some(server) = this.language_server_for_id(server_id)
6317                                        {
6318                                            let options = reg
6319                                                .register_options
6320                                                .map(|options| {
6321                                                    serde_json::from_value::<
6322                                                        lsp::DocumentFormattingOptions,
6323                                                    >(
6324                                                        options
6325                                                    )
6326                                                })
6327                                                .transpose()?;
6328                                            let provider = match options {
6329                                                None => OneOf::Left(true),
6330                                                Some(options) => OneOf::Right(options),
6331                                            };
6332                                            server.update_capabilities(|capabilities| {
6333                                                capabilities.document_formatting_provider =
6334                                                    Some(provider);
6335                                            })
6336                                        }
6337                                        anyhow::Ok(())
6338                                    })??;
6339                                }
6340                                _ => log::warn!("unhandled capability registration: {reg:?}"),
6341                            }
6342                        }
6343                        Ok(())
6344                    }
6345                }
6346            })
6347            .detach();
6348
6349        language_server
6350            .on_request::<lsp::request::UnregisterCapability, _, _>({
6351                let this = this.clone();
6352                move |params, mut cx| {
6353                    let this = this.clone();
6354                    async move {
6355                        for unreg in params.unregisterations.iter() {
6356                            match unreg.method.as_str() {
6357                                "workspace/didChangeWatchedFiles" => {
6358                                    this.update(&mut cx, |this, cx| {
6359                                        this.on_lsp_unregister_did_change_watched_files(
6360                                            server_id, &unreg.id, cx,
6361                                        );
6362                                    })?;
6363                                }
6364                                "textDocument/rename" => {
6365                                    this.update(&mut cx, |this, _| {
6366                                        if let Some(server) = this.language_server_for_id(server_id)
6367                                        {
6368                                            server.update_capabilities(|capabilities| {
6369                                                capabilities.rename_provider = None
6370                                            })
6371                                        }
6372                                    })?;
6373                                }
6374                                "textDocument/rangeFormatting" => {
6375                                    this.update(&mut cx, |this, _| {
6376                                        if let Some(server) = this.language_server_for_id(server_id)
6377                                        {
6378                                            server.update_capabilities(|capabilities| {
6379                                                capabilities.document_range_formatting_provider =
6380                                                    None
6381                                            })
6382                                        }
6383                                    })?;
6384                                }
6385                                "textDocument/onTypeFormatting" => {
6386                                    this.update(&mut cx, |this, _| {
6387                                        if let Some(server) = this.language_server_for_id(server_id)
6388                                        {
6389                                            server.update_capabilities(|capabilities| {
6390                                                capabilities.document_on_type_formatting_provider =
6391                                                    None;
6392                                            })
6393                                        }
6394                                    })?;
6395                                }
6396                                "textDocument/formatting" => {
6397                                    this.update(&mut cx, |this, _| {
6398                                        if let Some(server) = this.language_server_for_id(server_id)
6399                                        {
6400                                            server.update_capabilities(|capabilities| {
6401                                                capabilities.document_formatting_provider = None;
6402                                            })
6403                                        }
6404                                    })?;
6405                                }
6406                                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
6407                            }
6408                        }
6409                        Ok(())
6410                    }
6411                }
6412            })
6413            .detach();
6414
6415        language_server
6416            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
6417                let adapter = adapter.clone();
6418                let this = this.clone();
6419                move |params, cx| {
6420                    Self::on_lsp_workspace_edit(
6421                        this.clone(),
6422                        params,
6423                        server_id,
6424                        adapter.clone(),
6425                        cx,
6426                    )
6427                }
6428            })
6429            .detach();
6430
6431        language_server
6432            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
6433                let this = this.clone();
6434                move |(), mut cx| {
6435                    let this = this.clone();
6436                    async move {
6437                        this.update(&mut cx, |this, cx| {
6438                            cx.emit(LspStoreEvent::RefreshInlayHints);
6439                            this.downstream_client.as_ref().map(|(client, project_id)| {
6440                                client.send(proto::RefreshInlayHints {
6441                                    project_id: *project_id,
6442                                })
6443                            })
6444                        })?
6445                        .transpose()?;
6446                        Ok(())
6447                    }
6448                }
6449            })
6450            .detach();
6451
6452        language_server
6453            .on_request::<lsp::request::ShowMessageRequest, _, _>({
6454                let this = this.clone();
6455                let name = name.to_string();
6456                move |params, mut cx| {
6457                    let this = this.clone();
6458                    let name = name.to_string();
6459                    async move {
6460                        let actions = params.actions.unwrap_or_default();
6461                        let (tx, mut rx) = smol::channel::bounded(1);
6462                        let request = LanguageServerPromptRequest {
6463                            level: match params.typ {
6464                                lsp::MessageType::ERROR => PromptLevel::Critical,
6465                                lsp::MessageType::WARNING => PromptLevel::Warning,
6466                                _ => PromptLevel::Info,
6467                            },
6468                            message: params.message,
6469                            actions,
6470                            response_channel: tx,
6471                            lsp_name: name.clone(),
6472                        };
6473
6474                        let did_update = this
6475                            .update(&mut cx, |_, cx| {
6476                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
6477                            })
6478                            .is_ok();
6479                        if did_update {
6480                            let response = rx.next().await;
6481
6482                            Ok(response)
6483                        } else {
6484                            Ok(None)
6485                        }
6486                    }
6487                }
6488            })
6489            .detach();
6490
6491        language_server
6492            .on_notification::<ServerStatus, _>({
6493                let this = this.clone();
6494                let name = name.to_string();
6495                move |params, mut cx| {
6496                    let this = this.clone();
6497                    let name = name.to_string();
6498                    if let Some(ref message) = params.message {
6499                        let message = message.trim();
6500                        if !message.is_empty() {
6501                            let formatted_message = format!(
6502                                "Language server {name} (id {server_id}) status update: {message}"
6503                            );
6504                            match params.health {
6505                                ServerHealthStatus::Ok => log::info!("{}", formatted_message),
6506                                ServerHealthStatus::Warning => log::warn!("{}", formatted_message),
6507                                ServerHealthStatus::Error => {
6508                                    log::error!("{}", formatted_message);
6509                                    let (tx, _rx) = smol::channel::bounded(1);
6510                                    let request = LanguageServerPromptRequest {
6511                                        level: PromptLevel::Critical,
6512                                        message: params.message.unwrap_or_default(),
6513                                        actions: Vec::new(),
6514                                        response_channel: tx,
6515                                        lsp_name: name.clone(),
6516                                    };
6517                                    let _ = this
6518                                        .update(&mut cx, |_, cx| {
6519                                            cx.emit(LspStoreEvent::LanguageServerPrompt(request));
6520                                        })
6521                                        .ok();
6522                                }
6523                                ServerHealthStatus::Other(status) => {
6524                                    log::info!(
6525                                        "Unknown server health: {status}\n{formatted_message}"
6526                                    )
6527                                }
6528                            }
6529                        }
6530                    }
6531                }
6532            })
6533            .detach();
6534        language_server
6535            .on_notification::<lsp::notification::ShowMessage, _>({
6536                let this = this.clone();
6537                let name = name.to_string();
6538                move |params, mut cx| {
6539                    let this = this.clone();
6540                    let name = name.to_string();
6541
6542                    let (tx, _) = smol::channel::bounded(1);
6543                    let request = LanguageServerPromptRequest {
6544                        level: match params.typ {
6545                            lsp::MessageType::ERROR => PromptLevel::Critical,
6546                            lsp::MessageType::WARNING => PromptLevel::Warning,
6547                            _ => PromptLevel::Info,
6548                        },
6549                        message: params.message,
6550                        actions: vec![],
6551                        response_channel: tx,
6552                        lsp_name: name.clone(),
6553                    };
6554
6555                    let _ = this.update(&mut cx, |_, cx| {
6556                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
6557                    });
6558                }
6559            })
6560            .detach();
6561
6562        let disk_based_diagnostics_progress_token =
6563            adapter.disk_based_diagnostics_progress_token.clone();
6564
6565        language_server
6566            .on_notification::<lsp::notification::Progress, _>({
6567                let this = this.clone();
6568                move |params, mut cx| {
6569                    if let Some(this) = this.upgrade() {
6570                        this.update(&mut cx, |this, cx| {
6571                            this.on_lsp_progress(
6572                                params,
6573                                server_id,
6574                                disk_based_diagnostics_progress_token.clone(),
6575                                cx,
6576                            );
6577                        })
6578                        .ok();
6579                    }
6580                }
6581            })
6582            .detach();
6583
6584        language_server
6585            .on_notification::<lsp::notification::LogMessage, _>({
6586                let this = this.clone();
6587                move |params, mut cx| {
6588                    if let Some(this) = this.upgrade() {
6589                        this.update(&mut cx, |_, cx| {
6590                            cx.emit(LspStoreEvent::LanguageServerLog(
6591                                server_id,
6592                                LanguageServerLogType::Log(params.typ),
6593                                params.message,
6594                            ));
6595                        })
6596                        .ok();
6597                    }
6598                }
6599            })
6600            .detach();
6601
6602        language_server
6603            .on_notification::<lsp::notification::LogTrace, _>({
6604                let this = this.clone();
6605                move |params, mut cx| {
6606                    if let Some(this) = this.upgrade() {
6607                        this.update(&mut cx, |_, cx| {
6608                            cx.emit(LspStoreEvent::LanguageServerLog(
6609                                server_id,
6610                                LanguageServerLogType::Trace(params.verbose),
6611                                params.message,
6612                            ));
6613                        })
6614                        .ok();
6615                    }
6616                }
6617            })
6618            .detach();
6619    }
6620
6621    pub fn update_diagnostics(
6622        &mut self,
6623        language_server_id: LanguageServerId,
6624        mut params: lsp::PublishDiagnosticsParams,
6625        disk_based_sources: &[String],
6626        cx: &mut ModelContext<Self>,
6627    ) -> Result<()> {
6628        let abs_path = params
6629            .uri
6630            .to_file_path()
6631            .map_err(|_| anyhow!("URI is not a file"))?;
6632        let mut diagnostics = Vec::default();
6633        let mut primary_diagnostic_group_ids = HashMap::default();
6634        let mut sources_by_group_id = HashMap::default();
6635        let mut supporting_diagnostics = HashMap::default();
6636
6637        // Ensure that primary diagnostics are always the most severe
6638        params.diagnostics.sort_by_key(|item| item.severity);
6639
6640        for diagnostic in &params.diagnostics {
6641            let source = diagnostic.source.as_ref();
6642            let code = diagnostic.code.as_ref().map(|code| match code {
6643                lsp::NumberOrString::Number(code) => code.to_string(),
6644                lsp::NumberOrString::String(code) => code.clone(),
6645            });
6646            let range = range_from_lsp(diagnostic.range);
6647            let is_supporting = diagnostic
6648                .related_information
6649                .as_ref()
6650                .map_or(false, |infos| {
6651                    infos.iter().any(|info| {
6652                        primary_diagnostic_group_ids.contains_key(&(
6653                            source,
6654                            code.clone(),
6655                            range_from_lsp(info.location.range),
6656                        ))
6657                    })
6658                });
6659
6660            let is_unnecessary = diagnostic.tags.as_ref().map_or(false, |tags| {
6661                tags.iter().any(|tag| *tag == DiagnosticTag::UNNECESSARY)
6662            });
6663
6664            if is_supporting {
6665                supporting_diagnostics.insert(
6666                    (source, code.clone(), range),
6667                    (diagnostic.severity, is_unnecessary),
6668                );
6669            } else {
6670                let group_id = post_inc(&mut self.next_diagnostic_group_id);
6671                let is_disk_based =
6672                    source.map_or(false, |source| disk_based_sources.contains(source));
6673
6674                sources_by_group_id.insert(group_id, source);
6675                primary_diagnostic_group_ids
6676                    .insert((source, code.clone(), range.clone()), group_id);
6677
6678                diagnostics.push(DiagnosticEntry {
6679                    range,
6680                    diagnostic: Diagnostic {
6681                        source: diagnostic.source.clone(),
6682                        code: code.clone(),
6683                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
6684                        message: diagnostic.message.trim().to_string(),
6685                        group_id,
6686                        is_primary: true,
6687                        is_disk_based,
6688                        is_unnecessary,
6689                        data: diagnostic.data.clone(),
6690                    },
6691                });
6692                if let Some(infos) = &diagnostic.related_information {
6693                    for info in infos {
6694                        if info.location.uri == params.uri && !info.message.is_empty() {
6695                            let range = range_from_lsp(info.location.range);
6696                            diagnostics.push(DiagnosticEntry {
6697                                range,
6698                                diagnostic: Diagnostic {
6699                                    source: diagnostic.source.clone(),
6700                                    code: code.clone(),
6701                                    severity: DiagnosticSeverity::INFORMATION,
6702                                    message: info.message.trim().to_string(),
6703                                    group_id,
6704                                    is_primary: false,
6705                                    is_disk_based,
6706                                    is_unnecessary: false,
6707                                    data: diagnostic.data.clone(),
6708                                },
6709                            });
6710                        }
6711                    }
6712                }
6713            }
6714        }
6715
6716        for entry in &mut diagnostics {
6717            let diagnostic = &mut entry.diagnostic;
6718            if !diagnostic.is_primary {
6719                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
6720                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
6721                    source,
6722                    diagnostic.code.clone(),
6723                    entry.range.clone(),
6724                )) {
6725                    if let Some(severity) = severity {
6726                        diagnostic.severity = severity;
6727                    }
6728                    diagnostic.is_unnecessary = is_unnecessary;
6729                }
6730            }
6731        }
6732
6733        self.update_diagnostic_entries(
6734            language_server_id,
6735            abs_path,
6736            params.version,
6737            diagnostics,
6738            cx,
6739        )?;
6740        Ok(())
6741    }
6742
6743    fn insert_newly_running_language_server(
6744        &mut self,
6745        language: LanguageName,
6746        adapter: Arc<CachedLspAdapter>,
6747        language_server: Arc<LanguageServer>,
6748        server_id: LanguageServerId,
6749        key: (WorktreeId, LanguageServerName),
6750        cx: &mut ModelContext<Self>,
6751    ) {
6752        // If the language server for this key doesn't match the server id, don't store the
6753        // server. Which will cause it to be dropped, killing the process
6754        if self
6755            .language_server_ids
6756            .get(&key)
6757            .map(|id| id != &server_id)
6758            .unwrap_or(false)
6759        {
6760            return;
6761        }
6762
6763        // Update language_servers collection with Running variant of LanguageServerState
6764        // indicating that the server is up and running and ready
6765        if let Some(local) = self.as_local_mut() {
6766            local.language_servers.insert(
6767                server_id,
6768                LanguageServerState::Running {
6769                    adapter: adapter.clone(),
6770                    language: language.clone(),
6771                    server: language_server.clone(),
6772                    simulate_disk_based_diagnostics_completion: None,
6773                },
6774            );
6775            if let Some(file_ops_caps) = language_server
6776                .capabilities()
6777                .workspace
6778                .as_ref()
6779                .and_then(|ws| ws.file_operations.as_ref())
6780            {
6781                let did_rename_caps = file_ops_caps.did_rename.as_ref();
6782                let will_rename_caps = file_ops_caps.will_rename.as_ref();
6783                if did_rename_caps.or(will_rename_caps).is_some() {
6784                    let watcher = RenamePathsWatchedForServer::default()
6785                        .with_did_rename_patterns(did_rename_caps)
6786                        .with_will_rename_patterns(will_rename_caps);
6787                    local
6788                        .language_server_paths_watched_for_rename
6789                        .insert(server_id, watcher);
6790                }
6791            }
6792        }
6793
6794        self.language_server_statuses.insert(
6795            server_id,
6796            LanguageServerStatus {
6797                name: language_server.name().to_string(),
6798                pending_work: Default::default(),
6799                has_pending_diagnostic_updates: false,
6800                progress_tokens: Default::default(),
6801            },
6802        );
6803
6804        cx.emit(LspStoreEvent::LanguageServerAdded(
6805            server_id,
6806            language_server.name(),
6807            Some(key.0),
6808        ));
6809
6810        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
6811            downstream_client
6812                .send(proto::StartLanguageServer {
6813                    project_id: *project_id,
6814                    server: Some(proto::LanguageServer {
6815                        id: server_id.0 as u64,
6816                        name: language_server.name().to_string(),
6817                        worktree_id: Some(key.0.to_proto()),
6818                    }),
6819                })
6820                .log_err();
6821        }
6822
6823        // Tell the language server about every open buffer in the worktree that matches the language.
6824        self.buffer_store.update(cx, |buffer_store, cx| {
6825            for buffer_handle in buffer_store.buffers() {
6826                let buffer = buffer_handle.read(cx);
6827                let file = match File::from_dyn(buffer.file()) {
6828                    Some(file) => file,
6829                    None => continue,
6830                };
6831                let language = match buffer.language() {
6832                    Some(language) => language,
6833                    None => continue,
6834                };
6835
6836                if file.worktree.read(cx).id() != key.0
6837                    || !self
6838                        .languages
6839                        .lsp_adapters(&language.name())
6840                        .iter()
6841                        .any(|a| a.name == key.1)
6842                {
6843                    continue;
6844                }
6845
6846                let file = match file.as_local() {
6847                    Some(file) => file,
6848                    None => continue,
6849                };
6850
6851                let versions = self
6852                    .buffer_snapshots
6853                    .entry(buffer.remote_id())
6854                    .or_default()
6855                    .entry(server_id)
6856                    .or_insert_with(|| {
6857                        vec![LspBufferSnapshot {
6858                            version: 0,
6859                            snapshot: buffer.text_snapshot(),
6860                        }]
6861                    });
6862
6863                let snapshot = versions.last().unwrap();
6864                let version = snapshot.version;
6865                let initial_snapshot = &snapshot.snapshot;
6866                let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
6867                language_server
6868                    .notify::<lsp::notification::DidOpenTextDocument>(
6869                        lsp::DidOpenTextDocumentParams {
6870                            text_document: lsp::TextDocumentItem::new(
6871                                uri,
6872                                adapter.language_id(&language.name()),
6873                                version,
6874                                initial_snapshot.text(),
6875                            ),
6876                        },
6877                    )
6878                    .log_err();
6879
6880                buffer_handle.update(cx, |buffer, cx| {
6881                    buffer.set_completion_triggers(
6882                        server_id,
6883                        language_server
6884                            .capabilities()
6885                            .completion_provider
6886                            .as_ref()
6887                            .and_then(|provider| {
6888                                provider
6889                                    .trigger_characters
6890                                    .as_ref()
6891                                    .map(|characters| characters.iter().cloned().collect())
6892                            })
6893                            .unwrap_or_default(),
6894                        cx,
6895                    )
6896                });
6897            }
6898        });
6899
6900        cx.notify();
6901    }
6902
6903    fn buffer_snapshot_for_lsp_version(
6904        &mut self,
6905        buffer: &Model<Buffer>,
6906        server_id: LanguageServerId,
6907        version: Option<i32>,
6908        cx: &AppContext,
6909    ) -> Result<TextBufferSnapshot> {
6910        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
6911
6912        if let Some(version) = version {
6913            let buffer_id = buffer.read(cx).remote_id();
6914            let snapshots = self
6915                .buffer_snapshots
6916                .get_mut(&buffer_id)
6917                .and_then(|m| m.get_mut(&server_id))
6918                .ok_or_else(|| {
6919                    anyhow!("no snapshots found for buffer {buffer_id} and server {server_id}")
6920                })?;
6921
6922            let found_snapshot = snapshots
6923                    .binary_search_by_key(&version, |e| e.version)
6924                    .map(|ix| snapshots[ix].snapshot.clone())
6925                    .map_err(|_| {
6926                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
6927                    })?;
6928
6929            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
6930            Ok(found_snapshot)
6931        } else {
6932            Ok((buffer.read(cx)).text_snapshot())
6933        }
6934    }
6935
6936    pub fn language_servers_running_disk_based_diagnostics(
6937        &self,
6938    ) -> impl Iterator<Item = LanguageServerId> + '_ {
6939        self.language_server_statuses
6940            .iter()
6941            .filter_map(|(id, status)| {
6942                if status.has_pending_diagnostic_updates {
6943                    Some(*id)
6944                } else {
6945                    None
6946                }
6947            })
6948    }
6949
6950    pub(crate) fn language_servers_for_buffer<'a>(
6951        &'a self,
6952        buffer: &'a Buffer,
6953        cx: &'a AppContext,
6954    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
6955        self.language_server_ids_for_buffer(buffer, cx)
6956            .into_iter()
6957            .filter_map(
6958                |server_id| match self.as_local()?.language_servers.get(&server_id)? {
6959                    LanguageServerState::Running {
6960                        adapter, server, ..
6961                    } => Some((adapter, server)),
6962                    _ => None,
6963                },
6964            )
6965    }
6966
6967    pub(crate) fn cancel_language_server_work_for_buffers(
6968        &mut self,
6969        buffers: impl IntoIterator<Item = Model<Buffer>>,
6970        cx: &mut ModelContext<Self>,
6971    ) {
6972        if let Some((client, project_id)) = self.upstream_client() {
6973            let request = client.request(proto::CancelLanguageServerWork {
6974                project_id,
6975                work: Some(proto::cancel_language_server_work::Work::Buffers(
6976                    proto::cancel_language_server_work::Buffers {
6977                        buffer_ids: buffers
6978                            .into_iter()
6979                            .map(|b| b.read(cx).remote_id().to_proto())
6980                            .collect(),
6981                    },
6982                )),
6983            });
6984            cx.background_executor()
6985                .spawn(request)
6986                .detach_and_log_err(cx);
6987        } else {
6988            let servers = buffers
6989                .into_iter()
6990                .flat_map(|buffer| {
6991                    self.language_server_ids_for_buffer(buffer.read(cx), cx)
6992                        .into_iter()
6993                })
6994                .collect::<HashSet<_>>();
6995
6996            for server_id in servers {
6997                self.cancel_language_server_work(server_id, None, cx);
6998            }
6999        }
7000    }
7001
7002    pub(crate) fn cancel_language_server_work(
7003        &mut self,
7004        server_id: LanguageServerId,
7005        token_to_cancel: Option<String>,
7006        cx: &mut ModelContext<Self>,
7007    ) {
7008        if let Some(local) = self.as_local() {
7009            let status = self.language_server_statuses.get(&server_id);
7010            let server = local.language_servers.get(&server_id);
7011            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
7012            {
7013                for (token, progress) in &status.pending_work {
7014                    if let Some(token_to_cancel) = token_to_cancel.as_ref() {
7015                        if token != token_to_cancel {
7016                            continue;
7017                        }
7018                    }
7019                    if progress.is_cancellable {
7020                        server
7021                            .notify::<lsp::notification::WorkDoneProgressCancel>(
7022                                WorkDoneProgressCancelParams {
7023                                    token: lsp::NumberOrString::String(token.clone()),
7024                                },
7025                            )
7026                            .ok();
7027                    }
7028
7029                    if progress.is_cancellable {
7030                        server
7031                            .notify::<lsp::notification::WorkDoneProgressCancel>(
7032                                WorkDoneProgressCancelParams {
7033                                    token: lsp::NumberOrString::String(token.clone()),
7034                                },
7035                            )
7036                            .ok();
7037                    }
7038                }
7039            }
7040        } else if let Some((client, project_id)) = self.upstream_client() {
7041            let request = client.request(proto::CancelLanguageServerWork {
7042                project_id,
7043                work: Some(
7044                    proto::cancel_language_server_work::Work::LanguageServerWork(
7045                        proto::cancel_language_server_work::LanguageServerWork {
7046                            language_server_id: server_id.to_proto(),
7047                            token: token_to_cancel,
7048                        },
7049                    ),
7050                ),
7051            });
7052            cx.background_executor()
7053                .spawn(request)
7054                .detach_and_log_err(cx);
7055        }
7056    }
7057
7058    pub fn language_servers(
7059        &self,
7060    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName, WorktreeId)> {
7061        self.language_server_ids
7062            .iter()
7063            .map(|((worktree_id, server_name), server_id)| {
7064                (*server_id, server_name.clone(), *worktree_id)
7065            })
7066    }
7067
7068    fn register_supplementary_language_server(
7069        &mut self,
7070        id: LanguageServerId,
7071        name: LanguageServerName,
7072        server: Arc<LanguageServer>,
7073        cx: &mut ModelContext<Self>,
7074    ) {
7075        if let Some(local) = self.as_local_mut() {
7076            local
7077                .supplementary_language_servers
7078                .insert(id, (name.clone(), server));
7079            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
7080        }
7081    }
7082
7083    fn unregister_supplementary_language_server(
7084        &mut self,
7085        id: LanguageServerId,
7086        cx: &mut ModelContext<Self>,
7087    ) {
7088        if let Some(local) = self.as_local_mut() {
7089            local.supplementary_language_servers.remove(&id);
7090            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
7091        }
7092    }
7093
7094    pub fn supplementary_language_servers(
7095        &self,
7096    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
7097        self.as_local().into_iter().flat_map(|local| {
7098            local
7099                .supplementary_language_servers
7100                .iter()
7101                .map(|(id, (name, _))| (*id, name.clone()))
7102        })
7103    }
7104
7105    pub fn language_server_adapter_for_id(
7106        &self,
7107        id: LanguageServerId,
7108    ) -> Option<Arc<CachedLspAdapter>> {
7109        self.as_local()
7110            .and_then(|local| local.language_servers.get(&id))
7111            .and_then(|language_server_state| match language_server_state {
7112                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
7113                _ => None,
7114            })
7115    }
7116
7117    pub(super) fn update_local_worktree_language_servers(
7118        &mut self,
7119        worktree_handle: &Model<Worktree>,
7120        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
7121        cx: &mut ModelContext<Self>,
7122    ) {
7123        if changes.is_empty() {
7124            return;
7125        }
7126
7127        let Some(local) = self.as_local() else { return };
7128
7129        local.prettier_store.update(cx, |prettier_store, cx| {
7130            prettier_store.update_prettier_settings(&worktree_handle, changes, cx)
7131        });
7132
7133        let worktree_id = worktree_handle.read(cx).id();
7134        let mut language_server_ids = self
7135            .language_server_ids
7136            .iter()
7137            .filter_map(|((server_worktree_id, _), server_id)| {
7138                (*server_worktree_id == worktree_id).then_some(*server_id)
7139            })
7140            .collect::<Vec<_>>();
7141        language_server_ids.sort();
7142        language_server_ids.dedup();
7143
7144        let abs_path = worktree_handle.read(cx).abs_path();
7145        for server_id in &language_server_ids {
7146            if let Some(LanguageServerState::Running { server, .. }) =
7147                local.language_servers.get(server_id)
7148            {
7149                if let Some(watched_paths) = local
7150                    .language_server_watched_paths
7151                    .get(server_id)
7152                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
7153                {
7154                    let params = lsp::DidChangeWatchedFilesParams {
7155                        changes: changes
7156                            .iter()
7157                            .filter_map(|(path, _, change)| {
7158                                if !watched_paths.is_match(path) {
7159                                    return None;
7160                                }
7161                                let typ = match change {
7162                                    PathChange::Loaded => return None,
7163                                    PathChange::Added => lsp::FileChangeType::CREATED,
7164                                    PathChange::Removed => lsp::FileChangeType::DELETED,
7165                                    PathChange::Updated => lsp::FileChangeType::CHANGED,
7166                                    PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
7167                                };
7168                                Some(lsp::FileEvent {
7169                                    uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
7170                                    typ,
7171                                })
7172                            })
7173                            .collect(),
7174                    };
7175                    if !params.changes.is_empty() {
7176                        server
7177                            .notify::<lsp::notification::DidChangeWatchedFiles>(params)
7178                            .log_err();
7179                    }
7180                }
7181            }
7182        }
7183    }
7184
7185    pub fn wait_for_remote_buffer(
7186        &mut self,
7187        id: BufferId,
7188        cx: &mut ModelContext<Self>,
7189    ) -> Task<Result<Model<Buffer>>> {
7190        self.buffer_store.update(cx, |buffer_store, cx| {
7191            buffer_store.wait_for_remote_buffer(id, cx)
7192        })
7193    }
7194
7195    pub(crate) fn language_server_ids_for_buffer(
7196        &self,
7197        buffer: &Buffer,
7198        cx: &AppContext,
7199    ) -> Vec<LanguageServerId> {
7200        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
7201            let worktree_id = file.worktree_id(cx);
7202            self.languages
7203                .lsp_adapters(&language.name())
7204                .iter()
7205                .flat_map(|adapter| {
7206                    let key = (worktree_id, adapter.name.clone());
7207                    self.language_server_ids.get(&key).copied()
7208                })
7209                .collect()
7210        } else {
7211            Vec::new()
7212        }
7213    }
7214
7215    pub async fn deserialize_text_edits(
7216        this: Model<Self>,
7217        buffer_to_edit: Model<Buffer>,
7218        edits: Vec<lsp::TextEdit>,
7219        push_to_history: bool,
7220        _: Arc<CachedLspAdapter>,
7221        language_server: Arc<LanguageServer>,
7222        cx: &mut AsyncAppContext,
7223    ) -> Result<Option<Transaction>> {
7224        let edits = this
7225            .update(cx, |this, cx| {
7226                this.edits_from_lsp(
7227                    &buffer_to_edit,
7228                    edits,
7229                    language_server.server_id(),
7230                    None,
7231                    cx,
7232                )
7233            })?
7234            .await?;
7235
7236        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
7237            buffer.finalize_last_transaction();
7238            buffer.start_transaction();
7239            for (range, text) in edits {
7240                buffer.edit([(range, text)], None, cx);
7241            }
7242
7243            if buffer.end_transaction(cx).is_some() {
7244                let transaction = buffer.finalize_last_transaction().unwrap().clone();
7245                if !push_to_history {
7246                    buffer.forget_transaction(transaction.id);
7247                }
7248                Some(transaction)
7249            } else {
7250                None
7251            }
7252        })?;
7253
7254        Ok(transaction)
7255    }
7256
7257    pub(crate) async fn deserialize_workspace_edit(
7258        this: Model<Self>,
7259        edit: lsp::WorkspaceEdit,
7260        push_to_history: bool,
7261        lsp_adapter: Arc<CachedLspAdapter>,
7262        language_server: Arc<LanguageServer>,
7263        cx: &mut AsyncAppContext,
7264    ) -> Result<ProjectTransaction> {
7265        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
7266
7267        let mut operations = Vec::new();
7268        if let Some(document_changes) = edit.document_changes {
7269            match document_changes {
7270                lsp::DocumentChanges::Edits(edits) => {
7271                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
7272                }
7273                lsp::DocumentChanges::Operations(ops) => operations = ops,
7274            }
7275        } else if let Some(changes) = edit.changes {
7276            operations.extend(changes.into_iter().map(|(uri, edits)| {
7277                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
7278                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
7279                        uri,
7280                        version: None,
7281                    },
7282                    edits: edits.into_iter().map(Edit::Plain).collect(),
7283                })
7284            }));
7285        }
7286
7287        let mut project_transaction = ProjectTransaction::default();
7288        for operation in operations {
7289            match operation {
7290                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
7291                    let abs_path = op
7292                        .uri
7293                        .to_file_path()
7294                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7295
7296                    if let Some(parent_path) = abs_path.parent() {
7297                        fs.create_dir(parent_path).await?;
7298                    }
7299                    if abs_path.ends_with("/") {
7300                        fs.create_dir(&abs_path).await?;
7301                    } else {
7302                        fs.create_file(
7303                            &abs_path,
7304                            op.options
7305                                .map(|options| fs::CreateOptions {
7306                                    overwrite: options.overwrite.unwrap_or(false),
7307                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
7308                                })
7309                                .unwrap_or_default(),
7310                        )
7311                        .await?;
7312                    }
7313                }
7314
7315                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
7316                    let source_abs_path = op
7317                        .old_uri
7318                        .to_file_path()
7319                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7320                    let target_abs_path = op
7321                        .new_uri
7322                        .to_file_path()
7323                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7324                    fs.rename(
7325                        &source_abs_path,
7326                        &target_abs_path,
7327                        op.options
7328                            .map(|options| fs::RenameOptions {
7329                                overwrite: options.overwrite.unwrap_or(false),
7330                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
7331                            })
7332                            .unwrap_or_default(),
7333                    )
7334                    .await?;
7335                }
7336
7337                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
7338                    let abs_path = op
7339                        .uri
7340                        .to_file_path()
7341                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7342                    let options = op
7343                        .options
7344                        .map(|options| fs::RemoveOptions {
7345                            recursive: options.recursive.unwrap_or(false),
7346                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
7347                        })
7348                        .unwrap_or_default();
7349                    if abs_path.ends_with("/") {
7350                        fs.remove_dir(&abs_path, options).await?;
7351                    } else {
7352                        fs.remove_file(&abs_path, options).await?;
7353                    }
7354                }
7355
7356                lsp::DocumentChangeOperation::Edit(op) => {
7357                    let buffer_to_edit = this
7358                        .update(cx, |this, cx| {
7359                            this.open_local_buffer_via_lsp(
7360                                op.text_document.uri.clone(),
7361                                language_server.server_id(),
7362                                lsp_adapter.name.clone(),
7363                                cx,
7364                            )
7365                        })?
7366                        .await?;
7367
7368                    let edits = this
7369                        .update(cx, |this, cx| {
7370                            let path = buffer_to_edit.read(cx).project_path(cx);
7371                            let active_entry = this.active_entry;
7372                            let is_active_entry = path.clone().map_or(false, |project_path| {
7373                                this.worktree_store
7374                                    .read(cx)
7375                                    .entry_for_path(&project_path, cx)
7376                                    .map_or(false, |entry| Some(entry.id) == active_entry)
7377                            });
7378
7379                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
7380                            for edit in op.edits {
7381                                match edit {
7382                                    Edit::Plain(edit) => edits.push(edit),
7383                                    Edit::Annotated(edit) => edits.push(edit.text_edit),
7384                                    Edit::Snippet(edit) => {
7385                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
7386                                        else {
7387                                            continue;
7388                                        };
7389
7390                                        if is_active_entry {
7391                                            snippet_edits.push((edit.range, snippet));
7392                                        } else {
7393                                            // Since this buffer is not focused, apply a normal edit.
7394                                            edits.push(TextEdit {
7395                                                range: edit.range,
7396                                                new_text: snippet.text,
7397                                            });
7398                                        }
7399                                    }
7400                                }
7401                            }
7402                            if !snippet_edits.is_empty() {
7403                                let buffer_id = buffer_to_edit.read(cx).remote_id();
7404                                let version = if let Some(buffer_version) = op.text_document.version
7405                                {
7406                                    this.buffer_snapshot_for_lsp_version(
7407                                        &buffer_to_edit,
7408                                        language_server.server_id(),
7409                                        Some(buffer_version),
7410                                        cx,
7411                                    )
7412                                    .ok()
7413                                    .map(|snapshot| snapshot.version)
7414                                } else {
7415                                    Some(buffer_to_edit.read(cx).saved_version().clone())
7416                                };
7417
7418                                let most_recent_edit = version.and_then(|version| {
7419                                    version.iter().max_by_key(|timestamp| timestamp.value)
7420                                });
7421                                // Check if the edit that triggered that edit has been made by this participant.
7422
7423                                if let Some(most_recent_edit) = most_recent_edit {
7424                                    cx.emit(LspStoreEvent::SnippetEdit {
7425                                        buffer_id,
7426                                        edits: snippet_edits,
7427                                        most_recent_edit,
7428                                    });
7429                                }
7430                            }
7431
7432                            this.edits_from_lsp(
7433                                &buffer_to_edit,
7434                                edits,
7435                                language_server.server_id(),
7436                                op.text_document.version,
7437                                cx,
7438                            )
7439                        })?
7440                        .await?;
7441
7442                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
7443                        buffer.finalize_last_transaction();
7444                        buffer.start_transaction();
7445                        for (range, text) in edits {
7446                            buffer.edit([(range, text)], None, cx);
7447                        }
7448                        let transaction = if buffer.end_transaction(cx).is_some() {
7449                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
7450                            if !push_to_history {
7451                                buffer.forget_transaction(transaction.id);
7452                            }
7453                            Some(transaction)
7454                        } else {
7455                            None
7456                        };
7457
7458                        transaction
7459                    })?;
7460                    if let Some(transaction) = transaction {
7461                        project_transaction.0.insert(buffer_to_edit, transaction);
7462                    }
7463                }
7464            }
7465        }
7466
7467        Ok(project_transaction)
7468    }
7469
7470    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
7471        proto::Symbol {
7472            language_server_name: symbol.language_server_name.0.to_string(),
7473            source_worktree_id: symbol.source_worktree_id.to_proto(),
7474            worktree_id: symbol.path.worktree_id.to_proto(),
7475            path: symbol.path.path.to_string_lossy().to_string(),
7476            name: symbol.name.clone(),
7477            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
7478            start: Some(proto::PointUtf16 {
7479                row: symbol.range.start.0.row,
7480                column: symbol.range.start.0.column,
7481            }),
7482            end: Some(proto::PointUtf16 {
7483                row: symbol.range.end.0.row,
7484                column: symbol.range.end.0.column,
7485            }),
7486            signature: symbol.signature.to_vec(),
7487        }
7488    }
7489
7490    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
7491        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
7492        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
7493        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
7494        let path = ProjectPath {
7495            worktree_id,
7496            path: PathBuf::from(serialized_symbol.path).into(),
7497        };
7498
7499        let start = serialized_symbol
7500            .start
7501            .ok_or_else(|| anyhow!("invalid start"))?;
7502        let end = serialized_symbol
7503            .end
7504            .ok_or_else(|| anyhow!("invalid end"))?;
7505        Ok(CoreSymbol {
7506            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
7507            source_worktree_id,
7508            path,
7509            name: serialized_symbol.name,
7510            range: Unclipped(PointUtf16::new(start.row, start.column))
7511                ..Unclipped(PointUtf16::new(end.row, end.column)),
7512            kind,
7513            signature: serialized_symbol
7514                .signature
7515                .try_into()
7516                .map_err(|_| anyhow!("invalid signature"))?,
7517        })
7518    }
7519
7520    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
7521        proto::Completion {
7522            old_start: Some(serialize_anchor(&completion.old_range.start)),
7523            old_end: Some(serialize_anchor(&completion.old_range.end)),
7524            new_text: completion.new_text.clone(),
7525            server_id: completion.server_id.0 as u64,
7526            lsp_completion: serde_json::to_vec(&completion.lsp_completion).unwrap(),
7527        }
7528    }
7529
7530    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
7531        let old_start = completion
7532            .old_start
7533            .and_then(deserialize_anchor)
7534            .ok_or_else(|| anyhow!("invalid old start"))?;
7535        let old_end = completion
7536            .old_end
7537            .and_then(deserialize_anchor)
7538            .ok_or_else(|| anyhow!("invalid old end"))?;
7539        let lsp_completion = serde_json::from_slice(&completion.lsp_completion)?;
7540
7541        Ok(CoreCompletion {
7542            old_range: old_start..old_end,
7543            new_text: completion.new_text,
7544            server_id: LanguageServerId(completion.server_id as usize),
7545            lsp_completion,
7546        })
7547    }
7548
7549    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
7550        proto::CodeAction {
7551            server_id: action.server_id.0 as u64,
7552            start: Some(serialize_anchor(&action.range.start)),
7553            end: Some(serialize_anchor(&action.range.end)),
7554            lsp_action: serde_json::to_vec(&action.lsp_action).unwrap(),
7555        }
7556    }
7557
7558    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
7559        let start = action
7560            .start
7561            .and_then(deserialize_anchor)
7562            .ok_or_else(|| anyhow!("invalid start"))?;
7563        let end = action
7564            .end
7565            .and_then(deserialize_anchor)
7566            .ok_or_else(|| anyhow!("invalid end"))?;
7567        let lsp_action = serde_json::from_slice(&action.lsp_action)?;
7568        Ok(CodeAction {
7569            server_id: LanguageServerId(action.server_id as usize),
7570            range: start..end,
7571            lsp_action,
7572        })
7573    }
7574
7575    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
7576        match &formatting_result {
7577            Ok(_) => self.last_formatting_failure = None,
7578            Err(error) => {
7579                let error_string = format!("{error:#}");
7580                log::error!("Formatting failed: {error_string}");
7581                self.last_formatting_failure
7582                    .replace(error_string.lines().join(" "));
7583            }
7584        }
7585    }
7586}
7587
7588impl EventEmitter<LspStoreEvent> for LspStore {}
7589
7590fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
7591    hover
7592        .contents
7593        .retain(|hover_block| !hover_block.text.trim().is_empty());
7594    if hover.contents.is_empty() {
7595        None
7596    } else {
7597        Some(hover)
7598    }
7599}
7600
7601async fn populate_labels_for_completions(
7602    mut new_completions: Vec<CoreCompletion>,
7603    language_registry: &Arc<LanguageRegistry>,
7604    language: Option<Arc<Language>>,
7605    lsp_adapter: Option<Arc<CachedLspAdapter>>,
7606    completions: &mut Vec<Completion>,
7607) {
7608    let lsp_completions = new_completions
7609        .iter_mut()
7610        .map(|completion| mem::take(&mut completion.lsp_completion))
7611        .collect::<Vec<_>>();
7612
7613    let labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
7614        lsp_adapter
7615            .labels_for_completions(&lsp_completions, language)
7616            .await
7617            .log_err()
7618            .unwrap_or_default()
7619    } else {
7620        Vec::new()
7621    };
7622
7623    for ((completion, lsp_completion), label) in new_completions
7624        .into_iter()
7625        .zip(lsp_completions)
7626        .zip(labels.into_iter().chain(iter::repeat(None)))
7627    {
7628        let documentation = if let Some(docs) = &lsp_completion.documentation {
7629            Some(prepare_completion_documentation(docs, language_registry, language.clone()).await)
7630        } else {
7631            None
7632        };
7633
7634        completions.push(Completion {
7635            old_range: completion.old_range,
7636            new_text: completion.new_text,
7637            label: label.unwrap_or_else(|| {
7638                CodeLabel::plain(
7639                    lsp_completion.label.clone(),
7640                    lsp_completion.filter_text.as_deref(),
7641                )
7642            }),
7643            server_id: completion.server_id,
7644            documentation,
7645            lsp_completion,
7646            confirm: None,
7647        })
7648    }
7649}
7650
7651#[derive(Debug)]
7652pub enum LanguageServerToQuery {
7653    Primary,
7654    Other(LanguageServerId),
7655}
7656
7657#[derive(Default)]
7658struct RenamePathsWatchedForServer {
7659    did_rename: Vec<RenameActionPredicate>,
7660    will_rename: Vec<RenameActionPredicate>,
7661}
7662
7663impl RenamePathsWatchedForServer {
7664    fn with_did_rename_patterns(
7665        mut self,
7666        did_rename: Option<&FileOperationRegistrationOptions>,
7667    ) -> Self {
7668        if let Some(did_rename) = did_rename {
7669            self.did_rename = did_rename
7670                .filters
7671                .iter()
7672                .filter_map(|filter| filter.try_into().log_err())
7673                .collect();
7674        }
7675        self
7676    }
7677    fn with_will_rename_patterns(
7678        mut self,
7679        will_rename: Option<&FileOperationRegistrationOptions>,
7680    ) -> Self {
7681        if let Some(will_rename) = will_rename {
7682            self.will_rename = will_rename
7683                .filters
7684                .iter()
7685                .filter_map(|filter| filter.try_into().log_err())
7686                .collect();
7687        }
7688        self
7689    }
7690
7691    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
7692        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
7693    }
7694    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
7695        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
7696    }
7697}
7698
7699impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
7700    type Error = globset::Error;
7701    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
7702        Ok(Self {
7703            kind: ops.pattern.matches.clone(),
7704            glob: GlobBuilder::new(&ops.pattern.glob)
7705                .case_insensitive(
7706                    ops.pattern
7707                        .options
7708                        .as_ref()
7709                        .map_or(false, |ops| ops.ignore_case.unwrap_or(false)),
7710                )
7711                .build()?
7712                .compile_matcher(),
7713        })
7714    }
7715}
7716struct RenameActionPredicate {
7717    glob: GlobMatcher,
7718    kind: Option<FileOperationPatternKind>,
7719}
7720
7721impl RenameActionPredicate {
7722    // Returns true if language server should be notified
7723    fn eval(&self, path: &str, is_dir: bool) -> bool {
7724        self.kind.as_ref().map_or(true, |kind| {
7725            let expected_kind = if is_dir {
7726                FileOperationPatternKind::Folder
7727            } else {
7728                FileOperationPatternKind::File
7729            };
7730            kind == &expected_kind
7731        }) && self.glob.is_match(path)
7732    }
7733}
7734
7735#[derive(Default)]
7736struct LanguageServerWatchedPaths {
7737    worktree_paths: HashMap<WorktreeId, GlobSet>,
7738    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
7739}
7740
7741#[derive(Default)]
7742struct LanguageServerWatchedPathsBuilder {
7743    worktree_paths: HashMap<WorktreeId, GlobSet>,
7744    abs_paths: HashMap<Arc<Path>, GlobSet>,
7745}
7746
7747impl LanguageServerWatchedPathsBuilder {
7748    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
7749        self.worktree_paths.insert(worktree_id, glob_set);
7750    }
7751    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
7752        self.abs_paths.insert(path, glob_set);
7753    }
7754    fn build(
7755        self,
7756        fs: Arc<dyn Fs>,
7757        language_server_id: LanguageServerId,
7758        cx: &mut ModelContext<LspStore>,
7759    ) -> LanguageServerWatchedPaths {
7760        let project = cx.weak_model();
7761
7762        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
7763        let abs_paths = self
7764            .abs_paths
7765            .into_iter()
7766            .map(|(abs_path, globset)| {
7767                let task = cx.spawn({
7768                    let abs_path = abs_path.clone();
7769                    let fs = fs.clone();
7770
7771                    let lsp_store = project.clone();
7772                    |_, mut cx| async move {
7773                        maybe!(async move {
7774                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
7775                            while let Some(update) = push_updates.0.next().await {
7776                                let action = lsp_store
7777                                    .update(&mut cx, |this, _| {
7778                                        let Some(local) = this.as_local() else {
7779                                            return ControlFlow::Break(());
7780                                        };
7781                                        let Some(watcher) = local
7782                                            .language_server_watched_paths
7783                                            .get(&language_server_id)
7784                                        else {
7785                                            return ControlFlow::Break(());
7786                                        };
7787                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
7788                                            "Watched abs path is not registered with a watcher",
7789                                        );
7790                                        let matching_entries = update
7791                                            .into_iter()
7792                                            .filter(|event| globs.is_match(&event.path))
7793                                            .collect::<Vec<_>>();
7794                                        this.lsp_notify_abs_paths_changed(
7795                                            language_server_id,
7796                                            matching_entries,
7797                                        );
7798                                        ControlFlow::Continue(())
7799                                    })
7800                                    .ok()?;
7801
7802                                if action.is_break() {
7803                                    break;
7804                                }
7805                            }
7806                            Some(())
7807                        })
7808                        .await;
7809                    }
7810                });
7811                (abs_path, (globset, task))
7812            })
7813            .collect();
7814        LanguageServerWatchedPaths {
7815            worktree_paths: self.worktree_paths,
7816            abs_paths,
7817        }
7818    }
7819}
7820
7821struct LspBufferSnapshot {
7822    version: i32,
7823    snapshot: TextBufferSnapshot,
7824}
7825
7826/// A prompt requested by LSP server.
7827#[derive(Clone, Debug)]
7828pub struct LanguageServerPromptRequest {
7829    pub level: PromptLevel,
7830    pub message: String,
7831    pub actions: Vec<MessageActionItem>,
7832    pub lsp_name: String,
7833    pub(crate) response_channel: Sender<MessageActionItem>,
7834}
7835
7836impl LanguageServerPromptRequest {
7837    pub async fn respond(self, index: usize) -> Option<()> {
7838        if let Some(response) = self.actions.into_iter().nth(index) {
7839            self.response_channel.send(response).await.ok()
7840        } else {
7841            None
7842        }
7843    }
7844}
7845impl PartialEq for LanguageServerPromptRequest {
7846    fn eq(&self, other: &Self) -> bool {
7847        self.message == other.message && self.actions == other.actions
7848    }
7849}
7850
7851#[derive(Clone, Debug, PartialEq)]
7852pub enum LanguageServerLogType {
7853    Log(MessageType),
7854    Trace(Option<String>),
7855}
7856
7857impl LanguageServerLogType {
7858    pub fn to_proto(&self) -> proto::language_server_log::LogType {
7859        match self {
7860            Self::Log(log_type) => {
7861                let message_type = match *log_type {
7862                    MessageType::ERROR => 1,
7863                    MessageType::WARNING => 2,
7864                    MessageType::INFO => 3,
7865                    MessageType::LOG => 4,
7866                    other => {
7867                        log::warn!("Unknown lsp log message type: {:?}", other);
7868                        4
7869                    }
7870                };
7871                proto::language_server_log::LogType::LogMessageType(message_type)
7872            }
7873            Self::Trace(message) => {
7874                proto::language_server_log::LogType::LogTrace(proto::LspLogTrace {
7875                    message: message.clone(),
7876                })
7877            }
7878        }
7879    }
7880
7881    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
7882        match log_type {
7883            proto::language_server_log::LogType::LogMessageType(message_type) => {
7884                Self::Log(match message_type {
7885                    1 => MessageType::ERROR,
7886                    2 => MessageType::WARNING,
7887                    3 => MessageType::INFO,
7888                    4 => MessageType::LOG,
7889                    _ => MessageType::LOG,
7890                })
7891            }
7892            proto::language_server_log::LogType::LogTrace(trace) => Self::Trace(trace.message),
7893        }
7894    }
7895}
7896
7897pub enum LanguageServerState {
7898    Starting(Task<Option<Arc<LanguageServer>>>),
7899
7900    Running {
7901        language: LanguageName,
7902        adapter: Arc<CachedLspAdapter>,
7903        server: Arc<LanguageServer>,
7904        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
7905    },
7906}
7907
7908impl std::fmt::Debug for LanguageServerState {
7909    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7910        match self {
7911            LanguageServerState::Starting(_) => {
7912                f.debug_struct("LanguageServerState::Starting").finish()
7913            }
7914            LanguageServerState::Running { language, .. } => f
7915                .debug_struct("LanguageServerState::Running")
7916                .field("language", &language)
7917                .finish(),
7918        }
7919    }
7920}
7921
7922#[derive(Clone, Debug, Serialize)]
7923pub struct LanguageServerProgress {
7924    pub is_disk_based_diagnostics_progress: bool,
7925    pub is_cancellable: bool,
7926    pub title: Option<String>,
7927    pub message: Option<String>,
7928    pub percentage: Option<usize>,
7929    #[serde(skip_serializing)]
7930    pub last_update_at: Instant,
7931}
7932
7933#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
7934pub struct DiagnosticSummary {
7935    pub error_count: usize,
7936    pub warning_count: usize,
7937}
7938
7939impl DiagnosticSummary {
7940    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
7941        let mut this = Self {
7942            error_count: 0,
7943            warning_count: 0,
7944        };
7945
7946        for entry in diagnostics {
7947            if entry.diagnostic.is_primary {
7948                match entry.diagnostic.severity {
7949                    DiagnosticSeverity::ERROR => this.error_count += 1,
7950                    DiagnosticSeverity::WARNING => this.warning_count += 1,
7951                    _ => {}
7952                }
7953            }
7954        }
7955
7956        this
7957    }
7958
7959    pub fn is_empty(&self) -> bool {
7960        self.error_count == 0 && self.warning_count == 0
7961    }
7962
7963    pub fn to_proto(
7964        &self,
7965        language_server_id: LanguageServerId,
7966        path: &Path,
7967    ) -> proto::DiagnosticSummary {
7968        proto::DiagnosticSummary {
7969            path: path.to_string_lossy().to_string(),
7970            language_server_id: language_server_id.0 as u64,
7971            error_count: self.error_count as u32,
7972            warning_count: self.warning_count as u32,
7973        }
7974    }
7975}
7976
7977fn glob_literal_prefix(glob: &str) -> &str {
7978    let is_absolute = glob.starts_with(path::MAIN_SEPARATOR);
7979
7980    let mut literal_end = is_absolute as usize;
7981    for (i, part) in glob.split(path::MAIN_SEPARATOR).enumerate() {
7982        if part.contains(['*', '?', '{', '}']) {
7983            break;
7984        } else {
7985            if i > 0 {
7986                // Account for separator prior to this part
7987                literal_end += path::MAIN_SEPARATOR.len_utf8();
7988            }
7989            literal_end += part.len();
7990        }
7991    }
7992    let literal_end = literal_end.min(glob.len());
7993    &glob[..literal_end]
7994}
7995
7996pub struct SshLspAdapter {
7997    name: LanguageServerName,
7998    binary: LanguageServerBinary,
7999    initialization_options: Option<String>,
8000    code_action_kinds: Option<Vec<CodeActionKind>>,
8001}
8002
8003impl SshLspAdapter {
8004    pub fn new(
8005        name: LanguageServerName,
8006        binary: LanguageServerBinary,
8007        initialization_options: Option<String>,
8008        code_action_kinds: Option<String>,
8009    ) -> Self {
8010        Self {
8011            name,
8012            binary,
8013            initialization_options,
8014            code_action_kinds: code_action_kinds
8015                .as_ref()
8016                .and_then(|c| serde_json::from_str(c).ok()),
8017        }
8018    }
8019}
8020
8021#[async_trait(?Send)]
8022impl LspAdapter for SshLspAdapter {
8023    fn name(&self) -> LanguageServerName {
8024        self.name.clone()
8025    }
8026
8027    async fn initialization_options(
8028        self: Arc<Self>,
8029        _: &Arc<dyn LspAdapterDelegate>,
8030    ) -> Result<Option<serde_json::Value>> {
8031        let Some(options) = &self.initialization_options else {
8032            return Ok(None);
8033        };
8034        let result = serde_json::from_str(options)?;
8035        Ok(result)
8036    }
8037
8038    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
8039        self.code_action_kinds.clone()
8040    }
8041
8042    async fn check_if_user_installed(
8043        &self,
8044        _: &dyn LspAdapterDelegate,
8045        _: Arc<dyn LanguageToolchainStore>,
8046        _: &AsyncAppContext,
8047    ) -> Option<LanguageServerBinary> {
8048        Some(self.binary.clone())
8049    }
8050
8051    async fn cached_server_binary(
8052        &self,
8053        _: PathBuf,
8054        _: &dyn LspAdapterDelegate,
8055    ) -> Option<LanguageServerBinary> {
8056        None
8057    }
8058
8059    async fn fetch_latest_server_version(
8060        &self,
8061        _: &dyn LspAdapterDelegate,
8062    ) -> Result<Box<dyn 'static + Send + Any>> {
8063        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
8064    }
8065
8066    async fn fetch_server_binary(
8067        &self,
8068        _: Box<dyn 'static + Send + Any>,
8069        _: PathBuf,
8070        _: &dyn LspAdapterDelegate,
8071    ) -> Result<LanguageServerBinary> {
8072        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
8073    }
8074}
8075
8076pub fn language_server_settings<'a, 'b: 'a>(
8077    delegate: &'a dyn LspAdapterDelegate,
8078    language: &LanguageServerName,
8079    cx: &'b AppContext,
8080) -> Option<&'a LspSettings> {
8081    ProjectSettings::get(
8082        Some(SettingsLocation {
8083            worktree_id: delegate.worktree_id(),
8084            path: delegate.worktree_root_path(),
8085        }),
8086        cx,
8087    )
8088    .lsp
8089    .get(language)
8090}
8091
8092pub struct LocalLspAdapterDelegate {
8093    lsp_store: WeakModel<LspStore>,
8094    worktree: worktree::Snapshot,
8095    fs: Arc<dyn Fs>,
8096    http_client: Arc<dyn HttpClient>,
8097    language_registry: Arc<LanguageRegistry>,
8098    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
8099}
8100
8101impl LocalLspAdapterDelegate {
8102    fn for_local(
8103        lsp_store: &LspStore,
8104        worktree: &Model<Worktree>,
8105        cx: &mut ModelContext<LspStore>,
8106    ) -> Arc<Self> {
8107        let local = lsp_store
8108            .as_local()
8109            .expect("LocalLspAdapterDelegate cannot be constructed on a remote");
8110
8111        let http_client = local.http_client.clone();
8112
8113        Self::new(lsp_store, worktree, http_client, local.fs.clone(), cx)
8114    }
8115
8116    pub fn new(
8117        lsp_store: &LspStore,
8118        worktree: &Model<Worktree>,
8119        http_client: Arc<dyn HttpClient>,
8120        fs: Arc<dyn Fs>,
8121        cx: &mut ModelContext<LspStore>,
8122    ) -> Arc<Self> {
8123        let worktree_id = worktree.read(cx).id();
8124        let worktree_abs_path = worktree.read(cx).abs_path();
8125        let load_shell_env_task = if let Some(environment) =
8126            &lsp_store.as_local().map(|local| local.environment.clone())
8127        {
8128            environment.update(cx, |env, cx| {
8129                env.get_environment(Some(worktree_id), Some(worktree_abs_path), cx)
8130            })
8131        } else {
8132            Task::ready(None).shared()
8133        };
8134
8135        Arc::new(Self {
8136            lsp_store: cx.weak_model(),
8137            worktree: worktree.read(cx).snapshot(),
8138            fs,
8139            http_client,
8140            language_registry: lsp_store.languages.clone(),
8141            load_shell_env_task,
8142        })
8143    }
8144}
8145
8146#[async_trait]
8147impl LspAdapterDelegate for LocalLspAdapterDelegate {
8148    fn show_notification(&self, message: &str, cx: &mut AppContext) {
8149        self.lsp_store
8150            .update(cx, |_, cx| {
8151                cx.emit(LspStoreEvent::Notification(message.to_owned()))
8152            })
8153            .ok();
8154    }
8155
8156    fn http_client(&self) -> Arc<dyn HttpClient> {
8157        self.http_client.clone()
8158    }
8159
8160    fn worktree_id(&self) -> WorktreeId {
8161        self.worktree.id()
8162    }
8163
8164    fn worktree_root_path(&self) -> &Path {
8165        self.worktree.abs_path().as_ref()
8166    }
8167
8168    async fn shell_env(&self) -> HashMap<String, String> {
8169        let task = self.load_shell_env_task.clone();
8170        task.await.unwrap_or_default()
8171    }
8172
8173    async fn npm_package_installed_version(
8174        &self,
8175        package_name: &str,
8176    ) -> Result<Option<(PathBuf, String)>> {
8177        let local_package_directory = self.worktree_root_path();
8178        let node_modules_directory = local_package_directory.join("node_modules");
8179
8180        if let Some(version) =
8181            read_package_installed_version(node_modules_directory.clone(), package_name).await?
8182        {
8183            return Ok(Some((node_modules_directory, version)));
8184        }
8185        let Some(npm) = self.which("npm".as_ref()).await else {
8186            log::warn!(
8187                "Failed to find npm executable for {:?}",
8188                local_package_directory
8189            );
8190            return Ok(None);
8191        };
8192
8193        let env = self.shell_env().await;
8194        let output = util::command::new_smol_command(&npm)
8195            .args(["root", "-g"])
8196            .envs(env)
8197            .current_dir(local_package_directory)
8198            .output()
8199            .await?;
8200        let global_node_modules =
8201            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
8202
8203        if let Some(version) =
8204            read_package_installed_version(global_node_modules.clone(), package_name).await?
8205        {
8206            return Ok(Some((global_node_modules, version)));
8207        }
8208        return Ok(None);
8209    }
8210
8211    #[cfg(not(target_os = "windows"))]
8212    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
8213        let worktree_abs_path = self.worktree.abs_path();
8214        let shell_path = self.shell_env().await.get("PATH").cloned();
8215        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
8216    }
8217
8218    #[cfg(target_os = "windows")]
8219    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
8220        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
8221        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
8222        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
8223        which::which(command).ok()
8224    }
8225
8226    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
8227        let working_dir = self.worktree_root_path();
8228        let output = util::command::new_smol_command(&command.path)
8229            .args(command.arguments)
8230            .envs(command.env.clone().unwrap_or_default())
8231            .current_dir(working_dir)
8232            .output()
8233            .await?;
8234
8235        if output.status.success() {
8236            return Ok(());
8237        }
8238        Err(anyhow!(
8239            "{}, stdout: {:?}, stderr: {:?}",
8240            output.status,
8241            String::from_utf8_lossy(&output.stdout),
8242            String::from_utf8_lossy(&output.stderr)
8243        ))
8244    }
8245
8246    fn update_status(
8247        &self,
8248        server_name: LanguageServerName,
8249        status: language::LanguageServerBinaryStatus,
8250    ) {
8251        self.language_registry
8252            .update_lsp_status(server_name, status);
8253    }
8254
8255    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
8256        let dir = self.language_registry.language_server_download_dir(name)?;
8257
8258        if !dir.exists() {
8259            smol::fs::create_dir_all(&dir)
8260                .await
8261                .context("failed to create container directory")
8262                .log_err()?;
8263        }
8264
8265        Some(dir)
8266    }
8267
8268    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
8269        let entry = self
8270            .worktree
8271            .entry_for_path(&path)
8272            .with_context(|| format!("no worktree entry for path {path:?}"))?;
8273        let abs_path = self
8274            .worktree
8275            .absolutize(&entry.path)
8276            .with_context(|| format!("cannot absolutize path {path:?}"))?;
8277
8278        self.fs.load(&abs_path).await
8279    }
8280}
8281
8282async fn populate_labels_for_symbols(
8283    symbols: Vec<CoreSymbol>,
8284    language_registry: &Arc<LanguageRegistry>,
8285    default_language: Option<LanguageName>,
8286    lsp_adapter: Option<Arc<CachedLspAdapter>>,
8287    output: &mut Vec<Symbol>,
8288) {
8289    #[allow(clippy::mutable_key_type)]
8290    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
8291
8292    let mut unknown_path = None;
8293    for symbol in symbols {
8294        let language = language_registry
8295            .language_for_file_path(&symbol.path.path)
8296            .await
8297            .ok()
8298            .or_else(|| {
8299                unknown_path.get_or_insert(symbol.path.path.clone());
8300                default_language.as_ref().and_then(|name| {
8301                    language_registry
8302                        .language_for_name(&name.0)
8303                        .now_or_never()?
8304                        .ok()
8305                })
8306            });
8307        symbols_by_language
8308            .entry(language)
8309            .or_default()
8310            .push(symbol);
8311    }
8312
8313    if let Some(unknown_path) = unknown_path {
8314        log::info!(
8315            "no language found for symbol path {}",
8316            unknown_path.display()
8317        );
8318    }
8319
8320    let mut label_params = Vec::new();
8321    for (language, mut symbols) in symbols_by_language {
8322        label_params.clear();
8323        label_params.extend(
8324            symbols
8325                .iter_mut()
8326                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
8327        );
8328
8329        let mut labels = Vec::new();
8330        if let Some(language) = language {
8331            let lsp_adapter = lsp_adapter.clone().or_else(|| {
8332                language_registry
8333                    .lsp_adapters(&language.name())
8334                    .first()
8335                    .cloned()
8336            });
8337            if let Some(lsp_adapter) = lsp_adapter {
8338                labels = lsp_adapter
8339                    .labels_for_symbols(&label_params, &language)
8340                    .await
8341                    .log_err()
8342                    .unwrap_or_default();
8343            }
8344        }
8345
8346        for ((symbol, (name, _)), label) in symbols
8347            .into_iter()
8348            .zip(label_params.drain(..))
8349            .zip(labels.into_iter().chain(iter::repeat(None)))
8350        {
8351            output.push(Symbol {
8352                language_server_name: symbol.language_server_name,
8353                source_worktree_id: symbol.source_worktree_id,
8354                path: symbol.path,
8355                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
8356                name,
8357                kind: symbol.kind,
8358                range: symbol.range,
8359                signature: symbol.signature,
8360            });
8361        }
8362    }
8363}
8364
8365fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
8366    match server.capabilities().text_document_sync.as_ref()? {
8367        lsp::TextDocumentSyncCapability::Kind(kind) => match *kind {
8368            lsp::TextDocumentSyncKind::NONE => None,
8369            lsp::TextDocumentSyncKind::FULL => Some(true),
8370            lsp::TextDocumentSyncKind::INCREMENTAL => Some(false),
8371            _ => None,
8372        },
8373        lsp::TextDocumentSyncCapability::Options(options) => match options.save.as_ref()? {
8374            lsp::TextDocumentSyncSaveOptions::Supported(supported) => {
8375                if *supported {
8376                    Some(true)
8377                } else {
8378                    None
8379                }
8380            }
8381            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
8382                Some(save_options.include_text.unwrap_or(false))
8383            }
8384        },
8385    }
8386}
8387
8388#[cfg(test)]
8389#[test]
8390fn test_glob_literal_prefix() {
8391    assert_eq!(glob_literal_prefix("**/*.js"), "");
8392    assert_eq!(glob_literal_prefix("node_modules/**/*.js"), "node_modules");
8393    assert_eq!(glob_literal_prefix("foo/{bar,baz}.js"), "foo");
8394    assert_eq!(glob_literal_prefix("foo/bar/baz.js"), "foo/bar/baz.js");
8395}