Skip to content

Commit ce3216e

Browse files
committed
Auto merge of #15938 - Young-Flash:display_trait_item_when_hover, r=Veykril
feat: add hover display for trait assoc items This PR enable preview assoc items when hover on `trait` ![image](https://github.com/rust-lang/rust-analyzer/assets/71162630/d9c3949c-33cf-4a32-aa97-3af46b28033a) inspired by #15847
2 parents 0c2e9fe + dba67b4 commit ce3216e

File tree

9 files changed

+206
-28
lines changed

9 files changed

+206
-28
lines changed

crates/hir-ty/src/display.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub struct HirFormatter<'a> {
6363
buf: String,
6464
curr_size: usize,
6565
pub(crate) max_size: Option<usize>,
66+
pub limited_size: Option<usize>,
6667
omit_verbose_types: bool,
6768
closure_style: ClosureStyle,
6869
display_target: DisplayTarget,
@@ -86,6 +87,7 @@ pub trait HirDisplay {
8687
&'a self,
8788
db: &'a dyn HirDatabase,
8889
max_size: Option<usize>,
90+
limited_size: Option<usize>,
8991
omit_verbose_types: bool,
9092
display_target: DisplayTarget,
9193
closure_style: ClosureStyle,
@@ -101,6 +103,7 @@ pub trait HirDisplay {
101103
db,
102104
t: self,
103105
max_size,
106+
limited_size,
104107
omit_verbose_types,
105108
display_target,
106109
closure_style,
@@ -117,6 +120,7 @@ pub trait HirDisplay {
117120
db,
118121
t: self,
119122
max_size: None,
123+
limited_size: None,
120124
omit_verbose_types: false,
121125
closure_style: ClosureStyle::ImplFn,
122126
display_target: DisplayTarget::Diagnostics,
@@ -137,6 +141,28 @@ pub trait HirDisplay {
137141
db,
138142
t: self,
139143
max_size,
144+
limited_size: None,
145+
omit_verbose_types: true,
146+
closure_style: ClosureStyle::ImplFn,
147+
display_target: DisplayTarget::Diagnostics,
148+
}
149+
}
150+
151+
/// Returns a `Display`able type that is human-readable and tries to limit the item inside this type.
152+
/// Use this for showing types which may contain two many item when user hover on, like `trait`, `struct`, `enum`
153+
fn display_limited<'a>(
154+
&'a self,
155+
db: &'a dyn HirDatabase,
156+
limited_size: Option<usize>,
157+
) -> HirDisplayWrapper<'a, Self>
158+
where
159+
Self: Sized,
160+
{
161+
HirDisplayWrapper {
162+
db,
163+
t: self,
164+
max_size: None,
165+
limited_size,
140166
omit_verbose_types: true,
141167
closure_style: ClosureStyle::ImplFn,
142168
display_target: DisplayTarget::Diagnostics,
@@ -158,6 +184,7 @@ pub trait HirDisplay {
158184
buf: String::with_capacity(20),
159185
curr_size: 0,
160186
max_size: None,
187+
limited_size: None,
161188
omit_verbose_types: false,
162189
closure_style: ClosureStyle::ImplFn,
163190
display_target: DisplayTarget::SourceCode { module_id, allow_opaque },
@@ -178,6 +205,7 @@ pub trait HirDisplay {
178205
db,
179206
t: self,
180207
max_size: None,
208+
limited_size: None,
181209
omit_verbose_types: false,
182210
closure_style: ClosureStyle::ImplFn,
183211
display_target: DisplayTarget::Test,
@@ -295,6 +323,7 @@ pub struct HirDisplayWrapper<'a, T> {
295323
db: &'a dyn HirDatabase,
296324
t: &'a T,
297325
max_size: Option<usize>,
326+
limited_size: Option<usize>,
298327
omit_verbose_types: bool,
299328
closure_style: ClosureStyle,
300329
display_target: DisplayTarget,
@@ -323,6 +352,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
323352
buf: String::with_capacity(20),
324353
curr_size: 0,
325354
max_size: self.max_size,
355+
limited_size: self.limited_size,
326356
omit_verbose_types: self.omit_verbose_types,
327357
display_target: self.display_target,
328358
closure_style: self.closure_style,

crates/hir/src/display.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ use hir_ty::{
1717
};
1818

1919
use crate::{
20-
Adt, AsAssocItem, AssocItemContainer, Const, ConstParam, Enum, ExternCrateDecl, Field,
21-
Function, GenericParam, HasCrate, HasVisibility, LifetimeParam, Macro, Module, SelfParam,
22-
Static, Struct, Trait, TraitAlias, TupleField, TyBuilder, Type, TypeAlias, TypeOrConstParam,
23-
TypeParam, Union, Variant,
20+
Adt, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Enum, ExternCrateDecl,
21+
Field, Function, GenericParam, HasCrate, HasVisibility, LifetimeParam, Macro, Module,
22+
SelfParam, Static, Struct, Trait, TraitAlias, TupleField, TyBuilder, Type, TypeAlias,
23+
TypeOrConstParam, TypeParam, Union, Variant,
2424
};
2525

2626
impl HirDisplay for Function {
@@ -595,6 +595,36 @@ impl HirDisplay for Trait {
595595
let def_id = GenericDefId::TraitId(self.id);
596596
write_generic_params(def_id, f)?;
597597
write_where_clause(def_id, f)?;
598+
599+
let assoc_items = self.items(f.db);
600+
let assoc_items_size = assoc_items.len();
601+
let limited_size = f.limited_size.unwrap_or(assoc_items_size);
602+
if assoc_items.is_empty() {
603+
f.write_str(" {}")?;
604+
} else {
605+
f.write_str(" {\n")?;
606+
for (index, item) in assoc_items.iter().enumerate() {
607+
f.write_str(" ")?;
608+
match item {
609+
AssocItem::Function(func) => {
610+
func.hir_fmt(f)?;
611+
}
612+
AssocItem::Const(cst) => {
613+
cst.hir_fmt(f)?;
614+
}
615+
AssocItem::TypeAlias(type_alias) => {
616+
type_alias.hir_fmt(f)?;
617+
}
618+
};
619+
f.write_str(",\n")?;
620+
if index + 1 == limited_size && index + 1 != assoc_items_size {
621+
f.write_str(" ...\n")?;
622+
break;
623+
}
624+
}
625+
f.write_str("}")?;
626+
}
627+
598628
Ok(())
599629
}
600630
}

crates/ide/src/hover.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub struct HoverConfig {
3232
pub documentation: bool,
3333
pub keywords: bool,
3434
pub format: HoverDocFormat,
35+
pub trait_assoc_items_size: Option<usize>,
3536
}
3637

3738
#[derive(Copy, Clone, Debug, PartialEq, Eq)]

crates/ide/src/hover/render.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,12 @@ pub(super) fn definition(
406406
config: &HoverConfig,
407407
) -> Markup {
408408
let mod_path = definition_mod_path(db, &def);
409-
let label = def.label(db);
409+
let label = match def {
410+
Definition::Trait(trait_) => {
411+
trait_.display_limited(db, config.trait_assoc_items_size).to_string()
412+
}
413+
_ => def.label(db),
414+
};
410415
let docs = def.docs(db, famous_defs);
411416
let value = (|| match def {
412417
Definition::Variant(it) => {

0 commit comments

Comments
 (0)