Skip to content

Commit 57735f2

Browse files
bors[bot]robinvd
andauthored
Merge #6140
6140: honour hover.content_format client capability r=lnicola a=robinvd This removes all markdown when the client does not support the markdown MarkupKind. Otherwise the output on the editor will have some markdown boilerplate, making it less readable. For example kak_lsp does not currently support markdown. ![image](https://user-images.githubusercontent.com/22073483/95112949-ef0ff080-0741-11eb-82a7-0594fa2cd736.png) after: ![image](https://user-images.githubusercontent.com/22073483/95113089-2bdbe780-0742-11eb-94fa-bcfec6d7347a.png) Co-authored-by: Robin van Dijk <robin@robinjint.nl>
2 parents 63fa617 + bd7bf4a commit 57735f2

File tree

5 files changed

+81
-9
lines changed

5 files changed

+81
-9
lines changed

crates/ide/src/hover.rs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use test_utils::mark;
1515
use crate::{
1616
display::{macro_label, ShortLabel, ToNav, TryToNav},
1717
link_rewrite::{remove_links, rewrite_links},
18+
markdown_remove::remove_markdown,
1819
markup::Markup,
1920
runnables::runnable,
2021
FileId, FilePosition, NavigationTarget, RangeInfo, Runnable,
@@ -27,6 +28,7 @@ pub struct HoverConfig {
2728
pub debug: bool,
2829
pub goto_type_def: bool,
2930
pub links_in_hover: bool,
31+
pub markdown: bool,
3032
}
3133

3234
impl Default for HoverConfig {
@@ -37,6 +39,7 @@ impl Default for HoverConfig {
3739
debug: true,
3840
goto_type_def: true,
3941
links_in_hover: true,
42+
markdown: true,
4043
}
4144
}
4245
}
@@ -48,6 +51,7 @@ impl HoverConfig {
4851
debug: false,
4952
goto_type_def: false,
5053
links_in_hover: true,
54+
markdown: true,
5155
};
5256

5357
pub fn any(&self) -> bool {
@@ -91,6 +95,7 @@ pub(crate) fn hover(
9195
db: &RootDatabase,
9296
position: FilePosition,
9397
links_in_hover: bool,
98+
markdown: bool,
9499
) -> Option<RangeInfo<HoverResult>> {
95100
let sema = Semantics::new(db);
96101
let file = sema.parse(position.file_id).syntax().clone();
@@ -109,7 +114,9 @@ pub(crate) fn hover(
109114
};
110115
if let Some(definition) = definition {
111116
if let Some(markup) = hover_for_definition(db, definition) {
112-
let markup = if links_in_hover {
117+
let markup = if !markdown {
118+
remove_markdown(&markup.as_str())
119+
} else if links_in_hover {
113120
rewrite_links(db, &markup.as_str(), &definition)
114121
} else {
115122
remove_links(&markup.as_str())
@@ -147,7 +154,11 @@ pub(crate) fn hover(
147154
}
148155
};
149156

150-
res.markup = Markup::fenced_block(&ty.display(db));
157+
res.markup = if markdown {
158+
Markup::fenced_block(&ty.display(db))
159+
} else {
160+
ty.display(db).to_string().into()
161+
};
151162
let range = sema.original_range(&node).range;
152163
Some(RangeInfo::new(range, res))
153164
}
@@ -383,12 +394,12 @@ mod tests {
383394

384395
fn check_hover_no_result(ra_fixture: &str) {
385396
let (analysis, position) = fixture::position(ra_fixture);
386-
assert!(analysis.hover(position, true).unwrap().is_none());
397+
assert!(analysis.hover(position, true, true).unwrap().is_none());
387398
}
388399

389400
fn check(ra_fixture: &str, expect: Expect) {
390401
let (analysis, position) = fixture::position(ra_fixture);
391-
let hover = analysis.hover(position, true).unwrap().unwrap();
402+
let hover = analysis.hover(position, true, true).unwrap().unwrap();
392403

393404
let content = analysis.db.file_text(position.file_id);
394405
let hovered_element = &content[hover.range];
@@ -399,7 +410,18 @@ mod tests {
399410

400411
fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
401412
let (analysis, position) = fixture::position(ra_fixture);
402-
let hover = analysis.hover(position, false).unwrap().unwrap();
413+
let hover = analysis.hover(position, false, true).unwrap().unwrap();
414+
415+
let content = analysis.db.file_text(position.file_id);
416+
let hovered_element = &content[hover.range];
417+
418+
let actual = format!("*{}*\n{}\n", hovered_element, hover.info.markup);
419+
expect.assert_eq(&actual)
420+
}
421+
422+
fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
423+
let (analysis, position) = fixture::position(ra_fixture);
424+
let hover = analysis.hover(position, true, false).unwrap().unwrap();
403425

404426
let content = analysis.db.file_text(position.file_id);
405427
let hovered_element = &content[hover.range];
@@ -410,7 +432,7 @@ mod tests {
410432

411433
fn check_actions(ra_fixture: &str, expect: Expect) {
412434
let (analysis, position) = fixture::position(ra_fixture);
413-
let hover = analysis.hover(position, true).unwrap().unwrap();
435+
let hover = analysis.hover(position, true, true).unwrap().unwrap();
414436
expect.assert_debug_eq(&hover.info.actions)
415437
}
416438

@@ -433,6 +455,23 @@ fn main() {
433455
);
434456
}
435457

458+
#[test]
459+
fn hover_remove_markdown_if_configured() {
460+
check_hover_no_markdown(
461+
r#"
462+
pub fn foo() -> u32 { 1 }
463+
464+
fn main() {
465+
let foo_test = foo()<|>;
466+
}
467+
"#,
468+
expect![[r#"
469+
*foo()*
470+
u32
471+
"#]],
472+
);
473+
}
474+
436475
#[test]
437476
fn hover_shows_long_type_of_an_expression() {
438477
check(

crates/ide/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ mod syntax_highlighting;
4646
mod syntax_tree;
4747
mod typing;
4848
mod link_rewrite;
49+
mod markdown_remove;
4950

5051
use std::sync::Arc;
5152

@@ -376,8 +377,9 @@ impl Analysis {
376377
&self,
377378
position: FilePosition,
378379
links_in_hover: bool,
380+
markdown: bool,
379381
) -> Cancelable<Option<RangeInfo<HoverResult>>> {
380-
self.with_db(|db| hover::hover(db, position, links_in_hover))
382+
self.with_db(|db| hover::hover(db, position, links_in_hover, markdown))
381383
}
382384

383385
/// Computes parameter information for the given call expression.

crates/ide/src/markdown_remove.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//! Removes markdown from strings.
2+
3+
use pulldown_cmark::{Event, Parser, Tag};
4+
5+
/// Removes all markdown, keeping the text and code blocks
6+
///
7+
/// Currently limited in styling, i.e. no ascii tables or lists
8+
pub fn remove_markdown(markdown: &str) -> String {
9+
let mut out = String::new();
10+
let parser = Parser::new(markdown);
11+
12+
for event in parser {
13+
match event {
14+
Event::Text(text) | Event::Code(text) => out.push_str(&text),
15+
Event::SoftBreak | Event::HardBreak | Event::Rule | Event::End(Tag::CodeBlock(_)) => {
16+
out.push('\n')
17+
}
18+
_ => {}
19+
}
20+
}
21+
22+
out
23+
}

crates/rust-analyzer/src/config.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use ide::{
1515
AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig,
1616
MergeBehaviour,
1717
};
18-
use lsp_types::ClientCapabilities;
18+
use lsp_types::{ClientCapabilities, MarkupKind};
1919
use project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest};
2020
use rustc_hash::FxHashSet;
2121
use serde::Deserialize;
@@ -333,13 +333,17 @@ impl Config {
333333
debug: data.hoverActions_enable && data.hoverActions_debug,
334334
goto_type_def: data.hoverActions_enable && data.hoverActions_gotoTypeDef,
335335
links_in_hover: data.hoverActions_linksInHover,
336+
markdown: true,
336337
};
337338

338339
log::info!("Config::update() = {:#?}", self);
339340
}
340341

341342
pub fn update_caps(&mut self, caps: &ClientCapabilities) {
342343
if let Some(doc_caps) = caps.text_document.as_ref() {
344+
if let Some(value) = doc_caps.hover.as_ref().and_then(|it| it.content_format.as_ref()) {
345+
self.hover.markdown = value.contains(&MarkupKind::Markdown)
346+
}
343347
if let Some(value) = doc_caps.definition.as_ref().and_then(|it| it.link_support) {
344348
self.client_caps.location_link = value;
345349
}

crates/rust-analyzer/src/handlers.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,11 @@ pub(crate) fn handle_hover(
618618
) -> Result<Option<lsp_ext::Hover>> {
619619
let _p = profile::span("handle_hover");
620620
let position = from_proto::file_position(&snap, params.text_document_position_params)?;
621-
let info = match snap.analysis.hover(position, snap.config.hover.links_in_hover)? {
621+
let info = match snap.analysis.hover(
622+
position,
623+
snap.config.hover.links_in_hover,
624+
snap.config.hover.markdown,
625+
)? {
622626
None => return Ok(None),
623627
Some(info) => info,
624628
};

0 commit comments

Comments
 (0)