Skip to content

Commit 2991fe2

Browse files
fix
1 parent 4c9c1a3 commit 2991fe2

File tree

2 files changed

+59
-20
lines changed

2 files changed

+59
-20
lines changed

crates/pyrefly_types/src/display.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,47 @@ impl<'a> ClassDisplayContext<'a> {
809809
}
810810
}
811811

812+
#[derive(Debug, Clone)]
813+
pub struct HoverCodeSnippet {
814+
pub heading: Option<String>,
815+
pub body: String,
816+
pub default_kind_label: Option<&'static str>,
817+
}
818+
819+
pub fn format_hover_code_snippet(
820+
type_: &Type,
821+
name: Option<&str>,
822+
display: String,
823+
) -> HoverCodeSnippet {
824+
if type_.is_function_type() {
825+
if let Some(name) = name {
826+
let trimmed = display.trim_start();
827+
let body = if trimmed.starts_with('(') {
828+
format!("def {}{}: ...", name, trimmed)
829+
} else {
830+
display
831+
};
832+
HoverCodeSnippet {
833+
heading: Some(name.to_owned()),
834+
body,
835+
default_kind_label: Some("(function) "),
836+
}
837+
} else {
838+
HoverCodeSnippet {
839+
heading: None,
840+
body: display,
841+
default_kind_label: Some("(function) "),
842+
}
843+
}
844+
} else {
845+
HoverCodeSnippet {
846+
heading: None,
847+
body: display,
848+
default_kind_label: None,
849+
}
850+
}
851+
}
852+
812853
#[cfg(test)]
813854
pub mod tests {
814855
use std::path::PathBuf;

pyrefly/lib/lsp/wasm/hover.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use pyrefly_types::callable::Param;
2525
use pyrefly_types::callable::ParamList;
2626
use pyrefly_types::callable::Params;
2727
use pyrefly_types::callable::Required;
28+
use pyrefly_types::display::format_hover_code_snippet;
2829
use pyrefly_types::types::BoundMethodType;
2930
use pyrefly_types::types::Forallable;
3031
use pyrefly_types::types::Type;
@@ -233,27 +234,24 @@ impl HoverValue {
233234
.display
234235
.clone()
235236
.unwrap_or_else(|| self.type_.as_hover_string());
236-
237-
let is_function = self.type_.is_function_type();
238-
if is_function && kind_formatted.trim().is_empty() {
239-
kind_formatted = "(function) ".to_owned();
240-
}
241-
let trimmed_type_display = type_display.trim_start();
242-
let needs_def_wrapper = trimmed_type_display.starts_with('(');
243-
let (heading, body) = if is_function {
244-
let function_name = self.name.clone().unwrap_or_else(|| "function".to_owned());
245-
let heading = format!("{}{}\n", kind_formatted, function_name);
246-
let body = if needs_def_wrapper {
247-
format!("def {}{}: ...", function_name, trimmed_type_display)
248-
} else {
249-
type_display
250-
};
251-
(heading, body)
237+
let snippet = format_hover_code_snippet(&self.type_, self.name.as_deref(), type_display);
238+
let kind_formatted = self.kind.map_or_else(
239+
|| {
240+
snippet
241+
.default_kind_label
242+
.map(str::to_owned)
243+
.unwrap_or_default()
244+
},
245+
|kind| format!("{} ", kind.display_for_hover()),
246+
);
247+
let name_formatted = self
248+
.name
249+
.as_ref()
250+
.map_or("".to_owned(), |s| format!("{s}: "));
251+
let heading = if let Some(callable_heading) = snippet.heading.as_ref() {
252+
format!("{}{}\n", kind_formatted, callable_heading)
252253
} else {
253-
(
254-
format!("{}{}", kind_formatted, name_formatted),
255-
type_display,
256-
)
254+
format!("{}{}", kind_formatted, name_formatted)
257255
};
258256

259257
Hover {

0 commit comments

Comments
 (0)