feat: show target of label and con tent of metadata when hovering (#517)

This commit is contained in:
Myriad-Dreamin 2024-08-10 20:22:42 +08:00 committed by GitHub
parent 98570a00f0
commit 04cdcd3ac2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 48 additions and 11 deletions

View file

@ -72,8 +72,14 @@ pub fn find_definition(
name_range: None,
});
}
DerefTarget::Ref(r) => {
let ref_node = r.cast::<ast::Ref>()?.target();
DerefTarget::Label(r) | DerefTarget::Ref(r) => {
let ref_expr: ast::Expr = r.cast()?;
let ref_node = match ref_expr {
ast::Expr::Ref(r) => r.target(),
ast::Expr::Label(r) => r.get(),
_ => return None,
};
let doc = document?;
let introspector = &doc.document.introspector;
let label = Label::new(ref_node);
@ -103,14 +109,14 @@ pub fn find_definition(
Some(DefinitionLink {
kind: LexicalKind::Var(LexicalVarKind::Label),
name: r.text().to_string(),
value: None,
name: ref_node.to_owned(),
value: Some(Value::Content(elem)),
def_at: Some((fid, rng.clone())),
name_range: Some(rng.clone()),
})
});
}
DerefTarget::Label(..) | DerefTarget::Normal(..) => {
DerefTarget::Normal(..) => {
return None;
}
};

View file

@ -5,7 +5,9 @@ use crate::{
jump_from_cursor,
prelude::*,
syntax::{find_docs_before, get_deref_target, LexicalKind, LexicalVarKind},
upstream::{expr_tooltip, plain_docs_sentence, route_of_value, tooltip, Tooltip},
upstream::{
expr_tooltip, plain_docs_sentence, route_of_value, tooltip, truncated_repr, Tooltip,
},
LspHoverContents, StatefulRequest,
};
@ -141,11 +143,18 @@ fn def_tooltip(
match lnk.kind {
LexicalKind::Mod(_)
| LexicalKind::Var(LexicalVarKind::Label)
| LexicalKind::Var(LexicalVarKind::LabelRef)
| LexicalKind::Var(LexicalVarKind::ValRef)
| LexicalKind::Block
| LexicalKind::Heading(..) => None,
LexicalKind::Var(LexicalVarKind::Label) => {
results.push(MarkedString::String(format!("Label: {}\n", lnk.name)));
if let Some(c) = lnk.value.as_ref() {
let c = truncated_repr(c);
results.push(MarkedString::String(format!("{c}")));
}
Some(LspHoverContents::Array(results))
}
LexicalKind::Var(LexicalVarKind::BibKey) => {
results.push(MarkedString::String(format!("Bibliography: @{}", lnk.name)));

View file

@ -6,7 +6,8 @@ use serde::Deserialize;
use serde_yaml as yaml;
use typst::{
diag::{bail, StrResult},
foundations::{Func, Module, Type, Value},
foundations::{Content, Func, Module, Type, Value},
introspection::MetadataElem,
text::{FontInfo, FontStyle},
Library,
};
@ -396,6 +397,27 @@ fn summarize_font_family<'a>(variants: impl Iterator<Item = &'a FontInfo>) -> Ec
detail
}
pub fn truncated_repr(value: &Value) -> EcoString {
const _10MB: usize = 100 * 1024 * 1024;
use typst::foundations::Repr;
let data: Option<Content> = value.clone().cast().ok();
let metadata: Option<MetadataElem> = data.and_then(|content| content.unpack().ok());
// todo: early truncation
let repr = if let Some(metadata) = metadata {
metadata.value.repr()
} else {
value.repr()
};
if repr.len() > _10MB {
eco_format!("[truncated-repr: {} bytes]", repr.len())
} else {
repr
}
}
#[cfg(test)]
mod tests {
#[test]

View file

@ -3,14 +3,14 @@ use std::fmt::Write;
use ecow::{eco_format, EcoString};
use if_chain::if_chain;
use typst::eval::{CapturesVisitor, Tracer};
use typst::foundations::{repr, Capturer, CastInfo, Repr, Value};
use typst::foundations::{repr, Capturer, CastInfo, Value};
use typst::layout::Length;
use typst::model::Document;
use typst::syntax::{ast, LinkedNode, Source, SyntaxKind};
use typst::util::{round_2, Numeric};
use typst::World;
use super::{plain_docs_sentence, summarize_font_family};
use super::{plain_docs_sentence, summarize_font_family, truncated_repr};
use crate::analysis::{analyze_expr, analyze_labels, DynLabel};
/// Describe the item under the cursor.
@ -87,7 +87,7 @@ pub fn expr_tooltip(world: &dyn World, leaf: &LinkedNode) -> Option<Tooltip> {
write!(pieces.last_mut().unwrap(), " (x{count})").unwrap();
}
}
pieces.push(value.repr());
pieces.push(truncated_repr(value));
last = Some((value, 1));
}