Skip to content

Commit ce67dea

Browse files
committed
Auto merge of rust-lang#13988 - Veykril:hover-no-markdown, r=Veykril
Fix markdown removal in hover handling whitespace weirdly Fixes rust-lang/rust-analyzer#10028
2 parents d46d012 + c5b1e3f commit ce67dea

File tree

7 files changed

+202
-64
lines changed

7 files changed

+202
-64
lines changed

crates/ide/src/hover.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,17 @@ use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, T}
1919

2020
use crate::{
2121
doc_links::token_as_doc_comment,
22+
markdown_remove::remove_markdown,
2223
markup::Markup,
2324
runnables::{runnable_fn, runnable_mod},
2425
FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, TryToNav,
2526
};
2627
#[derive(Clone, Debug, PartialEq, Eq)]
2728
pub struct HoverConfig {
2829
pub links_in_hover: bool,
29-
pub documentation: Option<HoverDocFormat>,
30+
pub documentation: bool,
3031
pub keywords: bool,
31-
}
32-
33-
impl HoverConfig {
34-
fn markdown(&self) -> bool {
35-
matches!(self.documentation, Some(HoverDocFormat::Markdown))
36-
}
32+
pub format: HoverDocFormat,
3733
}
3834

3935
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -90,12 +86,23 @@ pub struct HoverResult {
9086
// image::https://user-images.githubusercontent.com/48062697/113020658-b5f98b80-917a-11eb-9f88-3dbc27320c95.gif[]
9187
pub(crate) fn hover(
9288
db: &RootDatabase,
93-
FileRange { file_id, range }: FileRange,
89+
file_range: FileRange,
9490
config: &HoverConfig,
9591
) -> Option<RangeInfo<HoverResult>> {
9692
let sema = &hir::Semantics::new(db);
97-
let file = sema.parse(file_id).syntax().clone();
93+
let mut res = hover_impl(sema, file_range, config)?;
94+
if let HoverDocFormat::PlainText = config.format {
95+
res.info.markup = remove_markdown(res.info.markup.as_str()).into();
96+
}
97+
Some(res)
98+
}
9899

100+
fn hover_impl(
101+
sema: &Semantics<'_, RootDatabase>,
102+
FileRange { file_id, range }: FileRange,
103+
config: &HoverConfig,
104+
) -> Option<RangeInfo<HoverResult>> {
105+
let file = sema.parse(file_id).syntax().clone();
99106
if !range.is_empty() {
100107
return hover_ranged(&file, range, sema, config);
101108
}

crates/ide/src/hover/render.rs

+18-39
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,12 @@ use syntax::{
2626
use crate::{
2727
doc_links::{remove_links, rewrite_links},
2828
hover::walk_and_push_ty,
29-
markdown_remove::remove_markdown,
3029
HoverAction, HoverConfig, HoverResult, Markup,
3130
};
3231

3332
pub(super) fn type_info(
3433
sema: &Semantics<'_, RootDatabase>,
35-
config: &HoverConfig,
34+
_config: &HoverConfig,
3635
expr_or_pat: &Either<ast::Expr, ast::Pat>,
3736
) -> Option<HoverResult> {
3837
let TypeInfo { original, adjusted } = match expr_or_pat {
@@ -55,27 +54,23 @@ pub(super) fn type_info(
5554
let adjusted = adjusted_ty.display(sema.db).to_string();
5655
let static_text_diff_len = "Coerced to: ".len() - "Type: ".len();
5756
format!(
58-
"{bt_start}Type: {:>apad$}\nCoerced to: {:>opad$}\n{bt_end}",
57+
"```text\nType: {:>apad$}\nCoerced to: {:>opad$}\n```\n",
5958
original,
6059
adjusted,
6160
apad = static_text_diff_len + adjusted.len().max(original.len()),
6261
opad = original.len(),
63-
bt_start = if config.markdown() { "```text\n" } else { "" },
64-
bt_end = if config.markdown() { "```\n" } else { "" }
6562
)
6663
.into()
67-
} else if config.markdown() {
68-
Markup::fenced_block(&original.display(sema.db))
6964
} else {
70-
original.display(sema.db).to_string().into()
65+
Markup::fenced_block(&original.display(sema.db))
7166
};
7267
res.actions.push(HoverAction::goto_type_from_targets(sema.db, targets));
7368
Some(res)
7469
}
7570

7671
pub(super) fn try_expr(
7772
sema: &Semantics<'_, RootDatabase>,
78-
config: &HoverConfig,
73+
_config: &HoverConfig,
7974
try_expr: &ast::TryExpr,
8075
) -> Option<HoverResult> {
8176
let inner_ty = sema.type_of_expr(&try_expr.expr()?)?.original;
@@ -151,22 +146,20 @@ pub(super) fn try_expr(
151146
let ppad = static_text_len_diff.min(0).abs() as usize;
152147

153148
res.markup = format!(
154-
"{bt_start}{} Type: {:>pad0$}\nPropagated as: {:>pad1$}\n{bt_end}",
149+
"```text\n{} Type: {:>pad0$}\nPropagated as: {:>pad1$}\n```\n",
155150
s,
156151
inner_ty,
157152
body_ty,
158153
pad0 = ty_len_max + tpad,
159154
pad1 = ty_len_max + ppad,
160-
bt_start = if config.markdown() { "```text\n" } else { "" },
161-
bt_end = if config.markdown() { "```\n" } else { "" }
162155
)
163156
.into();
164157
Some(res)
165158
}
166159

167160
pub(super) fn deref_expr(
168161
sema: &Semantics<'_, RootDatabase>,
169-
config: &HoverConfig,
162+
_config: &HoverConfig,
170163
deref_expr: &ast::PrefixExpr,
171164
) -> Option<HoverResult> {
172165
let inner_ty = sema.type_of_expr(&deref_expr.expr()?)?.original;
@@ -195,15 +188,13 @@ pub(super) fn deref_expr(
195188
.max(adjusted.len() + coerced_len)
196189
.max(inner.len() + deref_len);
197190
format!(
198-
"{bt_start}Dereferenced from: {:>ipad$}\nTo type: {:>apad$}\nCoerced to: {:>opad$}\n{bt_end}",
191+
"```text\nDereferenced from: {:>ipad$}\nTo type: {:>apad$}\nCoerced to: {:>opad$}\n```\n",
199192
inner,
200193
original,
201194
adjusted,
202195
ipad = max_len - deref_len,
203196
apad = max_len - type_len,
204197
opad = max_len - coerced_len,
205-
bt_start = if config.markdown() { "```text\n" } else { "" },
206-
bt_end = if config.markdown() { "```\n" } else { "" }
207198
)
208199
.into()
209200
} else {
@@ -213,13 +204,11 @@ pub(super) fn deref_expr(
213204
let deref_len = "Dereferenced from: ".len();
214205
let max_len = (original.len() + type_len).max(inner.len() + deref_len);
215206
format!(
216-
"{bt_start}Dereferenced from: {:>ipad$}\nTo type: {:>apad$}\n{bt_end}",
207+
"```text\nDereferenced from: {:>ipad$}\nTo type: {:>apad$}\n```\n",
217208
inner,
218209
original,
219210
ipad = max_len - deref_len,
220211
apad = max_len - type_len,
221-
bt_start = if config.markdown() { "```text\n" } else { "" },
222-
bt_end = if config.markdown() { "```\n" } else { "" }
223212
)
224213
.into()
225214
};
@@ -233,7 +222,7 @@ pub(super) fn keyword(
233222
config: &HoverConfig,
234223
token: &SyntaxToken,
235224
) -> Option<HoverResult> {
236-
if !token.kind().is_keyword() || !config.documentation.is_some() || !config.keywords {
225+
if !token.kind().is_keyword() || !config.documentation || !config.keywords {
237226
return None;
238227
}
239228
let parent = token.parent()?;
@@ -257,7 +246,7 @@ pub(super) fn keyword(
257246
/// i.e. `let S {a, ..} = S {a: 1, b: 2}`
258247
pub(super) fn struct_rest_pat(
259248
sema: &Semantics<'_, RootDatabase>,
260-
config: &HoverConfig,
249+
_config: &HoverConfig,
261250
pattern: &RecordPat,
262251
) -> HoverResult {
263252
let missing_fields = sema.record_pattern_missing_fields(pattern);
@@ -286,11 +275,7 @@ pub(super) fn struct_rest_pat(
286275
// get rid of trailing comma
287276
s.truncate(s.len() - 2);
288277

289-
if config.markdown() {
290-
Markup::fenced_block(&s)
291-
} else {
292-
s.into()
293-
}
278+
Markup::fenced_block(&s)
294279
};
295280
res.actions.push(HoverAction::goto_type_from_targets(sema.db, targets));
296281
res
@@ -344,13 +329,8 @@ pub(super) fn process_markup(
344329
config: &HoverConfig,
345330
) -> Markup {
346331
let markup = markup.as_str();
347-
let markup = if !config.markdown() {
348-
remove_markdown(markup)
349-
} else if config.links_in_hover {
350-
rewrite_links(db, markup, def)
351-
} else {
352-
remove_links(markup)
353-
};
332+
let markup =
333+
if config.links_in_hover { rewrite_links(db, markup, def) } else { remove_links(markup) };
354334
Markup::from(markup)
355335
}
356336

@@ -463,19 +443,18 @@ pub(super) fn definition(
463443
Definition::DeriveHelper(it) => (format!("derive_helper {}", it.name(db)), None),
464444
};
465445

466-
let docs = match config.documentation {
467-
Some(_) => docs.or_else(|| {
446+
let docs = docs
447+
.filter(|_| config.documentation)
448+
.or_else(|| {
468449
// docs are missing, for assoc items of trait impls try to fall back to the docs of the
469450
// original item of the trait
470451
let assoc = def.as_assoc_item(db)?;
471452
let trait_ = assoc.containing_trait_impl(db)?;
472453
let name = Some(assoc.name(db)?);
473454
let item = trait_.items(db).into_iter().find(|it| it.name(db) == name)?;
474455
item.docs(db)
475-
}),
476-
None => None,
477-
};
478-
let docs = docs.filter(|_| config.documentation.is_some()).map(Into::into);
456+
})
457+
.map(Into::into);
479458
markup(docs, label, mod_path)
480459
}
481460

crates/ide/src/hover/tests.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@ use expect_test::{expect, Expect};
22
use ide_db::base_db::{FileLoader, FileRange};
33
use syntax::TextRange;
44

5-
use crate::{fixture, hover::HoverDocFormat, HoverConfig};
5+
use crate::{fixture, HoverConfig, HoverDocFormat};
66

77
fn check_hover_no_result(ra_fixture: &str) {
88
let (analysis, position) = fixture::position(ra_fixture);
99
let hover = analysis
1010
.hover(
1111
&HoverConfig {
1212
links_in_hover: true,
13-
documentation: Some(HoverDocFormat::Markdown),
13+
documentation: true,
1414
keywords: true,
15+
format: HoverDocFormat::Markdown,
1516
},
1617
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
1718
)
@@ -26,8 +27,9 @@ fn check(ra_fixture: &str, expect: Expect) {
2627
.hover(
2728
&HoverConfig {
2829
links_in_hover: true,
29-
documentation: Some(HoverDocFormat::Markdown),
30+
documentation: true,
3031
keywords: true,
32+
format: HoverDocFormat::Markdown,
3133
},
3234
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
3335
)
@@ -47,8 +49,9 @@ fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
4749
.hover(
4850
&HoverConfig {
4951
links_in_hover: false,
50-
documentation: Some(HoverDocFormat::Markdown),
52+
documentation: true,
5153
keywords: true,
54+
format: HoverDocFormat::Markdown,
5255
},
5356
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
5457
)
@@ -68,8 +71,9 @@ fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
6871
.hover(
6972
&HoverConfig {
7073
links_in_hover: true,
71-
documentation: Some(HoverDocFormat::PlainText),
74+
documentation: true,
7275
keywords: true,
76+
format: HoverDocFormat::PlainText,
7377
},
7478
FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
7579
)
@@ -89,8 +93,9 @@ fn check_actions(ra_fixture: &str, expect: Expect) {
8993
.hover(
9094
&HoverConfig {
9195
links_in_hover: true,
92-
documentation: Some(HoverDocFormat::Markdown),
96+
documentation: true,
9397
keywords: true,
98+
format: HoverDocFormat::Markdown,
9499
},
95100
FileRange { file_id, range: position.range_or_empty() },
96101
)
@@ -105,8 +110,9 @@ fn check_hover_range(ra_fixture: &str, expect: Expect) {
105110
.hover(
106111
&HoverConfig {
107112
links_in_hover: false,
108-
documentation: Some(HoverDocFormat::Markdown),
113+
documentation: true,
109114
keywords: true,
115+
format: HoverDocFormat::Markdown,
110116
},
111117
range,
112118
)
@@ -121,8 +127,9 @@ fn check_hover_range_no_results(ra_fixture: &str) {
121127
.hover(
122128
&HoverConfig {
123129
links_in_hover: false,
124-
documentation: Some(HoverDocFormat::Markdown),
130+
documentation: true,
125131
keywords: true,
132+
format: HoverDocFormat::Markdown,
126133
},
127134
range,
128135
)

0 commit comments

Comments
 (0)