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    CompletionDocumentation, Diagnostic, DiagnosticEntry, DiagnosticSet, Diff, 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_entity_request_handler(Self::handle_multi_lsp_query);
2858        client.add_entity_request_handler(Self::handle_restart_language_servers);
2859        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
2860        client.add_entity_message_handler(Self::handle_start_language_server);
2861        client.add_entity_message_handler(Self::handle_update_language_server);
2862        client.add_entity_message_handler(Self::handle_language_server_log);
2863        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
2864        client.add_entity_request_handler(Self::handle_format_buffers);
2865        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
2866        client.add_entity_request_handler(Self::handle_apply_code_action);
2867        client.add_entity_request_handler(Self::handle_inlay_hints);
2868        client.add_entity_request_handler(Self::handle_get_project_symbols);
2869        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
2870        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
2871        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
2872        client.add_entity_request_handler(Self::handle_on_type_formatting);
2873        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
2874        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
2875        client.add_entity_request_handler(Self::handle_rename_project_entry);
2876        client.add_entity_request_handler(Self::handle_lsp_command::<GetCodeActions>);
2877        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
2878        client.add_entity_request_handler(Self::handle_lsp_command::<GetHover>);
2879        client.add_entity_request_handler(Self::handle_lsp_command::<GetDefinition>);
2880        client.add_entity_request_handler(Self::handle_lsp_command::<GetDeclaration>);
2881        client.add_entity_request_handler(Self::handle_lsp_command::<GetTypeDefinition>);
2882        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
2883        client.add_entity_request_handler(Self::handle_lsp_command::<GetReferences>);
2884        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
2885        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
2886        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
2887        client.add_entity_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(CompletionDocumentation::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 language = snapshot.language();
4368        let mut new_label = match language {
4369            Some(language) => {
4370                adapter
4371                    .labels_for_completions(&[completion_item.clone()], language)
4372                    .await?
4373            }
4374            None => Vec::new(),
4375        }
4376        .pop()
4377        .flatten()
4378        .unwrap_or_else(|| {
4379            CodeLabel::fallback_for_completion(
4380                &completion_item,
4381                language.map(|language| language.as_ref()),
4382            )
4383        });
4384        ensure_uniform_list_compatible_label(&mut new_label);
4385
4386        let mut completions = completions.borrow_mut();
4387        let completion = &mut completions[completion_index];
4388        if completion.label.filter_text() == new_label.filter_text() {
4389            completion.label = new_label;
4390        } else {
4391            log::error!(
4392                "Resolved completion changed display label from {} to {}. \
4393                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
4394                completion.label.text(),
4395                new_label.text(),
4396                completion.label.filter_text(),
4397                new_label.filter_text()
4398            );
4399        }
4400
4401        Ok(())
4402    }
4403
4404    #[allow(clippy::too_many_arguments)]
4405    async fn resolve_completion_remote(
4406        project_id: u64,
4407        server_id: LanguageServerId,
4408        buffer_id: BufferId,
4409        completions: Rc<RefCell<Box<[Completion]>>>,
4410        completion_index: usize,
4411        client: AnyProtoClient,
4412        language_registry: Arc<LanguageRegistry>,
4413    ) -> Result<()> {
4414        let lsp_completion = {
4415            let completion = &completions.borrow()[completion_index];
4416            if completion.resolved {
4417                return Ok(());
4418            }
4419            serde_json::to_string(&completion.lsp_completion)
4420                .unwrap()
4421                .into_bytes()
4422        };
4423        let request = proto::ResolveCompletionDocumentation {
4424            project_id,
4425            language_server_id: server_id.0 as u64,
4426            lsp_completion,
4427            buffer_id: buffer_id.into(),
4428        };
4429
4430        let response = client
4431            .request(request)
4432            .await
4433            .context("completion documentation resolve proto request")?;
4434        let lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
4435
4436        let documentation = if response.documentation.is_empty() {
4437            CompletionDocumentation::Undocumented
4438        } else if response.documentation_is_markdown {
4439            CompletionDocumentation::MultiLineMarkdown(
4440                markdown::parse_markdown(&response.documentation, Some(&language_registry), None)
4441                    .await,
4442            )
4443        } else if response.documentation.lines().count() <= 1 {
4444            CompletionDocumentation::SingleLine(response.documentation)
4445        } else {
4446            CompletionDocumentation::MultiLinePlainText(response.documentation)
4447        };
4448
4449        let mut completions = completions.borrow_mut();
4450        let completion = &mut completions[completion_index];
4451        completion.documentation = Some(documentation);
4452        completion.lsp_completion = lsp_completion;
4453        completion.resolved = true;
4454
4455        let old_range = response
4456            .old_start
4457            .and_then(deserialize_anchor)
4458            .zip(response.old_end.and_then(deserialize_anchor));
4459        if let Some((old_start, old_end)) = old_range {
4460            if !response.new_text.is_empty() {
4461                completion.new_text = response.new_text;
4462                completion.old_range = old_start..old_end;
4463            }
4464        }
4465
4466        Ok(())
4467    }
4468
4469    pub fn apply_additional_edits_for_completion(
4470        &self,
4471        buffer_handle: Entity<Buffer>,
4472        completions: Rc<RefCell<Box<[Completion]>>>,
4473        completion_index: usize,
4474        push_to_history: bool,
4475        cx: &mut Context<Self>,
4476    ) -> Task<Result<Option<Transaction>>> {
4477        let buffer = buffer_handle.read(cx);
4478        let buffer_id = buffer.remote_id();
4479
4480        if let Some((client, project_id)) = self.upstream_client() {
4481            cx.spawn(move |_, mut cx| async move {
4482                let request = {
4483                    let completion = completions.borrow()[completion_index].clone();
4484                    proto::ApplyCompletionAdditionalEdits {
4485                        project_id,
4486                        buffer_id: buffer_id.into(),
4487                        completion: Some(Self::serialize_completion(&CoreCompletion {
4488                            old_range: completion.old_range,
4489                            new_text: completion.new_text,
4490                            server_id: completion.server_id,
4491                            lsp_completion: completion.lsp_completion,
4492                            resolved: completion.resolved,
4493                        })),
4494                    }
4495                };
4496
4497                let response = client.request(request).await?;
4498                completions.borrow_mut()[completion_index].resolved = true;
4499
4500                if let Some(transaction) = response.transaction {
4501                    let transaction = language::proto::deserialize_transaction(transaction)?;
4502                    buffer_handle
4503                        .update(&mut cx, |buffer, _| {
4504                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
4505                        })?
4506                        .await?;
4507                    if push_to_history {
4508                        buffer_handle.update(&mut cx, |buffer, _| {
4509                            buffer.push_transaction(transaction.clone(), Instant::now());
4510                        })?;
4511                    }
4512                    Ok(Some(transaction))
4513                } else {
4514                    Ok(None)
4515                }
4516            })
4517        } else {
4518            let server_id = completions.borrow()[completion_index].server_id;
4519            let server = match self.language_server_for_local_buffer(buffer, server_id, cx) {
4520                Some((_, server)) => server.clone(),
4521                _ => return Task::ready(Ok(None)),
4522            };
4523            let snapshot = buffer_handle.read(&cx).snapshot();
4524
4525            cx.spawn(move |this, mut cx| async move {
4526                Self::resolve_completion_local(
4527                    server.clone(),
4528                    &snapshot,
4529                    completions.clone(),
4530                    completion_index,
4531                )
4532                .await
4533                .context("resolving completion")?;
4534                let completion = completions.borrow()[completion_index].clone();
4535                let additional_text_edits = completion.lsp_completion.additional_text_edits;
4536                if let Some(edits) = additional_text_edits {
4537                    let edits = this
4538                        .update(&mut cx, |this, cx| {
4539                            this.as_local_mut().unwrap().edits_from_lsp(
4540                                &buffer_handle,
4541                                edits,
4542                                server.server_id(),
4543                                None,
4544                                cx,
4545                            )
4546                        })?
4547                        .await?;
4548
4549                    buffer_handle.update(&mut cx, |buffer, cx| {
4550                        buffer.finalize_last_transaction();
4551                        buffer.start_transaction();
4552
4553                        for (range, text) in edits {
4554                            let primary = &completion.old_range;
4555                            let start_within = primary.start.cmp(&range.start, buffer).is_le()
4556                                && primary.end.cmp(&range.start, buffer).is_ge();
4557                            let end_within = range.start.cmp(&primary.end, buffer).is_le()
4558                                && range.end.cmp(&primary.end, buffer).is_ge();
4559
4560                            //Skip additional edits which overlap with the primary completion edit
4561                            //https://github.com/zed-industries/zed/pull/1871
4562                            if !start_within && !end_within {
4563                                buffer.edit([(range, text)], None, cx);
4564                            }
4565                        }
4566
4567                        let transaction = if buffer.end_transaction(cx).is_some() {
4568                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
4569                            if !push_to_history {
4570                                buffer.forget_transaction(transaction.id);
4571                            }
4572                            Some(transaction)
4573                        } else {
4574                            None
4575                        };
4576                        Ok(transaction)
4577                    })?
4578                } else {
4579                    Ok(None)
4580                }
4581            })
4582        }
4583    }
4584
4585    pub fn inlay_hints(
4586        &mut self,
4587        buffer_handle: Entity<Buffer>,
4588        range: Range<Anchor>,
4589        cx: &mut Context<Self>,
4590    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
4591        let buffer = buffer_handle.read(cx);
4592        let range_start = range.start;
4593        let range_end = range.end;
4594        let buffer_id = buffer.remote_id().into();
4595        let lsp_request = InlayHints { range };
4596
4597        if let Some((client, project_id)) = self.upstream_client() {
4598            let request = proto::InlayHints {
4599                project_id,
4600                buffer_id,
4601                start: Some(serialize_anchor(&range_start)),
4602                end: Some(serialize_anchor(&range_end)),
4603                version: serialize_version(&buffer_handle.read(cx).version()),
4604            };
4605            cx.spawn(move |project, cx| async move {
4606                let response = client
4607                    .request(request)
4608                    .await
4609                    .context("inlay hints proto request")?;
4610                LspCommand::response_from_proto(
4611                    lsp_request,
4612                    response,
4613                    project.upgrade().ok_or_else(|| anyhow!("No project"))?,
4614                    buffer_handle.clone(),
4615                    cx.clone(),
4616                )
4617                .await
4618                .context("inlay hints proto response conversion")
4619            })
4620        } else {
4621            let lsp_request_task = self.request_lsp(
4622                buffer_handle.clone(),
4623                LanguageServerToQuery::Primary,
4624                lsp_request,
4625                cx,
4626            );
4627            cx.spawn(move |_, mut cx| async move {
4628                buffer_handle
4629                    .update(&mut cx, |buffer, _| {
4630                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
4631                    })?
4632                    .await
4633                    .context("waiting for inlay hint request range edits")?;
4634                lsp_request_task.await.context("inlay hints LSP request")
4635            })
4636        }
4637    }
4638
4639    pub fn signature_help<T: ToPointUtf16>(
4640        &mut self,
4641        buffer: &Entity<Buffer>,
4642        position: T,
4643        cx: &mut Context<Self>,
4644    ) -> Task<Vec<SignatureHelp>> {
4645        let position = position.to_point_utf16(buffer.read(cx));
4646
4647        if let Some((client, upstream_project_id)) = self.upstream_client() {
4648            let request_task = client.request(proto::MultiLspQuery {
4649                buffer_id: buffer.read(cx).remote_id().into(),
4650                version: serialize_version(&buffer.read(cx).version()),
4651                project_id: upstream_project_id,
4652                strategy: Some(proto::multi_lsp_query::Strategy::All(
4653                    proto::AllLanguageServers {},
4654                )),
4655                request: Some(proto::multi_lsp_query::Request::GetSignatureHelp(
4656                    GetSignatureHelp { position }.to_proto(upstream_project_id, buffer.read(cx)),
4657                )),
4658            });
4659            let buffer = buffer.clone();
4660            cx.spawn(|weak_project, cx| async move {
4661                let Some(project) = weak_project.upgrade() else {
4662                    return Vec::new();
4663                };
4664                join_all(
4665                    request_task
4666                        .await
4667                        .log_err()
4668                        .map(|response| response.responses)
4669                        .unwrap_or_default()
4670                        .into_iter()
4671                        .filter_map(|lsp_response| match lsp_response.response? {
4672                            proto::lsp_response::Response::GetSignatureHelpResponse(response) => {
4673                                Some(response)
4674                            }
4675                            unexpected => {
4676                                debug_panic!("Unexpected response: {unexpected:?}");
4677                                None
4678                            }
4679                        })
4680                        .map(|signature_response| {
4681                            let response = GetSignatureHelp { position }.response_from_proto(
4682                                signature_response,
4683                                project.clone(),
4684                                buffer.clone(),
4685                                cx.clone(),
4686                            );
4687                            async move { response.await.log_err().flatten() }
4688                        }),
4689                )
4690                .await
4691                .into_iter()
4692                .flatten()
4693                .collect()
4694            })
4695        } else {
4696            let all_actions_task = self.request_multiple_lsp_locally(
4697                buffer,
4698                Some(position),
4699                GetSignatureHelp { position },
4700                cx,
4701            );
4702            cx.spawn(|_, _| async move {
4703                all_actions_task
4704                    .await
4705                    .into_iter()
4706                    .flatten()
4707                    .filter(|help| !help.markdown.is_empty())
4708                    .collect::<Vec<_>>()
4709            })
4710        }
4711    }
4712
4713    pub fn hover(
4714        &mut self,
4715        buffer: &Entity<Buffer>,
4716        position: PointUtf16,
4717        cx: &mut Context<Self>,
4718    ) -> Task<Vec<Hover>> {
4719        if let Some((client, upstream_project_id)) = self.upstream_client() {
4720            let request_task = client.request(proto::MultiLspQuery {
4721                buffer_id: buffer.read(cx).remote_id().into(),
4722                version: serialize_version(&buffer.read(cx).version()),
4723                project_id: upstream_project_id,
4724                strategy: Some(proto::multi_lsp_query::Strategy::All(
4725                    proto::AllLanguageServers {},
4726                )),
4727                request: Some(proto::multi_lsp_query::Request::GetHover(
4728                    GetHover { position }.to_proto(upstream_project_id, buffer.read(cx)),
4729                )),
4730            });
4731            let buffer = buffer.clone();
4732            cx.spawn(|weak_project, cx| async move {
4733                let Some(project) = weak_project.upgrade() else {
4734                    return Vec::new();
4735                };
4736                join_all(
4737                    request_task
4738                        .await
4739                        .log_err()
4740                        .map(|response| response.responses)
4741                        .unwrap_or_default()
4742                        .into_iter()
4743                        .filter_map(|lsp_response| match lsp_response.response? {
4744                            proto::lsp_response::Response::GetHoverResponse(response) => {
4745                                Some(response)
4746                            }
4747                            unexpected => {
4748                                debug_panic!("Unexpected response: {unexpected:?}");
4749                                None
4750                            }
4751                        })
4752                        .map(|hover_response| {
4753                            let response = GetHover { position }.response_from_proto(
4754                                hover_response,
4755                                project.clone(),
4756                                buffer.clone(),
4757                                cx.clone(),
4758                            );
4759                            async move {
4760                                response
4761                                    .await
4762                                    .log_err()
4763                                    .flatten()
4764                                    .and_then(remove_empty_hover_blocks)
4765                            }
4766                        }),
4767                )
4768                .await
4769                .into_iter()
4770                .flatten()
4771                .collect()
4772            })
4773        } else {
4774            let all_actions_task = self.request_multiple_lsp_locally(
4775                buffer,
4776                Some(position),
4777                GetHover { position },
4778                cx,
4779            );
4780            cx.spawn(|_, _| async move {
4781                all_actions_task
4782                    .await
4783                    .into_iter()
4784                    .filter_map(|hover| remove_empty_hover_blocks(hover?))
4785                    .collect::<Vec<Hover>>()
4786            })
4787        }
4788    }
4789
4790    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
4791        let language_registry = self.languages.clone();
4792
4793        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
4794            let request = upstream_client.request(proto::GetProjectSymbols {
4795                project_id: *project_id,
4796                query: query.to_string(),
4797            });
4798            cx.foreground_executor().spawn(async move {
4799                let response = request.await?;
4800                let mut symbols = Vec::new();
4801                let core_symbols = response
4802                    .symbols
4803                    .into_iter()
4804                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
4805                    .collect::<Vec<_>>();
4806                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
4807                    .await;
4808                Ok(symbols)
4809            })
4810        } else if let Some(local) = self.as_local() {
4811            struct WorkspaceSymbolsResult {
4812                lsp_adapter: Arc<CachedLspAdapter>,
4813                worktree: WeakEntity<Worktree>,
4814                worktree_abs_path: Arc<Path>,
4815                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
4816            }
4817
4818            let mut requests = Vec::new();
4819            for ((worktree_id, _), server_id) in local.language_server_ids.iter() {
4820                let Some(worktree_handle) = self
4821                    .worktree_store
4822                    .read(cx)
4823                    .worktree_for_id(*worktree_id, cx)
4824                else {
4825                    continue;
4826                };
4827                let worktree = worktree_handle.read(cx);
4828                if !worktree.is_visible() {
4829                    continue;
4830                }
4831                let worktree_abs_path = worktree.abs_path().clone();
4832
4833                let (lsp_adapter, server) = match local.language_servers.get(server_id) {
4834                    Some(LanguageServerState::Running {
4835                        adapter, server, ..
4836                    }) => (adapter.clone(), server),
4837
4838                    _ => continue,
4839                };
4840
4841                requests.push(
4842                        server
4843                            .request::<lsp::request::WorkspaceSymbolRequest>(
4844                                lsp::WorkspaceSymbolParams {
4845                                    query: query.to_string(),
4846                                    ..Default::default()
4847                                },
4848                            )
4849                            .log_err()
4850                            .map(move |response| {
4851                                let lsp_symbols = response.flatten().map(|symbol_response| match symbol_response {
4852                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
4853                                        flat_responses.into_iter().map(|lsp_symbol| {
4854                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
4855                                        }).collect::<Vec<_>>()
4856                                    }
4857                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
4858                                        nested_responses.into_iter().filter_map(|lsp_symbol| {
4859                                            let location = match lsp_symbol.location {
4860                                                OneOf::Left(location) => location,
4861                                                OneOf::Right(_) => {
4862                                                    log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
4863                                                    return None
4864                                                }
4865                                            };
4866                                            Some((lsp_symbol.name, lsp_symbol.kind, location))
4867                                        }).collect::<Vec<_>>()
4868                                    }
4869                                }).unwrap_or_default();
4870
4871                                WorkspaceSymbolsResult {
4872                                    lsp_adapter,
4873
4874                                    worktree: worktree_handle.downgrade(),
4875                                    worktree_abs_path,
4876                                    lsp_symbols,
4877                                }
4878                            }),
4879                    );
4880            }
4881
4882            cx.spawn(move |this, mut cx| async move {
4883                let responses = futures::future::join_all(requests).await;
4884                let this = match this.upgrade() {
4885                    Some(this) => this,
4886                    None => return Ok(Vec::new()),
4887                };
4888
4889                let mut symbols = Vec::new();
4890                for result in responses {
4891                    let core_symbols = this.update(&mut cx, |this, cx| {
4892                        result
4893                            .lsp_symbols
4894                            .into_iter()
4895                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
4896                                let abs_path = symbol_location.uri.to_file_path().ok()?;
4897                                let source_worktree = result.worktree.upgrade()?;
4898                                let source_worktree_id = source_worktree.read(cx).id();
4899
4900                                let path;
4901                                let worktree;
4902                                if let Some((tree, rel_path)) =
4903                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
4904                                {
4905                                    worktree = tree;
4906                                    path = rel_path;
4907                                } else {
4908                                    worktree = source_worktree.clone();
4909                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
4910                                }
4911
4912                                let worktree_id = worktree.read(cx).id();
4913                                let project_path = ProjectPath {
4914                                    worktree_id,
4915                                    path: path.into(),
4916                                };
4917                                let signature = this.symbol_signature(&project_path);
4918                                Some(CoreSymbol {
4919                                    language_server_name: result.lsp_adapter.name.clone(),
4920                                    source_worktree_id,
4921                                    path: project_path,
4922                                    kind: symbol_kind,
4923                                    name: symbol_name,
4924                                    range: range_from_lsp(symbol_location.range),
4925                                    signature,
4926                                })
4927                            })
4928                            .collect()
4929                    })?;
4930
4931                    populate_labels_for_symbols(
4932                        core_symbols,
4933                        &language_registry,
4934                        Some(result.lsp_adapter),
4935                        &mut symbols,
4936                    )
4937                    .await;
4938                }
4939
4940                Ok(symbols)
4941            })
4942        } else {
4943            Task::ready(Err(anyhow!("No upstream client or local language server")))
4944        }
4945    }
4946
4947    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
4948        let mut summary = DiagnosticSummary::default();
4949        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
4950            summary.error_count += path_summary.error_count;
4951            summary.warning_count += path_summary.warning_count;
4952        }
4953        summary
4954    }
4955
4956    pub fn diagnostic_summaries<'a>(
4957        &'a self,
4958        include_ignored: bool,
4959        cx: &'a App,
4960    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
4961        self.worktree_store
4962            .read(cx)
4963            .visible_worktrees(cx)
4964            .filter_map(|worktree| {
4965                let worktree = worktree.read(cx);
4966                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
4967            })
4968            .flat_map(move |(worktree, summaries)| {
4969                let worktree_id = worktree.id();
4970                summaries
4971                    .iter()
4972                    .filter(move |(path, _)| {
4973                        include_ignored
4974                            || worktree
4975                                .entry_for_path(path.as_ref())
4976                                .map_or(false, |entry| !entry.is_ignored)
4977                    })
4978                    .flat_map(move |(path, summaries)| {
4979                        summaries.iter().map(move |(server_id, summary)| {
4980                            (
4981                                ProjectPath {
4982                                    worktree_id,
4983                                    path: path.clone(),
4984                                },
4985                                *server_id,
4986                                *summary,
4987                            )
4988                        })
4989                    })
4990            })
4991    }
4992
4993    pub fn on_buffer_edited(
4994        &mut self,
4995        buffer: Entity<Buffer>,
4996        cx: &mut Context<Self>,
4997    ) -> Option<()> {
4998        let buffer = buffer.read(cx);
4999        let file = File::from_dyn(buffer.file())?;
5000        let abs_path = file.as_local()?.abs_path(cx);
5001        let uri = lsp::Url::from_file_path(abs_path).unwrap();
5002        let next_snapshot = buffer.text_snapshot();
5003
5004        let language_servers: Vec<_> = self
5005            .as_local()
5006            .unwrap()
5007            .language_servers_for_buffer(buffer, cx)
5008            .map(|i| i.1.clone())
5009            .collect();
5010
5011        for language_server in language_servers {
5012            let language_server = language_server.clone();
5013
5014            let buffer_snapshots = self
5015                .as_local_mut()
5016                .unwrap()
5017                .buffer_snapshots
5018                .get_mut(&buffer.remote_id())
5019                .and_then(|m| m.get_mut(&language_server.server_id()))?;
5020            let previous_snapshot = buffer_snapshots.last()?;
5021
5022            let build_incremental_change = || {
5023                buffer
5024                    .edits_since::<(PointUtf16, usize)>(previous_snapshot.snapshot.version())
5025                    .map(|edit| {
5026                        let edit_start = edit.new.start.0;
5027                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
5028                        let new_text = next_snapshot
5029                            .text_for_range(edit.new.start.1..edit.new.end.1)
5030                            .collect();
5031                        lsp::TextDocumentContentChangeEvent {
5032                            range: Some(lsp::Range::new(
5033                                point_to_lsp(edit_start),
5034                                point_to_lsp(edit_end),
5035                            )),
5036                            range_length: None,
5037                            text: new_text,
5038                        }
5039                    })
5040                    .collect()
5041            };
5042
5043            let document_sync_kind = language_server
5044                .capabilities()
5045                .text_document_sync
5046                .as_ref()
5047                .and_then(|sync| match sync {
5048                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
5049                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
5050                });
5051
5052            let content_changes: Vec<_> = match document_sync_kind {
5053                Some(lsp::TextDocumentSyncKind::FULL) => {
5054                    vec![lsp::TextDocumentContentChangeEvent {
5055                        range: None,
5056                        range_length: None,
5057                        text: next_snapshot.text(),
5058                    }]
5059                }
5060                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
5061                _ => {
5062                    #[cfg(any(test, feature = "test-support"))]
5063                    {
5064                        build_incremental_change()
5065                    }
5066
5067                    #[cfg(not(any(test, feature = "test-support")))]
5068                    {
5069                        continue;
5070                    }
5071                }
5072            };
5073
5074            let next_version = previous_snapshot.version + 1;
5075            buffer_snapshots.push(LspBufferSnapshot {
5076                version: next_version,
5077                snapshot: next_snapshot.clone(),
5078            });
5079
5080            language_server
5081                .notify::<lsp::notification::DidChangeTextDocument>(
5082                    &lsp::DidChangeTextDocumentParams {
5083                        text_document: lsp::VersionedTextDocumentIdentifier::new(
5084                            uri.clone(),
5085                            next_version,
5086                        ),
5087                        content_changes,
5088                    },
5089                )
5090                .log_err();
5091        }
5092
5093        None
5094    }
5095
5096    pub fn on_buffer_saved(
5097        &mut self,
5098        buffer: Entity<Buffer>,
5099        cx: &mut Context<Self>,
5100    ) -> Option<()> {
5101        let file = File::from_dyn(buffer.read(cx).file())?;
5102        let worktree_id = file.worktree_id(cx);
5103        let abs_path = file.as_local()?.abs_path(cx);
5104        let text_document = lsp::TextDocumentIdentifier {
5105            uri: lsp::Url::from_file_path(abs_path).log_err()?,
5106        };
5107        let local = self.as_local()?;
5108
5109        for server in local.language_servers_for_worktree(worktree_id) {
5110            if let Some(include_text) = include_text(server.as_ref()) {
5111                let text = if include_text {
5112                    Some(buffer.read(cx).text())
5113                } else {
5114                    None
5115                };
5116                server
5117                    .notify::<lsp::notification::DidSaveTextDocument>(
5118                        &lsp::DidSaveTextDocumentParams {
5119                            text_document: text_document.clone(),
5120                            text,
5121                        },
5122                    )
5123                    .log_err();
5124            }
5125        }
5126
5127        for language_server_id in local.language_server_ids_for_buffer(buffer.read(cx), cx) {
5128            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
5129        }
5130
5131        None
5132    }
5133
5134    pub(crate) async fn refresh_workspace_configurations(
5135        this: &WeakEntity<Self>,
5136        fs: Arc<dyn Fs>,
5137        mut cx: AsyncApp,
5138    ) {
5139        maybe!(async move {
5140            let servers = this
5141                .update(&mut cx, |this, cx| {
5142                    let Some(local) = this.as_local() else {
5143                        return Vec::default();
5144                    };
5145                    local
5146                        .language_server_ids
5147                        .iter()
5148                        .filter_map(|((worktree_id, _), server_id)| {
5149                            let worktree = this
5150                                .worktree_store
5151                                .read(cx)
5152                                .worktree_for_id(*worktree_id, cx)?;
5153                            let state = local.language_servers.get(server_id)?;
5154                            let delegate = LocalLspAdapterDelegate::new(
5155                                local.languages.clone(),
5156                                &local.environment,
5157                                cx.weak_entity(),
5158                                &worktree,
5159                                local.http_client.clone(),
5160                                local.fs.clone(),
5161                                cx,
5162                            );
5163                            match state {
5164                                LanguageServerState::Starting(_) => None,
5165                                LanguageServerState::Running {
5166                                    adapter, server, ..
5167                                } => Some((
5168                                    adapter.adapter.clone(),
5169                                    server.clone(),
5170                                    delegate as Arc<dyn LspAdapterDelegate>,
5171                                )),
5172                            }
5173                        })
5174                        .collect::<Vec<_>>()
5175                })
5176                .ok()?;
5177
5178            let toolchain_store = this
5179                .update(&mut cx, |this, cx| this.toolchain_store(cx))
5180                .ok()?;
5181            for (adapter, server, delegate) in servers {
5182                let settings = adapter
5183                    .workspace_configuration(
5184                        fs.as_ref(),
5185                        &delegate,
5186                        toolchain_store.clone(),
5187                        &mut cx,
5188                    )
5189                    .await
5190                    .ok()?;
5191
5192                server
5193                    .notify::<lsp::notification::DidChangeConfiguration>(
5194                        &lsp::DidChangeConfigurationParams { settings },
5195                    )
5196                    .ok();
5197            }
5198            Some(())
5199        })
5200        .await;
5201    }
5202
5203    fn toolchain_store(&self, cx: &App) -> Arc<dyn LanguageToolchainStore> {
5204        if let Some(toolchain_store) = self.toolchain_store.as_ref() {
5205            toolchain_store.read(cx).as_language_toolchain_store()
5206        } else {
5207            Arc::new(EmptyToolchainStore)
5208        }
5209    }
5210    fn maintain_workspace_config(
5211        fs: Arc<dyn Fs>,
5212        external_refresh_requests: watch::Receiver<()>,
5213        cx: &mut Context<Self>,
5214    ) -> Task<Result<()>> {
5215        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
5216        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
5217
5218        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
5219            *settings_changed_tx.borrow_mut() = ();
5220        });
5221
5222        let mut joint_future =
5223            futures::stream::select(settings_changed_rx, external_refresh_requests);
5224        cx.spawn(move |this, cx| async move {
5225            while let Some(()) = joint_future.next().await {
5226                Self::refresh_workspace_configurations(&this, fs.clone(), cx.clone()).await;
5227            }
5228
5229            drop(settings_observation);
5230            anyhow::Ok(())
5231        })
5232    }
5233
5234    pub(crate) fn language_servers_for_local_buffer<'a>(
5235        &'a self,
5236        buffer: &'a Buffer,
5237        cx: &'a App,
5238    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
5239        self.as_local().into_iter().flat_map(|local| {
5240            local
5241                .language_server_ids_for_buffer(buffer, cx)
5242                .into_iter()
5243                .filter_map(|server_id| match local.language_servers.get(&server_id)? {
5244                    LanguageServerState::Running {
5245                        adapter, server, ..
5246                    } => Some((adapter, server)),
5247                    _ => None,
5248                })
5249        })
5250    }
5251
5252    pub fn language_server_for_local_buffer<'a>(
5253        &'a self,
5254        buffer: &'a Buffer,
5255        server_id: LanguageServerId,
5256        cx: &'a App,
5257    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
5258        self.as_local()?
5259            .language_servers_for_buffer(buffer, cx)
5260            .find(|(_, s)| s.server_id() == server_id)
5261    }
5262
5263    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
5264        self.diagnostic_summaries.remove(&id_to_remove);
5265        let to_remove = Vec::new();
5266        if let Some(local) = self.as_local_mut() {
5267            local.diagnostics.remove(&id_to_remove);
5268            local.prettier_store.update(cx, |prettier_store, cx| {
5269                prettier_store.remove_worktree(id_to_remove, cx);
5270            });
5271
5272            let mut servers_to_remove = HashMap::default();
5273            let mut servers_to_preserve = HashSet::default();
5274            for ((worktree_id, server_name), &server_id) in &local.language_server_ids {
5275                if worktree_id == &id_to_remove {
5276                    servers_to_remove.insert(server_id, server_name.clone());
5277                } else {
5278                    servers_to_preserve.insert(server_id);
5279                }
5280            }
5281            servers_to_remove.retain(|server_id, _| !servers_to_preserve.contains(server_id));
5282            for (server_id_to_remove, server_name) in servers_to_remove {
5283                local
5284                    .language_server_ids
5285                    .remove(&(id_to_remove, server_name));
5286                local
5287                    .language_server_watched_paths
5288                    .remove(&server_id_to_remove);
5289                local
5290                    .last_workspace_edits_by_language_server
5291                    .remove(&server_id_to_remove);
5292                local.language_servers.remove(&server_id_to_remove);
5293                cx.emit(LspStoreEvent::LanguageServerRemoved(server_id_to_remove));
5294            }
5295        }
5296        for server in to_remove {
5297            self.language_server_statuses.remove(&server);
5298        }
5299    }
5300
5301    pub fn shared(
5302        &mut self,
5303        project_id: u64,
5304        downstream_client: AnyProtoClient,
5305        _: &mut Context<Self>,
5306    ) {
5307        self.downstream_client = Some((downstream_client.clone(), project_id));
5308
5309        for (server_id, status) in &self.language_server_statuses {
5310            downstream_client
5311                .send(proto::StartLanguageServer {
5312                    project_id,
5313                    server: Some(proto::LanguageServer {
5314                        id: server_id.0 as u64,
5315                        name: status.name.clone(),
5316                        worktree_id: None,
5317                    }),
5318                })
5319                .log_err();
5320        }
5321    }
5322
5323    pub fn disconnected_from_host(&mut self) {
5324        self.downstream_client.take();
5325    }
5326
5327    pub fn disconnected_from_ssh_remote(&mut self) {
5328        if let LspStoreMode::Remote(RemoteLspStore {
5329            upstream_client, ..
5330        }) = &mut self.mode
5331        {
5332            upstream_client.take();
5333        }
5334    }
5335
5336    pub(crate) fn set_language_server_statuses_from_proto(
5337        &mut self,
5338        language_servers: Vec<proto::LanguageServer>,
5339    ) {
5340        self.language_server_statuses = language_servers
5341            .into_iter()
5342            .map(|server| {
5343                (
5344                    LanguageServerId(server.id as usize),
5345                    LanguageServerStatus {
5346                        name: server.name,
5347                        pending_work: Default::default(),
5348                        has_pending_diagnostic_updates: false,
5349                        progress_tokens: Default::default(),
5350                    },
5351                )
5352            })
5353            .collect();
5354    }
5355
5356    fn register_local_language_server(
5357        &mut self,
5358        worktree_id: WorktreeId,
5359        language_server_name: LanguageServerName,
5360        language_server_id: LanguageServerId,
5361    ) {
5362        self.as_local_mut()
5363            .unwrap()
5364            .language_server_ids
5365            .insert((worktree_id, language_server_name), language_server_id);
5366    }
5367
5368    pub fn update_diagnostic_entries(
5369        &mut self,
5370        server_id: LanguageServerId,
5371        abs_path: PathBuf,
5372        version: Option<i32>,
5373        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
5374        cx: &mut Context<Self>,
5375    ) -> Result<(), anyhow::Error> {
5376        let Some((worktree, relative_path)) =
5377            self.worktree_store.read(cx).find_worktree(&abs_path, cx)
5378        else {
5379            log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
5380            return Ok(());
5381        };
5382
5383        let project_path = ProjectPath {
5384            worktree_id: worktree.read(cx).id(),
5385            path: relative_path.into(),
5386        };
5387
5388        if let Some(buffer) = self.buffer_store.read(cx).get_by_path(&project_path, cx) {
5389            self.as_local_mut().unwrap().update_buffer_diagnostics(
5390                &buffer,
5391                server_id,
5392                version,
5393                diagnostics.clone(),
5394                cx,
5395            )?;
5396        }
5397
5398        let updated = worktree.update(cx, |worktree, cx| {
5399            self.update_worktree_diagnostics(
5400                worktree.id(),
5401                server_id,
5402                project_path.path.clone(),
5403                diagnostics,
5404                cx,
5405            )
5406        })?;
5407        if updated {
5408            cx.emit(LspStoreEvent::DiagnosticsUpdated {
5409                language_server_id: server_id,
5410                path: project_path,
5411            })
5412        }
5413        Ok(())
5414    }
5415
5416    fn update_worktree_diagnostics(
5417        &mut self,
5418        worktree_id: WorktreeId,
5419        server_id: LanguageServerId,
5420        worktree_path: Arc<Path>,
5421        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
5422        _: &mut Context<Worktree>,
5423    ) -> Result<bool> {
5424        let local = match &mut self.mode {
5425            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
5426            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
5427        };
5428
5429        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
5430        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
5431        let summaries_by_server_id = summaries_for_tree.entry(worktree_path.clone()).or_default();
5432
5433        let old_summary = summaries_by_server_id
5434            .remove(&server_id)
5435            .unwrap_or_default();
5436
5437        let new_summary = DiagnosticSummary::new(&diagnostics);
5438        if new_summary.is_empty() {
5439            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&worktree_path) {
5440                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
5441                    diagnostics_by_server_id.remove(ix);
5442                }
5443                if diagnostics_by_server_id.is_empty() {
5444                    diagnostics_for_tree.remove(&worktree_path);
5445                }
5446            }
5447        } else {
5448            summaries_by_server_id.insert(server_id, new_summary);
5449            let diagnostics_by_server_id = diagnostics_for_tree
5450                .entry(worktree_path.clone())
5451                .or_default();
5452            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
5453                Ok(ix) => {
5454                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
5455                }
5456                Err(ix) => {
5457                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
5458                }
5459            }
5460        }
5461
5462        if !old_summary.is_empty() || !new_summary.is_empty() {
5463            if let Some((downstream_client, project_id)) = &self.downstream_client {
5464                downstream_client
5465                    .send(proto::UpdateDiagnosticSummary {
5466                        project_id: *project_id,
5467                        worktree_id: worktree_id.to_proto(),
5468                        summary: Some(proto::DiagnosticSummary {
5469                            path: worktree_path.to_string_lossy().to_string(),
5470                            language_server_id: server_id.0 as u64,
5471                            error_count: new_summary.error_count as u32,
5472                            warning_count: new_summary.warning_count as u32,
5473                        }),
5474                    })
5475                    .log_err();
5476            }
5477        }
5478
5479        Ok(!old_summary.is_empty() || !new_summary.is_empty())
5480    }
5481
5482    pub fn open_buffer_for_symbol(
5483        &mut self,
5484        symbol: &Symbol,
5485        cx: &mut Context<Self>,
5486    ) -> Task<Result<Entity<Buffer>>> {
5487        if let Some((client, project_id)) = self.upstream_client() {
5488            let request = client.request(proto::OpenBufferForSymbol {
5489                project_id,
5490                symbol: Some(Self::serialize_symbol(symbol)),
5491            });
5492            cx.spawn(move |this, mut cx| async move {
5493                let response = request.await?;
5494                let buffer_id = BufferId::new(response.buffer_id)?;
5495                this.update(&mut cx, |this, cx| {
5496                    this.wait_for_remote_buffer(buffer_id, cx)
5497                })?
5498                .await
5499            })
5500        } else if let Some(local) = self.as_local() {
5501            let Some(&language_server_id) = local.language_server_ids.get(&(
5502                symbol.source_worktree_id,
5503                symbol.language_server_name.clone(),
5504            )) else {
5505                return Task::ready(Err(anyhow!(
5506                    "language server for worktree and language not found"
5507                )));
5508            };
5509
5510            let worktree_abs_path = if let Some(worktree_abs_path) = self
5511                .worktree_store
5512                .read(cx)
5513                .worktree_for_id(symbol.path.worktree_id, cx)
5514                .map(|worktree| worktree.read(cx).abs_path())
5515            {
5516                worktree_abs_path
5517            } else {
5518                return Task::ready(Err(anyhow!("worktree not found for symbol")));
5519            };
5520
5521            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
5522            let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
5523                uri
5524            } else {
5525                return Task::ready(Err(anyhow!("invalid symbol path")));
5526            };
5527
5528            self.open_local_buffer_via_lsp(
5529                symbol_uri,
5530                language_server_id,
5531                symbol.language_server_name.clone(),
5532                cx,
5533            )
5534        } else {
5535            Task::ready(Err(anyhow!("no upstream client or local store")))
5536        }
5537    }
5538
5539    pub fn open_local_buffer_via_lsp(
5540        &mut self,
5541        mut abs_path: lsp::Url,
5542        language_server_id: LanguageServerId,
5543        language_server_name: LanguageServerName,
5544        cx: &mut Context<Self>,
5545    ) -> Task<Result<Entity<Buffer>>> {
5546        cx.spawn(move |lsp_store, mut cx| async move {
5547            // Escape percent-encoded string.
5548            let current_scheme = abs_path.scheme().to_owned();
5549            let _ = abs_path.set_scheme("file");
5550
5551            let abs_path = abs_path
5552                .to_file_path()
5553                .map_err(|_| anyhow!("can't convert URI to path"))?;
5554            let p = abs_path.clone();
5555            let yarn_worktree = lsp_store
5556                .update(&mut cx, move |lsp_store, cx| match lsp_store.as_local() {
5557                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
5558                        cx.spawn(|this, mut cx| async move {
5559                            let t = this
5560                                .update(&mut cx, |this, cx| {
5561                                    this.process_path(&p, &current_scheme, cx)
5562                                })
5563                                .ok()?;
5564                            t.await
5565                        })
5566                    }),
5567                    None => Task::ready(None),
5568                })?
5569                .await;
5570            let (worktree_root_target, known_relative_path) =
5571                if let Some((zip_root, relative_path)) = yarn_worktree {
5572                    (zip_root, Some(relative_path))
5573                } else {
5574                    (Arc::<Path>::from(abs_path.as_path()), None)
5575                };
5576            let (worktree, relative_path) = if let Some(result) =
5577                lsp_store.update(&mut cx, |lsp_store, cx| {
5578                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
5579                        worktree_store.find_worktree(&worktree_root_target, cx)
5580                    })
5581                })? {
5582                let relative_path =
5583                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
5584                (result.0, relative_path)
5585            } else {
5586                let worktree = lsp_store
5587                    .update(&mut cx, |lsp_store, cx| {
5588                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
5589                            worktree_store.create_worktree(&worktree_root_target, false, cx)
5590                        })
5591                    })?
5592                    .await?;
5593                if worktree.update(&mut cx, |worktree, _| worktree.is_local())? {
5594                    lsp_store
5595                        .update(&mut cx, |lsp_store, cx| {
5596                            lsp_store.register_local_language_server(
5597                                worktree.read(cx).id(),
5598                                language_server_name,
5599                                language_server_id,
5600                            )
5601                        })
5602                        .ok();
5603                }
5604                let worktree_root = worktree.update(&mut cx, |worktree, _| worktree.abs_path())?;
5605                let relative_path = if let Some(known_path) = known_relative_path {
5606                    known_path
5607                } else {
5608                    abs_path.strip_prefix(worktree_root)?.into()
5609                };
5610                (worktree, relative_path)
5611            };
5612            let project_path = ProjectPath {
5613                worktree_id: worktree.update(&mut cx, |worktree, _| worktree.id())?,
5614                path: relative_path,
5615            };
5616            lsp_store
5617                .update(&mut cx, |lsp_store, cx| {
5618                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
5619                        buffer_store.open_buffer(project_path, cx)
5620                    })
5621                })?
5622                .await
5623        })
5624    }
5625
5626    fn request_multiple_lsp_locally<P, R>(
5627        &mut self,
5628        buffer: &Entity<Buffer>,
5629        position: Option<P>,
5630        request: R,
5631        cx: &mut Context<'_, Self>,
5632    ) -> Task<Vec<R::Response>>
5633    where
5634        P: ToOffset,
5635        R: LspCommand + Clone,
5636        <R::LspRequest as lsp::request::Request>::Result: Send,
5637        <R::LspRequest as lsp::request::Request>::Params: Send,
5638    {
5639        let Some(local) = self.as_local() else {
5640            return Task::ready(Vec::new());
5641        };
5642
5643        let snapshot = buffer.read(cx).snapshot();
5644        let scope = position.and_then(|position| snapshot.language_scope_at(position));
5645        let server_ids = local
5646            .language_servers_for_buffer(buffer.read(cx), cx)
5647            .filter(|(adapter, _)| {
5648                scope
5649                    .as_ref()
5650                    .map(|scope| scope.language_allowed(&adapter.name))
5651                    .unwrap_or(true)
5652            })
5653            .map(|(_, server)| server.server_id())
5654            .collect::<Vec<_>>();
5655
5656        let mut response_results = server_ids
5657            .into_iter()
5658            .map(|server_id| {
5659                self.request_lsp(
5660                    buffer.clone(),
5661                    LanguageServerToQuery::Other(server_id),
5662                    request.clone(),
5663                    cx,
5664                )
5665            })
5666            .collect::<FuturesUnordered<_>>();
5667
5668        cx.spawn(|_, _| async move {
5669            let mut responses = Vec::with_capacity(response_results.len());
5670            while let Some(response_result) = response_results.next().await {
5671                if let Some(response) = response_result.log_err() {
5672                    responses.push(response);
5673                }
5674            }
5675            responses
5676        })
5677    }
5678
5679    async fn handle_lsp_command<T: LspCommand>(
5680        this: Entity<Self>,
5681        envelope: TypedEnvelope<T::ProtoRequest>,
5682        mut cx: AsyncApp,
5683    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
5684    where
5685        <T::LspRequest as lsp::request::Request>::Params: Send,
5686        <T::LspRequest as lsp::request::Request>::Result: Send,
5687    {
5688        let sender_id = envelope.original_sender_id().unwrap_or_default();
5689        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
5690        let buffer_handle = this.update(&mut cx, |this, cx| {
5691            this.buffer_store.read(cx).get_existing(buffer_id)
5692        })??;
5693        let request = T::from_proto(
5694            envelope.payload,
5695            this.clone(),
5696            buffer_handle.clone(),
5697            cx.clone(),
5698        )
5699        .await?;
5700        let response = this
5701            .update(&mut cx, |this, cx| {
5702                this.request_lsp(
5703                    buffer_handle.clone(),
5704                    LanguageServerToQuery::Primary,
5705                    request,
5706                    cx,
5707                )
5708            })?
5709            .await?;
5710        this.update(&mut cx, |this, cx| {
5711            Ok(T::response_to_proto(
5712                response,
5713                this,
5714                sender_id,
5715                &buffer_handle.read(cx).version(),
5716                cx,
5717            ))
5718        })?
5719    }
5720
5721    async fn handle_multi_lsp_query(
5722        this: Entity<Self>,
5723        envelope: TypedEnvelope<proto::MultiLspQuery>,
5724        mut cx: AsyncApp,
5725    ) -> Result<proto::MultiLspQueryResponse> {
5726        let response_from_ssh = this.update(&mut cx, |this, _| {
5727            let (upstream_client, project_id) = this.upstream_client()?;
5728            let mut payload = envelope.payload.clone();
5729            payload.project_id = project_id;
5730
5731            Some(upstream_client.request(payload))
5732        })?;
5733        if let Some(response_from_ssh) = response_from_ssh {
5734            return response_from_ssh.await;
5735        }
5736
5737        let sender_id = envelope.original_sender_id().unwrap_or_default();
5738        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
5739        let version = deserialize_version(&envelope.payload.version);
5740        let buffer = this.update(&mut cx, |this, cx| {
5741            this.buffer_store.read(cx).get_existing(buffer_id)
5742        })??;
5743        buffer
5744            .update(&mut cx, |buffer, _| {
5745                buffer.wait_for_version(version.clone())
5746            })?
5747            .await?;
5748        let buffer_version = buffer.update(&mut cx, |buffer, _| buffer.version())?;
5749        match envelope
5750            .payload
5751            .strategy
5752            .context("invalid request without the strategy")?
5753        {
5754            proto::multi_lsp_query::Strategy::All(_) => {
5755                // currently, there's only one multiple language servers query strategy,
5756                // so just ensure it's specified correctly
5757            }
5758        }
5759        match envelope.payload.request {
5760            Some(proto::multi_lsp_query::Request::GetHover(get_hover)) => {
5761                let get_hover =
5762                    GetHover::from_proto(get_hover, this.clone(), buffer.clone(), cx.clone())
5763                        .await?;
5764                let all_hovers = this
5765                    .update(&mut cx, |this, cx| {
5766                        this.request_multiple_lsp_locally(
5767                            &buffer,
5768                            Some(get_hover.position),
5769                            get_hover,
5770                            cx,
5771                        )
5772                    })?
5773                    .await
5774                    .into_iter()
5775                    .filter_map(|hover| remove_empty_hover_blocks(hover?));
5776                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
5777                    responses: all_hovers
5778                        .map(|hover| proto::LspResponse {
5779                            response: Some(proto::lsp_response::Response::GetHoverResponse(
5780                                GetHover::response_to_proto(
5781                                    Some(hover),
5782                                    project,
5783                                    sender_id,
5784                                    &buffer_version,
5785                                    cx,
5786                                ),
5787                            )),
5788                        })
5789                        .collect(),
5790                })
5791            }
5792            Some(proto::multi_lsp_query::Request::GetCodeActions(get_code_actions)) => {
5793                let get_code_actions = GetCodeActions::from_proto(
5794                    get_code_actions,
5795                    this.clone(),
5796                    buffer.clone(),
5797                    cx.clone(),
5798                )
5799                .await?;
5800
5801                let all_actions = this
5802                    .update(&mut cx, |project, cx| {
5803                        project.request_multiple_lsp_locally(
5804                            &buffer,
5805                            Some(get_code_actions.range.start),
5806                            get_code_actions,
5807                            cx,
5808                        )
5809                    })?
5810                    .await
5811                    .into_iter();
5812
5813                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
5814                    responses: all_actions
5815                        .map(|code_actions| proto::LspResponse {
5816                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
5817                                GetCodeActions::response_to_proto(
5818                                    code_actions,
5819                                    project,
5820                                    sender_id,
5821                                    &buffer_version,
5822                                    cx,
5823                                ),
5824                            )),
5825                        })
5826                        .collect(),
5827                })
5828            }
5829            Some(proto::multi_lsp_query::Request::GetSignatureHelp(get_signature_help)) => {
5830                let get_signature_help = GetSignatureHelp::from_proto(
5831                    get_signature_help,
5832                    this.clone(),
5833                    buffer.clone(),
5834                    cx.clone(),
5835                )
5836                .await?;
5837
5838                let all_signatures = this
5839                    .update(&mut cx, |project, cx| {
5840                        project.request_multiple_lsp_locally(
5841                            &buffer,
5842                            Some(get_signature_help.position),
5843                            get_signature_help,
5844                            cx,
5845                        )
5846                    })?
5847                    .await
5848                    .into_iter();
5849
5850                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
5851                    responses: all_signatures
5852                        .map(|signature_help| proto::LspResponse {
5853                            response: Some(
5854                                proto::lsp_response::Response::GetSignatureHelpResponse(
5855                                    GetSignatureHelp::response_to_proto(
5856                                        signature_help,
5857                                        project,
5858                                        sender_id,
5859                                        &buffer_version,
5860                                        cx,
5861                                    ),
5862                                ),
5863                            ),
5864                        })
5865                        .collect(),
5866                })
5867            }
5868            None => anyhow::bail!("empty multi lsp query request"),
5869        }
5870    }
5871
5872    async fn handle_apply_code_action(
5873        this: Entity<Self>,
5874        envelope: TypedEnvelope<proto::ApplyCodeAction>,
5875        mut cx: AsyncApp,
5876    ) -> Result<proto::ApplyCodeActionResponse> {
5877        let sender_id = envelope.original_sender_id().unwrap_or_default();
5878        let action = Self::deserialize_code_action(
5879            envelope
5880                .payload
5881                .action
5882                .ok_or_else(|| anyhow!("invalid action"))?,
5883        )?;
5884        let apply_code_action = this.update(&mut cx, |this, cx| {
5885            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
5886            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
5887            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
5888        })??;
5889
5890        let project_transaction = apply_code_action.await?;
5891        let project_transaction = this.update(&mut cx, |this, cx| {
5892            this.buffer_store.update(cx, |buffer_store, cx| {
5893                buffer_store.serialize_project_transaction_for_peer(
5894                    project_transaction,
5895                    sender_id,
5896                    cx,
5897                )
5898            })
5899        })?;
5900        Ok(proto::ApplyCodeActionResponse {
5901            transaction: Some(project_transaction),
5902        })
5903    }
5904
5905    async fn handle_register_buffer_with_language_servers(
5906        this: Entity<Self>,
5907        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
5908        mut cx: AsyncApp,
5909    ) -> Result<proto::Ack> {
5910        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
5911        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
5912        this.update(&mut cx, |this, cx| {
5913            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
5914                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
5915                    project_id: upstream_project_id,
5916                    buffer_id: buffer_id.to_proto(),
5917                });
5918            }
5919
5920            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
5921                anyhow::bail!("buffer is not open");
5922            };
5923
5924            let handle = this.register_buffer_with_language_servers(&buffer, cx);
5925            this.buffer_store().update(cx, |buffer_store, _| {
5926                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
5927            });
5928
5929            Ok(())
5930        })??;
5931        Ok(proto::Ack {})
5932    }
5933
5934    async fn handle_rename_project_entry(
5935        this: Entity<Self>,
5936        envelope: TypedEnvelope<proto::RenameProjectEntry>,
5937        mut cx: AsyncApp,
5938    ) -> Result<proto::ProjectEntryResponse> {
5939        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
5940        let (worktree_id, worktree, old_path, is_dir) = this
5941            .update(&mut cx, |this, cx| {
5942                this.worktree_store
5943                    .read(cx)
5944                    .worktree_and_entry_for_id(entry_id, cx)
5945                    .map(|(worktree, entry)| {
5946                        (
5947                            worktree.read(cx).id(),
5948                            worktree,
5949                            entry.path.clone(),
5950                            entry.is_dir(),
5951                        )
5952                    })
5953            })?
5954            .ok_or_else(|| anyhow!("worktree not found"))?;
5955        let (old_abs_path, new_abs_path) = {
5956            let root_path = worktree.update(&mut cx, |this, _| this.abs_path())?;
5957            (
5958                root_path.join(&old_path),
5959                root_path.join(&envelope.payload.new_path),
5960            )
5961        };
5962
5963        Self::will_rename_entry(
5964            this.downgrade(),
5965            worktree_id,
5966            &old_abs_path,
5967            &new_abs_path,
5968            is_dir,
5969            cx.clone(),
5970        )
5971        .await;
5972        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
5973        this.update(&mut cx, |this, _| {
5974            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
5975        })
5976        .ok();
5977        response
5978    }
5979
5980    async fn handle_update_diagnostic_summary(
5981        this: Entity<Self>,
5982        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
5983        mut cx: AsyncApp,
5984    ) -> Result<()> {
5985        this.update(&mut cx, |this, cx| {
5986            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
5987            if let Some(message) = envelope.payload.summary {
5988                let project_path = ProjectPath {
5989                    worktree_id,
5990                    path: Path::new(&message.path).into(),
5991                };
5992                let path = project_path.path.clone();
5993                let server_id = LanguageServerId(message.language_server_id as usize);
5994                let summary = DiagnosticSummary {
5995                    error_count: message.error_count as usize,
5996                    warning_count: message.warning_count as usize,
5997                };
5998
5999                if summary.is_empty() {
6000                    if let Some(worktree_summaries) =
6001                        this.diagnostic_summaries.get_mut(&worktree_id)
6002                    {
6003                        if let Some(summaries) = worktree_summaries.get_mut(&path) {
6004                            summaries.remove(&server_id);
6005                            if summaries.is_empty() {
6006                                worktree_summaries.remove(&path);
6007                            }
6008                        }
6009                    }
6010                } else {
6011                    this.diagnostic_summaries
6012                        .entry(worktree_id)
6013                        .or_default()
6014                        .entry(path)
6015                        .or_default()
6016                        .insert(server_id, summary);
6017                }
6018                if let Some((downstream_client, project_id)) = &this.downstream_client {
6019                    downstream_client
6020                        .send(proto::UpdateDiagnosticSummary {
6021                            project_id: *project_id,
6022                            worktree_id: worktree_id.to_proto(),
6023                            summary: Some(proto::DiagnosticSummary {
6024                                path: project_path.path.to_string_lossy().to_string(),
6025                                language_server_id: server_id.0 as u64,
6026                                error_count: summary.error_count as u32,
6027                                warning_count: summary.warning_count as u32,
6028                            }),
6029                        })
6030                        .log_err();
6031                }
6032                cx.emit(LspStoreEvent::DiagnosticsUpdated {
6033                    language_server_id: LanguageServerId(message.language_server_id as usize),
6034                    path: project_path,
6035                });
6036            }
6037            Ok(())
6038        })?
6039    }
6040
6041    async fn handle_start_language_server(
6042        this: Entity<Self>,
6043        envelope: TypedEnvelope<proto::StartLanguageServer>,
6044        mut cx: AsyncApp,
6045    ) -> Result<()> {
6046        let server = envelope
6047            .payload
6048            .server
6049            .ok_or_else(|| anyhow!("invalid server"))?;
6050
6051        this.update(&mut cx, |this, cx| {
6052            let server_id = LanguageServerId(server.id as usize);
6053            this.language_server_statuses.insert(
6054                server_id,
6055                LanguageServerStatus {
6056                    name: server.name.clone(),
6057                    pending_work: Default::default(),
6058                    has_pending_diagnostic_updates: false,
6059                    progress_tokens: Default::default(),
6060                },
6061            );
6062            cx.emit(LspStoreEvent::LanguageServerAdded(
6063                server_id,
6064                LanguageServerName(server.name.into()),
6065                server.worktree_id.map(WorktreeId::from_proto),
6066            ));
6067            cx.notify();
6068        })?;
6069        Ok(())
6070    }
6071
6072    async fn handle_update_language_server(
6073        this: Entity<Self>,
6074        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
6075        mut cx: AsyncApp,
6076    ) -> Result<()> {
6077        this.update(&mut cx, |this, cx| {
6078            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
6079
6080            match envelope
6081                .payload
6082                .variant
6083                .ok_or_else(|| anyhow!("invalid variant"))?
6084            {
6085                proto::update_language_server::Variant::WorkStart(payload) => {
6086                    this.on_lsp_work_start(
6087                        language_server_id,
6088                        payload.token,
6089                        LanguageServerProgress {
6090                            title: payload.title,
6091                            is_disk_based_diagnostics_progress: false,
6092                            is_cancellable: payload.is_cancellable.unwrap_or(false),
6093                            message: payload.message,
6094                            percentage: payload.percentage.map(|p| p as usize),
6095                            last_update_at: cx.background_executor().now(),
6096                        },
6097                        cx,
6098                    );
6099                }
6100
6101                proto::update_language_server::Variant::WorkProgress(payload) => {
6102                    this.on_lsp_work_progress(
6103                        language_server_id,
6104                        payload.token,
6105                        LanguageServerProgress {
6106                            title: None,
6107                            is_disk_based_diagnostics_progress: false,
6108                            is_cancellable: payload.is_cancellable.unwrap_or(false),
6109                            message: payload.message,
6110                            percentage: payload.percentage.map(|p| p as usize),
6111                            last_update_at: cx.background_executor().now(),
6112                        },
6113                        cx,
6114                    );
6115                }
6116
6117                proto::update_language_server::Variant::WorkEnd(payload) => {
6118                    this.on_lsp_work_end(language_server_id, payload.token, cx);
6119                }
6120
6121                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
6122                    this.disk_based_diagnostics_started(language_server_id, cx);
6123                }
6124
6125                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
6126                    this.disk_based_diagnostics_finished(language_server_id, cx)
6127                }
6128            }
6129
6130            Ok(())
6131        })?
6132    }
6133
6134    async fn handle_language_server_log(
6135        this: Entity<Self>,
6136        envelope: TypedEnvelope<proto::LanguageServerLog>,
6137        mut cx: AsyncApp,
6138    ) -> Result<()> {
6139        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
6140        let log_type = envelope
6141            .payload
6142            .log_type
6143            .map(LanguageServerLogType::from_proto)
6144            .context("invalid language server log type")?;
6145
6146        let message = envelope.payload.message;
6147
6148        this.update(&mut cx, |_, cx| {
6149            cx.emit(LspStoreEvent::LanguageServerLog(
6150                language_server_id,
6151                log_type,
6152                message,
6153            ));
6154        })
6155    }
6156
6157    pub fn disk_based_diagnostics_started(
6158        &mut self,
6159        language_server_id: LanguageServerId,
6160        cx: &mut Context<Self>,
6161    ) {
6162        if let Some(language_server_status) =
6163            self.language_server_statuses.get_mut(&language_server_id)
6164        {
6165            language_server_status.has_pending_diagnostic_updates = true;
6166        }
6167
6168        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
6169        cx.emit(LspStoreEvent::LanguageServerUpdate {
6170            language_server_id,
6171            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
6172                Default::default(),
6173            ),
6174        })
6175    }
6176
6177    pub fn disk_based_diagnostics_finished(
6178        &mut self,
6179        language_server_id: LanguageServerId,
6180        cx: &mut Context<Self>,
6181    ) {
6182        if let Some(language_server_status) =
6183            self.language_server_statuses.get_mut(&language_server_id)
6184        {
6185            language_server_status.has_pending_diagnostic_updates = false;
6186        }
6187
6188        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
6189        cx.emit(LspStoreEvent::LanguageServerUpdate {
6190            language_server_id,
6191            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
6192                Default::default(),
6193            ),
6194        })
6195    }
6196
6197    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
6198    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
6199    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
6200    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
6201    // the language server might take some time to publish diagnostics.
6202    fn simulate_disk_based_diagnostics_events_if_needed(
6203        &mut self,
6204        language_server_id: LanguageServerId,
6205        cx: &mut Context<Self>,
6206    ) {
6207        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
6208
6209        let Some(LanguageServerState::Running {
6210            simulate_disk_based_diagnostics_completion,
6211            adapter,
6212            ..
6213        }) = self
6214            .as_local_mut()
6215            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
6216        else {
6217            return;
6218        };
6219
6220        if adapter.disk_based_diagnostics_progress_token.is_some() {
6221            return;
6222        }
6223
6224        let prev_task = simulate_disk_based_diagnostics_completion.replace(cx.spawn(
6225            move |this, mut cx| async move {
6226                cx.background_executor()
6227                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
6228                    .await;
6229
6230                this.update(&mut cx, |this, cx| {
6231                    this.disk_based_diagnostics_finished(language_server_id, cx);
6232
6233                    if let Some(LanguageServerState::Running {
6234                        simulate_disk_based_diagnostics_completion,
6235                        ..
6236                    }) = this.as_local_mut().and_then(|local_store| {
6237                        local_store.language_servers.get_mut(&language_server_id)
6238                    }) {
6239                        *simulate_disk_based_diagnostics_completion = None;
6240                    }
6241                })
6242                .ok();
6243            },
6244        ));
6245
6246        if prev_task.is_none() {
6247            self.disk_based_diagnostics_started(language_server_id, cx);
6248        }
6249    }
6250
6251    pub fn language_server_statuses(
6252        &self,
6253    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
6254        self.language_server_statuses
6255            .iter()
6256            .map(|(key, value)| (*key, value))
6257    }
6258
6259    pub(super) fn did_rename_entry(
6260        &self,
6261        worktree_id: WorktreeId,
6262        old_path: &Path,
6263        new_path: &Path,
6264        is_dir: bool,
6265    ) {
6266        maybe!({
6267            let local_store = self.as_local()?;
6268
6269            let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from)?;
6270            let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from)?;
6271
6272            for language_server in local_store.language_servers_for_worktree(worktree_id) {
6273                let Some(filter) = local_store
6274                    .language_server_paths_watched_for_rename
6275                    .get(&language_server.server_id())
6276                else {
6277                    continue;
6278                };
6279
6280                if filter.should_send_did_rename(&old_uri, is_dir) {
6281                    language_server
6282                        .notify::<DidRenameFiles>(&RenameFilesParams {
6283                            files: vec![FileRename {
6284                                old_uri: old_uri.clone(),
6285                                new_uri: new_uri.clone(),
6286                            }],
6287                        })
6288                        .log_err();
6289                }
6290            }
6291            Some(())
6292        });
6293    }
6294
6295    pub(super) fn will_rename_entry(
6296        this: WeakEntity<Self>,
6297        worktree_id: WorktreeId,
6298        old_path: &Path,
6299        new_path: &Path,
6300        is_dir: bool,
6301        cx: AsyncApp,
6302    ) -> Task<()> {
6303        let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from);
6304        let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from);
6305        cx.spawn(move |mut cx| async move {
6306            let mut tasks = vec![];
6307            this.update(&mut cx, |this, cx| {
6308                let local_store = this.as_local()?;
6309                let old_uri = old_uri?;
6310                let new_uri = new_uri?;
6311                for language_server in local_store.language_servers_for_worktree(worktree_id) {
6312                    let Some(filter) = local_store
6313                        .language_server_paths_watched_for_rename
6314                        .get(&language_server.server_id())
6315                    else {
6316                        continue;
6317                    };
6318                    let Some(adapter) =
6319                        this.language_server_adapter_for_id(language_server.server_id())
6320                    else {
6321                        continue;
6322                    };
6323                    if filter.should_send_will_rename(&old_uri, is_dir) {
6324                        let apply_edit = cx.spawn({
6325                            let old_uri = old_uri.clone();
6326                            let new_uri = new_uri.clone();
6327                            let language_server = language_server.clone();
6328                            |this, mut cx| async move {
6329                                let edit = language_server
6330                                    .request::<WillRenameFiles>(RenameFilesParams {
6331                                        files: vec![FileRename { old_uri, new_uri }],
6332                                    })
6333                                    .log_err()
6334                                    .await
6335                                    .flatten()?;
6336
6337                                LocalLspStore::deserialize_workspace_edit(
6338                                    this.upgrade()?,
6339                                    edit,
6340                                    false,
6341                                    adapter.clone(),
6342                                    language_server.clone(),
6343                                    &mut cx,
6344                                )
6345                                .await
6346                                .ok();
6347                                Some(())
6348                            }
6349                        });
6350                        tasks.push(apply_edit);
6351                    }
6352                }
6353                Some(())
6354            })
6355            .ok()
6356            .flatten();
6357            for task in tasks {
6358                // Await on tasks sequentially so that the order of application of edits is deterministic
6359                // (at least with regards to the order of registration of language servers)
6360                task.await;
6361            }
6362        })
6363    }
6364
6365    fn lsp_notify_abs_paths_changed(
6366        &mut self,
6367        server_id: LanguageServerId,
6368        changes: Vec<PathEvent>,
6369    ) {
6370        maybe!({
6371            let server = self.language_server_for_id(server_id)?;
6372            let changes = changes
6373                .into_iter()
6374                .filter_map(|event| {
6375                    let typ = match event.kind? {
6376                        PathEventKind::Created => lsp::FileChangeType::CREATED,
6377                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
6378                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
6379                    };
6380                    Some(lsp::FileEvent {
6381                        uri: lsp::Url::from_file_path(&event.path).ok()?,
6382                        typ,
6383                    })
6384                })
6385                .collect::<Vec<_>>();
6386            if !changes.is_empty() {
6387                server
6388                    .notify::<lsp::notification::DidChangeWatchedFiles>(
6389                        &lsp::DidChangeWatchedFilesParams { changes },
6390                    )
6391                    .log_err();
6392            }
6393            Some(())
6394        });
6395    }
6396
6397    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
6398        if let Some(local_lsp_store) = self.as_local() {
6399            if let Some(LanguageServerState::Running { server, .. }) =
6400                local_lsp_store.language_servers.get(&id)
6401            {
6402                Some(server.clone())
6403            } else if let Some((_, server)) =
6404                local_lsp_store.supplementary_language_servers.get(&id)
6405            {
6406                Some(Arc::clone(server))
6407            } else {
6408                None
6409            }
6410        } else {
6411            None
6412        }
6413    }
6414
6415    fn on_lsp_progress(
6416        &mut self,
6417        progress: lsp::ProgressParams,
6418        language_server_id: LanguageServerId,
6419        disk_based_diagnostics_progress_token: Option<String>,
6420        cx: &mut Context<Self>,
6421    ) {
6422        let token = match progress.token {
6423            lsp::NumberOrString::String(token) => token,
6424            lsp::NumberOrString::Number(token) => {
6425                log::info!("skipping numeric progress token {}", token);
6426                return;
6427            }
6428        };
6429
6430        let lsp::ProgressParamsValue::WorkDone(progress) = progress.value;
6431        let language_server_status =
6432            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
6433                status
6434            } else {
6435                return;
6436            };
6437
6438        if !language_server_status.progress_tokens.contains(&token) {
6439            return;
6440        }
6441
6442        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
6443            .as_ref()
6444            .map_or(false, |disk_based_token| {
6445                token.starts_with(disk_based_token)
6446            });
6447
6448        match progress {
6449            lsp::WorkDoneProgress::Begin(report) => {
6450                if is_disk_based_diagnostics_progress {
6451                    self.disk_based_diagnostics_started(language_server_id, cx);
6452                }
6453                self.on_lsp_work_start(
6454                    language_server_id,
6455                    token.clone(),
6456                    LanguageServerProgress {
6457                        title: Some(report.title),
6458                        is_disk_based_diagnostics_progress,
6459                        is_cancellable: report.cancellable.unwrap_or(false),
6460                        message: report.message.clone(),
6461                        percentage: report.percentage.map(|p| p as usize),
6462                        last_update_at: cx.background_executor().now(),
6463                    },
6464                    cx,
6465                );
6466            }
6467            lsp::WorkDoneProgress::Report(report) => {
6468                if self.on_lsp_work_progress(
6469                    language_server_id,
6470                    token.clone(),
6471                    LanguageServerProgress {
6472                        title: None,
6473                        is_disk_based_diagnostics_progress,
6474                        is_cancellable: report.cancellable.unwrap_or(false),
6475                        message: report.message.clone(),
6476                        percentage: report.percentage.map(|p| p as usize),
6477                        last_update_at: cx.background_executor().now(),
6478                    },
6479                    cx,
6480                ) {
6481                    cx.emit(LspStoreEvent::LanguageServerUpdate {
6482                        language_server_id,
6483                        message: proto::update_language_server::Variant::WorkProgress(
6484                            proto::LspWorkProgress {
6485                                token,
6486                                message: report.message,
6487                                percentage: report.percentage,
6488                                is_cancellable: report.cancellable,
6489                            },
6490                        ),
6491                    })
6492                }
6493            }
6494            lsp::WorkDoneProgress::End(_) => {
6495                language_server_status.progress_tokens.remove(&token);
6496                self.on_lsp_work_end(language_server_id, token.clone(), cx);
6497                if is_disk_based_diagnostics_progress {
6498                    self.disk_based_diagnostics_finished(language_server_id, cx);
6499                }
6500            }
6501        }
6502    }
6503
6504    fn on_lsp_work_start(
6505        &mut self,
6506        language_server_id: LanguageServerId,
6507        token: String,
6508        progress: LanguageServerProgress,
6509        cx: &mut Context<Self>,
6510    ) {
6511        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
6512            status.pending_work.insert(token.clone(), progress.clone());
6513            cx.notify();
6514        }
6515        cx.emit(LspStoreEvent::LanguageServerUpdate {
6516            language_server_id,
6517            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
6518                token,
6519                title: progress.title,
6520                message: progress.message,
6521                percentage: progress.percentage.map(|p| p as u32),
6522                is_cancellable: Some(progress.is_cancellable),
6523            }),
6524        })
6525    }
6526
6527    fn on_lsp_work_progress(
6528        &mut self,
6529        language_server_id: LanguageServerId,
6530        token: String,
6531        progress: LanguageServerProgress,
6532        cx: &mut Context<Self>,
6533    ) -> bool {
6534        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
6535            match status.pending_work.entry(token) {
6536                btree_map::Entry::Vacant(entry) => {
6537                    entry.insert(progress);
6538                    cx.notify();
6539                    return true;
6540                }
6541                btree_map::Entry::Occupied(mut entry) => {
6542                    let entry = entry.get_mut();
6543                    if (progress.last_update_at - entry.last_update_at)
6544                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
6545                    {
6546                        entry.last_update_at = progress.last_update_at;
6547                        if progress.message.is_some() {
6548                            entry.message = progress.message;
6549                        }
6550                        if progress.percentage.is_some() {
6551                            entry.percentage = progress.percentage;
6552                        }
6553                        if progress.is_cancellable != entry.is_cancellable {
6554                            entry.is_cancellable = progress.is_cancellable;
6555                        }
6556                        cx.notify();
6557                        return true;
6558                    }
6559                }
6560            }
6561        }
6562
6563        false
6564    }
6565
6566    fn on_lsp_work_end(
6567        &mut self,
6568        language_server_id: LanguageServerId,
6569        token: String,
6570        cx: &mut Context<Self>,
6571    ) {
6572        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
6573            if let Some(work) = status.pending_work.remove(&token) {
6574                if !work.is_disk_based_diagnostics_progress {
6575                    cx.emit(LspStoreEvent::RefreshInlayHints);
6576                }
6577            }
6578            cx.notify();
6579        }
6580
6581        cx.emit(LspStoreEvent::LanguageServerUpdate {
6582            language_server_id,
6583            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
6584        })
6585    }
6586
6587    pub async fn handle_resolve_completion_documentation(
6588        this: Entity<Self>,
6589        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
6590        mut cx: AsyncApp,
6591    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
6592        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
6593
6594        let completion = this
6595            .read_with(&cx, |this, cx| {
6596                let id = LanguageServerId(envelope.payload.language_server_id as usize);
6597                let Some(server) = this.language_server_for_id(id) else {
6598                    return Err(anyhow!("No language server {id}"));
6599                };
6600
6601                Ok(cx.background_executor().spawn(async move {
6602                    let can_resolve = server
6603                        .capabilities()
6604                        .completion_provider
6605                        .as_ref()
6606                        .and_then(|options| options.resolve_provider)
6607                        .unwrap_or(false);
6608                    if can_resolve {
6609                        server
6610                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
6611                            .await
6612                    } else {
6613                        anyhow::Ok(lsp_completion)
6614                    }
6615                }))
6616            })??
6617            .await?;
6618
6619        let mut documentation_is_markdown = false;
6620        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
6621        let documentation = match completion.documentation {
6622            Some(lsp::Documentation::String(text)) => text,
6623
6624            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
6625                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
6626                value
6627            }
6628
6629            _ => String::new(),
6630        };
6631
6632        // If we have a new buffer_id, that means we're talking to a new client
6633        // and want to check for new text_edits in the completion too.
6634        let mut old_start = None;
6635        let mut old_end = None;
6636        let mut new_text = String::default();
6637        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
6638            let buffer_snapshot = this.update(&mut cx, |this, cx| {
6639                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
6640                anyhow::Ok(buffer.read(cx).snapshot())
6641            })??;
6642
6643            if let Some(text_edit) = completion.text_edit.as_ref() {
6644                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
6645
6646                if let Some((old_range, mut text_edit_new_text)) = edit {
6647                    LineEnding::normalize(&mut text_edit_new_text);
6648
6649                    new_text = text_edit_new_text;
6650                    old_start = Some(serialize_anchor(&old_range.start));
6651                    old_end = Some(serialize_anchor(&old_range.end));
6652                }
6653            }
6654        }
6655
6656        Ok(proto::ResolveCompletionDocumentationResponse {
6657            documentation,
6658            documentation_is_markdown,
6659            old_start,
6660            old_end,
6661            new_text,
6662            lsp_completion,
6663        })
6664    }
6665
6666    async fn handle_on_type_formatting(
6667        this: Entity<Self>,
6668        envelope: TypedEnvelope<proto::OnTypeFormatting>,
6669        mut cx: AsyncApp,
6670    ) -> Result<proto::OnTypeFormattingResponse> {
6671        let on_type_formatting = this.update(&mut cx, |this, cx| {
6672            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
6673            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
6674            let position = envelope
6675                .payload
6676                .position
6677                .and_then(deserialize_anchor)
6678                .ok_or_else(|| anyhow!("invalid position"))?;
6679            Ok::<_, anyhow::Error>(this.apply_on_type_formatting(
6680                buffer,
6681                position,
6682                envelope.payload.trigger.clone(),
6683                cx,
6684            ))
6685        })??;
6686
6687        let transaction = on_type_formatting
6688            .await?
6689            .as_ref()
6690            .map(language::proto::serialize_transaction);
6691        Ok(proto::OnTypeFormattingResponse { transaction })
6692    }
6693
6694    async fn handle_refresh_inlay_hints(
6695        this: Entity<Self>,
6696        _: TypedEnvelope<proto::RefreshInlayHints>,
6697        mut cx: AsyncApp,
6698    ) -> Result<proto::Ack> {
6699        this.update(&mut cx, |_, cx| {
6700            cx.emit(LspStoreEvent::RefreshInlayHints);
6701        })?;
6702        Ok(proto::Ack {})
6703    }
6704
6705    async fn handle_inlay_hints(
6706        this: Entity<Self>,
6707        envelope: TypedEnvelope<proto::InlayHints>,
6708        mut cx: AsyncApp,
6709    ) -> Result<proto::InlayHintsResponse> {
6710        let sender_id = envelope.original_sender_id().unwrap_or_default();
6711        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
6712        let buffer = this.update(&mut cx, |this, cx| {
6713            this.buffer_store.read(cx).get_existing(buffer_id)
6714        })??;
6715        buffer
6716            .update(&mut cx, |buffer, _| {
6717                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
6718            })?
6719            .await
6720            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
6721
6722        let start = envelope
6723            .payload
6724            .start
6725            .and_then(deserialize_anchor)
6726            .context("missing range start")?;
6727        let end = envelope
6728            .payload
6729            .end
6730            .and_then(deserialize_anchor)
6731            .context("missing range end")?;
6732        let buffer_hints = this
6733            .update(&mut cx, |lsp_store, cx| {
6734                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
6735            })?
6736            .await
6737            .context("inlay hints fetch")?;
6738
6739        this.update(&mut cx, |project, cx| {
6740            InlayHints::response_to_proto(
6741                buffer_hints,
6742                project,
6743                sender_id,
6744                &buffer.read(cx).version(),
6745                cx,
6746            )
6747        })
6748    }
6749
6750    async fn handle_resolve_inlay_hint(
6751        this: Entity<Self>,
6752        envelope: TypedEnvelope<proto::ResolveInlayHint>,
6753        mut cx: AsyncApp,
6754    ) -> Result<proto::ResolveInlayHintResponse> {
6755        let proto_hint = envelope
6756            .payload
6757            .hint
6758            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
6759        let hint = InlayHints::proto_to_project_hint(proto_hint)
6760            .context("resolved proto inlay hint conversion")?;
6761        let buffer = this.update(&mut cx, |this, cx| {
6762            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
6763            this.buffer_store.read(cx).get_existing(buffer_id)
6764        })??;
6765        let response_hint = this
6766            .update(&mut cx, |this, cx| {
6767                this.resolve_inlay_hint(
6768                    hint,
6769                    buffer,
6770                    LanguageServerId(envelope.payload.language_server_id as usize),
6771                    cx,
6772                )
6773            })?
6774            .await
6775            .context("inlay hints fetch")?;
6776        Ok(proto::ResolveInlayHintResponse {
6777            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
6778        })
6779    }
6780
6781    async fn handle_open_buffer_for_symbol(
6782        this: Entity<Self>,
6783        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
6784        mut cx: AsyncApp,
6785    ) -> Result<proto::OpenBufferForSymbolResponse> {
6786        let peer_id = envelope.original_sender_id().unwrap_or_default();
6787        let symbol = envelope
6788            .payload
6789            .symbol
6790            .ok_or_else(|| anyhow!("invalid symbol"))?;
6791        let symbol = Self::deserialize_symbol(symbol)?;
6792        let symbol = this.update(&mut cx, |this, _| {
6793            let signature = this.symbol_signature(&symbol.path);
6794            if signature == symbol.signature {
6795                Ok(symbol)
6796            } else {
6797                Err(anyhow!("invalid symbol signature"))
6798            }
6799        })??;
6800        let buffer = this
6801            .update(&mut cx, |this, cx| {
6802                this.open_buffer_for_symbol(
6803                    &Symbol {
6804                        language_server_name: symbol.language_server_name,
6805                        source_worktree_id: symbol.source_worktree_id,
6806                        path: symbol.path,
6807                        name: symbol.name,
6808                        kind: symbol.kind,
6809                        range: symbol.range,
6810                        signature: symbol.signature,
6811                        label: CodeLabel {
6812                            text: Default::default(),
6813                            runs: Default::default(),
6814                            filter_range: Default::default(),
6815                        },
6816                    },
6817                    cx,
6818                )
6819            })?
6820            .await?;
6821
6822        this.update(&mut cx, |this, cx| {
6823            let is_private = buffer
6824                .read(cx)
6825                .file()
6826                .map(|f| f.is_private())
6827                .unwrap_or_default();
6828            if is_private {
6829                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
6830            } else {
6831                this.buffer_store
6832                    .update(cx, |buffer_store, cx| {
6833                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
6834                    })
6835                    .detach_and_log_err(cx);
6836                let buffer_id = buffer.read(cx).remote_id().to_proto();
6837                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
6838            }
6839        })?
6840    }
6841
6842    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
6843        let mut hasher = Sha256::new();
6844        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
6845        hasher.update(project_path.path.to_string_lossy().as_bytes());
6846        hasher.update(self.nonce.to_be_bytes());
6847        hasher.finalize().as_slice().try_into().unwrap()
6848    }
6849
6850    pub async fn handle_get_project_symbols(
6851        this: Entity<Self>,
6852        envelope: TypedEnvelope<proto::GetProjectSymbols>,
6853        mut cx: AsyncApp,
6854    ) -> Result<proto::GetProjectSymbolsResponse> {
6855        let symbols = this
6856            .update(&mut cx, |this, cx| {
6857                this.symbols(&envelope.payload.query, cx)
6858            })?
6859            .await?;
6860
6861        Ok(proto::GetProjectSymbolsResponse {
6862            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
6863        })
6864    }
6865
6866    pub async fn handle_restart_language_servers(
6867        this: Entity<Self>,
6868        envelope: TypedEnvelope<proto::RestartLanguageServers>,
6869        mut cx: AsyncApp,
6870    ) -> Result<proto::Ack> {
6871        this.update(&mut cx, |this, cx| {
6872            let buffers = this.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
6873            this.restart_language_servers_for_buffers(buffers, cx);
6874        })?;
6875
6876        Ok(proto::Ack {})
6877    }
6878
6879    pub async fn handle_cancel_language_server_work(
6880        this: Entity<Self>,
6881        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
6882        mut cx: AsyncApp,
6883    ) -> Result<proto::Ack> {
6884        this.update(&mut cx, |this, cx| {
6885            if let Some(work) = envelope.payload.work {
6886                match work {
6887                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
6888                        let buffers =
6889                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
6890                        this.cancel_language_server_work_for_buffers(buffers, cx);
6891                    }
6892                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
6893                        let server_id = LanguageServerId::from_proto(work.language_server_id);
6894                        this.cancel_language_server_work(server_id, work.token, cx);
6895                    }
6896                }
6897            }
6898        })?;
6899
6900        Ok(proto::Ack {})
6901    }
6902
6903    fn buffer_ids_to_buffers(
6904        &mut self,
6905        buffer_ids: impl Iterator<Item = u64>,
6906        cx: &mut Context<Self>,
6907    ) -> Vec<Entity<Buffer>> {
6908        buffer_ids
6909            .into_iter()
6910            .flat_map(|buffer_id| {
6911                self.buffer_store
6912                    .read(cx)
6913                    .get(BufferId::new(buffer_id).log_err()?)
6914            })
6915            .collect::<Vec<_>>()
6916    }
6917
6918    async fn handle_apply_additional_edits_for_completion(
6919        this: Entity<Self>,
6920        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
6921        mut cx: AsyncApp,
6922    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
6923        let (buffer, completion) = this.update(&mut cx, |this, cx| {
6924            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
6925            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
6926            let completion = Self::deserialize_completion(
6927                envelope
6928                    .payload
6929                    .completion
6930                    .ok_or_else(|| anyhow!("invalid completion"))?,
6931            )?;
6932            anyhow::Ok((buffer, completion))
6933        })??;
6934
6935        let apply_additional_edits = this.update(&mut cx, |this, cx| {
6936            this.apply_additional_edits_for_completion(
6937                buffer,
6938                Rc::new(RefCell::new(Box::new([Completion {
6939                    old_range: completion.old_range,
6940                    new_text: completion.new_text,
6941                    lsp_completion: completion.lsp_completion,
6942                    server_id: completion.server_id,
6943                    documentation: None,
6944                    label: CodeLabel {
6945                        text: Default::default(),
6946                        runs: Default::default(),
6947                        filter_range: Default::default(),
6948                    },
6949                    confirm: None,
6950                    resolved: completion.resolved,
6951                }]))),
6952                0,
6953                false,
6954                cx,
6955            )
6956        })?;
6957
6958        Ok(proto::ApplyCompletionAdditionalEditsResponse {
6959            transaction: apply_additional_edits
6960                .await?
6961                .as_ref()
6962                .map(language::proto::serialize_transaction),
6963        })
6964    }
6965
6966    pub fn last_formatting_failure(&self) -> Option<&str> {
6967        self.last_formatting_failure.as_deref()
6968    }
6969
6970    pub fn reset_last_formatting_failure(&mut self) {
6971        self.last_formatting_failure = None;
6972    }
6973
6974    pub fn environment_for_buffer(
6975        &self,
6976        buffer: &Entity<Buffer>,
6977        cx: &mut Context<Self>,
6978    ) -> Shared<Task<Option<HashMap<String, String>>>> {
6979        let worktree_id = buffer.read(cx).file().map(|file| file.worktree_id(cx));
6980        let worktree_abs_path = worktree_id.and_then(|worktree_id| {
6981            self.worktree_store
6982                .read(cx)
6983                .worktree_for_id(worktree_id, cx)
6984                .map(|entry| entry.read(cx).abs_path().clone())
6985        });
6986
6987        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
6988            environment.update(cx, |env, cx| {
6989                env.get_environment(worktree_id, worktree_abs_path, cx)
6990            })
6991        } else {
6992            Task::ready(None).shared()
6993        }
6994    }
6995
6996    pub fn format(
6997        &mut self,
6998        buffers: HashSet<Entity<Buffer>>,
6999        target: LspFormatTarget,
7000        push_to_history: bool,
7001        trigger: FormatTrigger,
7002        cx: &mut Context<Self>,
7003    ) -> Task<anyhow::Result<ProjectTransaction>> {
7004        if let Some(_) = self.as_local() {
7005            let buffers = buffers
7006                .into_iter()
7007                .map(|buffer_handle| {
7008                    let buffer = buffer_handle.read(cx);
7009                    let buffer_abs_path = File::from_dyn(buffer.file())
7010                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
7011
7012                    (buffer_handle, buffer_abs_path, buffer.remote_id())
7013                })
7014                .collect::<Vec<_>>();
7015
7016            cx.spawn(move |lsp_store, mut cx| async move {
7017                let mut formattable_buffers = Vec::with_capacity(buffers.len());
7018
7019                for (handle, abs_path, id) in buffers {
7020                    let env = lsp_store
7021                        .update(&mut cx, |lsp_store, cx| {
7022                            lsp_store.environment_for_buffer(&handle, cx)
7023                        })?
7024                        .await;
7025
7026                    formattable_buffers.push(FormattableBuffer {
7027                        id,
7028                        handle,
7029                        abs_path,
7030                        env,
7031                    });
7032                }
7033
7034                let result = LocalLspStore::format_locally(
7035                    lsp_store.clone(),
7036                    formattable_buffers,
7037                    &target,
7038                    push_to_history,
7039                    trigger,
7040                    cx.clone(),
7041                )
7042                .await;
7043                lsp_store.update(&mut cx, |lsp_store, _| {
7044                    lsp_store.update_last_formatting_failure(&result);
7045                })?;
7046
7047                result
7048            })
7049        } else if let Some((client, project_id)) = self.upstream_client() {
7050            // Don't support formatting ranges via remote
7051            match target {
7052                LspFormatTarget::Buffers => {}
7053                LspFormatTarget::Ranges(_) => {
7054                    return Task::ready(Ok(ProjectTransaction::default()));
7055                }
7056            }
7057
7058            let buffer_store = self.buffer_store();
7059            cx.spawn(move |lsp_store, mut cx| async move {
7060                let result = client
7061                    .request(proto::FormatBuffers {
7062                        project_id,
7063                        trigger: trigger as i32,
7064                        buffer_ids: buffers
7065                            .iter()
7066                            .map(|buffer| {
7067                                buffer.update(&mut cx, |buffer, _| buffer.remote_id().into())
7068                            })
7069                            .collect::<Result<_>>()?,
7070                    })
7071                    .await
7072                    .and_then(|result| result.transaction.context("missing transaction"));
7073
7074                lsp_store.update(&mut cx, |lsp_store, _| {
7075                    lsp_store.update_last_formatting_failure(&result);
7076                })?;
7077
7078                let transaction_response = result?;
7079                buffer_store
7080                    .update(&mut cx, |buffer_store, cx| {
7081                        buffer_store.deserialize_project_transaction(
7082                            transaction_response,
7083                            push_to_history,
7084                            cx,
7085                        )
7086                    })?
7087                    .await
7088            })
7089        } else {
7090            Task::ready(Ok(ProjectTransaction::default()))
7091        }
7092    }
7093
7094    async fn handle_format_buffers(
7095        this: Entity<Self>,
7096        envelope: TypedEnvelope<proto::FormatBuffers>,
7097        mut cx: AsyncApp,
7098    ) -> Result<proto::FormatBuffersResponse> {
7099        let sender_id = envelope.original_sender_id().unwrap_or_default();
7100        let format = this.update(&mut cx, |this, cx| {
7101            let mut buffers = HashSet::default();
7102            for buffer_id in &envelope.payload.buffer_ids {
7103                let buffer_id = BufferId::new(*buffer_id)?;
7104                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
7105            }
7106            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
7107            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
7108        })??;
7109
7110        let project_transaction = format.await?;
7111        let project_transaction = this.update(&mut cx, |this, cx| {
7112            this.buffer_store.update(cx, |buffer_store, cx| {
7113                buffer_store.serialize_project_transaction_for_peer(
7114                    project_transaction,
7115                    sender_id,
7116                    cx,
7117                )
7118            })
7119        })?;
7120        Ok(proto::FormatBuffersResponse {
7121            transaction: Some(project_transaction),
7122        })
7123    }
7124
7125    async fn shutdown_language_server(
7126        server_state: Option<LanguageServerState>,
7127        name: LanguageServerName,
7128        cx: AsyncApp,
7129    ) {
7130        let server = match server_state {
7131            Some(LanguageServerState::Starting(task)) => {
7132                let mut timer = cx
7133                    .background_executor()
7134                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
7135                    .fuse();
7136
7137                select! {
7138                    server = task.fuse() => server,
7139                    _ = timer => {
7140                        log::info!(
7141                            "timeout waiting for language server {} to finish launching before stopping",
7142                            name
7143                        );
7144                        None
7145                    },
7146                }
7147            }
7148
7149            Some(LanguageServerState::Running { server, .. }) => Some(server),
7150
7151            None => None,
7152        };
7153
7154        if let Some(server) = server {
7155            if let Some(shutdown) = server.shutdown() {
7156                shutdown.await;
7157            }
7158        }
7159    }
7160
7161    // Returns a list of all of the worktrees which no longer have a language server and the root path
7162    // for the stopped server
7163    fn stop_local_language_server(
7164        &mut self,
7165        worktree_id: WorktreeId,
7166        adapter_name: LanguageServerName,
7167        cx: &mut Context<Self>,
7168    ) -> Task<Vec<WorktreeId>> {
7169        let key = (worktree_id, adapter_name);
7170        let local = match &mut self.mode {
7171            LspStoreMode::Local(local) => local,
7172            _ => {
7173                return Task::ready(Vec::new());
7174            }
7175        };
7176        let Some(server_id) = local.language_server_ids.remove(&key) else {
7177            return Task::ready(Vec::new());
7178        };
7179        let name = key.1;
7180        log::info!("stopping language server {name}");
7181
7182        // Remove other entries for this language server as well
7183        let mut orphaned_worktrees = vec![worktree_id];
7184        let other_keys = local
7185            .language_server_ids
7186            .keys()
7187            .cloned()
7188            .collect::<Vec<_>>();
7189        for other_key in other_keys {
7190            if local.language_server_ids.get(&other_key) == Some(&server_id) {
7191                local.language_server_ids.remove(&other_key);
7192                orphaned_worktrees.push(other_key.0);
7193            }
7194        }
7195
7196        self.buffer_store.update(cx, |buffer_store, cx| {
7197            for buffer in buffer_store.buffers() {
7198                buffer.update(cx, |buffer, cx| {
7199                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
7200                    buffer.set_completion_triggers(server_id, Default::default(), cx);
7201                });
7202            }
7203        });
7204
7205        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
7206            summaries.retain(|path, summaries_by_server_id| {
7207                if summaries_by_server_id.remove(&server_id).is_some() {
7208                    if let Some((client, project_id)) = self.downstream_client.clone() {
7209                        client
7210                            .send(proto::UpdateDiagnosticSummary {
7211                                project_id,
7212                                worktree_id: worktree_id.to_proto(),
7213                                summary: Some(proto::DiagnosticSummary {
7214                                    path: path.to_string_lossy().to_string(),
7215                                    language_server_id: server_id.0 as u64,
7216                                    error_count: 0,
7217                                    warning_count: 0,
7218                                }),
7219                            })
7220                            .log_err();
7221                    }
7222                    !summaries_by_server_id.is_empty()
7223                } else {
7224                    true
7225                }
7226            });
7227        }
7228
7229        self.language_server_statuses.remove(&server_id);
7230        let local = self.as_local_mut().unwrap();
7231        for diagnostics in local.diagnostics.values_mut() {
7232            diagnostics.retain(|_, diagnostics_by_server_id| {
7233                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
7234                    diagnostics_by_server_id.remove(ix);
7235                    !diagnostics_by_server_id.is_empty()
7236                } else {
7237                    true
7238                }
7239            });
7240        }
7241        local.language_server_watched_paths.remove(&server_id);
7242        let server_state = local.language_servers.remove(&server_id);
7243        cx.notify();
7244        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
7245        cx.spawn(move |_, cx| async move {
7246            Self::shutdown_language_server(server_state, name, cx).await;
7247            orphaned_worktrees
7248        })
7249    }
7250
7251    pub fn restart_language_servers_for_buffers(
7252        &mut self,
7253        buffers: impl IntoIterator<Item = Entity<Buffer>>,
7254        cx: &mut Context<Self>,
7255    ) {
7256        if let Some((client, project_id)) = self.upstream_client() {
7257            let request = client.request(proto::RestartLanguageServers {
7258                project_id,
7259                buffer_ids: buffers
7260                    .into_iter()
7261                    .map(|b| b.read(cx).remote_id().to_proto())
7262                    .collect(),
7263            });
7264            cx.background_executor()
7265                .spawn(request)
7266                .detach_and_log_err(cx);
7267        } else {
7268            let language_server_lookup_info: HashSet<(Entity<Worktree>, LanguageName)> = buffers
7269                .into_iter()
7270                .filter_map(|buffer| {
7271                    let buffer = buffer.read(cx);
7272                    let file = buffer.file()?;
7273                    let worktree = File::from_dyn(Some(file))?.worktree.clone();
7274                    let language =
7275                        self.languages
7276                            .language_for_file(file, Some(buffer.as_rope()), cx)?;
7277
7278                    Some((worktree, language.name()))
7279                })
7280                .collect();
7281
7282            for (worktree, language) in language_server_lookup_info {
7283                self.restart_local_language_servers(worktree, language, cx);
7284            }
7285        }
7286    }
7287
7288    fn restart_local_language_servers(
7289        &mut self,
7290        worktree: Entity<Worktree>,
7291        language: LanguageName,
7292        cx: &mut Context<Self>,
7293    ) {
7294        let worktree_id = worktree.read(cx).id();
7295
7296        let stop_tasks = self
7297            .languages
7298            .clone()
7299            .lsp_adapters(&language)
7300            .iter()
7301            .map(|adapter| {
7302                let stop_task =
7303                    self.stop_local_language_server(worktree_id, adapter.name.clone(), cx);
7304                (stop_task, adapter.name.clone())
7305            })
7306            .collect::<Vec<_>>();
7307        if stop_tasks.is_empty() {
7308            return;
7309        }
7310
7311        cx.spawn(move |this, mut cx| async move {
7312            // For each stopped language server, record all of the worktrees with which
7313            // it was associated.
7314            let mut affected_worktrees = Vec::new();
7315            for (stop_task, language_server_name) in stop_tasks {
7316                for affected_worktree_id in stop_task.await {
7317                    affected_worktrees.push((affected_worktree_id, language_server_name.clone()));
7318                }
7319            }
7320
7321            this.update(&mut cx, |this, cx| {
7322                let local = this.as_local_mut().unwrap();
7323                // Restart the language server for the given worktree.
7324                //
7325                local.start_language_servers(&worktree, language.clone(), cx);
7326
7327                // Lookup new server ids and set them for each of the orphaned worktrees
7328                for (affected_worktree_id, language_server_name) in affected_worktrees {
7329                    if let Some(new_server_id) = local
7330                        .language_server_ids
7331                        .get(&(worktree_id, language_server_name.clone()))
7332                        .cloned()
7333                    {
7334                        local
7335                            .language_server_ids
7336                            .insert((affected_worktree_id, language_server_name), new_server_id);
7337                    }
7338                }
7339            })
7340            .ok();
7341        })
7342        .detach();
7343    }
7344
7345    pub fn update_diagnostics(
7346        &mut self,
7347        language_server_id: LanguageServerId,
7348        mut params: lsp::PublishDiagnosticsParams,
7349        disk_based_sources: &[String],
7350        cx: &mut Context<Self>,
7351    ) -> Result<()> {
7352        if !self.mode.is_local() {
7353            anyhow::bail!("called update_diagnostics on remote");
7354        }
7355        let abs_path = params
7356            .uri
7357            .to_file_path()
7358            .map_err(|_| anyhow!("URI is not a file"))?;
7359        let mut diagnostics = Vec::default();
7360        let mut primary_diagnostic_group_ids = HashMap::default();
7361        let mut sources_by_group_id = HashMap::default();
7362        let mut supporting_diagnostics = HashMap::default();
7363
7364        // Ensure that primary diagnostics are always the most severe
7365        params.diagnostics.sort_by_key(|item| item.severity);
7366
7367        for diagnostic in &params.diagnostics {
7368            let source = diagnostic.source.as_ref();
7369            let code = diagnostic.code.as_ref().map(|code| match code {
7370                lsp::NumberOrString::Number(code) => code.to_string(),
7371                lsp::NumberOrString::String(code) => code.clone(),
7372            });
7373            let range = range_from_lsp(diagnostic.range);
7374            let is_supporting = diagnostic
7375                .related_information
7376                .as_ref()
7377                .map_or(false, |infos| {
7378                    infos.iter().any(|info| {
7379                        primary_diagnostic_group_ids.contains_key(&(
7380                            source,
7381                            code.clone(),
7382                            range_from_lsp(info.location.range),
7383                        ))
7384                    })
7385                });
7386
7387            let is_unnecessary = diagnostic.tags.as_ref().map_or(false, |tags| {
7388                tags.iter().any(|tag| *tag == DiagnosticTag::UNNECESSARY)
7389            });
7390
7391            if is_supporting {
7392                supporting_diagnostics.insert(
7393                    (source, code.clone(), range),
7394                    (diagnostic.severity, is_unnecessary),
7395                );
7396            } else {
7397                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
7398                let is_disk_based =
7399                    source.map_or(false, |source| disk_based_sources.contains(source));
7400
7401                sources_by_group_id.insert(group_id, source);
7402                primary_diagnostic_group_ids
7403                    .insert((source, code.clone(), range.clone()), group_id);
7404
7405                diagnostics.push(DiagnosticEntry {
7406                    range,
7407                    diagnostic: Diagnostic {
7408                        source: diagnostic.source.clone(),
7409                        code: code.clone(),
7410                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
7411                        message: diagnostic.message.trim().to_string(),
7412                        group_id,
7413                        is_primary: true,
7414                        is_disk_based,
7415                        is_unnecessary,
7416                        data: diagnostic.data.clone(),
7417                    },
7418                });
7419                if let Some(infos) = &diagnostic.related_information {
7420                    for info in infos {
7421                        if info.location.uri == params.uri && !info.message.is_empty() {
7422                            let range = range_from_lsp(info.location.range);
7423                            diagnostics.push(DiagnosticEntry {
7424                                range,
7425                                diagnostic: Diagnostic {
7426                                    source: diagnostic.source.clone(),
7427                                    code: code.clone(),
7428                                    severity: DiagnosticSeverity::INFORMATION,
7429                                    message: info.message.trim().to_string(),
7430                                    group_id,
7431                                    is_primary: false,
7432                                    is_disk_based,
7433                                    is_unnecessary: false,
7434                                    data: diagnostic.data.clone(),
7435                                },
7436                            });
7437                        }
7438                    }
7439                }
7440            }
7441        }
7442
7443        for entry in &mut diagnostics {
7444            let diagnostic = &mut entry.diagnostic;
7445            if !diagnostic.is_primary {
7446                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
7447                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
7448                    source,
7449                    diagnostic.code.clone(),
7450                    entry.range.clone(),
7451                )) {
7452                    if let Some(severity) = severity {
7453                        diagnostic.severity = severity;
7454                    }
7455                    diagnostic.is_unnecessary = is_unnecessary;
7456                }
7457            }
7458        }
7459
7460        self.update_diagnostic_entries(
7461            language_server_id,
7462            abs_path,
7463            params.version,
7464            diagnostics,
7465            cx,
7466        )?;
7467        Ok(())
7468    }
7469
7470    fn insert_newly_running_language_server(
7471        &mut self,
7472        adapter: Arc<CachedLspAdapter>,
7473        language_server: Arc<LanguageServer>,
7474        server_id: LanguageServerId,
7475        key: (WorktreeId, LanguageServerName),
7476        cx: &mut Context<Self>,
7477    ) {
7478        let Some(local) = self.as_local_mut() else {
7479            return;
7480        };
7481        // If the language server for this key doesn't match the server id, don't store the
7482        // server. Which will cause it to be dropped, killing the process
7483        if local
7484            .language_server_ids
7485            .get(&key)
7486            .map(|id| id != &server_id)
7487            .unwrap_or(false)
7488        {
7489            return;
7490        }
7491
7492        // Update language_servers collection with Running variant of LanguageServerState
7493        // indicating that the server is up and running and ready
7494        local.language_servers.insert(
7495            server_id,
7496            LanguageServerState::Running {
7497                adapter: adapter.clone(),
7498                server: language_server.clone(),
7499                simulate_disk_based_diagnostics_completion: None,
7500            },
7501        );
7502        if let Some(file_ops_caps) = language_server
7503            .capabilities()
7504            .workspace
7505            .as_ref()
7506            .and_then(|ws| ws.file_operations.as_ref())
7507        {
7508            let did_rename_caps = file_ops_caps.did_rename.as_ref();
7509            let will_rename_caps = file_ops_caps.will_rename.as_ref();
7510            if did_rename_caps.or(will_rename_caps).is_some() {
7511                let watcher = RenamePathsWatchedForServer::default()
7512                    .with_did_rename_patterns(did_rename_caps)
7513                    .with_will_rename_patterns(will_rename_caps);
7514                local
7515                    .language_server_paths_watched_for_rename
7516                    .insert(server_id, watcher);
7517            }
7518        }
7519
7520        self.language_server_statuses.insert(
7521            server_id,
7522            LanguageServerStatus {
7523                name: language_server.name().to_string(),
7524                pending_work: Default::default(),
7525                has_pending_diagnostic_updates: false,
7526                progress_tokens: Default::default(),
7527            },
7528        );
7529
7530        cx.emit(LspStoreEvent::LanguageServerAdded(
7531            server_id,
7532            language_server.name(),
7533            Some(key.0),
7534        ));
7535        cx.emit(LspStoreEvent::RefreshInlayHints);
7536
7537        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
7538            downstream_client
7539                .send(proto::StartLanguageServer {
7540                    project_id: *project_id,
7541                    server: Some(proto::LanguageServer {
7542                        id: server_id.0 as u64,
7543                        name: language_server.name().to_string(),
7544                        worktree_id: Some(key.0.to_proto()),
7545                    }),
7546                })
7547                .log_err();
7548        }
7549
7550        // Tell the language server about every open buffer in the worktree that matches the language.
7551        self.buffer_store.clone().update(cx, |buffer_store, cx| {
7552            for buffer_handle in buffer_store.buffers() {
7553                let buffer = buffer_handle.read(cx);
7554                let file = match File::from_dyn(buffer.file()) {
7555                    Some(file) => file,
7556                    None => continue,
7557                };
7558                let language = match buffer.language() {
7559                    Some(language) => language,
7560                    None => continue,
7561                };
7562
7563                if file.worktree.read(cx).id() != key.0
7564                    || !self
7565                        .languages
7566                        .lsp_adapters(&language.name())
7567                        .iter()
7568                        .any(|a| a.name == key.1)
7569                {
7570                    continue;
7571                }
7572                // didOpen
7573                let file = match file.as_local() {
7574                    Some(file) => file,
7575                    None => continue,
7576                };
7577
7578                let local = self.as_local_mut().unwrap();
7579
7580                if local.registered_buffers.contains_key(&buffer.remote_id()) {
7581                    let versions = local
7582                        .buffer_snapshots
7583                        .entry(buffer.remote_id())
7584                        .or_default()
7585                        .entry(server_id)
7586                        .or_insert_with(|| {
7587                            vec![LspBufferSnapshot {
7588                                version: 0,
7589                                snapshot: buffer.text_snapshot(),
7590                            }]
7591                        });
7592
7593                    let snapshot = versions.last().unwrap();
7594                    let version = snapshot.version;
7595                    let initial_snapshot = &snapshot.snapshot;
7596                    let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
7597                    language_server
7598                        .notify::<lsp::notification::DidOpenTextDocument>(
7599                            &lsp::DidOpenTextDocumentParams {
7600                                text_document: lsp::TextDocumentItem::new(
7601                                    uri,
7602                                    adapter.language_id(&language.name()),
7603                                    version,
7604                                    initial_snapshot.text(),
7605                                ),
7606                            },
7607                        )
7608                        .log_err();
7609                }
7610
7611                buffer_handle.update(cx, |buffer, cx| {
7612                    buffer.set_completion_triggers(
7613                        server_id,
7614                        language_server
7615                            .capabilities()
7616                            .completion_provider
7617                            .as_ref()
7618                            .and_then(|provider| {
7619                                provider
7620                                    .trigger_characters
7621                                    .as_ref()
7622                                    .map(|characters| characters.iter().cloned().collect())
7623                            })
7624                            .unwrap_or_default(),
7625                        cx,
7626                    )
7627                });
7628            }
7629        });
7630
7631        cx.notify();
7632    }
7633
7634    pub fn language_servers_running_disk_based_diagnostics(
7635        &self,
7636    ) -> impl Iterator<Item = LanguageServerId> + '_ {
7637        self.language_server_statuses
7638            .iter()
7639            .filter_map(|(id, status)| {
7640                if status.has_pending_diagnostic_updates {
7641                    Some(*id)
7642                } else {
7643                    None
7644                }
7645            })
7646    }
7647
7648    pub(crate) fn cancel_language_server_work_for_buffers(
7649        &mut self,
7650        buffers: impl IntoIterator<Item = Entity<Buffer>>,
7651        cx: &mut Context<Self>,
7652    ) {
7653        if let Some((client, project_id)) = self.upstream_client() {
7654            let request = client.request(proto::CancelLanguageServerWork {
7655                project_id,
7656                work: Some(proto::cancel_language_server_work::Work::Buffers(
7657                    proto::cancel_language_server_work::Buffers {
7658                        buffer_ids: buffers
7659                            .into_iter()
7660                            .map(|b| b.read(cx).remote_id().to_proto())
7661                            .collect(),
7662                    },
7663                )),
7664            });
7665            cx.background_executor()
7666                .spawn(request)
7667                .detach_and_log_err(cx);
7668        } else if let Some(local) = self.as_local() {
7669            let servers = buffers
7670                .into_iter()
7671                .flat_map(|buffer| {
7672                    local
7673                        .language_server_ids_for_buffer(buffer.read(cx), cx)
7674                        .into_iter()
7675                })
7676                .collect::<HashSet<_>>();
7677
7678            for server_id in servers {
7679                self.cancel_language_server_work(server_id, None, cx);
7680            }
7681        }
7682    }
7683
7684    pub(crate) fn cancel_language_server_work(
7685        &mut self,
7686        server_id: LanguageServerId,
7687        token_to_cancel: Option<String>,
7688        cx: &mut Context<Self>,
7689    ) {
7690        if let Some(local) = self.as_local() {
7691            let status = self.language_server_statuses.get(&server_id);
7692            let server = local.language_servers.get(&server_id);
7693            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
7694            {
7695                for (token, progress) in &status.pending_work {
7696                    if let Some(token_to_cancel) = token_to_cancel.as_ref() {
7697                        if token != token_to_cancel {
7698                            continue;
7699                        }
7700                    }
7701                    if progress.is_cancellable {
7702                        server
7703                            .notify::<lsp::notification::WorkDoneProgressCancel>(
7704                                &WorkDoneProgressCancelParams {
7705                                    token: lsp::NumberOrString::String(token.clone()),
7706                                },
7707                            )
7708                            .ok();
7709                    }
7710
7711                    if progress.is_cancellable {
7712                        server
7713                            .notify::<lsp::notification::WorkDoneProgressCancel>(
7714                                &WorkDoneProgressCancelParams {
7715                                    token: lsp::NumberOrString::String(token.clone()),
7716                                },
7717                            )
7718                            .ok();
7719                    }
7720                }
7721            }
7722        } else if let Some((client, project_id)) = self.upstream_client() {
7723            let request = client.request(proto::CancelLanguageServerWork {
7724                project_id,
7725                work: Some(
7726                    proto::cancel_language_server_work::Work::LanguageServerWork(
7727                        proto::cancel_language_server_work::LanguageServerWork {
7728                            language_server_id: server_id.to_proto(),
7729                            token: token_to_cancel,
7730                        },
7731                    ),
7732                ),
7733            });
7734            cx.background_executor()
7735                .spawn(request)
7736                .detach_and_log_err(cx);
7737        }
7738    }
7739
7740    fn register_supplementary_language_server(
7741        &mut self,
7742        id: LanguageServerId,
7743        name: LanguageServerName,
7744        server: Arc<LanguageServer>,
7745        cx: &mut Context<Self>,
7746    ) {
7747        if let Some(local) = self.as_local_mut() {
7748            local
7749                .supplementary_language_servers
7750                .insert(id, (name.clone(), server));
7751            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
7752        }
7753    }
7754
7755    fn unregister_supplementary_language_server(
7756        &mut self,
7757        id: LanguageServerId,
7758        cx: &mut Context<Self>,
7759    ) {
7760        if let Some(local) = self.as_local_mut() {
7761            local.supplementary_language_servers.remove(&id);
7762            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
7763        }
7764    }
7765
7766    pub fn supplementary_language_servers(
7767        &self,
7768    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
7769        self.as_local().into_iter().flat_map(|local| {
7770            local
7771                .supplementary_language_servers
7772                .iter()
7773                .map(|(id, (name, _))| (*id, name.clone()))
7774        })
7775    }
7776
7777    pub fn language_server_adapter_for_id(
7778        &self,
7779        id: LanguageServerId,
7780    ) -> Option<Arc<CachedLspAdapter>> {
7781        self.as_local()
7782            .and_then(|local| local.language_servers.get(&id))
7783            .and_then(|language_server_state| match language_server_state {
7784                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
7785                _ => None,
7786            })
7787    }
7788
7789    pub(super) fn update_local_worktree_language_servers(
7790        &mut self,
7791        worktree_handle: &Entity<Worktree>,
7792        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
7793        cx: &mut Context<Self>,
7794    ) {
7795        if changes.is_empty() {
7796            return;
7797        }
7798
7799        let Some(local) = self.as_local() else { return };
7800
7801        local.prettier_store.update(cx, |prettier_store, cx| {
7802            prettier_store.update_prettier_settings(&worktree_handle, changes, cx)
7803        });
7804
7805        let worktree_id = worktree_handle.read(cx).id();
7806        let mut language_server_ids = local
7807            .language_server_ids
7808            .iter()
7809            .filter_map(|((server_worktree_id, _), server_id)| {
7810                (*server_worktree_id == worktree_id).then_some(*server_id)
7811            })
7812            .collect::<Vec<_>>();
7813        language_server_ids.sort();
7814        language_server_ids.dedup();
7815
7816        let abs_path = worktree_handle.read(cx).abs_path();
7817        for server_id in &language_server_ids {
7818            if let Some(LanguageServerState::Running { server, .. }) =
7819                local.language_servers.get(server_id)
7820            {
7821                if let Some(watched_paths) = local
7822                    .language_server_watched_paths
7823                    .get(server_id)
7824                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
7825                {
7826                    let params = lsp::DidChangeWatchedFilesParams {
7827                        changes: changes
7828                            .iter()
7829                            .filter_map(|(path, _, change)| {
7830                                if !watched_paths.is_match(path) {
7831                                    return None;
7832                                }
7833                                let typ = match change {
7834                                    PathChange::Loaded => return None,
7835                                    PathChange::Added => lsp::FileChangeType::CREATED,
7836                                    PathChange::Removed => lsp::FileChangeType::DELETED,
7837                                    PathChange::Updated => lsp::FileChangeType::CHANGED,
7838                                    PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
7839                                };
7840                                Some(lsp::FileEvent {
7841                                    uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
7842                                    typ,
7843                                })
7844                            })
7845                            .collect(),
7846                    };
7847                    if !params.changes.is_empty() {
7848                        server
7849                            .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
7850                            .log_err();
7851                    }
7852                }
7853            }
7854        }
7855    }
7856
7857    pub fn wait_for_remote_buffer(
7858        &mut self,
7859        id: BufferId,
7860        cx: &mut Context<Self>,
7861    ) -> Task<Result<Entity<Buffer>>> {
7862        self.buffer_store.update(cx, |buffer_store, cx| {
7863            buffer_store.wait_for_remote_buffer(id, cx)
7864        })
7865    }
7866
7867    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
7868        proto::Symbol {
7869            language_server_name: symbol.language_server_name.0.to_string(),
7870            source_worktree_id: symbol.source_worktree_id.to_proto(),
7871            worktree_id: symbol.path.worktree_id.to_proto(),
7872            path: symbol.path.path.to_string_lossy().to_string(),
7873            name: symbol.name.clone(),
7874            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
7875            start: Some(proto::PointUtf16 {
7876                row: symbol.range.start.0.row,
7877                column: symbol.range.start.0.column,
7878            }),
7879            end: Some(proto::PointUtf16 {
7880                row: symbol.range.end.0.row,
7881                column: symbol.range.end.0.column,
7882            }),
7883            signature: symbol.signature.to_vec(),
7884        }
7885    }
7886
7887    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
7888        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
7889        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
7890        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
7891        let path = ProjectPath {
7892            worktree_id,
7893            path: PathBuf::from(serialized_symbol.path).into(),
7894        };
7895
7896        let start = serialized_symbol
7897            .start
7898            .ok_or_else(|| anyhow!("invalid start"))?;
7899        let end = serialized_symbol
7900            .end
7901            .ok_or_else(|| anyhow!("invalid end"))?;
7902        Ok(CoreSymbol {
7903            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
7904            source_worktree_id,
7905            path,
7906            name: serialized_symbol.name,
7907            range: Unclipped(PointUtf16::new(start.row, start.column))
7908                ..Unclipped(PointUtf16::new(end.row, end.column)),
7909            kind,
7910            signature: serialized_symbol
7911                .signature
7912                .try_into()
7913                .map_err(|_| anyhow!("invalid signature"))?,
7914        })
7915    }
7916
7917    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
7918        proto::Completion {
7919            old_start: Some(serialize_anchor(&completion.old_range.start)),
7920            old_end: Some(serialize_anchor(&completion.old_range.end)),
7921            new_text: completion.new_text.clone(),
7922            server_id: completion.server_id.0 as u64,
7923            lsp_completion: serde_json::to_vec(&completion.lsp_completion).unwrap(),
7924            resolved: completion.resolved,
7925        }
7926    }
7927
7928    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
7929        let old_start = completion
7930            .old_start
7931            .and_then(deserialize_anchor)
7932            .ok_or_else(|| anyhow!("invalid old start"))?;
7933        let old_end = completion
7934            .old_end
7935            .and_then(deserialize_anchor)
7936            .ok_or_else(|| anyhow!("invalid old end"))?;
7937        let lsp_completion = serde_json::from_slice(&completion.lsp_completion)?;
7938
7939        Ok(CoreCompletion {
7940            old_range: old_start..old_end,
7941            new_text: completion.new_text,
7942            server_id: LanguageServerId(completion.server_id as usize),
7943            lsp_completion,
7944            resolved: completion.resolved,
7945        })
7946    }
7947
7948    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
7949        proto::CodeAction {
7950            server_id: action.server_id.0 as u64,
7951            start: Some(serialize_anchor(&action.range.start)),
7952            end: Some(serialize_anchor(&action.range.end)),
7953            lsp_action: serde_json::to_vec(&action.lsp_action).unwrap(),
7954        }
7955    }
7956
7957    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
7958        let start = action
7959            .start
7960            .and_then(deserialize_anchor)
7961            .ok_or_else(|| anyhow!("invalid start"))?;
7962        let end = action
7963            .end
7964            .and_then(deserialize_anchor)
7965            .ok_or_else(|| anyhow!("invalid end"))?;
7966        let lsp_action = serde_json::from_slice(&action.lsp_action)?;
7967        Ok(CodeAction {
7968            server_id: LanguageServerId(action.server_id as usize),
7969            range: start..end,
7970            lsp_action,
7971        })
7972    }
7973
7974    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
7975        match &formatting_result {
7976            Ok(_) => self.last_formatting_failure = None,
7977            Err(error) => {
7978                let error_string = format!("{error:#}");
7979                log::error!("Formatting failed: {error_string}");
7980                self.last_formatting_failure
7981                    .replace(error_string.lines().join(" "));
7982            }
7983        }
7984    }
7985}
7986
7987impl EventEmitter<LspStoreEvent> for LspStore {}
7988
7989fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
7990    hover
7991        .contents
7992        .retain(|hover_block| !hover_block.text.trim().is_empty());
7993    if hover.contents.is_empty() {
7994        None
7995    } else {
7996        Some(hover)
7997    }
7998}
7999
8000async fn populate_labels_for_completions(
8001    mut new_completions: Vec<CoreCompletion>,
8002    language_registry: &Arc<LanguageRegistry>,
8003    language: Option<Arc<Language>>,
8004    lsp_adapter: Option<Arc<CachedLspAdapter>>,
8005    completions: &mut Vec<Completion>,
8006) {
8007    let lsp_completions = new_completions
8008        .iter_mut()
8009        .map(|completion| mem::take(&mut completion.lsp_completion))
8010        .collect::<Vec<_>>();
8011
8012    let labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
8013        lsp_adapter
8014            .labels_for_completions(&lsp_completions, language)
8015            .await
8016            .log_err()
8017            .unwrap_or_default()
8018    } else {
8019        Vec::new()
8020    };
8021
8022    for ((completion, lsp_completion), label) in new_completions
8023        .into_iter()
8024        .zip(lsp_completions)
8025        .zip(labels.into_iter().chain(iter::repeat(None)))
8026    {
8027        let documentation = if let Some(docs) = &lsp_completion.documentation {
8028            Some(prepare_completion_documentation(docs, language_registry, language.clone()).await)
8029        } else {
8030            None
8031        };
8032
8033        let mut label = label.unwrap_or_else(|| {
8034            CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
8035        });
8036        ensure_uniform_list_compatible_label(&mut label);
8037
8038        completions.push(Completion {
8039            old_range: completion.old_range,
8040            new_text: completion.new_text,
8041            label,
8042            server_id: completion.server_id,
8043            documentation,
8044            lsp_completion,
8045            confirm: None,
8046            resolved: false,
8047        })
8048    }
8049}
8050
8051#[derive(Debug)]
8052pub enum LanguageServerToQuery {
8053    Primary,
8054    Other(LanguageServerId),
8055}
8056
8057#[derive(Default)]
8058struct RenamePathsWatchedForServer {
8059    did_rename: Vec<RenameActionPredicate>,
8060    will_rename: Vec<RenameActionPredicate>,
8061}
8062
8063impl RenamePathsWatchedForServer {
8064    fn with_did_rename_patterns(
8065        mut self,
8066        did_rename: Option<&FileOperationRegistrationOptions>,
8067    ) -> Self {
8068        if let Some(did_rename) = did_rename {
8069            self.did_rename = did_rename
8070                .filters
8071                .iter()
8072                .filter_map(|filter| filter.try_into().log_err())
8073                .collect();
8074        }
8075        self
8076    }
8077    fn with_will_rename_patterns(
8078        mut self,
8079        will_rename: Option<&FileOperationRegistrationOptions>,
8080    ) -> Self {
8081        if let Some(will_rename) = will_rename {
8082            self.will_rename = will_rename
8083                .filters
8084                .iter()
8085                .filter_map(|filter| filter.try_into().log_err())
8086                .collect();
8087        }
8088        self
8089    }
8090
8091    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
8092        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
8093    }
8094    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
8095        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
8096    }
8097}
8098
8099impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
8100    type Error = globset::Error;
8101    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
8102        Ok(Self {
8103            kind: ops.pattern.matches.clone(),
8104            glob: GlobBuilder::new(&ops.pattern.glob)
8105                .case_insensitive(
8106                    ops.pattern
8107                        .options
8108                        .as_ref()
8109                        .map_or(false, |ops| ops.ignore_case.unwrap_or(false)),
8110                )
8111                .build()?
8112                .compile_matcher(),
8113        })
8114    }
8115}
8116struct RenameActionPredicate {
8117    glob: GlobMatcher,
8118    kind: Option<FileOperationPatternKind>,
8119}
8120
8121impl RenameActionPredicate {
8122    // Returns true if language server should be notified
8123    fn eval(&self, path: &str, is_dir: bool) -> bool {
8124        self.kind.as_ref().map_or(true, |kind| {
8125            let expected_kind = if is_dir {
8126                FileOperationPatternKind::Folder
8127            } else {
8128                FileOperationPatternKind::File
8129            };
8130            kind == &expected_kind
8131        }) && self.glob.is_match(path)
8132    }
8133}
8134
8135#[derive(Default)]
8136struct LanguageServerWatchedPaths {
8137    worktree_paths: HashMap<WorktreeId, GlobSet>,
8138    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
8139}
8140
8141#[derive(Default)]
8142struct LanguageServerWatchedPathsBuilder {
8143    worktree_paths: HashMap<WorktreeId, GlobSet>,
8144    abs_paths: HashMap<Arc<Path>, GlobSet>,
8145}
8146
8147impl LanguageServerWatchedPathsBuilder {
8148    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
8149        self.worktree_paths.insert(worktree_id, glob_set);
8150    }
8151    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
8152        self.abs_paths.insert(path, glob_set);
8153    }
8154    fn build(
8155        self,
8156        fs: Arc<dyn Fs>,
8157        language_server_id: LanguageServerId,
8158        cx: &mut Context<LspStore>,
8159    ) -> LanguageServerWatchedPaths {
8160        let project = cx.weak_entity();
8161
8162        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
8163        let abs_paths = self
8164            .abs_paths
8165            .into_iter()
8166            .map(|(abs_path, globset)| {
8167                let task = cx.spawn({
8168                    let abs_path = abs_path.clone();
8169                    let fs = fs.clone();
8170
8171                    let lsp_store = project.clone();
8172                    |_, mut cx| async move {
8173                        maybe!(async move {
8174                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
8175                            while let Some(update) = push_updates.0.next().await {
8176                                let action = lsp_store
8177                                    .update(&mut cx, |this, _| {
8178                                        let Some(local) = this.as_local() else {
8179                                            return ControlFlow::Break(());
8180                                        };
8181                                        let Some(watcher) = local
8182                                            .language_server_watched_paths
8183                                            .get(&language_server_id)
8184                                        else {
8185                                            return ControlFlow::Break(());
8186                                        };
8187                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
8188                                            "Watched abs path is not registered with a watcher",
8189                                        );
8190                                        let matching_entries = update
8191                                            .into_iter()
8192                                            .filter(|event| globs.is_match(&event.path))
8193                                            .collect::<Vec<_>>();
8194                                        this.lsp_notify_abs_paths_changed(
8195                                            language_server_id,
8196                                            matching_entries,
8197                                        );
8198                                        ControlFlow::Continue(())
8199                                    })
8200                                    .ok()?;
8201
8202                                if action.is_break() {
8203                                    break;
8204                                }
8205                            }
8206                            Some(())
8207                        })
8208                        .await;
8209                    }
8210                });
8211                (abs_path, (globset, task))
8212            })
8213            .collect();
8214        LanguageServerWatchedPaths {
8215            worktree_paths: self.worktree_paths,
8216            abs_paths,
8217        }
8218    }
8219}
8220
8221struct LspBufferSnapshot {
8222    version: i32,
8223    snapshot: TextBufferSnapshot,
8224}
8225
8226/// A prompt requested by LSP server.
8227#[derive(Clone, Debug)]
8228pub struct LanguageServerPromptRequest {
8229    pub level: PromptLevel,
8230    pub message: String,
8231    pub actions: Vec<MessageActionItem>,
8232    pub lsp_name: String,
8233    pub(crate) response_channel: Sender<MessageActionItem>,
8234}
8235
8236impl LanguageServerPromptRequest {
8237    pub async fn respond(self, index: usize) -> Option<()> {
8238        if let Some(response) = self.actions.into_iter().nth(index) {
8239            self.response_channel.send(response).await.ok()
8240        } else {
8241            None
8242        }
8243    }
8244}
8245impl PartialEq for LanguageServerPromptRequest {
8246    fn eq(&self, other: &Self) -> bool {
8247        self.message == other.message && self.actions == other.actions
8248    }
8249}
8250
8251#[derive(Clone, Debug, PartialEq)]
8252pub enum LanguageServerLogType {
8253    Log(MessageType),
8254    Trace(Option<String>),
8255}
8256
8257impl LanguageServerLogType {
8258    pub fn to_proto(&self) -> proto::language_server_log::LogType {
8259        match self {
8260            Self::Log(log_type) => {
8261                let message_type = match *log_type {
8262                    MessageType::ERROR => 1,
8263                    MessageType::WARNING => 2,
8264                    MessageType::INFO => 3,
8265                    MessageType::LOG => 4,
8266                    other => {
8267                        log::warn!("Unknown lsp log message type: {:?}", other);
8268                        4
8269                    }
8270                };
8271                proto::language_server_log::LogType::LogMessageType(message_type)
8272            }
8273            Self::Trace(message) => {
8274                proto::language_server_log::LogType::LogTrace(proto::LspLogTrace {
8275                    message: message.clone(),
8276                })
8277            }
8278        }
8279    }
8280
8281    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
8282        match log_type {
8283            proto::language_server_log::LogType::LogMessageType(message_type) => {
8284                Self::Log(match message_type {
8285                    1 => MessageType::ERROR,
8286                    2 => MessageType::WARNING,
8287                    3 => MessageType::INFO,
8288                    4 => MessageType::LOG,
8289                    _ => MessageType::LOG,
8290                })
8291            }
8292            proto::language_server_log::LogType::LogTrace(trace) => Self::Trace(trace.message),
8293        }
8294    }
8295}
8296
8297pub enum LanguageServerState {
8298    Starting(Task<Option<Arc<LanguageServer>>>),
8299
8300    Running {
8301        adapter: Arc<CachedLspAdapter>,
8302        server: Arc<LanguageServer>,
8303        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
8304    },
8305}
8306
8307impl std::fmt::Debug for LanguageServerState {
8308    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8309        match self {
8310            LanguageServerState::Starting(_) => {
8311                f.debug_struct("LanguageServerState::Starting").finish()
8312            }
8313            LanguageServerState::Running { .. } => {
8314                f.debug_struct("LanguageServerState::Running").finish()
8315            }
8316        }
8317    }
8318}
8319
8320#[derive(Clone, Debug, Serialize)]
8321pub struct LanguageServerProgress {
8322    pub is_disk_based_diagnostics_progress: bool,
8323    pub is_cancellable: bool,
8324    pub title: Option<String>,
8325    pub message: Option<String>,
8326    pub percentage: Option<usize>,
8327    #[serde(skip_serializing)]
8328    pub last_update_at: Instant,
8329}
8330
8331#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
8332pub struct DiagnosticSummary {
8333    pub error_count: usize,
8334    pub warning_count: usize,
8335}
8336
8337impl DiagnosticSummary {
8338    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
8339        let mut this = Self {
8340            error_count: 0,
8341            warning_count: 0,
8342        };
8343
8344        for entry in diagnostics {
8345            if entry.diagnostic.is_primary {
8346                match entry.diagnostic.severity {
8347                    DiagnosticSeverity::ERROR => this.error_count += 1,
8348                    DiagnosticSeverity::WARNING => this.warning_count += 1,
8349                    _ => {}
8350                }
8351            }
8352        }
8353
8354        this
8355    }
8356
8357    pub fn is_empty(&self) -> bool {
8358        self.error_count == 0 && self.warning_count == 0
8359    }
8360
8361    pub fn to_proto(
8362        &self,
8363        language_server_id: LanguageServerId,
8364        path: &Path,
8365    ) -> proto::DiagnosticSummary {
8366        proto::DiagnosticSummary {
8367            path: path.to_string_lossy().to_string(),
8368            language_server_id: language_server_id.0 as u64,
8369            error_count: self.error_count as u32,
8370            warning_count: self.warning_count as u32,
8371        }
8372    }
8373}
8374
8375fn glob_literal_prefix(glob: &Path) -> PathBuf {
8376    glob.components()
8377        .take_while(|component| match component {
8378            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
8379            _ => true,
8380        })
8381        .collect()
8382}
8383
8384pub struct SshLspAdapter {
8385    name: LanguageServerName,
8386    binary: LanguageServerBinary,
8387    initialization_options: Option<String>,
8388    code_action_kinds: Option<Vec<CodeActionKind>>,
8389}
8390
8391impl SshLspAdapter {
8392    pub fn new(
8393        name: LanguageServerName,
8394        binary: LanguageServerBinary,
8395        initialization_options: Option<String>,
8396        code_action_kinds: Option<String>,
8397    ) -> Self {
8398        Self {
8399            name,
8400            binary,
8401            initialization_options,
8402            code_action_kinds: code_action_kinds
8403                .as_ref()
8404                .and_then(|c| serde_json::from_str(c).ok()),
8405        }
8406    }
8407}
8408
8409#[async_trait(?Send)]
8410impl LspAdapter for SshLspAdapter {
8411    fn name(&self) -> LanguageServerName {
8412        self.name.clone()
8413    }
8414
8415    async fn initialization_options(
8416        self: Arc<Self>,
8417        _: &dyn Fs,
8418        _: &Arc<dyn LspAdapterDelegate>,
8419    ) -> Result<Option<serde_json::Value>> {
8420        let Some(options) = &self.initialization_options else {
8421            return Ok(None);
8422        };
8423        let result = serde_json::from_str(options)?;
8424        Ok(result)
8425    }
8426
8427    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
8428        self.code_action_kinds.clone()
8429    }
8430
8431    async fn check_if_user_installed(
8432        &self,
8433        _: &dyn LspAdapterDelegate,
8434        _: Arc<dyn LanguageToolchainStore>,
8435        _: &AsyncApp,
8436    ) -> Option<LanguageServerBinary> {
8437        Some(self.binary.clone())
8438    }
8439
8440    async fn cached_server_binary(
8441        &self,
8442        _: PathBuf,
8443        _: &dyn LspAdapterDelegate,
8444    ) -> Option<LanguageServerBinary> {
8445        None
8446    }
8447
8448    async fn fetch_latest_server_version(
8449        &self,
8450        _: &dyn LspAdapterDelegate,
8451    ) -> Result<Box<dyn 'static + Send + Any>> {
8452        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
8453    }
8454
8455    async fn fetch_server_binary(
8456        &self,
8457        _: Box<dyn 'static + Send + Any>,
8458        _: PathBuf,
8459        _: &dyn LspAdapterDelegate,
8460    ) -> Result<LanguageServerBinary> {
8461        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
8462    }
8463}
8464
8465pub fn language_server_settings<'a, 'b: 'a>(
8466    delegate: &'a dyn LspAdapterDelegate,
8467    language: &LanguageServerName,
8468    cx: &'b App,
8469) -> Option<&'a LspSettings> {
8470    ProjectSettings::get(
8471        Some(SettingsLocation {
8472            worktree_id: delegate.worktree_id(),
8473            path: delegate.worktree_root_path(),
8474        }),
8475        cx,
8476    )
8477    .lsp
8478    .get(language)
8479}
8480
8481pub struct LocalLspAdapterDelegate {
8482    lsp_store: WeakEntity<LspStore>,
8483    worktree: worktree::Snapshot,
8484    fs: Arc<dyn Fs>,
8485    http_client: Arc<dyn HttpClient>,
8486    language_registry: Arc<LanguageRegistry>,
8487    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
8488}
8489
8490impl LocalLspAdapterDelegate {
8491    pub fn new(
8492        language_registry: Arc<LanguageRegistry>,
8493        environment: &Entity<ProjectEnvironment>,
8494        lsp_store: WeakEntity<LspStore>,
8495        worktree: &Entity<Worktree>,
8496        http_client: Arc<dyn HttpClient>,
8497        fs: Arc<dyn Fs>,
8498        cx: &mut Context<LspStore>,
8499    ) -> Arc<Self> {
8500        let worktree_id = worktree.read(cx).id();
8501        let worktree_abs_path = worktree.read(cx).abs_path();
8502        let load_shell_env_task = environment.update(cx, |env, cx| {
8503            env.get_environment(Some(worktree_id), Some(worktree_abs_path), cx)
8504        });
8505
8506        Arc::new(Self {
8507            lsp_store,
8508            worktree: worktree.read(cx).snapshot(),
8509            fs,
8510            http_client,
8511            language_registry,
8512            load_shell_env_task,
8513        })
8514    }
8515}
8516
8517#[async_trait]
8518impl LspAdapterDelegate for LocalLspAdapterDelegate {
8519    fn show_notification(&self, message: &str, cx: &mut App) {
8520        self.lsp_store
8521            .update(cx, |_, cx| {
8522                cx.emit(LspStoreEvent::Notification(message.to_owned()))
8523            })
8524            .ok();
8525    }
8526
8527    fn http_client(&self) -> Arc<dyn HttpClient> {
8528        self.http_client.clone()
8529    }
8530
8531    fn worktree_id(&self) -> WorktreeId {
8532        self.worktree.id()
8533    }
8534
8535    fn worktree_root_path(&self) -> &Path {
8536        self.worktree.abs_path().as_ref()
8537    }
8538
8539    async fn shell_env(&self) -> HashMap<String, String> {
8540        let task = self.load_shell_env_task.clone();
8541        task.await.unwrap_or_default()
8542    }
8543
8544    async fn npm_package_installed_version(
8545        &self,
8546        package_name: &str,
8547    ) -> Result<Option<(PathBuf, String)>> {
8548        let local_package_directory = self.worktree_root_path();
8549        let node_modules_directory = local_package_directory.join("node_modules");
8550
8551        if let Some(version) =
8552            read_package_installed_version(node_modules_directory.clone(), package_name).await?
8553        {
8554            return Ok(Some((node_modules_directory, version)));
8555        }
8556        let Some(npm) = self.which("npm".as_ref()).await else {
8557            log::warn!(
8558                "Failed to find npm executable for {:?}",
8559                local_package_directory
8560            );
8561            return Ok(None);
8562        };
8563
8564        let env = self.shell_env().await;
8565        let output = util::command::new_smol_command(&npm)
8566            .args(["root", "-g"])
8567            .envs(env)
8568            .current_dir(local_package_directory)
8569            .output()
8570            .await?;
8571        let global_node_modules =
8572            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
8573
8574        if let Some(version) =
8575            read_package_installed_version(global_node_modules.clone(), package_name).await?
8576        {
8577            return Ok(Some((global_node_modules, version)));
8578        }
8579        return Ok(None);
8580    }
8581
8582    #[cfg(not(target_os = "windows"))]
8583    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
8584        let worktree_abs_path = self.worktree.abs_path();
8585        let shell_path = self.shell_env().await.get("PATH").cloned();
8586        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
8587    }
8588
8589    #[cfg(target_os = "windows")]
8590    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
8591        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
8592        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
8593        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
8594        which::which(command).ok()
8595    }
8596
8597    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
8598        let working_dir = self.worktree_root_path();
8599        let output = util::command::new_smol_command(&command.path)
8600            .args(command.arguments)
8601            .envs(command.env.clone().unwrap_or_default())
8602            .current_dir(working_dir)
8603            .output()
8604            .await?;
8605
8606        if output.status.success() {
8607            return Ok(());
8608        }
8609        Err(anyhow!(
8610            "{}, stdout: {:?}, stderr: {:?}",
8611            output.status,
8612            String::from_utf8_lossy(&output.stdout),
8613            String::from_utf8_lossy(&output.stderr)
8614        ))
8615    }
8616
8617    fn update_status(
8618        &self,
8619        server_name: LanguageServerName,
8620        status: language::LanguageServerBinaryStatus,
8621    ) {
8622        self.language_registry
8623            .update_lsp_status(server_name, status);
8624    }
8625
8626    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
8627        let dir = self.language_registry.language_server_download_dir(name)?;
8628
8629        if !dir.exists() {
8630            smol::fs::create_dir_all(&dir)
8631                .await
8632                .context("failed to create container directory")
8633                .log_err()?;
8634        }
8635
8636        Some(dir)
8637    }
8638
8639    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
8640        let entry = self
8641            .worktree
8642            .entry_for_path(&path)
8643            .with_context(|| format!("no worktree entry for path {path:?}"))?;
8644        let abs_path = self
8645            .worktree
8646            .absolutize(&entry.path)
8647            .with_context(|| format!("cannot absolutize path {path:?}"))?;
8648
8649        self.fs.load(&abs_path).await
8650    }
8651}
8652
8653async fn populate_labels_for_symbols(
8654    symbols: Vec<CoreSymbol>,
8655    language_registry: &Arc<LanguageRegistry>,
8656    lsp_adapter: Option<Arc<CachedLspAdapter>>,
8657    output: &mut Vec<Symbol>,
8658) {
8659    #[allow(clippy::mutable_key_type)]
8660    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
8661
8662    let mut unknown_paths = BTreeSet::new();
8663    for symbol in symbols {
8664        let language = language_registry
8665            .language_for_file_path(&symbol.path.path)
8666            .await
8667            .ok()
8668            .or_else(|| {
8669                unknown_paths.insert(symbol.path.path.clone());
8670                None
8671            });
8672        symbols_by_language
8673            .entry(language)
8674            .or_default()
8675            .push(symbol);
8676    }
8677
8678    for unknown_path in unknown_paths {
8679        log::info!(
8680            "no language found for symbol path {}",
8681            unknown_path.display()
8682        );
8683    }
8684
8685    let mut label_params = Vec::new();
8686    for (language, mut symbols) in symbols_by_language {
8687        label_params.clear();
8688        label_params.extend(
8689            symbols
8690                .iter_mut()
8691                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
8692        );
8693
8694        let mut labels = Vec::new();
8695        if let Some(language) = language {
8696            let lsp_adapter = lsp_adapter.clone().or_else(|| {
8697                language_registry
8698                    .lsp_adapters(&language.name())
8699                    .first()
8700                    .cloned()
8701            });
8702            if let Some(lsp_adapter) = lsp_adapter {
8703                labels = lsp_adapter
8704                    .labels_for_symbols(&label_params, &language)
8705                    .await
8706                    .log_err()
8707                    .unwrap_or_default();
8708            }
8709        }
8710
8711        for ((symbol, (name, _)), label) in symbols
8712            .into_iter()
8713            .zip(label_params.drain(..))
8714            .zip(labels.into_iter().chain(iter::repeat(None)))
8715        {
8716            output.push(Symbol {
8717                language_server_name: symbol.language_server_name,
8718                source_worktree_id: symbol.source_worktree_id,
8719                path: symbol.path,
8720                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
8721                name,
8722                kind: symbol.kind,
8723                range: symbol.range,
8724                signature: symbol.signature,
8725            });
8726        }
8727    }
8728}
8729
8730fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
8731    match server.capabilities().text_document_sync.as_ref()? {
8732        lsp::TextDocumentSyncCapability::Kind(kind) => match *kind {
8733            lsp::TextDocumentSyncKind::NONE => None,
8734            lsp::TextDocumentSyncKind::FULL => Some(true),
8735            lsp::TextDocumentSyncKind::INCREMENTAL => Some(false),
8736            _ => None,
8737        },
8738        lsp::TextDocumentSyncCapability::Options(options) => match options.save.as_ref()? {
8739            lsp::TextDocumentSyncSaveOptions::Supported(supported) => {
8740                if *supported {
8741                    Some(true)
8742                } else {
8743                    None
8744                }
8745            }
8746            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
8747                Some(save_options.include_text.unwrap_or(false))
8748            }
8749        },
8750    }
8751}
8752
8753/// Completion items are displayed in a `UniformList`.
8754/// Usually, those items are single-line strings, but in LSP responses,
8755/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
8756/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
8757/// 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,
8758/// breaking the completions menu presentation.
8759///
8760/// 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.
8761fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
8762    let mut new_text = String::with_capacity(label.text.len());
8763    let mut offset_map = vec![0; label.text.len() + 1];
8764    let mut last_char_was_space = false;
8765    let mut new_idx = 0;
8766    let mut chars = label.text.char_indices().fuse();
8767    let mut newlines_removed = false;
8768
8769    while let Some((idx, c)) = chars.next() {
8770        offset_map[idx] = new_idx;
8771
8772        match c {
8773            '\n' if last_char_was_space => {
8774                newlines_removed = true;
8775            }
8776            '\t' | ' ' if last_char_was_space => {}
8777            '\n' if !last_char_was_space => {
8778                new_text.push(' ');
8779                new_idx += 1;
8780                last_char_was_space = true;
8781                newlines_removed = true;
8782            }
8783            ' ' | '\t' => {
8784                new_text.push(' ');
8785                new_idx += 1;
8786                last_char_was_space = true;
8787            }
8788            _ => {
8789                new_text.push(c);
8790                new_idx += 1;
8791                last_char_was_space = false;
8792            }
8793        }
8794    }
8795    offset_map[label.text.len()] = new_idx;
8796
8797    // Only modify the label if newlines were removed.
8798    if !newlines_removed {
8799        return;
8800    }
8801
8802    let last_index = new_idx;
8803    let mut run_ranges_errors = Vec::new();
8804    label.runs.retain_mut(|(range, _)| {
8805        match offset_map.get(range.start) {
8806            Some(&start) => range.start = start,
8807            None => {
8808                run_ranges_errors.push(range.clone());
8809                return false;
8810            }
8811        }
8812
8813        match offset_map.get(range.end) {
8814            Some(&end) => range.end = end,
8815            None => {
8816                run_ranges_errors.push(range.clone());
8817                range.end = last_index;
8818            }
8819        }
8820        true
8821    });
8822    if !run_ranges_errors.is_empty() {
8823        log::error!(
8824            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
8825            label.text
8826        );
8827    }
8828
8829    let mut wrong_filter_range = None;
8830    if label.filter_range == (0..label.text.len()) {
8831        label.filter_range = 0..new_text.len();
8832    } else {
8833        let mut original_filter_range = Some(label.filter_range.clone());
8834        match offset_map.get(label.filter_range.start) {
8835            Some(&start) => label.filter_range.start = start,
8836            None => {
8837                wrong_filter_range = original_filter_range.take();
8838                label.filter_range.start = last_index;
8839            }
8840        }
8841
8842        match offset_map.get(label.filter_range.end) {
8843            Some(&end) => label.filter_range.end = end,
8844            None => {
8845                wrong_filter_range = original_filter_range.take();
8846                label.filter_range.end = last_index;
8847            }
8848        }
8849    }
8850    if let Some(wrong_filter_range) = wrong_filter_range {
8851        log::error!(
8852            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
8853            label.text
8854        );
8855    }
8856
8857    label.text = new_text;
8858}
8859
8860#[cfg(test)]
8861#[test]
8862fn test_glob_literal_prefix() {
8863    assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
8864    assert_eq!(
8865        glob_literal_prefix(Path::new("node_modules/**/*.js")),
8866        Path::new("node_modules")
8867    );
8868    assert_eq!(
8869        glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
8870        Path::new("foo")
8871    );
8872    assert_eq!(
8873        glob_literal_prefix(Path::new("foo/bar/baz.js")),
8874        Path::new("foo/bar/baz.js")
8875    );
8876
8877    #[cfg(target_os = "windows")]
8878    {
8879        assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
8880        assert_eq!(
8881            glob_literal_prefix(Path::new("node_modules\\**/*.js")),
8882            Path::new("node_modules")
8883        );
8884        assert_eq!(
8885            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
8886            Path::new("foo")
8887        );
8888        assert_eq!(
8889            glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
8890            Path::new("foo/bar/baz.js")
8891        );
8892    }
8893}