lsp_command.rs

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