lsp_store.rs

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