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