Skip to content

Commit 8e78de7

Browse files
committed
Add option to increase verbosity of types rendered in hovers
Fix EmmyLua/VSCode-EmmyLua#250
1 parent 5c6f4e1 commit 8e78de7

File tree

8 files changed

+248
-68
lines changed

8 files changed

+248
-68
lines changed

crates/emmylua_code_analysis/resources/schema.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@
8282
"hover": {
8383
"$ref": "#/$defs/EmmyrcHover",
8484
"default": {
85-
"enable": true
85+
"enable": true,
86+
"verbose": false
8687
}
8788
},
8889
"inlineValues": {
@@ -716,6 +717,12 @@
716717
"type": "boolean",
717718
"default": true,
718719
"x-vscode-setting": true
720+
},
721+
"verbose": {
722+
"description": "Increase verbosity of types shown in hovers.\n\nEnabling this option will increase maximum nesting of displayed types,\nadd alias expansions on top level, increase number of shown members.",
723+
"type": "boolean",
724+
"default": false,
725+
"x-vscode-setting": true
719726
}
720727
}
721728
},

crates/emmylua_code_analysis/src/config/configs/hover.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,21 @@ pub struct EmmyrcHover {
88
#[serde(default = "default_true")]
99
#[schemars(extend("x-vscode-setting" = true))]
1010
pub enable: bool,
11+
12+
/// Increase verbosity of types shown in hovers.
13+
///
14+
/// Enabling this option will increase maximum nesting of displayed types,
15+
/// add alias expansions on top level, increase number of shown members.
16+
#[serde(default)]
17+
#[schemars(extend("x-vscode-setting" = true))]
18+
pub verbose: bool,
1119
}
1220

1321
impl Default for EmmyrcHover {
1422
fn default() -> Self {
1523
Self {
1624
enable: default_true(),
25+
verbose: false,
1726
}
1827
}
1928
}

crates/emmylua_code_analysis/src/db_index/type/humanize_type.rs

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use std::collections::HashSet;
2-
31
use itertools::Itertools;
2+
use std::collections::HashSet;
43

