summaryrefslogtreecommitdiff
path: root/crates/typst-ide/src/complete.rs
diff options
context:
space:
mode:
authorIgor Khanin <igor@khanin.biz>2025-05-28 16:05:10 +0300
committerGitHub <noreply@github.com>2025-05-28 13:05:10 +0000
commit6e0f48e192ddbd934d3aadd056810c86bcc3defd (patch)
tree74ef59293c12e9b1114d365d877847c67d2cb9f4 /crates/typst-ide/src/complete.rs
parent2a258a0c3849073c56a0559dbd67ee2effcd1031 (diff)
More precise math font autocomplete suggestions (#6316)
Diffstat (limited to 'crates/typst-ide/src/complete.rs')
-rw-r--r--crates/typst-ide/src/complete.rs45
1 files changed, 41 insertions, 4 deletions
diff --git a/crates/typst-ide/src/complete.rs b/crates/typst-ide/src/complete.rs
index 91fa53f9..15b4296e 100644
--- a/crates/typst-ide/src/complete.rs
+++ b/crates/typst-ide/src/complete.rs
@@ -15,7 +15,7 @@ use typst::syntax::{
ast, is_id_continue, is_id_start, is_ident, FileId, LinkedNode, Side, Source,
SyntaxKind,
};
-use typst::text::RawElem;
+use typst::text::{FontFlags, RawElem};
use typst::visualize::Color;
use unscanny::Scanner;
@@ -1081,6 +1081,24 @@ fn code_completions(ctx: &mut CompletionContext, hash: bool) {
}
}
+/// See if the AST node is somewhere within a show rule applying to equations
+fn is_in_equation_show_rule(leaf: &LinkedNode<'_>) -> bool {
+ let mut node = leaf;
+ while let Some(parent) = node.parent() {
+ if_chain! {
+ if let Some(expr) = parent.get().cast::<ast::Expr>();
+ if let ast::Expr::ShowRule(show) = expr;
+ if let Some(ast::Expr::FieldAccess(field)) = show.selector();
+ if field.field().as_str() == "equation";
+ then {
+ return true;
+ }
+ }
+ node = parent;
+ }
+ false
+}
+
/// Context for autocompletion.
struct CompletionContext<'a> {
world: &'a (dyn IdeWorld + 'a),
@@ -1152,10 +1170,12 @@ impl<'a> CompletionContext<'a> {
/// Add completions for all font families.
fn font_completions(&mut self) {
- let equation = self.before_window(25).contains("equation");
+ let equation = is_in_equation_show_rule(self.leaf);
for (family, iter) in self.world.book().families() {
- let detail = summarize_font_family(iter);
- if !equation || family.contains("Math") {
+ let variants: Vec<_> = iter.collect();
+ let is_math = variants.iter().any(|f| f.flags.contains(FontFlags::MATH));
+ let detail = summarize_font_family(variants);
+ if !equation || is_math {
self.str_completion(
family,
Some(CompletionKind::Font),
@@ -1790,4 +1810,21 @@ mod tests {
.must_include(["r", "dashed"])
.must_exclude(["cases"]);
}
+
+ #[test]
+ fn test_autocomplete_fonts() {
+ test("#text(font:)", -1)
+ .must_include(["\"Libertinus Serif\"", "\"New Computer Modern Math\""]);
+
+ test("#show link: set text(font: )", -1)
+ .must_include(["\"Libertinus Serif\"", "\"New Computer Modern Math\""]);
+
+ test("#show math.equation: set text(font: )", -1)
+ .must_include(["\"New Computer Modern Math\""])
+ .must_exclude(["\"Libertinus Serif\""]);
+
+ test("#show math.equation: it => { set text(font: )\nit }", -6)
+ .must_include(["\"New Computer Modern Math\""])
+ .must_exclude(["\"Libertinus Serif\""]);
+ }
}