Tidy up collab-related signature help data (#14377)
Follow-up of https://github.com/zed-industries/zed/pull/12909 * Fully preserve LSP data when sending it via collab, and only strip it on the client. * Avoid extra custom request handlers, and extend multi LSP server query protocol instead. Release Notes: - N/A
This commit is contained in:
parent
dd63e25f23
commit
9ce989a704
5 changed files with 269 additions and 167 deletions
|
@ -5,6 +5,7 @@ use language::{
|
|||
markdown::{MarkdownHighlight, MarkdownHighlightStyle},
|
||||
Language,
|
||||
};
|
||||
use rpc::proto::{self, documentation};
|
||||
|
||||
pub const SIGNATURE_HELP_HIGHLIGHT_CURRENT: MarkdownHighlight =
|
||||
MarkdownHighlight::Style(MarkdownHighlightStyle {
|
||||
|
@ -26,38 +27,31 @@ pub const SIGNATURE_HELP_HIGHLIGHT_OVERLOAD: MarkdownHighlight =
|
|||
pub struct SignatureHelp {
|
||||
pub markdown: String,
|
||||
pub highlights: Vec<(Range<usize>, MarkdownHighlight)>,
|
||||
pub(super) original_data: lsp::SignatureHelp,
|
||||
}
|
||||
|
||||
impl SignatureHelp {
|
||||
pub fn new(
|
||||
lsp::SignatureHelp {
|
||||
signatures,
|
||||
active_signature,
|
||||
active_parameter,
|
||||
..
|
||||
}: lsp::SignatureHelp,
|
||||
language: Option<Arc<Language>>,
|
||||
) -> Option<Self> {
|
||||
let function_options_count = signatures.len();
|
||||
pub fn new(help: lsp::SignatureHelp, language: Option<Arc<Language>>) -> Option<Self> {
|
||||
let function_options_count = help.signatures.len();
|
||||
|
||||
let signature_information = active_signature
|
||||
.and_then(|active_signature| signatures.get(active_signature as usize))
|
||||
.or_else(|| signatures.first())?;
|
||||
let signature_information = help
|
||||
.active_signature
|
||||
.and_then(|active_signature| help.signatures.get(active_signature as usize))
|
||||
.or_else(|| help.signatures.first())?;
|
||||
|
||||
let str_for_join = ", ";
|
||||
let parameter_length = signature_information
|
||||
.parameters
|
||||
.as_ref()
|
||||
.map(|parameters| parameters.len())
|
||||
.unwrap_or(0);
|
||||
.map_or(0, |parameters| parameters.len());
|
||||
let mut highlight_start = 0;
|
||||
let (markdown, mut highlights): (Vec<_>, Vec<_>) = signature_information
|
||||
.parameters
|
||||
.as_ref()?
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, parameter_information)| {
|
||||
let string = match parameter_information.label.clone() {
|
||||
.map(|(i, parameter_information)| {
|
||||
let label = match parameter_information.label.clone() {
|
||||
lsp::ParameterLabel::Simple(string) => string,
|
||||
lsp::ParameterLabel::LabelOffsets(offset) => signature_information
|
||||
.label
|
||||
|
@ -66,33 +60,28 @@ impl SignatureHelp {
|
|||
.take((offset[1] - offset[0]) as usize)
|
||||
.collect::<String>(),
|
||||
};
|
||||
let string_length = string.len();
|
||||
let label_length = label.len();
|
||||
|
||||
let result = if let Some(active_parameter) = active_parameter {
|
||||
let highlights = help.active_parameter.and_then(|active_parameter| {
|
||||
if i == active_parameter as usize {
|
||||
Some((
|
||||
string,
|
||||
Some((
|
||||
highlight_start..(highlight_start + string_length),
|
||||
SIGNATURE_HELP_HIGHLIGHT_CURRENT,
|
||||
)),
|
||||
highlight_start..(highlight_start + label_length),
|
||||
SIGNATURE_HELP_HIGHLIGHT_CURRENT,
|
||||
))
|
||||
} else {
|
||||
Some((string, None))
|
||||
None
|
||||
}
|
||||
} else {
|
||||
Some((string, None))
|
||||
};
|
||||
});
|
||||
|
||||
if i != parameter_length {
|
||||
highlight_start += string_length + str_for_join.len();
|
||||
highlight_start += label_length + str_for_join.len();
|
||||
}
|
||||
|
||||
result
|
||||
(label, highlights)
|
||||
})
|
||||
.unzip();
|
||||
|
||||
let result = if markdown.is_empty() {
|
||||
if markdown.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let markdown = markdown.join(str_for_join);
|
||||
|
@ -112,16 +101,130 @@ impl SignatureHelp {
|
|||
format!("```{language_name}\n{markdown}")
|
||||
};
|
||||
|
||||
Some((markdown, highlights.into_iter().flatten().collect()))
|
||||
};
|
||||
|
||||
result.map(|(markdown, highlights)| Self {
|
||||
markdown,
|
||||
highlights,
|
||||
})
|
||||
Some(Self {
|
||||
markdown,
|
||||
highlights: highlights.into_iter().flatten().collect(),
|
||||
original_data: help,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lsp_to_proto_signature(lsp_help: lsp::SignatureHelp) -> proto::SignatureHelp {
|
||||
proto::SignatureHelp {
|
||||
signatures: lsp_help
|
||||
.signatures
|
||||
.into_iter()
|
||||
.map(|signature| proto::SignatureInformation {
|
||||
label: signature.label,
|
||||
documentation: signature
|
||||
.documentation
|
||||
.map(|documentation| lsp_to_proto_documentation(documentation)),
|
||||
parameters: signature
|
||||
.parameters
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|parameter_info| proto::ParameterInformation {
|
||||
label: Some(match parameter_info.label {
|
||||
lsp::ParameterLabel::Simple(label) => {
|
||||
proto::parameter_information::Label::Simple(label)
|
||||
}
|
||||
lsp::ParameterLabel::LabelOffsets(offsets) => {
|
||||
proto::parameter_information::Label::LabelOffsets(
|
||||
proto::LabelOffsets {
|
||||
start: offsets[0],
|
||||
end: offsets[1],
|
||||
},
|
||||
)
|
||||
}
|
||||
}),
|
||||
documentation: parameter_info.documentation.map(lsp_to_proto_documentation),
|
||||
})
|
||||
.collect(),
|
||||
active_parameter: signature.active_parameter,
|
||||
})
|
||||
.collect(),
|
||||
active_signature: lsp_help.active_signature,
|
||||
active_parameter: lsp_help.active_parameter,
|
||||
}
|
||||
}
|
||||
|
||||
fn lsp_to_proto_documentation(documentation: lsp::Documentation) -> proto::Documentation {
|
||||
proto::Documentation {
|
||||
content: Some(match documentation {
|
||||
lsp::Documentation::String(string) => proto::documentation::Content::Value(string),
|
||||
lsp::Documentation::MarkupContent(content) => {
|
||||
proto::documentation::Content::MarkupContent(proto::MarkupContent {
|
||||
is_markdown: matches!(content.kind, lsp::MarkupKind::Markdown),
|
||||
value: content.value,
|
||||
})
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn proto_to_lsp_signature(proto_help: proto::SignatureHelp) -> lsp::SignatureHelp {
|
||||
lsp::SignatureHelp {
|
||||
signatures: proto_help
|
||||
.signatures
|
||||
.into_iter()
|
||||
.map(|signature| lsp::SignatureInformation {
|
||||
label: signature.label,
|
||||
documentation: signature.documentation.and_then(proto_to_lsp_documentation),
|
||||
parameters: Some(
|
||||
signature
|
||||
.parameters
|
||||
.into_iter()
|
||||
.filter_map(|parameter_info| {
|
||||
Some(lsp::ParameterInformation {
|
||||
label: match parameter_info.label? {
|
||||
proto::parameter_information::Label::Simple(string) => {
|
||||
lsp::ParameterLabel::Simple(string)
|
||||
}
|
||||
proto::parameter_information::Label::LabelOffsets(offsets) => {
|
||||
lsp::ParameterLabel::LabelOffsets([
|
||||
offsets.start,
|
||||
offsets.end,
|
||||
])
|
||||
}
|
||||
},
|
||||
documentation: parameter_info
|
||||
.documentation
|
||||
.and_then(proto_to_lsp_documentation),
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
active_parameter: signature.active_parameter,
|
||||
})
|
||||
.collect(),
|
||||
active_signature: proto_help.active_signature,
|
||||
active_parameter: proto_help.active_parameter,
|
||||
}
|
||||
}
|
||||
|
||||
fn proto_to_lsp_documentation(documentation: proto::Documentation) -> Option<lsp::Documentation> {
|
||||
let documentation = {
|
||||
Some(match documentation.content? {
|
||||
documentation::Content::Value(string) => lsp::Documentation::String(string),
|
||||
documentation::Content::MarkupContent(markup) => {
|
||||
lsp::Documentation::MarkupContent(if markup.is_markdown {
|
||||
lsp::MarkupContent {
|
||||
kind: lsp::MarkupKind::Markdown,
|
||||
value: markup.value,
|
||||
}
|
||||
} else {
|
||||
lsp::MarkupContent {
|
||||
kind: lsp::MarkupKind::PlainText,
|
||||
value: markup.value,
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
};
|
||||
documentation
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::lsp_command::signature_help::{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue