137 lines · 3.7 KB · Rust
RawDownload
use std::{path::Path, sync::Arc}; use anyhow::{Context, Result};use async_trait::async_trait;use gpui::{AppContext, AsyncAppContext, Model};use language::{point_to_lsp, proto::deserialize_anchor, Buffer};use lsp::{LanguageServer, LanguageServerId};use rpc::proto::{self, PeerId};use serde::{Deserialize, Serialize};use text::{BufferId, PointUtf16, ToPointUtf16}; use crate::{lsp_command::LspCommand, Project}; pub enum LspExpandMacro {} impl lsp::request::Request for LspExpandMacro {    type Params = ExpandMacroParams;    type Result = Option<ExpandedMacro>;    const METHOD: &'static str = "rust-analyzer/expandMacro";} #[derive(Deserialize, Serialize, Debug)]#[serde(rename_all = "camelCase")]pub struct ExpandMacroParams {    pub text_document: lsp::TextDocumentIdentifier,    pub position: lsp::Position,} #[derive(Default, Deserialize, Serialize, Debug)]#[serde(rename_all = "camelCase")]pub struct ExpandedMacro {    pub name: String,    pub expansion: String,} impl ExpandedMacro {    pub fn is_empty(&self) -> bool {        self.name.is_empty() && self.expansion.is_empty()    }} pub struct ExpandMacro {    pub position: PointUtf16,} #[async_trait(?Send)]impl LspCommand for ExpandMacro {    type Response = ExpandedMacro;    type LspRequest = LspExpandMacro;    type ProtoRequest = proto::LspExtExpandMacro;     fn to_lsp(        &self,        path: &Path,        _: &Buffer,        _: &Arc<LanguageServer>,        _: &AppContext,    ) -> ExpandMacroParams {        ExpandMacroParams {            text_document: lsp::TextDocumentIdentifier {                uri: lsp::Url::from_file_path(path).unwrap(),            },            position: point_to_lsp(self.position),        }    }     async fn response_from_lsp(        self,        message: Option<ExpandedMacro>,        _: Model<Project>,        _: Model<Buffer>,        _: LanguageServerId,        _: AsyncAppContext,    ) -> anyhow::Result<ExpandedMacro> {        Ok(message            .map(|message| ExpandedMacro {                name: message.name,                expansion: message.expansion,            })            .unwrap_or_default())    }     fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::LspExtExpandMacro {        proto::LspExtExpandMacro {            project_id,            buffer_id: buffer.remote_id().into(),            position: Some(language::proto::serialize_anchor(                &buffer.anchor_before(self.position),            )),        }    }     async fn from_proto(        message: Self::ProtoRequest,        _: Model<Project>,        buffer: Model<Buffer>,        mut cx: AsyncAppContext,    ) -> anyhow::Result<Self> {        let position = message            .position            .and_then(deserialize_anchor)            .context("invalid position")?;        Ok(Self {            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,        })    }     fn response_to_proto(        response: ExpandedMacro,        _: &mut Project,        _: PeerId,        _: &clock::Global,        _: &mut AppContext,    ) -> proto::LspExtExpandMacroResponse {        proto::LspExtExpandMacroResponse {            name: response.name,            expansion: response.expansion,        }    }     async fn response_from_proto(        self,        message: proto::LspExtExpandMacroResponse,        _: Model<Project>,        _: Model<Buffer>,        _: AsyncAppContext,    ) -> anyhow::Result<ExpandedMacro> {        Ok(ExpandedMacro {            name: message.name,            expansion: message.expansion,        })    }     fn buffer_id_from_proto(message: &proto::LspExtExpandMacro) -> Result<BufferId> {        BufferId::new(message.buffer_id)    }}