54
use crate::{
65
DbIndex, GenericTpl, LuaAliasCallType, LuaFunctionType, LuaGenericType, LuaInstanceType,
@@ -13,6 +12,7 @@ use super::{LuaAliasCallKind, LuaMultiLineUnion};
1312
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1413
pub enum RenderLevel {
1514
Documentation,
15+
Verbose,
1616
Detailed,
1717
Simple,
1818
Normal,
@@ -24,6 +24,7 @@ impl RenderLevel {
2424
pub fn next_level(self) -> RenderLevel {
2525
match self {
2626
RenderLevel::Documentation => RenderLevel::Simple,
27+
RenderLevel::Verbose => RenderLevel::Detailed,
2728
RenderLevel::Detailed => RenderLevel::Simple,
2829
RenderLevel::Simple => RenderLevel::Normal,
2930
RenderLevel::Normal => RenderLevel::Brief,
@@ -74,7 +75,7 @@ pub fn humanize_type(db: &DbIndex, ty: &LuaType, level: RenderLevel) -> String {
7475
LuaType::Ref(id) => {
7576
if let Some(type_decl) = db.get_type_index().get_type_decl(id) {
7677
let name = type_decl.get_full_name().to_string();
77-
humanize_simple_type(db, id, &name, level).unwrap_or(name)
78+
humanize_simple_type(db, id, &name, level)
7879
} else {
7980
id.get_name().to_string()
8081
}
@@ -114,10 +115,7 @@ fn humanize_def_type(db: &DbIndex, id: &LuaTypeDeclId, level: RenderLevel) -> St
114115
let full_name = type_decl.get_full_name();
115116
let generic = match db.get_type_index().get_generic_params(id) {
116117
Some(generic) => generic,
117-
None => {
118-
return humanize_simple_type(db, id, &full_name, level)
119-
.unwrap_or(full_name.to_string());
120-
}
118+
None => return humanize_simple_type(db, id, &full_name, level),
121119
};
122120

123121
let generic_names = generic
@@ -133,15 +131,20 @@ fn humanize_simple_type(
133131
id: &LuaTypeDeclId,
134132
name: &str,
135133
level: RenderLevel,
136-
) -> Option<String> {
137-
if !matches!(level, RenderLevel::Detailed | RenderLevel::Documentation) {
138-
return Some(name.to_string());
134+
) -> String {
135+
if !matches!(
136+
level,
137+
RenderLevel::Detailed | RenderLevel::Verbose | RenderLevel::Documentation
138+
) {
139+
return name.to_string();
139140
}
140141
let max_display_count = 12;
141142

142143
let member_owner = LuaMemberOwner::Type(id.clone());
143144
let member_index = db.get_member_index();
144-
let members = member_index.get_sorted_members(&member_owner)?;
145+
let members = member_index
146+
.get_sorted_members(&member_owner)
147+
.unwrap_or_default();
145148
let mut member_vec = Vec::new();
146149
let mut function_vec = Vec::new();
147150
for member in members {
@@ -159,7 +162,23 @@ fn humanize_simple_type(
159162
}
160163

161164
if member_vec.is_empty() && function_vec.is_empty() {
162-
return Some(name.to_string());
165+
if matches!(level, RenderLevel::Detailed | RenderLevel::Verbose) {
166+
'expand: {
167+
let Some(type_decl) = db.get_type_index().get_type_decl(id) else {
168+
break 'expand;
169+
};
170+
let Some(origin) = type_decl.get_alias_ref() else {
171+
break 'expand;
172+
};
173+
return format!(
174+
"{} {}",
175+
name,
176+
humanize_type(db, &origin, level.next_level())
177+
);
178+
}
179+
}
180+
181+
return name.to_string();
163182
}
164183
let all_count = member_vec.len() + function_vec.len();
165184

@@ -171,7 +190,8 @@ fn humanize_simple_type(
171190
typ,
172191
humanize_type(db, typ, level.next_level()),
173192
level,
174-
);
193+
)
194+
.replace("\n", "\n ");
175195

176196
member_strings.push_str(&format!(" {},\n", member_string));
177197
count += 1;
@@ -186,7 +206,8 @@ fn humanize_simple_type(
186206
&LuaType::Function,
187207
"function".to_string(),
188208
level,
189-
);
209+
)
210+
.replace("\n", "\n ");
190211

191212
member_strings.push_str(&format!(" {},\n", member_string));
192213
count += 1;
@@ -198,7 +219,7 @@ fn humanize_simple_type(
198219
if count >= max_display_count {
199220
member_strings.push_str(&format!(" ...(+{})\n", all_count - max_display_count));
200221
}
201-
Some(format!("{} {{\n{}}}", name, member_strings))
222+
format!("{} {{\n{}}}", name, member_strings)
202223
}
203224

204225
fn humanize_union_type(db: &DbIndex, union: &LuaUnionType, level: RenderLevel) -> String {
@@ -218,6 +239,7 @@ where
218239
let types = union.into_vec();
219240
let num = match level {
220241
RenderLevel::Documentation => 500,
242+
RenderLevel::Verbose => 10,
221243
RenderLevel::Detailed => 8,
222244
RenderLevel::Simple => 6,
223245
RenderLevel::Normal => 4,
@@ -243,7 +265,7 @@ where
243265
}
244266
let dots = if type_strings.len() > num { "..." } else { "" };
245267
let display_types: Vec<_> = type_strings.into_iter().take(num).collect();
246-
let type_str = display_types.join("|");
268+
let type_str = display_types.join(" | ");
247269

248270
if display_types.len() == 1 {
249271
if has_function && has_nil {
@@ -264,6 +286,7 @@ fn humanize_multi_line_union_type(
264286
let members = multi_union.get_unions();
265287
let num = match level {
266288
RenderLevel::Documentation => 500,
289+
RenderLevel::Verbose => 15,
267290
RenderLevel::Detailed => 10,
268291
RenderLevel::Simple => 8,
269292
RenderLevel::Normal => 4,
@@ -277,7 +300,7 @@ fn humanize_multi_line_union_type(
277300
.take(num)
278301
.map(|(ty, _)| humanize_type(db, ty, level.next_level()))
279302
.collect::<Vec<_>>()
280-
.join("|");
303+
.join(" | ");
281304

282305
let mut text = format!("({}{})", type_str, dots);
283306
if level != RenderLevel::Detailed {
@@ -304,6 +327,7 @@ fn humanize_tuple_type(db: &DbIndex, tuple: &LuaTupleType, level: RenderLevel) -
304327
let types = tuple.get_types();
305328
let num = match level {
306329
RenderLevel::Documentation => 500,
330+
RenderLevel::Verbose => 15,
307331
RenderLevel::Detailed => 10,
308332
RenderLevel::Simple => 8,
309333
RenderLevel::Normal => 4,
@@ -318,7 +342,7 @@ fn humanize_tuple_type(db: &DbIndex, tuple: &LuaTupleType, level: RenderLevel) -
318342
.take(num)
319343
.map(|ty| humanize_type(db, ty, level.next_level()))
320344
.collect::<Vec<_>>()
321-
.join(",");
345+
.join(", ");
322346
format!("({}{})", type_str, dots)
323347
}
324348

@@ -344,7 +368,7 @@ fn humanize_call_type(db: &DbIndex, inner: &LuaAliasCallType, level: RenderLevel
344368
.iter()
345369
.map(|ty| humanize_type(db, ty, level.next_level()))
346370
.collect::<Vec<_>>()
347-
.join(",");
371+
.join(", ");
348372

349373
format!("{}<{}>", basic, operands)
350374
}
@@ -398,6 +422,7 @@ fn humanize_doc_function_type(
398422
fn humanize_object_type(db: &DbIndex, object: &LuaObjectType, level: RenderLevel) -> String {
399423
let num = match level {
400424
RenderLevel::Documentation => 500,
425+
RenderLevel::Verbose => 15,
401426
RenderLevel::Detailed => 10,
402427
RenderLevel::Simple => 8,
403428
RenderLevel::Normal => 4,
@@ -440,7 +465,7 @@ fn humanize_object_type(db: &DbIndex, object: &LuaObjectType, level: RenderLevel
440465
format!("[{}]: {}", key_str, value_str)
441466
})
442467
.collect::<Vec<_>>()
443-
.join(",");
468+
.join(", ");
444469

445470
if access.is_empty() {
446471
return format!("{{ {}{} }}", fields, dots);
@@ -457,6 +482,7 @@ fn humanize_intersect_type(
457482
) -> String {
458483
let num = match level {
459484
RenderLevel::Documentation => 500,
485+
RenderLevel::Verbose => 15,
460486
RenderLevel::Detailed => 10,
461487
RenderLevel::Simple => 8,
462488
RenderLevel::Normal => 4,
@@ -490,7 +516,7 @@ fn humanize_generic_type(db: &DbIndex, generic: &LuaGenericType, level: RenderLe
490516
.iter()
491517
.map(|ty| humanize_type(db, ty, level.next_level()))
492518
.collect::<Vec<_>>()
493-
.join(",");
519+
.join(", ");
494520

495521
format!("{}<{}>", full_name, generic_params)
496522
}
@@ -518,7 +544,8 @@ fn humanize_table_const_type_detail_and_simple(
518544
&type_cache.as_type(),
519545
humanize_type(db, &type_cache.as_type(), level.next_level()),
520546
level,
521-
);
547+
)
548+
.replace("\n", "\n ");
522549

523550
match level {
524551
RenderLevel::Detailed => {
@@ -575,6 +602,7 @@ fn humanize_table_generic_type(
575602
) -> String {
576603
let num = match level {
577604
RenderLevel::Documentation => 500,
605+
RenderLevel::Verbose => 15,
578606
RenderLevel::Detailed => 10,
579607
RenderLevel::Simple => 8,
580608
RenderLevel::Normal => 4,
@@ -595,7 +623,7 @@ fn humanize_table_generic_type(
595623
.take(num)
596624
.map(|ty| humanize_type(db, ty, level.next_level()))
597625
.collect::<Vec<_>>()
598-
.join(",");
626+
.join(", ");
599627

600628
format!("table<{}{}>", generic_params, dots)
601629
}
@@ -622,6 +650,7 @@ fn humanize_variadic_type(db: &DbIndex, multi: &VariadicType, level: RenderLevel
622650
VariadicType::Multi(types) => {
623651
let max_num = match level {
624652
RenderLevel::Documentation => 500,
653+
RenderLevel::Verbose => 15,
625654
RenderLevel::Detailed => 10,
626655
RenderLevel::Simple => 8,
627656
RenderLevel::Normal => 4,
@@ -637,7 +666,7 @@ fn humanize_variadic_type(db: &DbIndex, multi: &VariadicType, level: RenderLevel
637666
.take(max_num)
638667
.map(|ty| humanize_type(db, ty, level.next_level()))
639668
.collect::<Vec<_>>()
640-
.join(",");
669+
.join(", ");
641670
format!("({}{})", type_str, dots)
642671
}
643672
}
@@ -709,7 +738,7 @@ fn humanize_signature_type(
709738
if rets.is_empty() {
710739
"".to_string()
711740
} else {
712-
format!(" -> {}", rets.join(","))
741+
format!(" -> {}", rets.join(", "))
713742
}
714743
}
715744
};

0 commit comments

Comments
 (0)