Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/inlay_hints/closing_brace.rs')
-rw-r--r--crates/ide/src/inlay_hints/closing_brace.rs102
1 files changed, 92 insertions, 10 deletions
diff --git a/crates/ide/src/inlay_hints/closing_brace.rs b/crates/ide/src/inlay_hints/closing_brace.rs
index ca3a982760..b2ee254701 100644
--- a/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/crates/ide/src/inlay_hints/closing_brace.rs
@@ -91,9 +91,9 @@ pub(super) fn hints(
match_ast! {
match parent {
ast::Fn(it) => {
- // FIXME: this could include parameters, but `HirDisplay` prints too much info
- // and doesn't respect the max length either, so the hints end up way too long
- (format!("fn {}", it.name()?), it.name().map(name))
+ let hint_text = format_function_hint(&it, config.max_length?)
+ .unwrap_or_else(|| format!("fn {}", it.name().map(|n| n.to_string()).unwrap_or_default()));
+ (hint_text, it.name().map(name))
},
ast::Static(it) => (format!("static {}", it.name()?), it.name().map(name)),
ast::Const(it) => {
@@ -156,6 +156,47 @@ pub(super) fn hints(
None
}
+fn format_function_hint(func: &ast::Fn, max_length: usize) -> Option<String> {
+ let name = func.name()?;
+ let name_str = name.to_string();
+
+ let params = if let Some(param_list) = func.param_list() {
+ let mut param_parts = Vec::new();
+ let mut total_len = 0;
+ let max_param_len = max_length.saturating_sub(name_str.len() + 4);
+
+ for param in param_list.params() {
+ let param_text = if let Some(pat) = param.pat() {
+ if let Some(ty) = param.ty() { format!("{}: {}", pat, ty) } else { pat.to_string() }
+ } else if let Some(ty) = param.ty() {
+ format!("_: {}", ty)
+ } else {
+ let param_source = param.syntax().text().to_string();
+ if param_source.trim() == "..." { "...".to_string() } else { "_".to_string() }
+ };
+
+ let param_len = param_text.len() + if param_parts.is_empty() { 0 } else { 2 };
+ if total_len + param_len > max_param_len {
+ param_parts.push("...".to_string());
+ break;
+ }
+
+ total_len += param_len;
+ param_parts.push(param_text);
+ }
+
+ if param_parts.is_empty() {
+ "()".to_string()
+ } else {
+ format!("({})", param_parts.join(", "))
+ }
+ } else {
+ "()".to_string()
+ };
+
+ Some(format!("fn {}{}", name_str, params))
+}
+
#[cfg(test)]
mod tests {
use crate::{
@@ -166,7 +207,11 @@ mod tests {
#[test]
fn hints_closing_brace() {
check_with_config(
- InlayHintsConfig { closing_brace_hints_min_lines: Some(2), ..DISABLED_CONFIG },
+ InlayHintsConfig {
+ closing_brace_hints_min_lines: Some(2),
+ max_length: Some(30),
+ ..DISABLED_CONFIG
+ },
r#"
fn a() {}
@@ -175,17 +220,17 @@ fn f() {
fn g() {
}
-//^ fn g
+//^ fn g()
fn h<T>(with: T, arguments: u8, ...) {
}
-//^ fn h
+//^ fn h(with: T, arguments: u8, ...)
trait Tr {
fn f();
fn g() {
}
- //^ fn g
+ //^ fn g()
}
//^ trait Tr
impl Tr for () {
@@ -222,7 +267,7 @@ fn f() {
let v = vec![
];
}
-//^ fn f
+//^ fn f()
"#,
);
}
@@ -230,7 +275,11 @@ fn f() {
#[test]
fn hints_closing_brace_for_block_expr() {
check_with_config(
- InlayHintsConfig { closing_brace_hints_min_lines: Some(2), ..DISABLED_CONFIG },
+ InlayHintsConfig {
+ closing_brace_hints_min_lines: Some(2),
+ max_length: Some(10),
+ ..DISABLED_CONFIG
+ },
r#"
fn test() {
'end: {
@@ -258,7 +307,40 @@ fn test() {
//^ 'a
}
-//^ fn test
+//^ fn test()
+"#,
+ );
+ }
+
+ #[test]
+ fn hints_closing_brace_function_parameters() {
+ check_with_config(
+ InlayHintsConfig {
+ closing_brace_hints_min_lines: Some(1),
+ max_length: Some(50),
+ ..DISABLED_CONFIG
+ },
+ r#"
+fn simple() {
+ let v = vec![
+ ];
+ }
+//^ fn simple()
+
+fn with_params(x: i32, y: String) {
+
+ }
+//^ fn with_params(x: i32, y: String)
+
+fn long_params(very_long_parameter_name: ComplexType, another: AnotherType) {
+
+ }
+//^ fn long_params(...)
+
+fn many_params(a: i32, b: i32, c: i32, d: i32, e: i32) {
+
+ }
+//^ fn many_params(a: i32, b: i32, c: i32, d: i32, ...)
"#,
);
}