mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-20 02:47:34 +03:00
Fix some issues found when testing Elixir-LS (#2583)
Closes https://linear.app/zed-industries/issue/Z-2209/popovers-dont-always-have-syntax-highlighted-code Closes https://linear.app/zed-industries/issue/Z-2206/highlight-syntax-in-hover-docs * Fix a ton of errors in our logs due to us not recognizing that `elixir-ls` does not support code actions. * Syntax-highlight elixir code blocks in hover popovers
This commit is contained in:
commit
351e4863cd
@ -221,6 +221,7 @@ fn show_hover(
|
|||||||
project: project.clone(),
|
project: project.clone(),
|
||||||
symbol_range: range,
|
symbol_range: range,
|
||||||
blocks: hover_result.contents,
|
blocks: hover_result.contents,
|
||||||
|
language: hover_result.language,
|
||||||
rendered_content: None,
|
rendered_content: None,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -253,6 +254,7 @@ fn render_blocks(
|
|||||||
theme_id: usize,
|
theme_id: usize,
|
||||||
blocks: &[HoverBlock],
|
blocks: &[HoverBlock],
|
||||||
language_registry: &Arc<LanguageRegistry>,
|
language_registry: &Arc<LanguageRegistry>,
|
||||||
|
language: Option<&Arc<Language>>,
|
||||||
style: &EditorStyle,
|
style: &EditorStyle,
|
||||||
) -> RenderedInfo {
|
) -> RenderedInfo {
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
@ -351,11 +353,13 @@ fn render_blocks(
|
|||||||
}
|
}
|
||||||
Tag::CodeBlock(kind) => {
|
Tag::CodeBlock(kind) => {
|
||||||
new_paragraph(&mut text, &mut list_stack);
|
new_paragraph(&mut text, &mut list_stack);
|
||||||
if let CodeBlockKind::Fenced(language) = kind {
|
current_language = if let CodeBlockKind::Fenced(language) = kind {
|
||||||
current_language = language_registry
|
language_registry
|
||||||
.language_for_name(language.as_ref())
|
.language_for_name(language.as_ref())
|
||||||
.now_or_never()
|
.now_or_never()
|
||||||
.and_then(Result::ok);
|
.and_then(Result::ok)
|
||||||
|
} else {
|
||||||
|
language.cloned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Tag::Emphasis => italic_depth += 1,
|
Tag::Emphasis => italic_depth += 1,
|
||||||
@ -414,10 +418,6 @@ fn render_blocks(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !text.is_empty() && !text.ends_with('\n') {
|
|
||||||
text.push('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderedInfo {
|
RenderedInfo {
|
||||||
theme_id,
|
theme_id,
|
||||||
text,
|
text,
|
||||||
@ -524,6 +524,7 @@ pub struct InfoPopover {
|
|||||||
pub project: ModelHandle<Project>,
|
pub project: ModelHandle<Project>,
|
||||||
pub symbol_range: Range<Anchor>,
|
pub symbol_range: Range<Anchor>,
|
||||||
pub blocks: Vec<HoverBlock>,
|
pub blocks: Vec<HoverBlock>,
|
||||||
|
language: Option<Arc<Language>>,
|
||||||
rendered_content: Option<RenderedInfo>,
|
rendered_content: Option<RenderedInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,6 +560,7 @@ impl InfoPopover {
|
|||||||
style.theme_id,
|
style.theme_id,
|
||||||
&self.blocks,
|
&self.blocks,
|
||||||
self.project.read(cx).languages(),
|
self.project.read(cx).languages(),
|
||||||
|
self.language.as_ref(),
|
||||||
style,
|
style,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
@ -588,10 +590,7 @@ impl InfoPopover {
|
|||||||
MouseRegion::new::<Self>(view_id, region_id, bounds)
|
MouseRegion::new::<Self>(view_id, region_id, bounds)
|
||||||
.on_click::<Editor, _>(
|
.on_click::<Editor, _>(
|
||||||
MouseButton::Left,
|
MouseButton::Left,
|
||||||
move |_, _, cx| {
|
move |_, _, cx| cx.platform().open_url(&url),
|
||||||
println!("clicked link {url}");
|
|
||||||
cx.platform().open_url(&url);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -906,7 +905,7 @@ mod tests {
|
|||||||
text: "one **two** three".to_string(),
|
text: "one **two** three".to_string(),
|
||||||
kind: HoverBlockKind::Markdown,
|
kind: HoverBlockKind::Markdown,
|
||||||
}],
|
}],
|
||||||
expected_marked_text: "one «two» three\n".to_string(),
|
expected_marked_text: "one «two» three".to_string(),
|
||||||
expected_styles: vec![HighlightStyle {
|
expected_styles: vec![HighlightStyle {
|
||||||
weight: Some(Weight::BOLD),
|
weight: Some(Weight::BOLD),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -918,7 +917,7 @@ mod tests {
|
|||||||
text: "one [two](the-url) three".to_string(),
|
text: "one [two](the-url) three".to_string(),
|
||||||
kind: HoverBlockKind::Markdown,
|
kind: HoverBlockKind::Markdown,
|
||||||
}],
|
}],
|
||||||
expected_marked_text: "one «two» three\n".to_string(),
|
expected_marked_text: "one «two» three".to_string(),
|
||||||
expected_styles: vec![HighlightStyle {
|
expected_styles: vec![HighlightStyle {
|
||||||
underline: Some(Underline {
|
underline: Some(Underline {
|
||||||
thickness: 1.0.into(),
|
thickness: 1.0.into(),
|
||||||
@ -937,8 +936,7 @@ mod tests {
|
|||||||
- b
|
- b
|
||||||
* two
|
* two
|
||||||
- [c](the-url)
|
- [c](the-url)
|
||||||
- d
|
- d"
|
||||||
"
|
|
||||||
.unindent(),
|
.unindent(),
|
||||||
kind: HoverBlockKind::Markdown,
|
kind: HoverBlockKind::Markdown,
|
||||||
}],
|
}],
|
||||||
@ -949,8 +947,7 @@ mod tests {
|
|||||||
- b
|
- b
|
||||||
- two
|
- two
|
||||||
- «c»
|
- «c»
|
||||||
- d
|
- d"
|
||||||
"
|
|
||||||
.unindent(),
|
.unindent(),
|
||||||
expected_styles: vec![HighlightStyle {
|
expected_styles: vec![HighlightStyle {
|
||||||
underline: Some(Underline {
|
underline: Some(Underline {
|
||||||
@ -973,8 +970,7 @@ mod tests {
|
|||||||
|
|
||||||
nine
|
nine
|
||||||
* ten
|
* ten
|
||||||
* six
|
* six"
|
||||||
"
|
|
||||||
.unindent(),
|
.unindent(),
|
||||||
kind: HoverBlockKind::Markdown,
|
kind: HoverBlockKind::Markdown,
|
||||||
}],
|
}],
|
||||||
@ -985,8 +981,7 @@ mod tests {
|
|||||||
|
|
||||||
nine
|
nine
|
||||||
- ten
|
- ten
|
||||||
- six
|
- six"
|
||||||
"
|
|
||||||
.unindent(),
|
.unindent(),
|
||||||
expected_styles: vec![HighlightStyle {
|
expected_styles: vec![HighlightStyle {
|
||||||
underline: Some(Underline {
|
underline: Some(Underline {
|
||||||
@ -1004,7 +999,7 @@ mod tests {
|
|||||||
expected_styles,
|
expected_styles,
|
||||||
} in &rows[0..]
|
} in &rows[0..]
|
||||||
{
|
{
|
||||||
let rendered = render_blocks(0, &blocks, &Default::default(), &style);
|
let rendered = render_blocks(0, &blocks, &Default::default(), None, &style);
|
||||||
|
|
||||||
let (expected_text, ranges) = marked_text_ranges(expected_marked_text, false);
|
let (expected_text, ranges) = marked_text_ranges(expected_marked_text, false);
|
||||||
let expected_highlights = ranges
|
let expected_highlights = ranges
|
||||||
|
@ -260,9 +260,10 @@ impl LanguageServer {
|
|||||||
buffer.clear();
|
buffer.clear();
|
||||||
stdout.read_until(b'\n', &mut buffer).await?;
|
stdout.read_until(b'\n', &mut buffer).await?;
|
||||||
stdout.read_until(b'\n', &mut buffer).await?;
|
stdout.read_until(b'\n', &mut buffer).await?;
|
||||||
let message_len: usize = std::str::from_utf8(&buffer)?
|
let header = std::str::from_utf8(&buffer)?;
|
||||||
|
let message_len: usize = header
|
||||||
.strip_prefix(CONTENT_LEN_HEADER)
|
.strip_prefix(CONTENT_LEN_HEADER)
|
||||||
.ok_or_else(|| anyhow!("invalid header"))?
|
.ok_or_else(|| anyhow!("invalid LSP message header {header:?}"))?
|
||||||
.trim_end()
|
.trim_end()
|
||||||
.parse()?;
|
.parse()?;
|
||||||
|
|
||||||
@ -301,7 +302,7 @@ impl LanguageServer {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!(
|
warn!(
|
||||||
"Failed to deserialize message:\n{}",
|
"failed to deserialize LSP message:\n{}",
|
||||||
std::str::from_utf8(&buffer)?
|
std::str::from_utf8(&buffer)?
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1111,14 +1111,18 @@ impl LspCommand for GetHover {
|
|||||||
cx: AsyncAppContext,
|
cx: AsyncAppContext,
|
||||||
) -> Result<Self::Response> {
|
) -> Result<Self::Response> {
|
||||||
Ok(message.and_then(|hover| {
|
Ok(message.and_then(|hover| {
|
||||||
let range = hover.range.map(|range| {
|
let (language, range) = cx.read(|cx| {
|
||||||
cx.read(|cx| {
|
|
||||||
let buffer = buffer.read(cx);
|
let buffer = buffer.read(cx);
|
||||||
|
(
|
||||||
|
buffer.language().cloned(),
|
||||||
|
hover.range.map(|range| {
|
||||||
let token_start =
|
let token_start =
|
||||||
buffer.clip_point_utf16(point_from_lsp(range.start), Bias::Left);
|
buffer.clip_point_utf16(point_from_lsp(range.start), Bias::Left);
|
||||||
let token_end = buffer.clip_point_utf16(point_from_lsp(range.end), Bias::Left);
|
let token_end =
|
||||||
|
buffer.clip_point_utf16(point_from_lsp(range.end), Bias::Left);
|
||||||
buffer.anchor_after(token_start)..buffer.anchor_before(token_end)
|
buffer.anchor_after(token_start)..buffer.anchor_before(token_end)
|
||||||
})
|
}),
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
fn hover_blocks_from_marked_string(
|
fn hover_blocks_from_marked_string(
|
||||||
@ -1163,7 +1167,11 @@ impl LspCommand for GetHover {
|
|||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(Hover { contents, range })
|
Some(Hover {
|
||||||
|
contents,
|
||||||
|
range,
|
||||||
|
language,
|
||||||
|
})
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1247,16 +1255,9 @@ impl LspCommand for GetHover {
|
|||||||
self,
|
self,
|
||||||
message: proto::GetHoverResponse,
|
message: proto::GetHoverResponse,
|
||||||
_: ModelHandle<Project>,
|
_: ModelHandle<Project>,
|
||||||
_: ModelHandle<Buffer>,
|
buffer: ModelHandle<Buffer>,
|
||||||
_: AsyncAppContext,
|
cx: AsyncAppContext,
|
||||||
) -> Result<Self::Response> {
|
) -> Result<Self::Response> {
|
||||||
let range = if let (Some(start), Some(end)) = (message.start, message.end) {
|
|
||||||
language::proto::deserialize_anchor(start)
|
|
||||||
.and_then(|start| language::proto::deserialize_anchor(end).map(|end| start..end))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let contents: Vec<_> = message
|
let contents: Vec<_> = message
|
||||||
.contents
|
.contents
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -1271,12 +1272,23 @@ impl LspCommand for GetHover {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
if contents.is_empty() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(if contents.is_empty() {
|
let language = buffer.read_with(&cx, |buffer, _| buffer.language().cloned());
|
||||||
None
|
let range = if let (Some(start), Some(end)) = (message.start, message.end) {
|
||||||
|
language::proto::deserialize_anchor(start)
|
||||||
|
.and_then(|start| language::proto::deserialize_anchor(end).map(|end| start..end))
|
||||||
} else {
|
} else {
|
||||||
Some(Hover { contents, range })
|
None
|
||||||
})
|
};
|
||||||
|
|
||||||
|
Ok(Some(Hover {
|
||||||
|
contents,
|
||||||
|
range,
|
||||||
|
language,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn buffer_id_from_proto(message: &Self::ProtoRequest) -> u64 {
|
fn buffer_id_from_proto(message: &Self::ProtoRequest) -> u64 {
|
||||||
@ -1499,7 +1511,11 @@ impl LspCommand for GetCodeActions {
|
|||||||
type ProtoRequest = proto::GetCodeActions;
|
type ProtoRequest = proto::GetCodeActions;
|
||||||
|
|
||||||
fn check_capabilities(&self, capabilities: &ServerCapabilities) -> bool {
|
fn check_capabilities(&self, capabilities: &ServerCapabilities) -> bool {
|
||||||
capabilities.code_action_provider.is_some()
|
match &capabilities.code_action_provider {
|
||||||
|
None => false,
|
||||||
|
Some(lsp::CodeActionProviderCapability::Simple(false)) => false,
|
||||||
|
_ => true,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_lsp(
|
fn to_lsp(
|
||||||
|
@ -359,6 +359,7 @@ pub enum HoverBlockKind {
|
|||||||
pub struct Hover {
|
pub struct Hover {
|
||||||
pub contents: Vec<HoverBlock>,
|
pub contents: Vec<HoverBlock>,
|
||||||
pub range: Option<Range<language::Anchor>>,
|
pub range: Option<Range<language::Anchor>>,
|
||||||
|
pub language: Option<Arc<Language>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
Loading…
Reference in New Issue
Block a user