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