This commit is contained in:
Richard Feldman 2025-07-10 17:32:12 -04:00
parent 8ee82395b8
commit b6bd9c0682
No known key found for this signature in database

View file

@ -7,7 +7,7 @@ use crate::{
scroll::ScrollAmount,
};
use gpui::{App, AsyncWindowContext, Context, Entity, Modifiers, Task, Window, px};
use language::{Bias, ToOffset};
use language::{Bias, ToOffset, point_from_lsp};
use linkify::{LinkFinder, LinkKind};
use lsp::LanguageServerId;
use project::{
@ -448,7 +448,7 @@ pub fn update_inlay_link_and_hover_points(
.next_back()
.unwrap_or("unknown")
.to_string();
let loading_text = format!(
let _loading_text = format!(
"{}\n\nLoading documentation from {}...",
part.value.trim(),
filename
@ -461,7 +461,7 @@ pub fn update_inlay_link_and_hover_points(
editor,
InlayHover {
tooltip: HoverBlock {
text: loading_text.clone(),
text: "Loading documentation...".to_string(),
kind: HoverBlockKind::PlainText,
},
range: highlight.clone(),
@ -471,14 +471,15 @@ pub fn update_inlay_link_and_hover_points(
);
hover_updated = true;
// Now perform the "Go to Definition" flow to get hover documentation
if let Some(project) = editor.project.clone() {
let highlight = highlight.clone();
// Prepare data needed for the async task
let project = editor.project.clone().unwrap();
let hint_value = part.value.clone();
let location_uri = location.uri.clone();
let location_uri = location.uri.as_str().to_string();
let highlight = highlight.clone();
let filename = filename.clone();
// Spawn async task to fetch documentation
cx.spawn_in(window, async move |editor, cx| {
async move {
eprintln!("Starting async documentation fetch for {}", hint_value);
// Small delay to show the loading message first
@ -499,9 +500,90 @@ pub fn update_inlay_link_and_hover_points(
project.open_local_buffer(file_path, cx)
})?
.await?;
eprintln!("Successfully opened definition buffer");
// Extract documentation directly from the source
// Register the buffer with language servers
eprintln!("Registering buffer with language servers");
let _lsp_handle = project.update(cx, |project, cx| {
project.register_buffer_with_language_servers(&definition_buffer, cx)
})?;
eprintln!("Successfully opened and registered definition buffer with LSP");
// Give LSP a moment to process the didOpen notification
cx.background_executor()
.timer(std::time::Duration::from_millis(100))
.await;
// Try to get hover documentation from LSP
let hover_position = location.range.start;
eprintln!("Requesting hover at position {:?}", hover_position);
// Convert LSP position to a point
let hover_point = definition_buffer.update(cx, |buffer, _| {
let point_utf16 = point_from_lsp(hover_position);
let snapshot = buffer.snapshot();
let point = snapshot.clip_point_utf16(point_utf16, Bias::Left);
snapshot.anchor_after(point)
})?;
let hover_response = project
.update(cx, |project, cx| {
project.hover(&definition_buffer, hover_point, cx)
})?
.await;
eprintln!("Hover response: {} hovers", hover_response.len());
if !hover_response.is_empty() {
// Get the first hover response
let hover = &hover_response[0];
if !hover.contents.is_empty() {
eprintln!("Got {} hover blocks from LSP!", hover.contents.len());
// Format the hover blocks as markdown
let mut formatted_docs = String::new();
// Add the type signature first
formatted_docs.push_str(&format!("```rust\n{}\n```\n\n", hint_value.trim()));
// Add all the hover content
for block in &hover.contents {
match &block.kind {
HoverBlockKind::Markdown => {
formatted_docs.push_str(&block.text);
formatted_docs.push_str("\n\n");
}
HoverBlockKind::Code { language } => {
formatted_docs.push_str(&format!("```{}\n{}\n```\n\n", language, block.text));
}
HoverBlockKind::PlainText => {
formatted_docs.push_str(&block.text);
formatted_docs.push_str("\n\n");
}
}
}
editor.update_in(cx, |editor, window, cx| {
hover_popover::hover_at_inlay(
editor,
InlayHover {
tooltip: HoverBlock {
text: formatted_docs.trim().to_string(),
kind: HoverBlockKind::Markdown,
},
range: highlight,
},
window,
cx,
);
}).log_err();
return Ok(());
}
}
eprintln!("No hover documentation from LSP, falling back to parsing source");
// Fallback: Extract documentation directly from the source
let documentation = definition_buffer.update(cx, |buffer, _| {
let line_number = location.range.start.line as usize;
eprintln!("Looking for documentation at line {}", line_number);
@ -605,12 +687,8 @@ pub fn update_inlay_link_and_hover_points(
eprintln!("Documentation fetch complete");
anyhow::Ok(())
}
.log_err()
.await
}).detach();
}
}
if let Some((language_server_id, location)) = &part.location {
if secondary_held