From af7fe4d76083c597ec2198a73383b9e3899d75ea Mon Sep 17 00:00:00 2001 From: Laurenz Date: Fri, 17 Mar 2023 16:27:40 +0100 Subject: Hover and autocomplete in show rules --- src/model/content.rs | 10 ++-------- src/model/realize.rs | 8 ++++---- src/model/styles.rs | 32 +++++++++++++++++++++----------- src/model/typeset.rs | 19 ++++++++++++++----- 4 files changed, 41 insertions(+), 28 deletions(-) (limited to 'src/model') diff --git a/src/model/content.rs b/src/model/content.rs index bd24829d..5317236e 100644 --- a/src/model/content.rs +++ b/src/model/content.rs @@ -4,7 +4,6 @@ use std::hash::{Hash, Hasher}; use std::iter::{self, Sum}; use std::ops::{Add, AddAssign, Deref}; -use comemo::Tracked; use ecow::{eco_format, EcoString, EcoVec}; use once_cell::sync::Lazy; @@ -19,7 +18,6 @@ use crate::eval::{ }; use crate::syntax::Span; use crate::util::pretty_array_like; -use crate::World; /// Composable representation of styled content. #[derive(Clone, Hash)] @@ -219,13 +217,9 @@ impl Content { } /// Style this content with a recipe, eagerly applying it if possible. - pub fn styled_with_recipe( - self, - world: Tracked, - recipe: Recipe, - ) -> SourceResult { + pub fn styled_with_recipe(self, vm: &mut Vm, recipe: Recipe) -> SourceResult { if recipe.selector.is_none() { - recipe.apply(world, self) + recipe.apply_vm(vm, self) } else { Ok(self.styled(Style::Recipe(recipe))) } diff --git a/src/model/realize.rs b/src/model/realize.rs index 70c75644..634a31fd 100644 --- a/src/model/realize.rs +++ b/src/model/realize.rs @@ -97,7 +97,7 @@ pub fn realize( /// Try to apply a recipe to the target. fn try_apply( - vt: &Vt, + vt: &mut Vt, target: &Content, recipe: &Recipe, guard: Guard, @@ -108,7 +108,7 @@ fn try_apply( return Ok(None); } - recipe.apply(vt.world, target.clone().guarded(guard)).map(Some) + recipe.apply_vt(vt, target.clone().guarded(guard)).map(Some) } Some(Selector::Label(label)) => { @@ -116,7 +116,7 @@ fn try_apply( return Ok(None); } - recipe.apply(vt.world, target.clone().guarded(guard)).map(Some) + recipe.apply_vt(vt, target.clone().guarded(guard)).map(Some) } Some(Selector::Regex(regex)) => { @@ -140,7 +140,7 @@ fn try_apply( } let piece = make(m.as_str().into()).guarded(guard); - let transformed = recipe.apply(vt.world, piece)?; + let transformed = recipe.apply_vt(vt, piece)?; result.push(transformed); cursor = m.end(); } diff --git a/src/model/styles.rs b/src/model/styles.rs index 359f1461..8cccb5f6 100644 --- a/src/model/styles.rs +++ b/src/model/styles.rs @@ -1,15 +1,13 @@ use std::fmt::{self, Debug, Formatter, Write}; use std::iter; -use comemo::Tracked; use ecow::{eco_format, EcoString, EcoVec}; -use super::{Content, Label, Node, NodeId}; +use super::{Content, Label, Node, NodeId, Vt}; use crate::diag::{SourceResult, Trace, Tracepoint}; -use crate::eval::{cast_from_value, Args, Cast, Dict, Func, Regex, Value}; +use crate::eval::{cast_from_value, Args, Cast, Dict, Func, Regex, Value, Vm}; use crate::syntax::Span; use crate::util::pretty_array_like; -use crate::World; /// A map of style properties. #[derive(Default, Clone, Hash)] @@ -197,20 +195,32 @@ impl Recipe { } /// Apply the recipe to the given content. - pub fn apply( - &self, - world: Tracked, - content: Content, - ) -> SourceResult { + pub fn apply_vm(&self, vm: &mut Vm, content: Content) -> SourceResult { match &self.transform { Transform::Content(content) => Ok(content.clone()), Transform::Func(func) => { let args = Args::new(self.span, [Value::Content(content.clone())]); - let mut result = func.call_detached(world, args); + let mut result = func.call_vm(vm, args); // For selector-less show rules, a tracepoint makes no sense. if self.selector.is_some() { let point = || Tracepoint::Show(content.id().name.into()); - result = result.trace(world, point, content.span()); + result = result.trace(vm.world(), point, content.span()); + } + Ok(result?.display()) + } + Transform::Style(styles) => Ok(content.styled_with_map(styles.clone())), + } + } + + /// Apply the recipe to the given content. + pub fn apply_vt(&self, vt: &mut Vt, content: Content) -> SourceResult { + match &self.transform { + Transform::Content(content) => Ok(content.clone()), + Transform::Func(func) => { + let mut result = func.call_vt(vt, [Value::Content(content.clone())]); + if self.selector.is_some() { + let point = || Tracepoint::Show(content.id().name.into()); + result = result.trace(vt.world, point, content.span()); } Ok(result?.display()) } diff --git a/src/model/typeset.rs b/src/model/typeset.rs index e9cb3d2c..683f2846 100644 --- a/src/model/typeset.rs +++ b/src/model/typeset.rs @@ -6,13 +6,18 @@ use comemo::{Constraint, Track, Tracked, TrackedMut}; use super::{Content, Selector, StyleChain}; use crate::diag::SourceResult; use crate::doc::{Document, Element, Frame, Location, Meta}; +use crate::eval::Tracer; use crate::geom::{Point, Transform}; use crate::util::NonZeroExt; use crate::World; /// Typeset content into a fully layouted document. #[comemo::memoize] -pub fn typeset(world: Tracked, content: &Content) -> SourceResult { +pub fn typeset( + world: Tracked, + mut tracer: TrackedMut, + content: &Content, +) -> SourceResult { let library = world.library(); let styles = StyleChain::new(&library.styles); @@ -27,6 +32,7 @@ pub fn typeset(world: Tracked, content: &Content) -> SourceResult, content: &Content) -> SourceResult { /// The compilation environment. pub world: Tracked<'a, dyn World>, + /// The tracer for inspection of the values an expression produces. + pub tracer: TrackedMut<'a, Tracer>, /// Provides stable identities to nodes. pub provider: TrackedMut<'a, StabilityProvider>, /// Provides access to information about the document. @@ -162,8 +170,8 @@ impl Introspector { } /// Query for all metadata matches for the given selector. - pub fn query(&self, selector: Selector) -> Vec<&Content> { - self.all().filter(|node| selector.matches(node)).collect() + pub fn query(&self, selector: Selector) -> Vec { + self.all().filter(|node| selector.matches(node)).cloned().collect() } /// Query for all metadata matches before the given id. @@ -171,14 +179,15 @@ impl Introspector { &self, selector: Selector, id: StableId, - ) -> (Vec<&Content>, Vec<&Content>) { + ) -> (Vec, Vec) { let mut iter = self.all(); let before = iter .by_ref() .take_while(|node| node.stable_id() != Some(id)) .filter(|node| selector.matches(node)) + .cloned() .collect(); - let after = iter.filter(|node| selector.matches(node)).collect(); + let after = iter.filter(|node| selector.matches(node)).cloned().collect(); (before, after) } -- cgit v1.2.3