clangd: Implement switch source/header extension (#14646)
Release Notes: - Added switch source/header action for clangd language server (fixes [#12801](https://github.com/zed-industries/zed/issues/12801)). Note: I'm new to both rust and this codebase. I started my implementation by copying how rust analyzer's "expand macro" LSP extension is implemented. I don't yet understand some of the code I copied (mostly the way to get the `server_to_query` in `clangd_ext.rs` and the whole proto implementation). --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev>
This commit is contained in:
parent
96bcceed40
commit
f85ca387a7
9 changed files with 286 additions and 55 deletions
|
@ -135,3 +135,97 @@ impl LspCommand for ExpandMacro {
|
|||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum LspSwitchSourceHeader {}
|
||||
|
||||
impl lsp::request::Request for LspSwitchSourceHeader {
|
||||
type Params = SwitchSourceHeaderParams;
|
||||
type Result = Option<SwitchSourceHeaderResult>;
|
||||
const METHOD: &'static str = "textDocument/switchSourceHeader";
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SwitchSourceHeaderParams(lsp::TextDocumentIdentifier);
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SwitchSourceHeaderResult(pub String);
|
||||
|
||||
#[derive(Default, Deserialize, Serialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SwitchSourceHeader;
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl LspCommand for SwitchSourceHeader {
|
||||
type Response = SwitchSourceHeaderResult;
|
||||
type LspRequest = LspSwitchSourceHeader;
|
||||
type ProtoRequest = proto::LspExtSwitchSourceHeader;
|
||||
|
||||
fn to_lsp(
|
||||
&self,
|
||||
path: &Path,
|
||||
_: &Buffer,
|
||||
_: &Arc<LanguageServer>,
|
||||
_: &AppContext,
|
||||
) -> SwitchSourceHeaderParams {
|
||||
SwitchSourceHeaderParams(lsp::TextDocumentIdentifier {
|
||||
uri: lsp::Url::from_file_path(path).unwrap(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn response_from_lsp(
|
||||
self,
|
||||
message: Option<SwitchSourceHeaderResult>,
|
||||
_: Model<Project>,
|
||||
_: Model<Buffer>,
|
||||
_: LanguageServerId,
|
||||
_: AsyncAppContext,
|
||||
) -> anyhow::Result<SwitchSourceHeaderResult> {
|
||||
Ok(message
|
||||
.map(|message| SwitchSourceHeaderResult(message.0))
|
||||
.unwrap_or_default())
|
||||
}
|
||||
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::LspExtSwitchSourceHeader {
|
||||
proto::LspExtSwitchSourceHeader {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn from_proto(
|
||||
_: Self::ProtoRequest,
|
||||
_: Model<Project>,
|
||||
_: Model<Buffer>,
|
||||
_: AsyncAppContext,
|
||||
) -> anyhow::Result<Self> {
|
||||
Ok(Self {})
|
||||
}
|
||||
|
||||
fn response_to_proto(
|
||||
response: SwitchSourceHeaderResult,
|
||||
_: &mut Project,
|
||||
_: PeerId,
|
||||
_: &clock::Global,
|
||||
_: &mut AppContext,
|
||||
) -> proto::LspExtSwitchSourceHeaderResponse {
|
||||
proto::LspExtSwitchSourceHeaderResponse {
|
||||
target_file: response.0,
|
||||
}
|
||||
}
|
||||
|
||||
async fn response_from_proto(
|
||||
self,
|
||||
message: proto::LspExtSwitchSourceHeaderResponse,
|
||||
_: Model<Project>,
|
||||
_: Model<Buffer>,
|
||||
_: AsyncAppContext,
|
||||
) -> anyhow::Result<SwitchSourceHeaderResult> {
|
||||
Ok(SwitchSourceHeaderResult(message.target_file))
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::LspExtSwitchSourceHeader) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue