mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-24 13:13:43 +00:00
feat: lsp label descriptions for labels (#228)
This commit is contained in:
parent
0a76b4b18a
commit
97043b9789
3 changed files with 51 additions and 17 deletions
|
@ -78,36 +78,59 @@ pub fn analyze_import(world: &dyn World, source: &LinkedNode) -> Option<Value> {
|
|||
.map(Value::Module)
|
||||
}
|
||||
|
||||
/// A label with a description and details.
|
||||
pub struct DynLabel {
|
||||
/// The label itself.
|
||||
pub label: Label,
|
||||
/// A description of the label.
|
||||
pub label_desc: Option<EcoString>,
|
||||
/// Additional details about the label.
|
||||
pub detail: Option<EcoString>,
|
||||
}
|
||||
|
||||
/// Find all labels and details for them.
|
||||
///
|
||||
/// Returns:
|
||||
/// - All labels and descriptions for them, if available
|
||||
/// - A split offset: All labels before this offset belong to nodes, all after
|
||||
/// belong to a bibliography.
|
||||
pub fn analyze_labels(document: &Document) -> (Vec<(Label, Option<EcoString>)>, usize) {
|
||||
pub fn analyze_labels(document: &Document) -> (Vec<DynLabel>, usize) {
|
||||
let mut output = vec![];
|
||||
|
||||
// Labels in the document.
|
||||
for elem in document.introspector.all() {
|
||||
let Some(label) = elem.label() else { continue };
|
||||
let details = elem
|
||||
.get_by_name("caption")
|
||||
.or_else(|| elem.get_by_name("body"))
|
||||
.and_then(|field| match field {
|
||||
Value::Content(content) => Some(content),
|
||||
_ => None,
|
||||
})
|
||||
.as_ref()
|
||||
.unwrap_or(elem)
|
||||
.plain_text();
|
||||
output.push((label, Some(details)));
|
||||
let (is_derived, details) = {
|
||||
let derived = elem
|
||||
.get_by_name("caption")
|
||||
.or_else(|| elem.get_by_name("body"));
|
||||
|
||||
match derived {
|
||||
Some(Value::Content(content)) => (true, content.plain_text()),
|
||||
Some(Value::Str(s)) => (true, s.into()),
|
||||
_ => (false, elem.plain_text()),
|
||||
}
|
||||
};
|
||||
output.push(DynLabel {
|
||||
label,
|
||||
label_desc: Some(if is_derived {
|
||||
details.clone()
|
||||
} else {
|
||||
eco_format!("{}(..)", elem.func().name())
|
||||
}),
|
||||
detail: Some(details),
|
||||
});
|
||||
}
|
||||
|
||||
let split = output.len();
|
||||
|
||||
// Bibliography keys.
|
||||
for (key, detail) in BibliographyElem::keys(document.introspector.track()) {
|
||||
output.push((Label::new(&key), detail));
|
||||
output.push(DynLabel {
|
||||
label: Label::new(&key),
|
||||
label_desc: detail.clone(),
|
||||
detail,
|
||||
});
|
||||
}
|
||||
|
||||
(output, split)
|
||||
|
|
|
@ -17,7 +17,7 @@ use typst::visualize::Color;
|
|||
use unscanny::Scanner;
|
||||
|
||||
use super::{plain_docs_sentence, summarize_font_family};
|
||||
use crate::analysis::{analyze_expr, analyze_import, analyze_labels};
|
||||
use crate::analysis::{analyze_expr, analyze_import, analyze_labels, DynLabel};
|
||||
use crate::AnalysisContext;
|
||||
|
||||
mod ext;
|
||||
|
@ -1144,7 +1144,12 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
|
|||
(0, split)
|
||||
};
|
||||
|
||||
for (label, detail) in labels.into_iter().skip(skip).take(take) {
|
||||
for DynLabel {
|
||||
label,
|
||||
label_desc,
|
||||
detail,
|
||||
} in labels.into_iter().skip(skip).take(take)
|
||||
{
|
||||
self.completions.push(Completion {
|
||||
kind: CompletionKind::Constant,
|
||||
apply: (open || close).then(|| {
|
||||
|
@ -1155,6 +1160,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
|
|||
if close { ">" } else { "" }
|
||||
)
|
||||
}),
|
||||
label_detail: label_desc,
|
||||
label: label.as_str().into(),
|
||||
detail,
|
||||
..Completion::default()
|
||||
|
|
|
@ -11,7 +11,7 @@ use typst::util::{round_2, Numeric};
|
|||
use typst::World;
|
||||
|
||||
use super::summarize_font_family;
|
||||
use crate::analysis::{analyze_expr, analyze_labels};
|
||||
use crate::analysis::{analyze_expr, analyze_labels, DynLabel};
|
||||
|
||||
/// Describe the item under the cursor.
|
||||
///
|
||||
|
@ -161,7 +161,12 @@ fn label_tooltip(document: &Document, leaf: &LinkedNode) -> Option<Tooltip> {
|
|||
_ => return None,
|
||||
};
|
||||
|
||||
for (label, detail) in analyze_labels(document).0 {
|
||||
for DynLabel {
|
||||
label,
|
||||
label_desc: _,
|
||||
detail,
|
||||
} in analyze_labels(document).0
|
||||
{
|
||||
if label.as_str() == target {
|
||||
return Some(Tooltip::Text(detail?));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue