lsp_command.rs

   1mod signature_help;
   2
   3use crate::{
   4    lsp_store::{LocalLspStore, LspStore},
   5    CodeAction, CompletionSource, CoreCompletion, DocumentHighlight, DocumentSymbol, Hover,
   6    HoverBlock, HoverBlockKind, InlayHint, InlayHintLabel, InlayHintLabelPart,
   7    InlayHintLabelPartTooltip, InlayHintTooltip, Location, LocationLink, LspAction, MarkupContent,
   8    PrepareRenameResponse, ProjectTransaction, ResolveState,
   9};
  10use anyhow::{anyhow, Context as _, Result};
  11use async_trait::async_trait;
  12use client::proto::{self, PeerId};
  13use clock::Global;
  14use collections::HashSet;
  15use futures::future;
  16use gpui::{App, AsyncApp, Entity};
  17use language::{
  18    language_settings::{language_settings, InlayHintKind, LanguageSettings},
  19    point_from_lsp, point_to_lsp,
  20    proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
  21    range_from_lsp, range_to_lsp, Anchor, Bias, Buffer, BufferSnapshot, CachedLspAdapter, CharKind,
  22    OffsetRangeExt, PointUtf16, ToOffset, ToPointUtf16, Transaction, Unclipped,
  23};
  24use lsp::{
  25    AdapterServerCapabilities, CodeActionKind, CodeActionOptions, CompletionContext,
  26    CompletionListItemDefaultsEditRange, CompletionTriggerKind, DocumentHighlightKind,
  27    LanguageServer, LanguageServerId, LinkedEditingRangeServerCapabilities, OneOf, RenameOptions,
  28    ServerCapabilities,
  29};
  30use signature_help::{lsp_to_proto_signature, proto_to_lsp_signature};
  31use std::{cmp::Reverse, mem, ops::Range, path::Path, sync::Arc};
  32use text::{BufferId, LineEnding};
  33
  34pub use signature_help::SignatureHelp;
  35
  36pub fn lsp_formatting_options(settings: &LanguageSettings) -> lsp::FormattingOptions {
  37    lsp::FormattingOptions {
  38        tab_size: settings.tab_size.into(),
  39        insert_spaces: !settings.hard_tabs,
  40        trim_trailing_whitespace: Some(settings.remove_trailing_whitespace_on_save),
  41        trim_final_newlines: Some(settings.ensure_final_newline_on_save),
  42        insert_final_newline: Some(settings.ensure_final_newline_on_save),
  43        ..lsp::FormattingOptions::default()
  44    }
  45}
  46
  47pub(crate) fn file_path_to_lsp_url(path: &Path) -> Result<lsp::Url> {
  48    match lsp::Url::from_file_path(path) {
  49        Ok(url) => Ok(url),
  50        Err(()) => Err(anyhow!(
  51            "Invalid file path provided to LSP request: {path:?}"
  52        )),
  53    }
  54}
  55
  56pub(crate) fn make_text_document_identifier(path: &Path) -> Result<lsp::TextDocumentIdentifier> {
  57    Ok(lsp::TextDocumentIdentifier {
  58        uri: file_path_to_lsp_url(path)?,
  59    })
  60}
  61
  62pub(crate) fn make_lsp_text_document_position(
  63    path: &Path,
  64    position: PointUtf16,
  65) -> Result<lsp::TextDocumentPositionParams> {
  66    Ok(lsp::TextDocumentPositionParams {
  67        text_document: make_text_document_identifier(path)?,
  68        position: point_to_lsp(position),
  69    })
  70}
  71
  72#[async_trait(?Send)]
  73pub trait LspCommand: 'static + Sized + Send + std::fmt::Debug {
  74    type Response: 'static + Default + Send + std::fmt::Debug;
  75    type LspRequest: 'static + Send + lsp::request::Request;
  76    type ProtoRequest: 'static + Send + proto::RequestMessage;
  77
  78    fn display_name(&self) -> &str;
  79
  80    fn status(&self) -> Option<String> {
  81        None
  82    }
  83
  84    fn to_lsp_params_or_response(
  85        &self,
  86        path: &Path,
  87        buffer: &Buffer,
  88        language_server: &Arc<LanguageServer>,
  89        cx: &App,
  90    ) -> Result<
  91        LspParamsOrResponse<<Self::LspRequest as lsp::request::Request>::Params, Self::Response>,
  92    > {
  93        if self.check_capabilities(language_server.adapter_server_capabilities()) {
  94            Ok(LspParamsOrResponse::Params(self.to_lsp(
  95                path,
  96                buffer,
  97                language_server,
  98                cx,
  99            )?))
 100        } else {
 101            Ok(LspParamsOrResponse::Response(Default::default()))
 102        }
 103    }
 104
 105    /// When false, `to_lsp_params_or_response` default implementation will return the default response.
 106    fn check_capabilities(&self, _: AdapterServerCapabilities) -> bool {
 107        true
 108    }
 109
 110    fn to_lsp(
 111        &self,
 112        path: &Path,
 113        buffer: &Buffer,
 114        language_server: &Arc<LanguageServer>,
 115        cx: &App,
 116    ) -> Result<<Self::LspRequest as lsp::request::Request>::Params>;
 117
 118    async fn response_from_lsp(
 119        self,
 120        message: <Self::LspRequest as lsp::request::Request>::Result,
 121        lsp_store: Entity<LspStore>,
 122        buffer: Entity<Buffer>,
 123        server_id: LanguageServerId,
 124        cx: AsyncApp,
 125    ) -> Result<Self::Response>;
 126
 127    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> Self::ProtoRequest;
 128
 129    async fn from_proto(
 130        message: Self::ProtoRequest,
 131        lsp_store: Entity<LspStore>,
 132        buffer: Entity<Buffer>,
 133        cx: AsyncApp,
 134    ) -> Result<Self>;
 135
 136    fn response_to_proto(
 137        response: Self::Response,
 138        lsp_store: &mut LspStore,
 139        peer_id: PeerId,
 140        buffer_version: &clock::Global,
 141        cx: &mut App,
 142    ) -> <Self::ProtoRequest as proto::RequestMessage>::Response;
 143
 144    async fn response_from_proto(
 145        self,
 146        message: <Self::ProtoRequest as proto::RequestMessage>::Response,
 147        lsp_store: Entity<LspStore>,
 148        buffer: Entity<Buffer>,
 149        cx: AsyncApp,
 150    ) -> Result<Self::Response>;
 151
 152    fn buffer_id_from_proto(message: &Self::ProtoRequest) -> Result<BufferId>;
 153}
 154
 155pub enum LspParamsOrResponse<P, R> {
 156    Params(P),
 157    Response(R),
 158}
 159
 160#[derive(Debug)]
 161pub(crate) struct PrepareRename {
 162    pub position: PointUtf16,
 163}
 164
 165#[derive(Debug)]
 166pub(crate) struct PerformRename {
 167    pub position: PointUtf16,
 168    pub new_name: String,
 169    pub push_to_history: bool,
 170}
 171
 172#[derive(Debug)]
 173pub struct GetDefinition {
 174    pub position: PointUtf16,
 175}
 176
 177#[derive(Debug)]
 178pub(crate) struct GetDeclaration {
 179    pub position: PointUtf16,
 180}
 181
 182#[derive(Debug)]
 183pub(crate) struct GetTypeDefinition {
 184    pub position: PointUtf16,
 185}
 186
 187#[derive(Debug)]
 188pub(crate) struct GetImplementation {
 189    pub position: PointUtf16,
 190}
 191
 192#[derive(Debug)]
 193pub(crate) struct GetReferences {
 194    pub position: PointUtf16,
 195}
 196
 197#[derive(Debug)]
 198pub(crate) struct GetDocumentHighlights {
 199    pub position: PointUtf16,
 200}
 201
 202#[derive(Debug, Copy, Clone)]
 203pub(crate) struct GetDocumentSymbols;
 204
 205#[derive(Clone, Debug)]
 206pub(crate) struct GetSignatureHelp {
 207    pub position: PointUtf16,
 208}
 209
 210#[derive(Clone, Debug)]
 211pub(crate) struct GetHover {
 212    pub position: PointUtf16,
 213}
 214
 215#[derive(Debug)]
 216pub(crate) struct GetCompletions {
 217    pub position: PointUtf16,
 218    pub context: CompletionContext,
 219}
 220
 221#[derive(Clone, Debug)]
 222pub(crate) struct GetCodeActions {
 223    pub range: Range<Anchor>,
 224    pub kinds: Option<Vec<lsp::CodeActionKind>>,
 225}
 226
 227#[derive(Debug)]
 228pub(crate) struct OnTypeFormatting {
 229    pub position: PointUtf16,
 230    pub trigger: String,
 231    pub options: lsp::FormattingOptions,
 232    pub push_to_history: bool,
 233}
 234
 235#[derive(Debug)]
 236pub(crate) struct InlayHints {
 237    pub range: Range<Anchor>,
 238}
 239
 240#[derive(Debug, Copy, Clone)]
 241pub(crate) struct GetCodeLens;
 242
 243impl GetCodeLens {
 244    pub(crate) fn can_resolve_lens(capabilities: &ServerCapabilities) -> bool {
 245        capabilities
 246            .code_lens_provider
 247            .as_ref()
 248            .and_then(|code_lens_options| code_lens_options.resolve_provider)
 249            .unwrap_or(false)
 250    }
 251}
 252
 253#[derive(Debug)]
 254pub(crate) struct LinkedEditingRange {
 255    pub position: Anchor,
 256}
 257
 258#[async_trait(?Send)]
 259impl LspCommand for PrepareRename {
 260    type Response = PrepareRenameResponse;
 261    type LspRequest = lsp::request::PrepareRenameRequest;
 262    type ProtoRequest = proto::PrepareRename;
 263
 264    fn display_name(&self) -> &str {
 265        "Prepare rename"
 266    }
 267
 268    fn to_lsp_params_or_response(
 269        &self,
 270        path: &Path,
 271        buffer: &Buffer,
 272        language_server: &Arc<LanguageServer>,
 273        cx: &App,
 274    ) -> Result<LspParamsOrResponse<lsp::TextDocumentPositionParams, PrepareRenameResponse>> {
 275        let rename_provider = language_server
 276            .adapter_server_capabilities()
 277            .server_capabilities
 278            .rename_provider;
 279        match rename_provider {
 280            Some(lsp::OneOf::Right(RenameOptions {
 281                prepare_provider: Some(true),
 282                ..
 283            })) => Ok(LspParamsOrResponse::Params(self.to_lsp(
 284                path,
 285                buffer,
 286                language_server,
 287                cx,
 288            )?)),
 289            Some(lsp::OneOf::Right(_)) => Ok(LspParamsOrResponse::Response(
 290                PrepareRenameResponse::OnlyUnpreparedRenameSupported,
 291            )),
 292            Some(lsp::OneOf::Left(true)) => Ok(LspParamsOrResponse::Response(
 293                PrepareRenameResponse::OnlyUnpreparedRenameSupported,
 294            )),
 295            _ => Err(anyhow!("Rename not supported")),
 296        }
 297    }
 298
 299    fn to_lsp(
 300        &self,
 301        path: &Path,
 302        _: &Buffer,
 303        _: &Arc<LanguageServer>,
 304        _: &App,
 305    ) -> Result<lsp::TextDocumentPositionParams> {
 306        make_lsp_text_document_position(path, self.position)
 307    }
 308
 309    async fn response_from_lsp(
 310        self,
 311        message: Option<lsp::PrepareRenameResponse>,
 312        _: Entity<LspStore>,
 313        buffer: Entity<Buffer>,
 314        _: LanguageServerId,
 315        mut cx: AsyncApp,
 316    ) -> Result<PrepareRenameResponse> {
 317        buffer.update(&mut cx, |buffer, _| match message {
 318            Some(lsp::PrepareRenameResponse::Range(range))
 319            | Some(lsp::PrepareRenameResponse::RangeWithPlaceholder { range, .. }) => {
 320                let Range { start, end } = range_from_lsp(range);
 321                if buffer.clip_point_utf16(start, Bias::Left) == start.0
 322                    && buffer.clip_point_utf16(end, Bias::Left) == end.0
 323                {
 324                    Ok(PrepareRenameResponse::Success(
 325                        buffer.anchor_after(start)..buffer.anchor_before(end),
 326                    ))
 327                } else {
 328                    Ok(PrepareRenameResponse::InvalidPosition)
 329                }
 330            }
 331            Some(lsp::PrepareRenameResponse::DefaultBehavior { .. }) => {
 332                let snapshot = buffer.snapshot();
 333                let (range, _) = snapshot.surrounding_word(self.position);
 334                let range = snapshot.anchor_after(range.start)..snapshot.anchor_before(range.end);
 335                Ok(PrepareRenameResponse::Success(range))
 336            }
 337            None => Ok(PrepareRenameResponse::InvalidPosition),
 338        })?
 339    }
 340
 341    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::PrepareRename {
 342        proto::PrepareRename {
 343            project_id,
 344            buffer_id: buffer.remote_id().into(),
 345            position: Some(language::proto::serialize_anchor(
 346                &buffer.anchor_before(self.position),
 347            )),
 348            version: serialize_version(&buffer.version()),
 349        }
 350    }
 351
 352    async fn from_proto(
 353        message: proto::PrepareRename,
 354        _: Entity<LspStore>,
 355        buffer: Entity<Buffer>,
 356        mut cx: AsyncApp,
 357    ) -> Result<Self> {
 358        let position = message
 359            .position
 360            .and_then(deserialize_anchor)
 361            .ok_or_else(|| anyhow!("invalid position"))?;
 362        buffer
 363            .update(&mut cx, |buffer, _| {
 364                buffer.wait_for_version(deserialize_version(&message.version))
 365            })?
 366            .await?;
 367
 368        Ok(Self {
 369            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,
 370        })
 371    }
 372
 373    fn response_to_proto(
 374        response: PrepareRenameResponse,
 375        _: &mut LspStore,
 376        _: PeerId,
 377        buffer_version: &clock::Global,
 378        _: &mut App,
 379    ) -> proto::PrepareRenameResponse {
 380        match response {
 381            PrepareRenameResponse::Success(range) => proto::PrepareRenameResponse {
 382                can_rename: true,
 383                only_unprepared_rename_supported: false,
 384                start: Some(language::proto::serialize_anchor(&range.start)),
 385                end: Some(language::proto::serialize_anchor(&range.end)),
 386                version: serialize_version(buffer_version),
 387            },
 388            PrepareRenameResponse::OnlyUnpreparedRenameSupported => proto::PrepareRenameResponse {
 389                can_rename: false,
 390                only_unprepared_rename_supported: true,
 391                start: None,
 392                end: None,
 393                version: vec![],
 394            },
 395            PrepareRenameResponse::InvalidPosition => proto::PrepareRenameResponse {
 396                can_rename: false,
 397                only_unprepared_rename_supported: false,
 398                start: None,
 399                end: None,
 400                version: vec![],
 401            },
 402        }
 403    }
 404
 405    async fn response_from_proto(
 406        self,
 407        message: proto::PrepareRenameResponse,
 408        _: Entity<LspStore>,
 409        buffer: Entity<Buffer>,
 410        mut cx: AsyncApp,
 411    ) -> Result<PrepareRenameResponse> {
 412        if message.can_rename {
 413            buffer
 414                .update(&mut cx, |buffer, _| {
 415                    buffer.wait_for_version(deserialize_version(&message.version))
 416                })?
 417                .await?;
 418            if let (Some(start), Some(end)) = (
 419                message.start.and_then(deserialize_anchor),
 420                message.end.and_then(deserialize_anchor),
 421            ) {
 422                Ok(PrepareRenameResponse::Success(start..end))
 423            } else {
 424                Err(anyhow!(
 425                    "Missing start or end position in remote project PrepareRenameResponse"
 426                ))
 427            }
 428        } else if message.only_unprepared_rename_supported {
 429            Ok(PrepareRenameResponse::OnlyUnpreparedRenameSupported)
 430        } else {
 431            Ok(PrepareRenameResponse::InvalidPosition)
 432        }
 433    }
 434
 435    fn buffer_id_from_proto(message: &proto::PrepareRename) -> Result<BufferId> {
 436        BufferId::new(message.buffer_id)
 437    }
 438}
 439
 440#[async_trait(?Send)]
 441impl LspCommand for PerformRename {
 442    type Response = ProjectTransaction;
 443    type LspRequest = lsp::request::Rename;
 444    type ProtoRequest = proto::PerformRename;
 445
 446    fn display_name(&self) -> &str {
 447        "Rename"
 448    }
 449
 450    fn to_lsp(
 451        &self,
 452        path: &Path,
 453        _: &Buffer,
 454        _: &Arc<LanguageServer>,
 455        _: &App,
 456    ) -> Result<lsp::RenameParams> {
 457        Ok(lsp::RenameParams {
 458            text_document_position: make_lsp_text_document_position(path, self.position)?,
 459            new_name: self.new_name.clone(),
 460            work_done_progress_params: Default::default(),
 461        })
 462    }
 463
 464    async fn response_from_lsp(
 465        self,
 466        message: Option<lsp::WorkspaceEdit>,
 467        lsp_store: Entity<LspStore>,
 468        buffer: Entity<Buffer>,
 469        server_id: LanguageServerId,
 470        mut cx: AsyncApp,
 471    ) -> Result<ProjectTransaction> {
 472        if let Some(edit) = message {
 473            let (lsp_adapter, lsp_server) =
 474                language_server_for_buffer(&lsp_store, &buffer, server_id, &mut cx)?;
 475            LocalLspStore::deserialize_workspace_edit(
 476                lsp_store,
 477                edit,
 478                self.push_to_history,
 479                lsp_adapter,
 480                lsp_server,
 481                &mut cx,
 482            )
 483            .await
 484        } else {
 485            Ok(ProjectTransaction::default())
 486        }
 487    }
 488
 489    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::PerformRename {
 490        proto::PerformRename {
 491            project_id,
 492            buffer_id: buffer.remote_id().into(),
 493            position: Some(language::proto::serialize_anchor(
 494                &buffer.anchor_before(self.position),
 495            )),
 496            new_name: self.new_name.clone(),
 497            version: serialize_version(&buffer.version()),
 498        }
 499    }
 500
 501    async fn from_proto(
 502        message: proto::PerformRename,
 503        _: Entity<LspStore>,
 504        buffer: Entity<Buffer>,
 505        mut cx: AsyncApp,
 506    ) -> Result<Self> {
 507        let position = message
 508            .position
 509            .and_then(deserialize_anchor)
 510            .ok_or_else(|| anyhow!("invalid position"))?;
 511        buffer
 512            .update(&mut cx, |buffer, _| {
 513                buffer.wait_for_version(deserialize_version(&message.version))
 514            })?
 515            .await?;
 516        Ok(Self {
 517            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,
 518            new_name: message.new_name,
 519            push_to_history: false,
 520        })
 521    }
 522
 523    fn response_to_proto(
 524        response: ProjectTransaction,
 525        lsp_store: &mut LspStore,
 526        peer_id: PeerId,
 527        _: &clock::Global,
 528        cx: &mut App,
 529    ) -> proto::PerformRenameResponse {
 530        let transaction = lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 531            buffer_store.serialize_project_transaction_for_peer(response, peer_id, cx)
 532        });
 533        proto::PerformRenameResponse {
 534            transaction: Some(transaction),
 535        }
 536    }
 537
 538    async fn response_from_proto(
 539        self,
 540        message: proto::PerformRenameResponse,
 541        lsp_store: Entity<LspStore>,
 542        _: Entity<Buffer>,
 543        mut cx: AsyncApp,
 544    ) -> Result<ProjectTransaction> {
 545        let message = message
 546            .transaction
 547            .ok_or_else(|| anyhow!("missing transaction"))?;
 548        lsp_store
 549            .update(&mut cx, |lsp_store, cx| {
 550                lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 551                    buffer_store.deserialize_project_transaction(message, self.push_to_history, cx)
 552                })
 553            })?
 554            .await
 555    }
 556
 557    fn buffer_id_from_proto(message: &proto::PerformRename) -> Result<BufferId> {
 558        BufferId::new(message.buffer_id)
 559    }
 560}
 561
 562#[async_trait(?Send)]
 563impl LspCommand for GetDefinition {
 564    type Response = Vec<LocationLink>;
 565    type LspRequest = lsp::request::GotoDefinition;
 566    type ProtoRequest = proto::GetDefinition;
 567
 568    fn display_name(&self) -> &str {
 569        "Get definition"
 570    }
 571
 572    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
 573        capabilities
 574            .server_capabilities
 575            .definition_provider
 576            .is_some()
 577    }
 578
 579    fn to_lsp(
 580        &self,
 581        path: &Path,
 582        _: &Buffer,
 583        _: &Arc<LanguageServer>,
 584        _: &App,
 585    ) -> Result<lsp::GotoDefinitionParams> {
 586        Ok(lsp::GotoDefinitionParams {
 587            text_document_position_params: make_lsp_text_document_position(path, self.position)?,
 588            work_done_progress_params: Default::default(),
 589            partial_result_params: Default::default(),
 590        })
 591    }
 592
 593    async fn response_from_lsp(
 594        self,
 595        message: Option<lsp::GotoDefinitionResponse>,
 596        lsp_store: Entity<LspStore>,
 597        buffer: Entity<Buffer>,
 598        server_id: LanguageServerId,
 599        cx: AsyncApp,
 600    ) -> Result<Vec<LocationLink>> {
 601        location_links_from_lsp(message, lsp_store, buffer, server_id, cx).await
 602    }
 603
 604    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetDefinition {
 605        proto::GetDefinition {
 606            project_id,
 607            buffer_id: buffer.remote_id().into(),
 608            position: Some(language::proto::serialize_anchor(
 609                &buffer.anchor_before(self.position),
 610            )),
 611            version: serialize_version(&buffer.version()),
 612        }
 613    }
 614
 615    async fn from_proto(
 616        message: proto::GetDefinition,
 617        _: Entity<LspStore>,
 618        buffer: Entity<Buffer>,
 619        mut cx: AsyncApp,
 620    ) -> Result<Self> {
 621        let position = message
 622            .position
 623            .and_then(deserialize_anchor)
 624            .ok_or_else(|| anyhow!("invalid position"))?;
 625        buffer
 626            .update(&mut cx, |buffer, _| {
 627                buffer.wait_for_version(deserialize_version(&message.version))
 628            })?
 629            .await?;
 630        Ok(Self {
 631            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,
 632        })
 633    }
 634
 635    fn response_to_proto(
 636        response: Vec<LocationLink>,
 637        lsp_store: &mut LspStore,
 638        peer_id: PeerId,
 639        _: &clock::Global,
 640        cx: &mut App,
 641    ) -> proto::GetDefinitionResponse {
 642        let links = location_links_to_proto(response, lsp_store, peer_id, cx);
 643        proto::GetDefinitionResponse { links }
 644    }
 645
 646    async fn response_from_proto(
 647        self,
 648        message: proto::GetDefinitionResponse,
 649        lsp_store: Entity<LspStore>,
 650        _: Entity<Buffer>,
 651        cx: AsyncApp,
 652    ) -> Result<Vec<LocationLink>> {
 653        location_links_from_proto(message.links, lsp_store, cx).await
 654    }
 655
 656    fn buffer_id_from_proto(message: &proto::GetDefinition) -> Result<BufferId> {
 657        BufferId::new(message.buffer_id)
 658    }
 659}
 660
 661#[async_trait(?Send)]
 662impl LspCommand for GetDeclaration {
 663    type Response = Vec<LocationLink>;
 664    type LspRequest = lsp::request::GotoDeclaration;
 665    type ProtoRequest = proto::GetDeclaration;
 666
 667    fn display_name(&self) -> &str {
 668        "Get declaration"
 669    }
 670
 671    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
 672        capabilities
 673            .server_capabilities
 674            .declaration_provider
 675            .is_some()
 676    }
 677
 678    fn to_lsp(
 679        &self,
 680        path: &Path,
 681        _: &Buffer,
 682        _: &Arc<LanguageServer>,
 683        _: &App,
 684    ) -> Result<lsp::GotoDeclarationParams> {
 685        Ok(lsp::GotoDeclarationParams {
 686            text_document_position_params: make_lsp_text_document_position(path, self.position)?,
 687            work_done_progress_params: Default::default(),
 688            partial_result_params: Default::default(),
 689        })
 690    }
 691
 692    async fn response_from_lsp(
 693        self,
 694        message: Option<lsp::GotoDeclarationResponse>,
 695        lsp_store: Entity<LspStore>,
 696        buffer: Entity<Buffer>,
 697        server_id: LanguageServerId,
 698        cx: AsyncApp,
 699    ) -> Result<Vec<LocationLink>> {
 700        location_links_from_lsp(message, lsp_store, buffer, server_id, cx).await
 701    }
 702
 703    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetDeclaration {
 704        proto::GetDeclaration {
 705            project_id,
 706            buffer_id: buffer.remote_id().into(),
 707            position: Some(language::proto::serialize_anchor(
 708                &buffer.anchor_before(self.position),
 709            )),
 710            version: serialize_version(&buffer.version()),
 711        }
 712    }
 713
 714    async fn from_proto(
 715        message: proto::GetDeclaration,
 716        _: Entity<LspStore>,
 717        buffer: Entity<Buffer>,
 718        mut cx: AsyncApp,
 719    ) -> Result<Self> {
 720        let position = message
 721            .position
 722            .and_then(deserialize_anchor)
 723            .ok_or_else(|| anyhow!("invalid position"))?;
 724        buffer
 725            .update(&mut cx, |buffer, _| {
 726                buffer.wait_for_version(deserialize_version(&message.version))
 727            })?
 728            .await?;
 729        Ok(Self {
 730            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,
 731        })
 732    }
 733
 734    fn response_to_proto(
 735        response: Vec<LocationLink>,
 736        lsp_store: &mut LspStore,
 737        peer_id: PeerId,
 738        _: &clock::Global,
 739        cx: &mut App,
 740    ) -> proto::GetDeclarationResponse {
 741        let links = location_links_to_proto(response, lsp_store, peer_id, cx);
 742        proto::GetDeclarationResponse { links }
 743    }
 744
 745    async fn response_from_proto(
 746        self,
 747        message: proto::GetDeclarationResponse,
 748        lsp_store: Entity<LspStore>,
 749        _: Entity<Buffer>,
 750        cx: AsyncApp,
 751    ) -> Result<Vec<LocationLink>> {
 752        location_links_from_proto(message.links, lsp_store, cx).await
 753    }
 754
 755    fn buffer_id_from_proto(message: &proto::GetDeclaration) -> Result<BufferId> {
 756        BufferId::new(message.buffer_id)
 757    }
 758}
 759
 760#[async_trait(?Send)]
 761impl LspCommand for GetImplementation {
 762    type Response = Vec<LocationLink>;
 763    type LspRequest = lsp::request::GotoImplementation;
 764    type ProtoRequest = proto::GetImplementation;
 765
 766    fn display_name(&self) -> &str {
 767        "Get implementation"
 768    }
 769
 770    fn to_lsp(
 771        &self,
 772        path: &Path,
 773        _: &Buffer,
 774        _: &Arc<LanguageServer>,
 775        _: &App,
 776    ) -> Result<lsp::GotoImplementationParams> {
 777        Ok(lsp::GotoImplementationParams {
 778            text_document_position_params: make_lsp_text_document_position(path, self.position)?,
 779            work_done_progress_params: Default::default(),
 780            partial_result_params: Default::default(),
 781        })
 782    }
 783
 784    async fn response_from_lsp(
 785        self,
 786        message: Option<lsp::GotoImplementationResponse>,
 787        lsp_store: Entity<LspStore>,
 788        buffer: Entity<Buffer>,
 789        server_id: LanguageServerId,
 790        cx: AsyncApp,
 791    ) -> Result<Vec<LocationLink>> {
 792        location_links_from_lsp(message, lsp_store, buffer, server_id, cx).await
 793    }
 794
 795    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetImplementation {
 796        proto::GetImplementation {
 797            project_id,
 798            buffer_id: buffer.remote_id().into(),
 799            position: Some(language::proto::serialize_anchor(
 800                &buffer.anchor_before(self.position),
 801            )),
 802            version: serialize_version(&buffer.version()),
 803        }
 804    }
 805
 806    async fn from_proto(
 807        message: proto::GetImplementation,
 808        _: Entity<LspStore>,
 809        buffer: Entity<Buffer>,
 810        mut cx: AsyncApp,
 811    ) -> Result<Self> {
 812        let position = message
 813            .position
 814            .and_then(deserialize_anchor)
 815            .ok_or_else(|| anyhow!("invalid position"))?;
 816        buffer
 817            .update(&mut cx, |buffer, _| {
 818                buffer.wait_for_version(deserialize_version(&message.version))
 819            })?
 820            .await?;
 821        Ok(Self {
 822            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,
 823        })
 824    }
 825
 826    fn response_to_proto(
 827        response: Vec<LocationLink>,
 828        lsp_store: &mut LspStore,
 829        peer_id: PeerId,
 830        _: &clock::Global,
 831        cx: &mut App,
 832    ) -> proto::GetImplementationResponse {
 833        let links = location_links_to_proto(response, lsp_store, peer_id, cx);
 834        proto::GetImplementationResponse { links }
 835    }
 836
 837    async fn response_from_proto(
 838        self,
 839        message: proto::GetImplementationResponse,
 840        project: Entity<LspStore>,
 841        _: Entity<Buffer>,
 842        cx: AsyncApp,
 843    ) -> Result<Vec<LocationLink>> {
 844        location_links_from_proto(message.links, project, cx).await
 845    }
 846
 847    fn buffer_id_from_proto(message: &proto::GetImplementation) -> Result<BufferId> {
 848        BufferId::new(message.buffer_id)
 849    }
 850}
 851
 852#[async_trait(?Send)]
 853impl LspCommand for GetTypeDefinition {
 854    type Response = Vec<LocationLink>;
 855    type LspRequest = lsp::request::GotoTypeDefinition;
 856    type ProtoRequest = proto::GetTypeDefinition;
 857
 858    fn display_name(&self) -> &str {
 859        "Get type definition"
 860    }
 861
 862    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
 863        !matches!(
 864            &capabilities.server_capabilities.type_definition_provider,
 865            None | Some(lsp::TypeDefinitionProviderCapability::Simple(false))
 866        )
 867    }
 868
 869    fn to_lsp(
 870        &self,
 871        path: &Path,
 872        _: &Buffer,
 873        _: &Arc<LanguageServer>,
 874        _: &App,
 875    ) -> Result<lsp::GotoTypeDefinitionParams> {
 876        Ok(lsp::GotoTypeDefinitionParams {
 877            text_document_position_params: make_lsp_text_document_position(path, self.position)?,
 878            work_done_progress_params: Default::default(),
 879            partial_result_params: Default::default(),
 880        })
 881    }
 882
 883    async fn response_from_lsp(
 884        self,
 885        message: Option<lsp::GotoTypeDefinitionResponse>,
 886        project: Entity<LspStore>,
 887        buffer: Entity<Buffer>,
 888        server_id: LanguageServerId,
 889        cx: AsyncApp,
 890    ) -> Result<Vec<LocationLink>> {
 891        location_links_from_lsp(message, project, buffer, server_id, cx).await
 892    }
 893
 894    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetTypeDefinition {
 895        proto::GetTypeDefinition {
 896            project_id,
 897            buffer_id: buffer.remote_id().into(),
 898            position: Some(language::proto::serialize_anchor(
 899                &buffer.anchor_before(self.position),
 900            )),
 901            version: serialize_version(&buffer.version()),
 902        }
 903    }
 904
 905    async fn from_proto(
 906        message: proto::GetTypeDefinition,
 907        _: Entity<LspStore>,
 908        buffer: Entity<Buffer>,
 909        mut cx: AsyncApp,
 910    ) -> Result<Self> {
 911        let position = message
 912            .position
 913            .and_then(deserialize_anchor)
 914            .ok_or_else(|| anyhow!("invalid position"))?;
 915        buffer
 916            .update(&mut cx, |buffer, _| {
 917                buffer.wait_for_version(deserialize_version(&message.version))
 918            })?
 919            .await?;
 920        Ok(Self {
 921            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,
 922        })
 923    }
 924
 925    fn response_to_proto(
 926        response: Vec<LocationLink>,
 927        lsp_store: &mut LspStore,
 928        peer_id: PeerId,
 929        _: &clock::Global,
 930        cx: &mut App,
 931    ) -> proto::GetTypeDefinitionResponse {
 932        let links = location_links_to_proto(response, lsp_store, peer_id, cx);
 933        proto::GetTypeDefinitionResponse { links }
 934    }
 935
 936    async fn response_from_proto(
 937        self,
 938        message: proto::GetTypeDefinitionResponse,
 939        project: Entity<LspStore>,
 940        _: Entity<Buffer>,
 941        cx: AsyncApp,
 942    ) -> Result<Vec<LocationLink>> {
 943        location_links_from_proto(message.links, project, cx).await
 944    }
 945
 946    fn buffer_id_from_proto(message: &proto::GetTypeDefinition) -> Result<BufferId> {
 947        BufferId::new(message.buffer_id)
 948    }
 949}
 950
 951fn language_server_for_buffer(
 952    lsp_store: &Entity<LspStore>,
 953    buffer: &Entity<Buffer>,
 954    server_id: LanguageServerId,
 955    cx: &mut AsyncApp,
 956) -> Result<(Arc<CachedLspAdapter>, Arc<LanguageServer>)> {
 957    lsp_store
 958        .update(cx, |lsp_store, cx| {
 959            buffer.update(cx, |buffer, cx| {
 960                lsp_store
 961                    .language_server_for_local_buffer(buffer, server_id, cx)
 962                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 963            })
 964        })?
 965        .ok_or_else(|| anyhow!("no language server found for buffer"))
 966}
 967
 968async fn location_links_from_proto(
 969    proto_links: Vec<proto::LocationLink>,
 970    lsp_store: Entity<LspStore>,
 971    mut cx: AsyncApp,
 972) -> Result<Vec<LocationLink>> {
 973    let mut links = Vec::new();
 974
 975    for link in proto_links {
 976        let origin = match link.origin {
 977            Some(origin) => {
 978                let buffer_id = BufferId::new(origin.buffer_id)?;
 979                let buffer = lsp_store
 980                    .update(&mut cx, |lsp_store, cx| {
 981                        lsp_store.wait_for_remote_buffer(buffer_id, cx)
 982                    })?
 983                    .await?;
 984                let start = origin
 985                    .start
 986                    .and_then(deserialize_anchor)
 987                    .ok_or_else(|| anyhow!("missing origin start"))?;
 988                let end = origin
 989                    .end
 990                    .and_then(deserialize_anchor)
 991                    .ok_or_else(|| anyhow!("missing origin end"))?;
 992                buffer
 993                    .update(&mut cx, |buffer, _| buffer.wait_for_anchors([start, end]))?
 994                    .await?;
 995                Some(Location {
 996                    buffer,
 997                    range: start..end,
 998                })
 999            }
1000            None => None,
1001        };
1002
1003        let target = link.target.ok_or_else(|| anyhow!("missing target"))?;
1004        let buffer_id = BufferId::new(target.buffer_id)?;
1005        let buffer = lsp_store
1006            .update(&mut cx, |lsp_store, cx| {
1007                lsp_store.wait_for_remote_buffer(buffer_id, cx)
1008            })?
1009            .await?;
1010        let start = target
1011            .start
1012            .and_then(deserialize_anchor)
1013            .ok_or_else(|| anyhow!("missing target start"))?;
1014        let end = target
1015            .end
1016            .and_then(deserialize_anchor)
1017            .ok_or_else(|| anyhow!("missing target end"))?;
1018        buffer
1019            .update(&mut cx, |buffer, _| buffer.wait_for_anchors([start, end]))?
1020            .await?;
1021        let target = Location {
1022            buffer,
1023            range: start..end,
1024        };
1025
1026        links.push(LocationLink { origin, target })
1027    }
1028
1029    Ok(links)
1030}
1031
1032async fn location_links_from_lsp(
1033    message: Option<lsp::GotoDefinitionResponse>,
1034    lsp_store: Entity<LspStore>,
1035    buffer: Entity<Buffer>,
1036    server_id: LanguageServerId,
1037    mut cx: AsyncApp,
1038) -> Result<Vec<LocationLink>> {
1039    let message = match message {
1040        Some(message) => message,
1041        None => return Ok(Vec::new()),
1042    };
1043
1044    let mut unresolved_links = Vec::new();
1045    match message {
1046        lsp::GotoDefinitionResponse::Scalar(loc) => {
1047            unresolved_links.push((None, loc.uri, loc.range));
1048        }
1049
1050        lsp::GotoDefinitionResponse::Array(locs) => {
1051            unresolved_links.extend(locs.into_iter().map(|l| (None, l.uri, l.range)));
1052        }
1053
1054        lsp::GotoDefinitionResponse::Link(links) => {
1055            unresolved_links.extend(links.into_iter().map(|l| {
1056                (
1057                    l.origin_selection_range,
1058                    l.target_uri,
1059                    l.target_selection_range,
1060                )
1061            }));
1062        }
1063    }
1064
1065    let (lsp_adapter, language_server) =
1066        language_server_for_buffer(&lsp_store, &buffer, server_id, &mut cx)?;
1067    let mut definitions = Vec::new();
1068    for (origin_range, target_uri, target_range) in unresolved_links {
1069        let target_buffer_handle = lsp_store
1070            .update(&mut cx, |this, cx| {
1071                this.open_local_buffer_via_lsp(
1072                    target_uri,
1073                    language_server.server_id(),
1074                    lsp_adapter.name.clone(),
1075                    cx,
1076                )
1077            })?
1078            .await?;
1079
1080        cx.update(|cx| {
1081            let origin_location = origin_range.map(|origin_range| {
1082                let origin_buffer = buffer.read(cx);
1083                let origin_start =
1084                    origin_buffer.clip_point_utf16(point_from_lsp(origin_range.start), Bias::Left);
1085                let origin_end =
1086                    origin_buffer.clip_point_utf16(point_from_lsp(origin_range.end), Bias::Left);
1087                Location {
1088                    buffer: buffer.clone(),
1089                    range: origin_buffer.anchor_after(origin_start)
1090                        ..origin_buffer.anchor_before(origin_end),
1091                }
1092            });
1093
1094            let target_buffer = target_buffer_handle.read(cx);
1095            let target_start =
1096                target_buffer.clip_point_utf16(point_from_lsp(target_range.start), Bias::Left);
1097            let target_end =
1098                target_buffer.clip_point_utf16(point_from_lsp(target_range.end), Bias::Left);
1099            let target_location = Location {
1100                buffer: target_buffer_handle,
1101                range: target_buffer.anchor_after(target_start)
1102                    ..target_buffer.anchor_before(target_end),
1103            };
1104
1105            definitions.push(LocationLink {
1106                origin: origin_location,
1107                target: target_location,
1108            })
1109        })?;
1110    }
1111    Ok(definitions)
1112}
1113
1114fn location_links_to_proto(
1115    links: Vec<LocationLink>,
1116    lsp_store: &mut LspStore,
1117    peer_id: PeerId,
1118    cx: &mut App,
1119) -> Vec<proto::LocationLink> {
1120    links
1121        .into_iter()
1122        .map(|definition| {
1123            let origin = definition.origin.map(|origin| {
1124                lsp_store
1125                    .buffer_store()
1126                    .update(cx, |buffer_store, cx| {
1127                        buffer_store.create_buffer_for_peer(&origin.buffer, peer_id, cx)
1128                    })
1129                    .detach_and_log_err(cx);
1130
1131                let buffer_id = origin.buffer.read(cx).remote_id().into();
1132                proto::Location {
1133                    start: Some(serialize_anchor(&origin.range.start)),
1134                    end: Some(serialize_anchor(&origin.range.end)),
1135                    buffer_id,
1136                }
1137            });
1138
1139            lsp_store
1140                .buffer_store()
1141                .update(cx, |buffer_store, cx| {
1142                    buffer_store.create_buffer_for_peer(&definition.target.buffer, peer_id, cx)
1143                })
1144                .detach_and_log_err(cx);
1145
1146            let buffer_id = definition.target.buffer.read(cx).remote_id().into();
1147            let target = proto::Location {
1148                start: Some(serialize_anchor(&definition.target.range.start)),
1149                end: Some(serialize_anchor(&definition.target.range.end)),
1150                buffer_id,
1151            };
1152
1153            proto::LocationLink {
1154                origin,
1155                target: Some(target),
1156            }
1157        })
1158        .collect()
1159}
1160
1161#[async_trait(?Send)]
1162impl LspCommand for GetReferences {
1163    type Response = Vec<Location>;
1164    type LspRequest = lsp::request::References;
1165    type ProtoRequest = proto::GetReferences;
1166
1167    fn display_name(&self) -> &str {
1168        "Find all references"
1169    }
1170
1171    fn status(&self) -> Option<String> {
1172        Some("Finding references...".to_owned())
1173    }
1174
1175    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
1176        match &capabilities.server_capabilities.references_provider {
1177            Some(OneOf::Left(has_support)) => *has_support,
1178            Some(OneOf::Right(_)) => true,
1179            None => false,
1180        }
1181    }
1182
1183    fn to_lsp(
1184        &self,
1185        path: &Path,
1186        _: &Buffer,
1187        _: &Arc<LanguageServer>,
1188        _: &App,
1189    ) -> Result<lsp::ReferenceParams> {
1190        Ok(lsp::ReferenceParams {
1191            text_document_position: make_lsp_text_document_position(path, self.position)?,
1192            work_done_progress_params: Default::default(),
1193            partial_result_params: Default::default(),
1194            context: lsp::ReferenceContext {
1195                include_declaration: true,
1196            },
1197        })
1198    }
1199
1200    async fn response_from_lsp(
1201        self,
1202        locations: Option<Vec<lsp::Location>>,
1203        lsp_store: Entity<LspStore>,
1204        buffer: Entity<Buffer>,
1205        server_id: LanguageServerId,
1206        mut cx: AsyncApp,
1207    ) -> Result<Vec<Location>> {
1208        let mut references = Vec::new();
1209        let (lsp_adapter, language_server) =
1210            language_server_for_buffer(&lsp_store, &buffer, server_id, &mut cx)?;
1211
1212        if let Some(locations) = locations {
1213            for lsp_location in locations {
1214                let target_buffer_handle = lsp_store
1215                    .update(&mut cx, |lsp_store, cx| {
1216                        lsp_store.open_local_buffer_via_lsp(
1217                            lsp_location.uri,
1218                            language_server.server_id(),
1219                            lsp_adapter.name.clone(),
1220                            cx,
1221                        )
1222                    })?
1223                    .await?;
1224
1225                target_buffer_handle
1226                    .clone()
1227                    .update(&mut cx, |target_buffer, _| {
1228                        let target_start = target_buffer
1229                            .clip_point_utf16(point_from_lsp(lsp_location.range.start), Bias::Left);
1230                        let target_end = target_buffer
1231                            .clip_point_utf16(point_from_lsp(lsp_location.range.end), Bias::Left);
1232                        references.push(Location {
1233                            buffer: target_buffer_handle,
1234                            range: target_buffer.anchor_after(target_start)
1235                                ..target_buffer.anchor_before(target_end),
1236                        });
1237                    })?;
1238            }
1239        }
1240
1241        Ok(references)
1242    }
1243
1244    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetReferences {
1245        proto::GetReferences {
1246            project_id,
1247            buffer_id: buffer.remote_id().into(),
1248            position: Some(language::proto::serialize_anchor(
1249                &buffer.anchor_before(self.position),
1250            )),
1251            version: serialize_version(&buffer.version()),
1252        }
1253    }
1254
1255    async fn from_proto(
1256        message: proto::GetReferences,
1257        _: Entity<LspStore>,
1258        buffer: Entity<Buffer>,
1259        mut cx: AsyncApp,
1260    ) -> Result<Self> {
1261        let position = message
1262            .position
1263            .and_then(deserialize_anchor)
1264            .ok_or_else(|| anyhow!("invalid position"))?;
1265        buffer
1266            .update(&mut cx, |buffer, _| {
1267                buffer.wait_for_version(deserialize_version(&message.version))
1268            })?
1269            .await?;
1270        Ok(Self {
1271            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,
1272        })
1273    }
1274
1275    fn response_to_proto(
1276        response: Vec<Location>,
1277        lsp_store: &mut LspStore,
1278        peer_id: PeerId,
1279        _: &clock::Global,
1280        cx: &mut App,
1281    ) -> proto::GetReferencesResponse {
1282        let locations = response
1283            .into_iter()
1284            .map(|definition| {
1285                lsp_store
1286                    .buffer_store()
1287                    .update(cx, |buffer_store, cx| {
1288                        buffer_store.create_buffer_for_peer(&definition.buffer, peer_id, cx)
1289                    })
1290                    .detach_and_log_err(cx);
1291                let buffer_id = definition.buffer.read(cx).remote_id();
1292                proto::Location {
1293                    start: Some(serialize_anchor(&definition.range.start)),
1294                    end: Some(serialize_anchor(&definition.range.end)),
1295                    buffer_id: buffer_id.into(),
1296                }
1297            })
1298            .collect();
1299        proto::GetReferencesResponse { locations }
1300    }
1301
1302    async fn response_from_proto(
1303        self,
1304        message: proto::GetReferencesResponse,
1305        project: Entity<LspStore>,
1306        _: Entity<Buffer>,
1307        mut cx: AsyncApp,
1308    ) -> Result<Vec<Location>> {
1309        let mut locations = Vec::new();
1310        for location in message.locations {
1311            let buffer_id = BufferId::new(location.buffer_id)?;
1312            let target_buffer = project
1313                .update(&mut cx, |this, cx| {
1314                    this.wait_for_remote_buffer(buffer_id, cx)
1315                })?
1316                .await?;
1317            let start = location
1318                .start
1319                .and_then(deserialize_anchor)
1320                .ok_or_else(|| anyhow!("missing target start"))?;
1321            let end = location
1322                .end
1323                .and_then(deserialize_anchor)
1324                .ok_or_else(|| anyhow!("missing target end"))?;
1325            target_buffer
1326                .update(&mut cx, |buffer, _| buffer.wait_for_anchors([start, end]))?
1327                .await?;
1328            locations.push(Location {
1329                buffer: target_buffer,
1330                range: start..end,
1331            })
1332        }
1333        Ok(locations)
1334    }
1335
1336    fn buffer_id_from_proto(message: &proto::GetReferences) -> Result<BufferId> {
1337        BufferId::new(message.buffer_id)
1338    }
1339}
1340
1341#[async_trait(?Send)]
1342impl LspCommand for GetDocumentHighlights {
1343    type Response = Vec<DocumentHighlight>;
1344    type LspRequest = lsp::request::DocumentHighlightRequest;
1345    type ProtoRequest = proto::GetDocumentHighlights;
1346
1347    fn display_name(&self) -> &str {
1348        "Get document highlights"
1349    }
1350
1351    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
1352        capabilities
1353            .server_capabilities
1354            .document_highlight_provider
1355            .is_some()
1356    }
1357
1358    fn to_lsp(
1359        &self,
1360        path: &Path,
1361        _: &Buffer,
1362        _: &Arc<LanguageServer>,
1363        _: &App,
1364    ) -> Result<lsp::DocumentHighlightParams> {
1365        Ok(lsp::DocumentHighlightParams {
1366            text_document_position_params: make_lsp_text_document_position(path, self.position)?,
1367            work_done_progress_params: Default::default(),
1368            partial_result_params: Default::default(),
1369        })
1370    }
1371
1372    async fn response_from_lsp(
1373        self,
1374        lsp_highlights: Option<Vec<lsp::DocumentHighlight>>,
1375        _: Entity<LspStore>,
1376        buffer: Entity<Buffer>,
1377        _: LanguageServerId,
1378        mut cx: AsyncApp,
1379    ) -> Result<Vec<DocumentHighlight>> {
1380        buffer.update(&mut cx, |buffer, _| {
1381            let mut lsp_highlights = lsp_highlights.unwrap_or_default();
1382            lsp_highlights.sort_unstable_by_key(|h| (h.range.start, Reverse(h.range.end)));
1383            lsp_highlights
1384                .into_iter()
1385                .map(|lsp_highlight| {
1386                    let start = buffer
1387                        .clip_point_utf16(point_from_lsp(lsp_highlight.range.start), Bias::Left);
1388                    let end = buffer
1389                        .clip_point_utf16(point_from_lsp(lsp_highlight.range.end), Bias::Left);
1390                    DocumentHighlight {
1391                        range: buffer.anchor_after(start)..buffer.anchor_before(end),
1392                        kind: lsp_highlight
1393                            .kind
1394                            .unwrap_or(lsp::DocumentHighlightKind::READ),
1395                    }
1396                })
1397                .collect()
1398        })
1399    }
1400
1401    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetDocumentHighlights {
1402        proto::GetDocumentHighlights {
1403            project_id,
1404            buffer_id: buffer.remote_id().into(),
1405            position: Some(language::proto::serialize_anchor(
1406                &buffer.anchor_before(self.position),
1407            )),
1408            version: serialize_version(&buffer.version()),
1409        }
1410    }
1411
1412    async fn from_proto(
1413        message: proto::GetDocumentHighlights,
1414        _: Entity<LspStore>,
1415        buffer: Entity<Buffer>,
1416        mut cx: AsyncApp,
1417    ) -> Result<Self> {
1418        let position = message
1419            .position
1420            .and_then(deserialize_anchor)
1421            .ok_or_else(|| anyhow!("invalid position"))?;
1422        buffer
1423            .update(&mut cx, |buffer, _| {
1424                buffer.wait_for_version(deserialize_version(&message.version))
1425            })?
1426            .await?;
1427        Ok(Self {
1428            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,
1429        })
1430    }
1431
1432    fn response_to_proto(
1433        response: Vec<DocumentHighlight>,
1434        _: &mut LspStore,
1435        _: PeerId,
1436        _: &clock::Global,
1437        _: &mut App,
1438    ) -> proto::GetDocumentHighlightsResponse {
1439        let highlights = response
1440            .into_iter()
1441            .map(|highlight| proto::DocumentHighlight {
1442                start: Some(serialize_anchor(&highlight.range.start)),
1443                end: Some(serialize_anchor(&highlight.range.end)),
1444                kind: match highlight.kind {
1445                    DocumentHighlightKind::TEXT => proto::document_highlight::Kind::Text.into(),
1446                    DocumentHighlightKind::WRITE => proto::document_highlight::Kind::Write.into(),
1447                    DocumentHighlightKind::READ => proto::document_highlight::Kind::Read.into(),
1448                    _ => proto::document_highlight::Kind::Text.into(),
1449                },
1450            })
1451            .collect();
1452        proto::GetDocumentHighlightsResponse { highlights }
1453    }
1454
1455    async fn response_from_proto(
1456        self,
1457        message: proto::GetDocumentHighlightsResponse,
1458        _: Entity<LspStore>,
1459        buffer: Entity<Buffer>,
1460        mut cx: AsyncApp,
1461    ) -> Result<Vec<DocumentHighlight>> {
1462        let mut highlights = Vec::new();
1463        for highlight in message.highlights {
1464            let start = highlight
1465                .start
1466                .and_then(deserialize_anchor)
1467                .ok_or_else(|| anyhow!("missing target start"))?;
1468            let end = highlight
1469                .end
1470                .and_then(deserialize_anchor)
1471                .ok_or_else(|| anyhow!("missing target end"))?;
1472            buffer
1473                .update(&mut cx, |buffer, _| buffer.wait_for_anchors([start, end]))?
1474                .await?;
1475            let kind = match proto::document_highlight::Kind::from_i32(highlight.kind) {
1476                Some(proto::document_highlight::Kind::Text) => DocumentHighlightKind::TEXT,
1477                Some(proto::document_highlight::Kind::Read) => DocumentHighlightKind::READ,
1478                Some(proto::document_highlight::Kind::Write) => DocumentHighlightKind::WRITE,
1479                None => DocumentHighlightKind::TEXT,
1480            };
1481            highlights.push(DocumentHighlight {
1482                range: start..end,
1483                kind,
1484            });
1485        }
1486        Ok(highlights)
1487    }
1488
1489    fn buffer_id_from_proto(message: &proto::GetDocumentHighlights) -> Result<BufferId> {
1490        BufferId::new(message.buffer_id)
1491    }
1492}
1493
1494#[async_trait(?Send)]
1495impl LspCommand for GetDocumentSymbols {
1496    type Response = Vec<DocumentSymbol>;
1497    type LspRequest = lsp::request::DocumentSymbolRequest;
1498    type ProtoRequest = proto::GetDocumentSymbols;
1499
1500    fn display_name(&self) -> &str {
1501        "Get document symbols"
1502    }
1503
1504    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
1505        capabilities
1506            .server_capabilities
1507            .document_symbol_provider
1508            .is_some()
1509    }
1510
1511    fn to_lsp(
1512        &self,
1513        path: &Path,
1514        _: &Buffer,
1515        _: &Arc<LanguageServer>,
1516        _: &App,
1517    ) -> Result<lsp::DocumentSymbolParams> {
1518        Ok(lsp::DocumentSymbolParams {
1519            text_document: make_text_document_identifier(path)?,
1520            work_done_progress_params: Default::default(),
1521            partial_result_params: Default::default(),
1522        })
1523    }
1524
1525    async fn response_from_lsp(
1526        self,
1527        lsp_symbols: Option<lsp::DocumentSymbolResponse>,
1528        _: Entity<LspStore>,
1529        _: Entity<Buffer>,
1530        _: LanguageServerId,
1531        _: AsyncApp,
1532    ) -> Result<Vec<DocumentSymbol>> {
1533        let Some(lsp_symbols) = lsp_symbols else {
1534            return Ok(Vec::new());
1535        };
1536
1537        let symbols: Vec<_> = match lsp_symbols {
1538            lsp::DocumentSymbolResponse::Flat(symbol_information) => symbol_information
1539                .into_iter()
1540                .map(|lsp_symbol| DocumentSymbol {
1541                    name: lsp_symbol.name,
1542                    kind: lsp_symbol.kind,
1543                    range: range_from_lsp(lsp_symbol.location.range),
1544                    selection_range: range_from_lsp(lsp_symbol.location.range),
1545                    children: Vec::new(),
1546                })
1547                .collect(),
1548            lsp::DocumentSymbolResponse::Nested(nested_responses) => {
1549                fn convert_symbol(lsp_symbol: lsp::DocumentSymbol) -> DocumentSymbol {
1550                    DocumentSymbol {
1551                        name: lsp_symbol.name,
1552                        kind: lsp_symbol.kind,
1553                        range: range_from_lsp(lsp_symbol.range),
1554                        selection_range: range_from_lsp(lsp_symbol.selection_range),
1555                        children: lsp_symbol
1556                            .children
1557                            .map(|children| {
1558                                children.into_iter().map(convert_symbol).collect::<Vec<_>>()
1559                            })
1560                            .unwrap_or_default(),
1561                    }
1562                }
1563                nested_responses.into_iter().map(convert_symbol).collect()
1564            }
1565        };
1566        Ok(symbols)
1567    }
1568
1569    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetDocumentSymbols {
1570        proto::GetDocumentSymbols {
1571            project_id,
1572            buffer_id: buffer.remote_id().into(),
1573            version: serialize_version(&buffer.version()),
1574        }
1575    }
1576
1577    async fn from_proto(
1578        message: proto::GetDocumentSymbols,
1579        _: Entity<LspStore>,
1580        buffer: Entity<Buffer>,
1581        mut cx: AsyncApp,
1582    ) -> Result<Self> {
1583        buffer
1584            .update(&mut cx, |buffer, _| {
1585                buffer.wait_for_version(deserialize_version(&message.version))
1586            })?
1587            .await?;
1588        Ok(Self)
1589    }
1590
1591    fn response_to_proto(
1592        response: Vec<DocumentSymbol>,
1593        _: &mut LspStore,
1594        _: PeerId,
1595        _: &clock::Global,
1596        _: &mut App,
1597    ) -> proto::GetDocumentSymbolsResponse {
1598        let symbols = response
1599            .into_iter()
1600            .map(|symbol| {
1601                fn convert_symbol_to_proto(symbol: DocumentSymbol) -> proto::DocumentSymbol {
1602                    proto::DocumentSymbol {
1603                        name: symbol.name.clone(),
1604                        kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
1605                        start: Some(proto::PointUtf16 {
1606                            row: symbol.range.start.0.row,
1607                            column: symbol.range.start.0.column,
1608                        }),
1609                        end: Some(proto::PointUtf16 {
1610                            row: symbol.range.end.0.row,
1611                            column: symbol.range.end.0.column,
1612                        }),
1613                        selection_start: Some(proto::PointUtf16 {
1614                            row: symbol.selection_range.start.0.row,
1615                            column: symbol.selection_range.start.0.column,
1616                        }),
1617                        selection_end: Some(proto::PointUtf16 {
1618                            row: symbol.selection_range.end.0.row,
1619                            column: symbol.selection_range.end.0.column,
1620                        }),
1621                        children: symbol
1622                            .children
1623                            .into_iter()
1624                            .map(convert_symbol_to_proto)
1625                            .collect(),
1626                    }
1627                }
1628                convert_symbol_to_proto(symbol)
1629            })
1630            .collect::<Vec<_>>();
1631
1632        proto::GetDocumentSymbolsResponse { symbols }
1633    }
1634
1635    async fn response_from_proto(
1636        self,
1637        message: proto::GetDocumentSymbolsResponse,
1638        _: Entity<LspStore>,
1639        _: Entity<Buffer>,
1640        _: AsyncApp,
1641    ) -> Result<Vec<DocumentSymbol>> {
1642        let mut symbols = Vec::with_capacity(message.symbols.len());
1643        for serialized_symbol in message.symbols {
1644            fn deserialize_symbol_with_children(
1645                serialized_symbol: proto::DocumentSymbol,
1646            ) -> Result<DocumentSymbol> {
1647                let kind =
1648                    unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
1649
1650                let start = serialized_symbol
1651                    .start
1652                    .ok_or_else(|| anyhow!("invalid start"))?;
1653                let end = serialized_symbol
1654                    .end
1655                    .ok_or_else(|| anyhow!("invalid end"))?;
1656
1657                let selection_start = serialized_symbol
1658                    .selection_start
1659                    .ok_or_else(|| anyhow!("invalid selection start"))?;
1660                let selection_end = serialized_symbol
1661                    .selection_end
1662                    .ok_or_else(|| anyhow!("invalid selection end"))?;
1663
1664                Ok(DocumentSymbol {
1665                    name: serialized_symbol.name,
1666                    kind,
1667                    range: Unclipped(PointUtf16::new(start.row, start.column))
1668                        ..Unclipped(PointUtf16::new(end.row, end.column)),
1669                    selection_range: Unclipped(PointUtf16::new(
1670                        selection_start.row,
1671                        selection_start.column,
1672                    ))
1673                        ..Unclipped(PointUtf16::new(selection_end.row, selection_end.column)),
1674                    children: serialized_symbol
1675                        .children
1676                        .into_iter()
1677                        .filter_map(|symbol| deserialize_symbol_with_children(symbol).ok())
1678                        .collect::<Vec<_>>(),
1679                })
1680            }
1681
1682            symbols.push(deserialize_symbol_with_children(serialized_symbol)?);
1683        }
1684
1685        Ok(symbols)
1686    }
1687
1688    fn buffer_id_from_proto(message: &proto::GetDocumentSymbols) -> Result<BufferId> {
1689        BufferId::new(message.buffer_id)
1690    }
1691}
1692
1693#[async_trait(?Send)]
1694impl LspCommand for GetSignatureHelp {
1695    type Response = Option<SignatureHelp>;
1696    type LspRequest = lsp::SignatureHelpRequest;
1697    type ProtoRequest = proto::GetSignatureHelp;
1698
1699    fn display_name(&self) -> &str {
1700        "Get signature help"
1701    }
1702
1703    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
1704        capabilities
1705            .server_capabilities
1706            .signature_help_provider
1707            .is_some()
1708    }
1709
1710    fn to_lsp(
1711        &self,
1712        path: &Path,
1713        _: &Buffer,
1714        _: &Arc<LanguageServer>,
1715        _cx: &App,
1716    ) -> Result<lsp::SignatureHelpParams> {
1717        Ok(lsp::SignatureHelpParams {
1718            text_document_position_params: make_lsp_text_document_position(path, self.position)?,
1719            context: None,
1720            work_done_progress_params: Default::default(),
1721        })
1722    }
1723
1724    async fn response_from_lsp(
1725        self,
1726        message: Option<lsp::SignatureHelp>,
1727        _: Entity<LspStore>,
1728        _: Entity<Buffer>,
1729        _: LanguageServerId,
1730        _: AsyncApp,
1731    ) -> Result<Self::Response> {
1732        Ok(message.and_then(SignatureHelp::new))
1733    }
1734
1735    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> Self::ProtoRequest {
1736        let offset = buffer.point_utf16_to_offset(self.position);
1737        proto::GetSignatureHelp {
1738            project_id,
1739            buffer_id: buffer.remote_id().to_proto(),
1740            position: Some(serialize_anchor(&buffer.anchor_after(offset))),
1741            version: serialize_version(&buffer.version()),
1742        }
1743    }
1744
1745    async fn from_proto(
1746        payload: Self::ProtoRequest,
1747        _: Entity<LspStore>,
1748        buffer: Entity<Buffer>,
1749        mut cx: AsyncApp,
1750    ) -> Result<Self> {
1751        buffer
1752            .update(&mut cx, |buffer, _| {
1753                buffer.wait_for_version(deserialize_version(&payload.version))
1754            })?
1755            .await
1756            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
1757        let buffer_snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot())?;
1758        Ok(Self {
1759            position: payload
1760                .position
1761                .and_then(deserialize_anchor)
1762                .context("invalid position")?
1763                .to_point_utf16(&buffer_snapshot),
1764        })
1765    }
1766
1767    fn response_to_proto(
1768        response: Self::Response,
1769        _: &mut LspStore,
1770        _: PeerId,
1771        _: &Global,
1772        _: &mut App,
1773    ) -> proto::GetSignatureHelpResponse {
1774        proto::GetSignatureHelpResponse {
1775            signature_help: response
1776                .map(|signature_help| lsp_to_proto_signature(signature_help.original_data)),
1777        }
1778    }
1779
1780    async fn response_from_proto(
1781        self,
1782        response: proto::GetSignatureHelpResponse,
1783        _: Entity<LspStore>,
1784        _: Entity<Buffer>,
1785        _: AsyncApp,
1786    ) -> Result<Self::Response> {
1787        Ok(response
1788            .signature_help
1789            .map(proto_to_lsp_signature)
1790            .and_then(SignatureHelp::new))
1791    }
1792
1793    fn buffer_id_from_proto(message: &Self::ProtoRequest) -> Result<BufferId> {
1794        BufferId::new(message.buffer_id)
1795    }
1796}
1797
1798#[async_trait(?Send)]
1799impl LspCommand for GetHover {
1800    type Response = Option<Hover>;
1801    type LspRequest = lsp::request::HoverRequest;
1802    type ProtoRequest = proto::GetHover;
1803
1804    fn display_name(&self) -> &str {
1805        "Get hover"
1806    }
1807
1808    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
1809        match capabilities.server_capabilities.hover_provider {
1810            Some(lsp::HoverProviderCapability::Simple(enabled)) => enabled,
1811            Some(lsp::HoverProviderCapability::Options(_)) => true,
1812            None => false,
1813        }
1814    }
1815
1816    fn to_lsp(
1817        &self,
1818        path: &Path,
1819        _: &Buffer,
1820        _: &Arc<LanguageServer>,
1821        _: &App,
1822    ) -> Result<lsp::HoverParams> {
1823        Ok(lsp::HoverParams {
1824            text_document_position_params: make_lsp_text_document_position(path, self.position)?,
1825            work_done_progress_params: Default::default(),
1826        })
1827    }
1828
1829    async fn response_from_lsp(
1830        self,
1831        message: Option<lsp::Hover>,
1832        _: Entity<LspStore>,
1833        buffer: Entity<Buffer>,
1834        _: LanguageServerId,
1835        mut cx: AsyncApp,
1836    ) -> Result<Self::Response> {
1837        let Some(hover) = message else {
1838            return Ok(None);
1839        };
1840
1841        let (language, range) = buffer.update(&mut cx, |buffer, _| {
1842            (
1843                buffer.language().cloned(),
1844                hover.range.map(|range| {
1845                    let token_start =
1846                        buffer.clip_point_utf16(point_from_lsp(range.start), Bias::Left);
1847                    let token_end = buffer.clip_point_utf16(point_from_lsp(range.end), Bias::Left);
1848                    buffer.anchor_after(token_start)..buffer.anchor_before(token_end)
1849                }),
1850            )
1851        })?;
1852
1853        fn hover_blocks_from_marked_string(marked_string: lsp::MarkedString) -> Option<HoverBlock> {
1854            let block = match marked_string {
1855                lsp::MarkedString::String(content) => HoverBlock {
1856                    text: content,
1857                    kind: HoverBlockKind::Markdown,
1858                },
1859                lsp::MarkedString::LanguageString(lsp::LanguageString { language, value }) => {
1860                    HoverBlock {
1861                        text: value,
1862                        kind: HoverBlockKind::Code { language },
1863                    }
1864                }
1865            };
1866            if block.text.is_empty() {
1867                None
1868            } else {
1869                Some(block)
1870            }
1871        }
1872
1873        let contents = match hover.contents {
1874            lsp::HoverContents::Scalar(marked_string) => {
1875                hover_blocks_from_marked_string(marked_string)
1876                    .into_iter()
1877                    .collect()
1878            }
1879            lsp::HoverContents::Array(marked_strings) => marked_strings
1880                .into_iter()
1881                .filter_map(hover_blocks_from_marked_string)
1882                .collect(),
1883            lsp::HoverContents::Markup(markup_content) => vec![HoverBlock {
1884                text: markup_content.value,
1885                kind: if markup_content.kind == lsp::MarkupKind::Markdown {
1886                    HoverBlockKind::Markdown
1887                } else {
1888                    HoverBlockKind::PlainText
1889                },
1890            }],
1891        };
1892
1893        Ok(Some(Hover {
1894            contents,
1895            range,
1896            language,
1897        }))
1898    }
1899
1900    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> Self::ProtoRequest {
1901        proto::GetHover {
1902            project_id,
1903            buffer_id: buffer.remote_id().into(),
1904            position: Some(language::proto::serialize_anchor(
1905                &buffer.anchor_before(self.position),
1906            )),
1907            version: serialize_version(&buffer.version),
1908        }
1909    }
1910
1911    async fn from_proto(
1912        message: Self::ProtoRequest,
1913        _: Entity<LspStore>,
1914        buffer: Entity<Buffer>,
1915        mut cx: AsyncApp,
1916    ) -> Result<Self> {
1917        let position = message
1918            .position
1919            .and_then(deserialize_anchor)
1920            .ok_or_else(|| anyhow!("invalid position"))?;
1921        buffer
1922            .update(&mut cx, |buffer, _| {
1923                buffer.wait_for_version(deserialize_version(&message.version))
1924            })?
1925            .await?;
1926        Ok(Self {
1927            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,
1928        })
1929    }
1930
1931    fn response_to_proto(
1932        response: Self::Response,
1933        _: &mut LspStore,
1934        _: PeerId,
1935        _: &clock::Global,
1936        _: &mut App,
1937    ) -> proto::GetHoverResponse {
1938        if let Some(response) = response {
1939            let (start, end) = if let Some(range) = response.range {
1940                (
1941                    Some(language::proto::serialize_anchor(&range.start)),
1942                    Some(language::proto::serialize_anchor(&range.end)),
1943                )
1944            } else {
1945                (None, None)
1946            };
1947
1948            let contents = response
1949                .contents
1950                .into_iter()
1951                .map(|block| proto::HoverBlock {
1952                    text: block.text,
1953                    is_markdown: block.kind == HoverBlockKind::Markdown,
1954                    language: if let HoverBlockKind::Code { language } = block.kind {
1955                        Some(language)
1956                    } else {
1957                        None
1958                    },
1959                })
1960                .collect();
1961
1962            proto::GetHoverResponse {
1963                start,
1964                end,
1965                contents,
1966            }
1967        } else {
1968            proto::GetHoverResponse {
1969                start: None,
1970                end: None,
1971                contents: Vec::new(),
1972            }
1973        }
1974    }
1975
1976    async fn response_from_proto(
1977        self,
1978        message: proto::GetHoverResponse,
1979        _: Entity<LspStore>,
1980        buffer: Entity<Buffer>,
1981        mut cx: AsyncApp,
1982    ) -> Result<Self::Response> {
1983        let contents: Vec<_> = message
1984            .contents
1985            .into_iter()
1986            .map(|block| HoverBlock {
1987                text: block.text,
1988                kind: if let Some(language) = block.language {
1989                    HoverBlockKind::Code { language }
1990                } else if block.is_markdown {
1991                    HoverBlockKind::Markdown
1992                } else {
1993                    HoverBlockKind::PlainText
1994                },
1995            })
1996            .collect();
1997        if contents.is_empty() {
1998            return Ok(None);
1999        }
2000
2001        let language = buffer.update(&mut cx, |buffer, _| buffer.language().cloned())?;
2002        let range = if let (Some(start), Some(end)) = (message.start, message.end) {
2003            language::proto::deserialize_anchor(start)
2004                .and_then(|start| language::proto::deserialize_anchor(end).map(|end| start..end))
2005        } else {
2006            None
2007        };
2008        if let Some(range) = range.as_ref() {
2009            buffer
2010                .update(&mut cx, |buffer, _| {
2011                    buffer.wait_for_anchors([range.start, range.end])
2012                })?
2013                .await?;
2014        }
2015
2016        Ok(Some(Hover {
2017            contents,
2018            range,
2019            language,
2020        }))
2021    }
2022
2023    fn buffer_id_from_proto(message: &Self::ProtoRequest) -> Result<BufferId> {
2024        BufferId::new(message.buffer_id)
2025    }
2026}
2027
2028#[async_trait(?Send)]
2029impl LspCommand for GetCompletions {
2030    type Response = Vec<CoreCompletion>;
2031    type LspRequest = lsp::request::Completion;
2032    type ProtoRequest = proto::GetCompletions;
2033
2034    fn display_name(&self) -> &str {
2035        "Get completion"
2036    }
2037
2038    fn to_lsp(
2039        &self,
2040        path: &Path,
2041        _: &Buffer,
2042        _: &Arc<LanguageServer>,
2043        _: &App,
2044    ) -> Result<lsp::CompletionParams> {
2045        Ok(lsp::CompletionParams {
2046            text_document_position: make_lsp_text_document_position(path, self.position)?,
2047            context: Some(self.context.clone()),
2048            work_done_progress_params: Default::default(),
2049            partial_result_params: Default::default(),
2050        })
2051    }
2052
2053    async fn response_from_lsp(
2054        self,
2055        completions: Option<lsp::CompletionResponse>,
2056        lsp_store: Entity<LspStore>,
2057        buffer: Entity<Buffer>,
2058        server_id: LanguageServerId,
2059        mut cx: AsyncApp,
2060    ) -> Result<Self::Response> {
2061        let mut response_list = None;
2062        let mut completions = if let Some(completions) = completions {
2063            match completions {
2064                lsp::CompletionResponse::Array(completions) => completions,
2065                lsp::CompletionResponse::List(mut list) => {
2066                    let items = std::mem::take(&mut list.items);
2067                    response_list = Some(list);
2068                    items
2069                }
2070            }
2071        } else {
2072            Vec::new()
2073        };
2074
2075        let language_server_adapter = lsp_store
2076            .update(&mut cx, |lsp_store, _| {
2077                lsp_store.language_server_adapter_for_id(server_id)
2078            })?
2079            .with_context(|| format!("no language server with id {server_id}"))?;
2080
2081        let lsp_defaults = response_list
2082            .as_ref()
2083            .and_then(|list| list.item_defaults.clone())
2084            .map(Arc::new);
2085
2086        let mut completion_edits = Vec::new();
2087        buffer.update(&mut cx, |buffer, _cx| {
2088            let snapshot = buffer.snapshot();
2089            let clipped_position = buffer.clip_point_utf16(Unclipped(self.position), Bias::Left);
2090
2091            let mut range_for_token = None;
2092            completions.retain(|lsp_completion| {
2093                let lsp_edit = lsp_completion.text_edit.clone().or_else(|| {
2094                    let default_text_edit = lsp_defaults.as_deref()?.edit_range.as_ref()?;
2095                    match default_text_edit {
2096                        CompletionListItemDefaultsEditRange::Range(range) => {
2097                            Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
2098                                range: *range,
2099                                new_text: lsp_completion.label.clone(),
2100                            }))
2101                        }
2102                        CompletionListItemDefaultsEditRange::InsertAndReplace {
2103                            insert,
2104                            replace,
2105                        } => Some(lsp::CompletionTextEdit::InsertAndReplace(
2106                            lsp::InsertReplaceEdit {
2107                                new_text: lsp_completion.label.clone(),
2108                                insert: *insert,
2109                                replace: *replace,
2110                            },
2111                        )),
2112                    }
2113                });
2114
2115                let edit = match lsp_edit {
2116                    // If the language server provides a range to overwrite, then
2117                    // check that the range is valid.
2118                    Some(completion_text_edit) => {
2119                        match parse_completion_text_edit(&completion_text_edit, &snapshot) {
2120                            Some(edit) => edit,
2121                            None => return false,
2122                        }
2123                    }
2124
2125                    // If the language server does not provide a range, then infer
2126                    // the range based on the syntax tree.
2127                    None => {
2128                        if self.position != clipped_position {
2129                            log::info!("completion out of expected range");
2130                            return false;
2131                        }
2132
2133                        let default_edit_range = lsp_defaults.as_ref().and_then(|lsp_defaults| {
2134                            lsp_defaults
2135                                .edit_range
2136                                .as_ref()
2137                                .and_then(|range| match range {
2138                                    CompletionListItemDefaultsEditRange::Range(r) => Some(r),
2139                                    _ => None,
2140                                })
2141                        });
2142
2143                        let range = if let Some(range) = default_edit_range {
2144                            let range = range_from_lsp(*range);
2145                            let start = snapshot.clip_point_utf16(range.start, Bias::Left);
2146                            let end = snapshot.clip_point_utf16(range.end, Bias::Left);
2147                            if start != range.start.0 || end != range.end.0 {
2148                                log::info!("completion out of expected range");
2149                                return false;
2150                            }
2151
2152                            snapshot.anchor_before(start)..snapshot.anchor_after(end)
2153                        } else {
2154                            range_for_token
2155                                .get_or_insert_with(|| {
2156                                    let offset = self.position.to_offset(&snapshot);
2157                                    let (range, kind) = snapshot.surrounding_word(offset);
2158                                    let range = if kind == Some(CharKind::Word) {
2159                                        range
2160                                    } else {
2161                                        offset..offset
2162                                    };
2163
2164                                    snapshot.anchor_before(range.start)
2165                                        ..snapshot.anchor_after(range.end)
2166                                })
2167                                .clone()
2168                        };
2169
2170                        let text = lsp_completion
2171                            .insert_text
2172                            .as_ref()
2173                            .unwrap_or(&lsp_completion.label)
2174                            .clone();
2175                        (range, text)
2176                    }
2177                };
2178
2179                completion_edits.push(edit);
2180                true
2181            });
2182        })?;
2183
2184        language_server_adapter
2185            .process_completions(&mut completions)
2186            .await;
2187
2188        Ok(completions
2189            .into_iter()
2190            .zip(completion_edits)
2191            .map(|(mut lsp_completion, (old_range, mut new_text))| {
2192                LineEnding::normalize(&mut new_text);
2193                if lsp_completion.data.is_none() {
2194                    if let Some(default_data) = lsp_defaults
2195                        .as_ref()
2196                        .and_then(|item_defaults| item_defaults.data.clone())
2197                    {
2198                        // Servers (e.g. JDTLS) prefer unchanged completions, when resolving the items later,
2199                        // so we do not insert the defaults here, but `data` is needed for resolving, so this is an exception.
2200                        lsp_completion.data = Some(default_data);
2201                    }
2202                }
2203                CoreCompletion {
2204                    old_range,
2205                    new_text,
2206                    source: CompletionSource::Lsp {
2207                        server_id,
2208                        lsp_completion: Box::new(lsp_completion),
2209                        lsp_defaults: lsp_defaults.clone(),
2210                        resolved: false,
2211                    },
2212                }
2213            })
2214            .collect())
2215    }
2216
2217    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetCompletions {
2218        let anchor = buffer.anchor_after(self.position);
2219        proto::GetCompletions {
2220            project_id,
2221            buffer_id: buffer.remote_id().into(),
2222            position: Some(language::proto::serialize_anchor(&anchor)),
2223            version: serialize_version(&buffer.version()),
2224        }
2225    }
2226
2227    async fn from_proto(
2228        message: proto::GetCompletions,
2229        _: Entity<LspStore>,
2230        buffer: Entity<Buffer>,
2231        mut cx: AsyncApp,
2232    ) -> Result<Self> {
2233        let version = deserialize_version(&message.version);
2234        buffer
2235            .update(&mut cx, |buffer, _| buffer.wait_for_version(version))?
2236            .await?;
2237        let position = message
2238            .position
2239            .and_then(language::proto::deserialize_anchor)
2240            .map(|p| {
2241                buffer.update(&mut cx, |buffer, _| {
2242                    buffer.clip_point_utf16(Unclipped(p.to_point_utf16(buffer)), Bias::Left)
2243                })
2244            })
2245            .ok_or_else(|| anyhow!("invalid position"))??;
2246        Ok(Self {
2247            position,
2248            context: CompletionContext {
2249                trigger_kind: CompletionTriggerKind::INVOKED,
2250                trigger_character: None,
2251            },
2252        })
2253    }
2254
2255    fn response_to_proto(
2256        completions: Vec<CoreCompletion>,
2257        _: &mut LspStore,
2258        _: PeerId,
2259        buffer_version: &clock::Global,
2260        _: &mut App,
2261    ) -> proto::GetCompletionsResponse {
2262        proto::GetCompletionsResponse {
2263            completions: completions
2264                .iter()
2265                .map(LspStore::serialize_completion)
2266                .collect(),
2267            version: serialize_version(buffer_version),
2268        }
2269    }
2270
2271    async fn response_from_proto(
2272        self,
2273        message: proto::GetCompletionsResponse,
2274        _project: Entity<LspStore>,
2275        buffer: Entity<Buffer>,
2276        mut cx: AsyncApp,
2277    ) -> Result<Self::Response> {
2278        buffer
2279            .update(&mut cx, |buffer, _| {
2280                buffer.wait_for_version(deserialize_version(&message.version))
2281            })?
2282            .await?;
2283
2284        message
2285            .completions
2286            .into_iter()
2287            .map(LspStore::deserialize_completion)
2288            .collect()
2289    }
2290
2291    fn buffer_id_from_proto(message: &proto::GetCompletions) -> Result<BufferId> {
2292        BufferId::new(message.buffer_id)
2293    }
2294}
2295
2296pub(crate) fn parse_completion_text_edit(
2297    edit: &lsp::CompletionTextEdit,
2298    snapshot: &BufferSnapshot,
2299) -> Option<(Range<Anchor>, String)> {
2300    match edit {
2301        lsp::CompletionTextEdit::Edit(edit) => {
2302            let range = range_from_lsp(edit.range);
2303            let start = snapshot.clip_point_utf16(range.start, Bias::Left);
2304            let end = snapshot.clip_point_utf16(range.end, Bias::Left);
2305            if start != range.start.0 || end != range.end.0 {
2306                log::info!("completion out of expected range");
2307                None
2308            } else {
2309                Some((
2310                    snapshot.anchor_before(start)..snapshot.anchor_after(end),
2311                    edit.new_text.clone(),
2312                ))
2313            }
2314        }
2315
2316        lsp::CompletionTextEdit::InsertAndReplace(edit) => {
2317            let range = range_from_lsp(edit.replace);
2318
2319            let start = snapshot.clip_point_utf16(range.start, Bias::Left);
2320            let end = snapshot.clip_point_utf16(range.end, Bias::Left);
2321            if start != range.start.0 || end != range.end.0 {
2322                log::info!("completion out of expected range");
2323                None
2324            } else {
2325                Some((
2326                    snapshot.anchor_before(start)..snapshot.anchor_after(end),
2327                    edit.new_text.clone(),
2328                ))
2329            }
2330        }
2331    }
2332}
2333
2334#[async_trait(?Send)]
2335impl LspCommand for GetCodeActions {
2336    type Response = Vec<CodeAction>;
2337    type LspRequest = lsp::request::CodeActionRequest;
2338    type ProtoRequest = proto::GetCodeActions;
2339
2340    fn display_name(&self) -> &str {
2341        "Get code actions"
2342    }
2343
2344    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
2345        match &capabilities.server_capabilities.code_action_provider {
2346            None => false,
2347            Some(lsp::CodeActionProviderCapability::Simple(false)) => false,
2348            _ => {
2349                // If we do know that we want specific code actions AND we know that
2350                // the server only supports specific code actions, then we want to filter
2351                // down to the ones that are supported.
2352                if let Some((requested, supported)) = self
2353                    .kinds
2354                    .as_ref()
2355                    .zip(Self::supported_code_action_kinds(capabilities))
2356                {
2357                    let server_supported = supported.into_iter().collect::<HashSet<_>>();
2358                    requested.iter().any(|kind| server_supported.contains(kind))
2359                } else {
2360                    true
2361                }
2362            }
2363        }
2364    }
2365
2366    fn to_lsp(
2367        &self,
2368        path: &Path,
2369        buffer: &Buffer,
2370        language_server: &Arc<LanguageServer>,
2371        _: &App,
2372    ) -> Result<lsp::CodeActionParams> {
2373        let mut relevant_diagnostics = Vec::new();
2374        for entry in buffer
2375            .snapshot()
2376            .diagnostics_in_range::<_, language::PointUtf16>(self.range.clone(), false)
2377        {
2378            relevant_diagnostics.push(entry.to_lsp_diagnostic_stub()?);
2379        }
2380
2381        let supported =
2382            Self::supported_code_action_kinds(language_server.adapter_server_capabilities());
2383
2384        let only = if let Some(requested) = &self.kinds {
2385            if let Some(supported_kinds) = supported {
2386                let server_supported = supported_kinds.into_iter().collect::<HashSet<_>>();
2387
2388                let filtered = requested
2389                    .iter()
2390                    .filter(|kind| server_supported.contains(kind))
2391                    .cloned()
2392                    .collect();
2393                Some(filtered)
2394            } else {
2395                Some(requested.clone())
2396            }
2397        } else {
2398            supported
2399        };
2400
2401        Ok(lsp::CodeActionParams {
2402            text_document: make_text_document_identifier(path)?,
2403            range: range_to_lsp(self.range.to_point_utf16(buffer))?,
2404            work_done_progress_params: Default::default(),
2405            partial_result_params: Default::default(),
2406            context: lsp::CodeActionContext {
2407                diagnostics: relevant_diagnostics,
2408                only,
2409                ..lsp::CodeActionContext::default()
2410            },
2411        })
2412    }
2413
2414    async fn response_from_lsp(
2415        self,
2416        actions: Option<lsp::CodeActionResponse>,
2417        lsp_store: Entity<LspStore>,
2418        _: Entity<Buffer>,
2419        server_id: LanguageServerId,
2420        cx: AsyncApp,
2421    ) -> Result<Vec<CodeAction>> {
2422        let requested_kinds_set = if let Some(kinds) = self.kinds {
2423            Some(kinds.into_iter().collect::<HashSet<_>>())
2424        } else {
2425            None
2426        };
2427
2428        let language_server = cx.update(|cx| {
2429            lsp_store
2430                .read(cx)
2431                .language_server_for_id(server_id)
2432                .with_context(|| {
2433                    format!("Missing the language server that just returned a response {server_id}")
2434                })
2435        })??;
2436
2437        let server_capabilities = language_server.capabilities();
2438        let available_commands = server_capabilities
2439            .execute_command_provider
2440            .as_ref()
2441            .map(|options| options.commands.as_slice())
2442            .unwrap_or_default();
2443        Ok(actions
2444            .unwrap_or_default()
2445            .into_iter()
2446            .filter_map(|entry| {
2447                let (lsp_action, resolved) = match entry {
2448                    lsp::CodeActionOrCommand::CodeAction(lsp_action) => {
2449                        if let Some(command) = lsp_action.command.as_ref() {
2450                            if !available_commands.contains(&command.command) {
2451                                return None;
2452                            }
2453                        }
2454                        (LspAction::Action(Box::new(lsp_action)), false)
2455                    }
2456                    lsp::CodeActionOrCommand::Command(command) => {
2457                        if available_commands.contains(&command.command) {
2458                            (LspAction::Command(command), true)
2459                        } else {
2460                            return None;
2461                        }
2462                    }
2463                };
2464
2465                if let Some((requested_kinds, kind)) =
2466                    requested_kinds_set.as_ref().zip(lsp_action.action_kind())
2467                {
2468                    if !requested_kinds.contains(&kind) {
2469                        return None;
2470                    }
2471                }
2472
2473                Some(CodeAction {
2474                    server_id,
2475                    range: self.range.clone(),
2476                    lsp_action,
2477                    resolved,
2478                })
2479            })
2480            .collect())
2481    }
2482
2483    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetCodeActions {
2484        proto::GetCodeActions {
2485            project_id,
2486            buffer_id: buffer.remote_id().into(),
2487            start: Some(language::proto::serialize_anchor(&self.range.start)),
2488            end: Some(language::proto::serialize_anchor(&self.range.end)),
2489            version: serialize_version(&buffer.version()),
2490        }
2491    }
2492
2493    async fn from_proto(
2494        message: proto::GetCodeActions,
2495        _: Entity<LspStore>,
2496        buffer: Entity<Buffer>,
2497        mut cx: AsyncApp,
2498    ) -> Result<Self> {
2499        let start = message
2500            .start
2501            .and_then(language::proto::deserialize_anchor)
2502            .ok_or_else(|| anyhow!("invalid start"))?;
2503        let end = message
2504            .end
2505            .and_then(language::proto::deserialize_anchor)
2506            .ok_or_else(|| anyhow!("invalid end"))?;
2507        buffer
2508            .update(&mut cx, |buffer, _| {
2509                buffer.wait_for_version(deserialize_version(&message.version))
2510            })?
2511            .await?;
2512
2513        Ok(Self {
2514            range: start..end,
2515            kinds: None,
2516        })
2517    }
2518
2519    fn response_to_proto(
2520        code_actions: Vec<CodeAction>,
2521        _: &mut LspStore,
2522        _: PeerId,
2523        buffer_version: &clock::Global,
2524        _: &mut App,
2525    ) -> proto::GetCodeActionsResponse {
2526        proto::GetCodeActionsResponse {
2527            actions: code_actions
2528                .iter()
2529                .map(LspStore::serialize_code_action)
2530                .collect(),
2531            version: serialize_version(buffer_version),
2532        }
2533    }
2534
2535    async fn response_from_proto(
2536        self,
2537        message: proto::GetCodeActionsResponse,
2538        _: Entity<LspStore>,
2539        buffer: Entity<Buffer>,
2540        mut cx: AsyncApp,
2541    ) -> Result<Vec<CodeAction>> {
2542        buffer
2543            .update(&mut cx, |buffer, _| {
2544                buffer.wait_for_version(deserialize_version(&message.version))
2545            })?
2546            .await?;
2547        message
2548            .actions
2549            .into_iter()
2550            .map(LspStore::deserialize_code_action)
2551            .collect()
2552    }
2553
2554    fn buffer_id_from_proto(message: &proto::GetCodeActions) -> Result<BufferId> {
2555        BufferId::new(message.buffer_id)
2556    }
2557}
2558
2559impl GetCodeActions {
2560    fn supported_code_action_kinds(
2561        capabilities: AdapterServerCapabilities,
2562    ) -> Option<Vec<CodeActionKind>> {
2563        match capabilities.server_capabilities.code_action_provider {
2564            Some(lsp::CodeActionProviderCapability::Options(CodeActionOptions {
2565                code_action_kinds: Some(supported_action_kinds),
2566                ..
2567            })) => Some(supported_action_kinds.clone()),
2568            _ => capabilities.code_action_kinds,
2569        }
2570    }
2571
2572    pub fn can_resolve_actions(capabilities: &ServerCapabilities) -> bool {
2573        capabilities
2574            .code_action_provider
2575            .as_ref()
2576            .and_then(|options| match options {
2577                lsp::CodeActionProviderCapability::Simple(_is_supported) => None,
2578                lsp::CodeActionProviderCapability::Options(options) => options.resolve_provider,
2579            })
2580            .unwrap_or(false)
2581    }
2582}
2583
2584#[async_trait(?Send)]
2585impl LspCommand for OnTypeFormatting {
2586    type Response = Option<Transaction>;
2587    type LspRequest = lsp::request::OnTypeFormatting;
2588    type ProtoRequest = proto::OnTypeFormatting;
2589
2590    fn display_name(&self) -> &str {
2591        "Formatting on typing"
2592    }
2593
2594    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
2595        let Some(on_type_formatting_options) = &capabilities
2596            .server_capabilities
2597            .document_on_type_formatting_provider
2598        else {
2599            return false;
2600        };
2601        on_type_formatting_options
2602            .first_trigger_character
2603            .contains(&self.trigger)
2604            || on_type_formatting_options
2605                .more_trigger_character
2606                .iter()
2607                .flatten()
2608                .any(|chars| chars.contains(&self.trigger))
2609    }
2610
2611    fn to_lsp(
2612        &self,
2613        path: &Path,
2614        _: &Buffer,
2615        _: &Arc<LanguageServer>,
2616        _: &App,
2617    ) -> Result<lsp::DocumentOnTypeFormattingParams> {
2618        Ok(lsp::DocumentOnTypeFormattingParams {
2619            text_document_position: make_lsp_text_document_position(path, self.position)?,
2620            ch: self.trigger.clone(),
2621            options: self.options.clone(),
2622        })
2623    }
2624
2625    async fn response_from_lsp(
2626        self,
2627        message: Option<Vec<lsp::TextEdit>>,
2628        lsp_store: Entity<LspStore>,
2629        buffer: Entity<Buffer>,
2630        server_id: LanguageServerId,
2631        mut cx: AsyncApp,
2632    ) -> Result<Option<Transaction>> {
2633        if let Some(edits) = message {
2634            let (lsp_adapter, lsp_server) =
2635                language_server_for_buffer(&lsp_store, &buffer, server_id, &mut cx)?;
2636            LocalLspStore::deserialize_text_edits(
2637                lsp_store,
2638                buffer,
2639                edits,
2640                self.push_to_history,
2641                lsp_adapter,
2642                lsp_server,
2643                &mut cx,
2644            )
2645            .await
2646        } else {
2647            Ok(None)
2648        }
2649    }
2650
2651    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::OnTypeFormatting {
2652        proto::OnTypeFormatting {
2653            project_id,
2654            buffer_id: buffer.remote_id().into(),
2655            position: Some(language::proto::serialize_anchor(
2656                &buffer.anchor_before(self.position),
2657            )),
2658            trigger: self.trigger.clone(),
2659            version: serialize_version(&buffer.version()),
2660        }
2661    }
2662
2663    async fn from_proto(
2664        message: proto::OnTypeFormatting,
2665        _: Entity<LspStore>,
2666        buffer: Entity<Buffer>,
2667        mut cx: AsyncApp,
2668    ) -> Result<Self> {
2669        let position = message
2670            .position
2671            .and_then(deserialize_anchor)
2672            .ok_or_else(|| anyhow!("invalid position"))?;
2673        buffer
2674            .update(&mut cx, |buffer, _| {
2675                buffer.wait_for_version(deserialize_version(&message.version))
2676            })?
2677            .await?;
2678
2679        let options = buffer.update(&mut cx, |buffer, cx| {
2680            lsp_formatting_options(
2681                language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx).as_ref(),
2682            )
2683        })?;
2684
2685        Ok(Self {
2686            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,
2687            trigger: message.trigger.clone(),
2688            options,
2689            push_to_history: false,
2690        })
2691    }
2692
2693    fn response_to_proto(
2694        response: Option<Transaction>,
2695        _: &mut LspStore,
2696        _: PeerId,
2697        _: &clock::Global,
2698        _: &mut App,
2699    ) -> proto::OnTypeFormattingResponse {
2700        proto::OnTypeFormattingResponse {
2701            transaction: response
2702                .map(|transaction| language::proto::serialize_transaction(&transaction)),
2703        }
2704    }
2705
2706    async fn response_from_proto(
2707        self,
2708        message: proto::OnTypeFormattingResponse,
2709        _: Entity<LspStore>,
2710        _: Entity<Buffer>,
2711        _: AsyncApp,
2712    ) -> Result<Option<Transaction>> {
2713        let Some(transaction) = message.transaction else {
2714            return Ok(None);
2715        };
2716        Ok(Some(language::proto::deserialize_transaction(transaction)?))
2717    }
2718
2719    fn buffer_id_from_proto(message: &proto::OnTypeFormatting) -> Result<BufferId> {
2720        BufferId::new(message.buffer_id)
2721    }
2722}
2723
2724impl InlayHints {
2725    pub async fn lsp_to_project_hint(
2726        lsp_hint: lsp::InlayHint,
2727        buffer_handle: &Entity<Buffer>,
2728        server_id: LanguageServerId,
2729        resolve_state: ResolveState,
2730        force_no_type_left_padding: bool,
2731        cx: &mut AsyncApp,
2732    ) -> anyhow::Result<InlayHint> {
2733        let kind = lsp_hint.kind.and_then(|kind| match kind {
2734            lsp::InlayHintKind::TYPE => Some(InlayHintKind::Type),
2735            lsp::InlayHintKind::PARAMETER => Some(InlayHintKind::Parameter),
2736            _ => None,
2737        });
2738
2739        let position = buffer_handle.update(cx, |buffer, _| {
2740            let position = buffer.clip_point_utf16(point_from_lsp(lsp_hint.position), Bias::Left);
2741            if kind == Some(InlayHintKind::Parameter) {
2742                buffer.anchor_before(position)
2743            } else {
2744                buffer.anchor_after(position)
2745            }
2746        })?;
2747        let label = Self::lsp_inlay_label_to_project(lsp_hint.label, server_id)
2748            .await
2749            .context("lsp to project inlay hint conversion")?;
2750        let padding_left = if force_no_type_left_padding && kind == Some(InlayHintKind::Type) {
2751            false
2752        } else {
2753            lsp_hint.padding_left.unwrap_or(false)
2754        };
2755
2756        Ok(InlayHint {
2757            position,
2758            padding_left,
2759            padding_right: lsp_hint.padding_right.unwrap_or(false),
2760            label,
2761            kind,
2762            tooltip: lsp_hint.tooltip.map(|tooltip| match tooltip {
2763                lsp::InlayHintTooltip::String(s) => InlayHintTooltip::String(s),
2764                lsp::InlayHintTooltip::MarkupContent(markup_content) => {
2765                    InlayHintTooltip::MarkupContent(MarkupContent {
2766                        kind: match markup_content.kind {
2767                            lsp::MarkupKind::PlainText => HoverBlockKind::PlainText,
2768                            lsp::MarkupKind::Markdown => HoverBlockKind::Markdown,
2769                        },
2770                        value: markup_content.value,
2771                    })
2772                }
2773            }),
2774            resolve_state,
2775        })
2776    }
2777
2778    async fn lsp_inlay_label_to_project(
2779        lsp_label: lsp::InlayHintLabel,
2780        server_id: LanguageServerId,
2781    ) -> anyhow::Result<InlayHintLabel> {
2782        let label = match lsp_label {
2783            lsp::InlayHintLabel::String(s) => InlayHintLabel::String(s),
2784            lsp::InlayHintLabel::LabelParts(lsp_parts) => {
2785                let mut parts = Vec::with_capacity(lsp_parts.len());
2786                for lsp_part in lsp_parts {
2787                    parts.push(InlayHintLabelPart {
2788                        value: lsp_part.value,
2789                        tooltip: lsp_part.tooltip.map(|tooltip| match tooltip {
2790                            lsp::InlayHintLabelPartTooltip::String(s) => {
2791                                InlayHintLabelPartTooltip::String(s)
2792                            }
2793                            lsp::InlayHintLabelPartTooltip::MarkupContent(markup_content) => {
2794                                InlayHintLabelPartTooltip::MarkupContent(MarkupContent {
2795                                    kind: match markup_content.kind {
2796                                        lsp::MarkupKind::PlainText => HoverBlockKind::PlainText,
2797                                        lsp::MarkupKind::Markdown => HoverBlockKind::Markdown,
2798                                    },
2799                                    value: markup_content.value,
2800                                })
2801                            }
2802                        }),
2803                        location: Some(server_id).zip(lsp_part.location),
2804                    });
2805                }
2806                InlayHintLabel::LabelParts(parts)
2807            }
2808        };
2809
2810        Ok(label)
2811    }
2812
2813    pub fn project_to_proto_hint(response_hint: InlayHint) -> proto::InlayHint {
2814        let (state, lsp_resolve_state) = match response_hint.resolve_state {
2815            ResolveState::Resolved => (0, None),
2816            ResolveState::CanResolve(server_id, resolve_data) => (
2817                1,
2818                Some(proto::resolve_state::LspResolveState {
2819                    server_id: server_id.0 as u64,
2820                    value: resolve_data.map(|json_data| {
2821                        serde_json::to_string(&json_data)
2822                            .expect("failed to serialize resolve json data")
2823                    }),
2824                }),
2825            ),
2826            ResolveState::Resolving => (2, None),
2827        };
2828        let resolve_state = Some(proto::ResolveState {
2829            state,
2830            lsp_resolve_state,
2831        });
2832        proto::InlayHint {
2833            position: Some(language::proto::serialize_anchor(&response_hint.position)),
2834            padding_left: response_hint.padding_left,
2835            padding_right: response_hint.padding_right,
2836            label: Some(proto::InlayHintLabel {
2837                label: Some(match response_hint.label {
2838                    InlayHintLabel::String(s) => proto::inlay_hint_label::Label::Value(s),
2839                    InlayHintLabel::LabelParts(label_parts) => {
2840                        proto::inlay_hint_label::Label::LabelParts(proto::InlayHintLabelParts {
2841                            parts: label_parts.into_iter().map(|label_part| {
2842                                let location_url = label_part.location.as_ref().map(|(_, location)| location.uri.to_string());
2843                                let location_range_start = label_part.location.as_ref().map(|(_, location)| point_from_lsp(location.range.start).0).map(|point| proto::PointUtf16 { row: point.row, column: point.column });
2844                                let location_range_end = label_part.location.as_ref().map(|(_, location)| point_from_lsp(location.range.end).0).map(|point| proto::PointUtf16 { row: point.row, column: point.column });
2845                                proto::InlayHintLabelPart {
2846                                value: label_part.value,
2847                                tooltip: label_part.tooltip.map(|tooltip| {
2848                                    let proto_tooltip = match tooltip {
2849                                        InlayHintLabelPartTooltip::String(s) => proto::inlay_hint_label_part_tooltip::Content::Value(s),
2850                                        InlayHintLabelPartTooltip::MarkupContent(markup_content) => proto::inlay_hint_label_part_tooltip::Content::MarkupContent(proto::MarkupContent {
2851                                            is_markdown: markup_content.kind == HoverBlockKind::Markdown,
2852                                            value: markup_content.value,
2853                                        }),
2854                                    };
2855                                    proto::InlayHintLabelPartTooltip {content: Some(proto_tooltip)}
2856                                }),
2857                                location_url,
2858                                location_range_start,
2859                                location_range_end,
2860                                language_server_id: label_part.location.as_ref().map(|(server_id, _)| server_id.0 as u64),
2861                            }}).collect()
2862                        })
2863                    }
2864                }),
2865            }),
2866            kind: response_hint.kind.map(|kind| kind.name().to_string()),
2867            tooltip: response_hint.tooltip.map(|response_tooltip| {
2868                let proto_tooltip = match response_tooltip {
2869                    InlayHintTooltip::String(s) => proto::inlay_hint_tooltip::Content::Value(s),
2870                    InlayHintTooltip::MarkupContent(markup_content) => {
2871                        proto::inlay_hint_tooltip::Content::MarkupContent(proto::MarkupContent {
2872                            is_markdown: markup_content.kind == HoverBlockKind::Markdown,
2873                            value: markup_content.value,
2874                        })
2875                    }
2876                };
2877                proto::InlayHintTooltip {
2878                    content: Some(proto_tooltip),
2879                }
2880            }),
2881            resolve_state,
2882        }
2883    }
2884
2885    pub fn proto_to_project_hint(message_hint: proto::InlayHint) -> anyhow::Result<InlayHint> {
2886        let resolve_state = message_hint.resolve_state.as_ref().unwrap_or_else(|| {
2887            panic!("incorrect proto inlay hint message: no resolve state in hint {message_hint:?}",)
2888        });
2889        let resolve_state_data = resolve_state
2890            .lsp_resolve_state.as_ref()
2891            .map(|lsp_resolve_state| {
2892                let value = lsp_resolve_state.value.as_deref().map(|value| {
2893                    serde_json::from_str::<Option<lsp::LSPAny>>(value)
2894                        .with_context(|| format!("incorrect proto inlay hint message: non-json resolve state {lsp_resolve_state:?}"))
2895                }).transpose()?.flatten();
2896                anyhow::Ok((LanguageServerId(lsp_resolve_state.server_id as usize), value))
2897            })
2898            .transpose()?;
2899        let resolve_state = match resolve_state.state {
2900            0 => ResolveState::Resolved,
2901            1 => {
2902                let (server_id, lsp_resolve_state) = resolve_state_data.with_context(|| {
2903                    format!(
2904                        "No lsp resolve data for the hint that can be resolved: {message_hint:?}"
2905                    )
2906                })?;
2907                ResolveState::CanResolve(server_id, lsp_resolve_state)
2908            }
2909            2 => ResolveState::Resolving,
2910            invalid => {
2911                anyhow::bail!("Unexpected resolve state {invalid} for hint {message_hint:?}")
2912            }
2913        };
2914        Ok(InlayHint {
2915            position: message_hint
2916                .position
2917                .and_then(language::proto::deserialize_anchor)
2918                .context("invalid position")?,
2919            label: match message_hint
2920                .label
2921                .and_then(|label| label.label)
2922                .context("missing label")?
2923            {
2924                proto::inlay_hint_label::Label::Value(s) => InlayHintLabel::String(s),
2925                proto::inlay_hint_label::Label::LabelParts(parts) => {
2926                    let mut label_parts = Vec::new();
2927                    for part in parts.parts {
2928                        label_parts.push(InlayHintLabelPart {
2929                            value: part.value,
2930                            tooltip: part.tooltip.map(|tooltip| match tooltip.content {
2931                                Some(proto::inlay_hint_label_part_tooltip::Content::Value(s)) => {
2932                                    InlayHintLabelPartTooltip::String(s)
2933                                }
2934                                Some(
2935                                    proto::inlay_hint_label_part_tooltip::Content::MarkupContent(
2936                                        markup_content,
2937                                    ),
2938                                ) => InlayHintLabelPartTooltip::MarkupContent(MarkupContent {
2939                                    kind: if markup_content.is_markdown {
2940                                        HoverBlockKind::Markdown
2941                                    } else {
2942                                        HoverBlockKind::PlainText
2943                                    },
2944                                    value: markup_content.value,
2945                                }),
2946                                None => InlayHintLabelPartTooltip::String(String::new()),
2947                            }),
2948                            location: {
2949                                match part
2950                                    .location_url
2951                                    .zip(
2952                                        part.location_range_start.and_then(|start| {
2953                                            Some(start..part.location_range_end?)
2954                                        }),
2955                                    )
2956                                    .zip(part.language_server_id)
2957                                {
2958                                    Some(((uri, range), server_id)) => Some((
2959                                        LanguageServerId(server_id as usize),
2960                                        lsp::Location {
2961                                            uri: lsp::Url::parse(&uri)
2962                                                .context("invalid uri in hint part {part:?}")?,
2963                                            range: lsp::Range::new(
2964                                                point_to_lsp(PointUtf16::new(
2965                                                    range.start.row,
2966                                                    range.start.column,
2967                                                )),
2968                                                point_to_lsp(PointUtf16::new(
2969                                                    range.end.row,
2970                                                    range.end.column,
2971                                                )),
2972                                            ),
2973                                        },
2974                                    )),
2975                                    None => None,
2976                                }
2977                            },
2978                        });
2979                    }
2980
2981                    InlayHintLabel::LabelParts(label_parts)
2982                }
2983            },
2984            padding_left: message_hint.padding_left,
2985            padding_right: message_hint.padding_right,
2986            kind: message_hint
2987                .kind
2988                .as_deref()
2989                .and_then(InlayHintKind::from_name),
2990            tooltip: message_hint.tooltip.and_then(|tooltip| {
2991                Some(match tooltip.content? {
2992                    proto::inlay_hint_tooltip::Content::Value(s) => InlayHintTooltip::String(s),
2993                    proto::inlay_hint_tooltip::Content::MarkupContent(markup_content) => {
2994                        InlayHintTooltip::MarkupContent(MarkupContent {
2995                            kind: if markup_content.is_markdown {
2996                                HoverBlockKind::Markdown
2997                            } else {
2998                                HoverBlockKind::PlainText
2999                            },
3000                            value: markup_content.value,
3001                        })
3002                    }
3003                })
3004            }),
3005            resolve_state,
3006        })
3007    }
3008
3009    pub fn project_to_lsp_hint(hint: InlayHint, snapshot: &BufferSnapshot) -> lsp::InlayHint {
3010        lsp::InlayHint {
3011            position: point_to_lsp(hint.position.to_point_utf16(snapshot)),
3012            kind: hint.kind.map(|kind| match kind {
3013                InlayHintKind::Type => lsp::InlayHintKind::TYPE,
3014                InlayHintKind::Parameter => lsp::InlayHintKind::PARAMETER,
3015            }),
3016            text_edits: None,
3017            tooltip: hint.tooltip.and_then(|tooltip| {
3018                Some(match tooltip {
3019                    InlayHintTooltip::String(s) => lsp::InlayHintTooltip::String(s),
3020                    InlayHintTooltip::MarkupContent(markup_content) => {
3021                        lsp::InlayHintTooltip::MarkupContent(lsp::MarkupContent {
3022                            kind: match markup_content.kind {
3023                                HoverBlockKind::PlainText => lsp::MarkupKind::PlainText,
3024                                HoverBlockKind::Markdown => lsp::MarkupKind::Markdown,
3025                                HoverBlockKind::Code { .. } => return None,
3026                            },
3027                            value: markup_content.value,
3028                        })
3029                    }
3030                })
3031            }),
3032            label: match hint.label {
3033                InlayHintLabel::String(s) => lsp::InlayHintLabel::String(s),
3034                InlayHintLabel::LabelParts(label_parts) => lsp::InlayHintLabel::LabelParts(
3035                    label_parts
3036                        .into_iter()
3037                        .map(|part| lsp::InlayHintLabelPart {
3038                            value: part.value,
3039                            tooltip: part.tooltip.and_then(|tooltip| {
3040                                Some(match tooltip {
3041                                    InlayHintLabelPartTooltip::String(s) => {
3042                                        lsp::InlayHintLabelPartTooltip::String(s)
3043                                    }
3044                                    InlayHintLabelPartTooltip::MarkupContent(markup_content) => {
3045                                        lsp::InlayHintLabelPartTooltip::MarkupContent(
3046                                            lsp::MarkupContent {
3047                                                kind: match markup_content.kind {
3048                                                    HoverBlockKind::PlainText => {
3049                                                        lsp::MarkupKind::PlainText
3050                                                    }
3051                                                    HoverBlockKind::Markdown => {
3052                                                        lsp::MarkupKind::Markdown
3053                                                    }
3054                                                    HoverBlockKind::Code { .. } => return None,
3055                                                },
3056                                                value: markup_content.value,
3057                                            },
3058                                        )
3059                                    }
3060                                })
3061                            }),
3062                            location: part.location.map(|(_, location)| location),
3063                            command: None,
3064                        })
3065                        .collect(),
3066                ),
3067            },
3068            padding_left: Some(hint.padding_left),
3069            padding_right: Some(hint.padding_right),
3070            data: match hint.resolve_state {
3071                ResolveState::CanResolve(_, data) => data,
3072                ResolveState::Resolving | ResolveState::Resolved => None,
3073            },
3074        }
3075    }
3076
3077    pub fn can_resolve_inlays(capabilities: &ServerCapabilities) -> bool {
3078        capabilities
3079            .inlay_hint_provider
3080            .as_ref()
3081            .and_then(|options| match options {
3082                OneOf::Left(_is_supported) => None,
3083                OneOf::Right(capabilities) => match capabilities {
3084                    lsp::InlayHintServerCapabilities::Options(o) => o.resolve_provider,
3085                    lsp::InlayHintServerCapabilities::RegistrationOptions(o) => {
3086                        o.inlay_hint_options.resolve_provider
3087                    }
3088                },
3089            })
3090            .unwrap_or(false)
3091    }
3092}
3093
3094#[async_trait(?Send)]
3095impl LspCommand for InlayHints {
3096    type Response = Vec<InlayHint>;
3097    type LspRequest = lsp::InlayHintRequest;
3098    type ProtoRequest = proto::InlayHints;
3099
3100    fn display_name(&self) -> &str {
3101        "Inlay hints"
3102    }
3103
3104    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
3105        let Some(inlay_hint_provider) = &capabilities.server_capabilities.inlay_hint_provider
3106        else {
3107            return false;
3108        };
3109        match inlay_hint_provider {
3110            lsp::OneOf::Left(enabled) => *enabled,
3111            lsp::OneOf::Right(inlay_hint_capabilities) => match inlay_hint_capabilities {
3112                lsp::InlayHintServerCapabilities::Options(_) => true,
3113                lsp::InlayHintServerCapabilities::RegistrationOptions(_) => false,
3114            },
3115        }
3116    }
3117
3118    fn to_lsp(
3119        &self,
3120        path: &Path,
3121        buffer: &Buffer,
3122        _: &Arc<LanguageServer>,
3123        _: &App,
3124    ) -> Result<lsp::InlayHintParams> {
3125        Ok(lsp::InlayHintParams {
3126            text_document: lsp::TextDocumentIdentifier {
3127                uri: file_path_to_lsp_url(path)?,
3128            },
3129            range: range_to_lsp(self.range.to_point_utf16(buffer))?,
3130            work_done_progress_params: Default::default(),
3131        })
3132    }
3133
3134    async fn response_from_lsp(
3135        self,
3136        message: Option<Vec<lsp::InlayHint>>,
3137        lsp_store: Entity<LspStore>,
3138        buffer: Entity<Buffer>,
3139        server_id: LanguageServerId,
3140        mut cx: AsyncApp,
3141    ) -> anyhow::Result<Vec<InlayHint>> {
3142        let (lsp_adapter, lsp_server) =
3143            language_server_for_buffer(&lsp_store, &buffer, server_id, &mut cx)?;
3144        // `typescript-language-server` adds padding to the left for type hints, turning
3145        // `const foo: boolean` into `const foo : boolean` which looks odd.
3146        // `rust-analyzer` does not have the padding for this case, and we have to accommodate both.
3147        //
3148        // We could trim the whole string, but being pessimistic on par with the situation above,
3149        // there might be a hint with multiple whitespaces at the end(s) which we need to display properly.
3150        // Hence let's use a heuristic first to handle the most awkward case and look for more.
3151        let force_no_type_left_padding =
3152            lsp_adapter.name.0.as_ref() == "typescript-language-server";
3153
3154        let hints = message.unwrap_or_default().into_iter().map(|lsp_hint| {
3155            let resolve_state = if InlayHints::can_resolve_inlays(&lsp_server.capabilities()) {
3156                ResolveState::CanResolve(lsp_server.server_id(), lsp_hint.data.clone())
3157            } else {
3158                ResolveState::Resolved
3159            };
3160
3161            let buffer = buffer.clone();
3162            cx.spawn(async move |cx| {
3163                InlayHints::lsp_to_project_hint(
3164                    lsp_hint,
3165                    &buffer,
3166                    server_id,
3167                    resolve_state,
3168                    force_no_type_left_padding,
3169                    cx,
3170                )
3171                .await
3172            })
3173        });
3174        future::join_all(hints)
3175            .await
3176            .into_iter()
3177            .collect::<anyhow::Result<_>>()
3178            .context("lsp to project inlay hints conversion")
3179    }
3180
3181    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::InlayHints {
3182        proto::InlayHints {
3183            project_id,
3184            buffer_id: buffer.remote_id().into(),
3185            start: Some(language::proto::serialize_anchor(&self.range.start)),
3186            end: Some(language::proto::serialize_anchor(&self.range.end)),
3187            version: serialize_version(&buffer.version()),
3188        }
3189    }
3190
3191    async fn from_proto(
3192        message: proto::InlayHints,
3193        _: Entity<LspStore>,
3194        buffer: Entity<Buffer>,
3195        mut cx: AsyncApp,
3196    ) -> Result<Self> {
3197        let start = message
3198            .start
3199            .and_then(language::proto::deserialize_anchor)
3200            .context("invalid start")?;
3201        let end = message
3202            .end
3203            .and_then(language::proto::deserialize_anchor)
3204            .context("invalid end")?;
3205        buffer
3206            .update(&mut cx, |buffer, _| {
3207                buffer.wait_for_version(deserialize_version(&message.version))
3208            })?
3209            .await?;
3210
3211        Ok(Self { range: start..end })
3212    }
3213
3214    fn response_to_proto(
3215        response: Vec<InlayHint>,
3216        _: &mut LspStore,
3217        _: PeerId,
3218        buffer_version: &clock::Global,
3219        _: &mut App,
3220    ) -> proto::InlayHintsResponse {
3221        proto::InlayHintsResponse {
3222            hints: response
3223                .into_iter()
3224                .map(InlayHints::project_to_proto_hint)
3225                .collect(),
3226            version: serialize_version(buffer_version),
3227        }
3228    }
3229
3230    async fn response_from_proto(
3231        self,
3232        message: proto::InlayHintsResponse,
3233        _: Entity<LspStore>,
3234        buffer: Entity<Buffer>,
3235        mut cx: AsyncApp,
3236    ) -> anyhow::Result<Vec<InlayHint>> {
3237        buffer
3238            .update(&mut cx, |buffer, _| {
3239                buffer.wait_for_version(deserialize_version(&message.version))
3240            })?
3241            .await?;
3242
3243        let mut hints = Vec::new();
3244        for message_hint in message.hints {
3245            hints.push(InlayHints::proto_to_project_hint(message_hint)?);
3246        }
3247
3248        Ok(hints)
3249    }
3250
3251    fn buffer_id_from_proto(message: &proto::InlayHints) -> Result<BufferId> {
3252        BufferId::new(message.buffer_id)
3253    }
3254}
3255
3256#[async_trait(?Send)]
3257impl LspCommand for GetCodeLens {
3258    type Response = Vec<CodeAction>;
3259    type LspRequest = lsp::CodeLensRequest;
3260    type ProtoRequest = proto::GetCodeLens;
3261
3262    fn display_name(&self) -> &str {
3263        "Code Lens"
3264    }
3265
3266    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
3267        capabilities
3268            .server_capabilities
3269            .code_lens_provider
3270            .as_ref()
3271            .map_or(false, |code_lens_options| {
3272                code_lens_options.resolve_provider.unwrap_or(false)
3273            })
3274    }
3275
3276    fn to_lsp(
3277        &self,
3278        path: &Path,
3279        _: &Buffer,
3280        _: &Arc<LanguageServer>,
3281        _: &App,
3282    ) -> Result<lsp::CodeLensParams> {
3283        Ok(lsp::CodeLensParams {
3284            text_document: lsp::TextDocumentIdentifier {
3285                uri: file_path_to_lsp_url(path)?,
3286            },
3287            work_done_progress_params: lsp::WorkDoneProgressParams::default(),
3288            partial_result_params: lsp::PartialResultParams::default(),
3289        })
3290    }
3291
3292    async fn response_from_lsp(
3293        self,
3294        message: Option<Vec<lsp::CodeLens>>,
3295        lsp_store: Entity<LspStore>,
3296        buffer: Entity<Buffer>,
3297        server_id: LanguageServerId,
3298        mut cx: AsyncApp,
3299    ) -> anyhow::Result<Vec<CodeAction>> {
3300        let snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot())?;
3301        let language_server = cx.update(|cx| {
3302            lsp_store
3303                .read(cx)
3304                .language_server_for_id(server_id)
3305                .with_context(|| {
3306                    format!("Missing the language server that just returned a response {server_id}")
3307                })
3308        })??;
3309        let server_capabilities = language_server.capabilities();
3310        let available_commands = server_capabilities
3311            .execute_command_provider
3312            .as_ref()
3313            .map(|options| options.commands.as_slice())
3314            .unwrap_or_default();
3315        Ok(message
3316            .unwrap_or_default()
3317            .into_iter()
3318            .filter(|code_lens| {
3319                code_lens
3320                    .command
3321                    .as_ref()
3322                    .is_none_or(|command| available_commands.contains(&command.command))
3323            })
3324            .map(|code_lens| {
3325                let code_lens_range = range_from_lsp(code_lens.range);
3326                let start = snapshot.clip_point_utf16(code_lens_range.start, Bias::Left);
3327                let end = snapshot.clip_point_utf16(code_lens_range.end, Bias::Right);
3328                let range = snapshot.anchor_before(start)..snapshot.anchor_after(end);
3329                CodeAction {
3330                    server_id,
3331                    range,
3332                    lsp_action: LspAction::CodeLens(code_lens),
3333                    resolved: false,
3334                }
3335            })
3336            .collect())
3337    }
3338
3339    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetCodeLens {
3340        proto::GetCodeLens {
3341            project_id,
3342            buffer_id: buffer.remote_id().into(),
3343            version: serialize_version(&buffer.version()),
3344        }
3345    }
3346
3347    async fn from_proto(
3348        message: proto::GetCodeLens,
3349        _: Entity<LspStore>,
3350        buffer: Entity<Buffer>,
3351        mut cx: AsyncApp,
3352    ) -> Result<Self> {
3353        buffer
3354            .update(&mut cx, |buffer, _| {
3355                buffer.wait_for_version(deserialize_version(&message.version))
3356            })?
3357            .await?;
3358        Ok(Self)
3359    }
3360
3361    fn response_to_proto(
3362        response: Vec<CodeAction>,
3363        _: &mut LspStore,
3364        _: PeerId,
3365        buffer_version: &clock::Global,
3366        _: &mut App,
3367    ) -> proto::GetCodeLensResponse {
3368        proto::GetCodeLensResponse {
3369            lens_actions: response
3370                .iter()
3371                .map(LspStore::serialize_code_action)
3372                .collect(),
3373            version: serialize_version(buffer_version),
3374        }
3375    }
3376
3377    async fn response_from_proto(
3378        self,
3379        message: proto::GetCodeLensResponse,
3380        _: Entity<LspStore>,
3381        buffer: Entity<Buffer>,
3382        mut cx: AsyncApp,
3383    ) -> anyhow::Result<Vec<CodeAction>> {
3384        buffer
3385            .update(&mut cx, |buffer, _| {
3386                buffer.wait_for_version(deserialize_version(&message.version))
3387            })?
3388            .await?;
3389        message
3390            .lens_actions
3391            .into_iter()
3392            .map(LspStore::deserialize_code_action)
3393            .collect::<Result<Vec<_>>>()
3394            .context("deserializing proto code lens response")
3395    }
3396
3397    fn buffer_id_from_proto(message: &proto::GetCodeLens) -> Result<BufferId> {
3398        BufferId::new(message.buffer_id)
3399    }
3400}
3401
3402#[async_trait(?Send)]
3403impl LspCommand for LinkedEditingRange {
3404    type Response = Vec<Range<Anchor>>;
3405    type LspRequest = lsp::request::LinkedEditingRange;
3406    type ProtoRequest = proto::LinkedEditingRange;
3407
3408    fn display_name(&self) -> &str {
3409        "Linked editing range"
3410    }
3411
3412    fn check_capabilities(&self, capabilities: AdapterServerCapabilities) -> bool {
3413        let Some(linked_editing_options) = &capabilities
3414            .server_capabilities
3415            .linked_editing_range_provider
3416        else {
3417            return false;
3418        };
3419        if let LinkedEditingRangeServerCapabilities::Simple(false) = linked_editing_options {
3420            return false;
3421        }
3422        true
3423    }
3424
3425    fn to_lsp(
3426        &self,
3427        path: &Path,
3428        buffer: &Buffer,
3429        _server: &Arc<LanguageServer>,
3430        _: &App,
3431    ) -> Result<lsp::LinkedEditingRangeParams> {
3432        let position = self.position.to_point_utf16(&buffer.snapshot());
3433        Ok(lsp::LinkedEditingRangeParams {
3434            text_document_position_params: make_lsp_text_document_position(path, position)?,
3435            work_done_progress_params: Default::default(),
3436        })
3437    }
3438
3439    async fn response_from_lsp(
3440        self,
3441        message: Option<lsp::LinkedEditingRanges>,
3442        _: Entity<LspStore>,
3443        buffer: Entity<Buffer>,
3444        _server_id: LanguageServerId,
3445        cx: AsyncApp,
3446    ) -> Result<Vec<Range<Anchor>>> {
3447        if let Some(lsp::LinkedEditingRanges { mut ranges, .. }) = message {
3448            ranges.sort_by_key(|range| range.start);
3449
3450            buffer.read_with(&cx, |buffer, _| {
3451                ranges
3452                    .into_iter()
3453                    .map(|range| {
3454                        let start =
3455                            buffer.clip_point_utf16(point_from_lsp(range.start), Bias::Left);
3456                        let end = buffer.clip_point_utf16(point_from_lsp(range.end), Bias::Left);
3457                        buffer.anchor_before(start)..buffer.anchor_after(end)
3458                    })
3459                    .collect()
3460            })
3461        } else {
3462            Ok(vec![])
3463        }
3464    }
3465
3466    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::LinkedEditingRange {
3467        proto::LinkedEditingRange {
3468            project_id,
3469            buffer_id: buffer.remote_id().to_proto(),
3470            position: Some(serialize_anchor(&self.position)),
3471            version: serialize_version(&buffer.version()),
3472        }
3473    }
3474
3475    async fn from_proto(
3476        message: proto::LinkedEditingRange,
3477        _: Entity<LspStore>,
3478        buffer: Entity<Buffer>,
3479        mut cx: AsyncApp,
3480    ) -> Result<Self> {
3481        let position = message
3482            .position
3483            .ok_or_else(|| anyhow!("invalid position"))?;
3484        buffer
3485            .update(&mut cx, |buffer, _| {
3486                buffer.wait_for_version(deserialize_version(&message.version))
3487            })?
3488            .await?;
3489        let position = deserialize_anchor(position).ok_or_else(|| anyhow!("invalid position"))?;
3490        buffer
3491            .update(&mut cx, |buffer, _| buffer.wait_for_anchors([position]))?
3492            .await?;
3493        Ok(Self { position })
3494    }
3495
3496    fn response_to_proto(
3497        response: Vec<Range<Anchor>>,
3498        _: &mut LspStore,
3499        _: PeerId,
3500        buffer_version: &clock::Global,
3501        _: &mut App,
3502    ) -> proto::LinkedEditingRangeResponse {
3503        proto::LinkedEditingRangeResponse {
3504            items: response
3505                .into_iter()
3506                .map(|range| proto::AnchorRange {
3507                    start: Some(serialize_anchor(&range.start)),
3508                    end: Some(serialize_anchor(&range.end)),
3509                })
3510                .collect(),
3511            version: serialize_version(buffer_version),
3512        }
3513    }
3514
3515    async fn response_from_proto(
3516        self,
3517        message: proto::LinkedEditingRangeResponse,
3518        _: Entity<LspStore>,
3519        buffer: Entity<Buffer>,
3520        mut cx: AsyncApp,
3521    ) -> Result<Vec<Range<Anchor>>> {
3522        buffer
3523            .update(&mut cx, |buffer, _| {
3524                buffer.wait_for_version(deserialize_version(&message.version))
3525            })?
3526            .await?;
3527        let items: Vec<Range<Anchor>> = message
3528            .items
3529            .into_iter()
3530            .filter_map(|range| {
3531                let start = deserialize_anchor(range.start?)?;
3532                let end = deserialize_anchor(range.end?)?;
3533                Some(start..end)
3534            })
3535            .collect();
3536        for range in &items {
3537            buffer
3538                .update(&mut cx, |buffer, _| {
3539                    buffer.wait_for_anchors([range.start, range.end])
3540                })?
3541                .await?;
3542        }
3543        Ok(items)
3544    }
3545
3546    fn buffer_id_from_proto(message: &proto::LinkedEditingRange) -> Result<BufferId> {
3547        BufferId::new(message.buffer_id)
3548    }
3549}