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