Extract IDE crate

This commit is contained in:
Laurenz 2023-09-26 17:12:18 +02:00
parent 0d39fa021f
commit d7928a8ea3
16 changed files with 86 additions and 60 deletions

13
Cargo.lock generated
View File

@ -2739,7 +2739,6 @@ dependencies = [
"ecow",
"flate2",
"fontdb",
"if_chain",
"image",
"indexmap 2.0.0",
"log",
@ -2841,6 +2840,18 @@ dependencies = [
"yaml-front-matter",
]
[[package]]
name = "typst-ide"
version = "0.8.0"
dependencies = [
"comemo",
"ecow",
"if_chain",
"serde",
"typst",
"unscanny",
]
[[package]]
name = "typst-library"
version = "0.8.0"

View File

@ -215,7 +215,7 @@ impl<'a> Handler<'a> {
};
let root = parser(&code[1..code.len() - 1]);
let html = typst::ide::highlight_html(&root);
let html = typst::syntax::highlight_html(&root);
*event = md::Event::Html(html.into());
}
@ -370,7 +370,7 @@ fn code_block(resolver: &dyn Resolver, lang: &str, text: &str) -> Html {
}
let root = typst::syntax::parse(&display);
let highlighted = Html::new(typst::ide::highlight_html(&root));
let highlighted = Html::new(typst::syntax::highlight_html(&root));
if lang == "typ" {
return Html::new(format!("<pre>{}</pre>", highlighted.as_str()));
}

View File

@ -382,7 +382,7 @@ fn param_model(resolver: &dyn Resolver, info: &ParamInfo) -> ParamModel {
strings,
default: info.default.map(|default| {
let node = typst::syntax::parse_code(&default().repr());
Html::new(typst::ide::highlight_html(&node))
Html::new(typst::syntax::highlight_html(&node))
}),
positional: info.positional,
named: info.named,

View File

@ -0,0 +1,25 @@
[package]
name = "typst-ide"
description = "IDE functionality for Typst."
categories = ["compilers", "science"]
keywords = ["typst"]
version.workspace = true
rust-version.workspace = true
authors.workspace = true
edition.workspace = true
homepage.workspace = true
repository.workspace = true
license.workspace = true
[lib]
test = false
doctest = false
bench = false
[dependencies]
typst = { path = "../typst" }
comemo = "0.3"
ecow = { version = "0.1.2", features = ["serde"] }
if_chain = "1"
serde = { version = "1.0.184", features = ["derive"] }
unscanny = "0.1"

View File

@ -1,11 +1,10 @@
use comemo::Track;
use ecow::{eco_vec, EcoString, EcoVec};
use crate::doc::Frame;
use crate::eval::{Route, Scopes, Tracer, Value, Vm};
use crate::model::{DelayedErrors, Introspector, Label, Locator, Vt};
use crate::syntax::{ast, LinkedNode, Span, SyntaxKind};
use crate::World;
use typst::doc::Frame;
use typst::eval::{Route, Scopes, Tracer, Value, Vm};
use typst::model::{DelayedErrors, Introspector, Label, Locator, Vt};
use typst::syntax::{ast, LinkedNode, Span, SyntaxKind};
use typst::World;
/// Try to determine a set of possible values for an expression.
pub fn analyze_expr(world: &dyn World, node: &LinkedNode) -> EcoVec<Value> {
@ -35,7 +34,7 @@ pub fn analyze_expr(world: &dyn World, node: &LinkedNode) -> EcoVec<Value> {
let mut tracer = Tracer::new();
tracer.inspect(node.span());
crate::compile(world, &mut tracer).ok();
typst::compile(world, &mut tracer).ok();
tracer.values()
}
@ -65,7 +64,7 @@ pub fn analyze_import(world: &dyn World, source: &LinkedNode) -> Option<Value> {
let route = Route::default();
let mut vm = Vm::new(vt, route.track(), Some(id), Scopes::new(Some(world.library())));
crate::eval::import(&mut vm, source, Span::detached(), true)
typst::eval::import(&mut vm, source, Span::detached(), true)
.ok()
.map(Value::Module)
}

View File

@ -4,20 +4,20 @@ use std::collections::{BTreeSet, HashSet};
use ecow::{eco_format, EcoString};
use if_chain::if_chain;
use serde::{Deserialize, Serialize};
use typst::doc::Frame;
use typst::eval::{
format_str, AutoValue, CastInfo, Func, Library, NoneValue, Scope, Type, Value,
};
use typst::geom::Color;
use typst::syntax::{
ast, is_id_continue, is_id_start, is_ident, LinkedNode, Source, SyntaxKind,
};
use typst::util::separated_list;
use typst::World;
use unscanny::Scanner;
use super::analyze::analyze_labels;
use super::{analyze_expr, analyze_import, plain_docs_sentence, summarize_font_family};
use crate::doc::Frame;
use crate::eval::{
format_str, AutoValue, CastInfo, Func, Library, NoneValue, Scope, Type, Value,
};
use crate::geom::Color;
use crate::syntax::{
ast, is_id_continue, is_id_start, is_ident, LinkedNode, Source, SyntaxKind,
};
use crate::util::separated_list;
use crate::World;
/// Autocomplete a cursor position in a source file.
///
@ -365,7 +365,7 @@ fn field_access_completions(ctx: &mut CompletionContext, value: &Value) {
}
}
for &(method, args) in crate::eval::mutable_methods_on(value.ty()) {
for &(method, args) in typst::eval::mutable_methods_on(value.ty()) {
ctx.completions.push(Completion {
kind: CompletionKind::Func,
label: method.into(),
@ -378,7 +378,7 @@ fn field_access_completions(ctx: &mut CompletionContext, value: &Value) {
})
}
for &field in crate::eval::fields_on(value.ty()) {
for &field in typst::eval::fields_on(value.ty()) {
// Complete the field name along with its value. Notes:
// 1. No parentheses since function fields cannot currently be called
// with method syntax;
@ -1136,7 +1136,7 @@ impl<'a> CompletionContext<'a> {
/// Add completions for a castable.
fn cast_completions(&mut self, cast: &'a CastInfo) {
// Prevent duplicate completions from appearing.
if !self.seen_casts.insert(crate::util::hash128(cast)) {
if !self.seen_casts.insert(typst::util::hash128(cast)) {
return;
}

View File

@ -1,12 +1,11 @@
use std::num::NonZeroUsize;
use ecow::EcoString;
use crate::doc::{Destination, Frame, FrameItem, Meta, Position};
use crate::geom::{Geometry, Point, Size};
use crate::model::Introspector;
use crate::syntax::{FileId, LinkedNode, Source, Span, SyntaxKind};
use crate::World;
use typst::doc::{Destination, Frame, FrameItem, Meta, Position};
use typst::geom::{Geometry, Point, Size};
use typst::model::Introspector;
use typst::syntax::{FileId, LinkedNode, Source, Span, SyntaxKind};
use typst::World;
/// Where to [jump](jump_from_click) to.
#[derive(Debug, Clone, Eq, PartialEq)]

View File

@ -2,22 +2,20 @@
mod analyze;
mod complete;
mod highlight;
mod jump;
mod tooltip;
pub use self::analyze::analyze_labels;
pub use self::complete::{autocomplete, Completion, CompletionKind};
pub use self::highlight::{highlight, highlight_html, Tag};
pub use self::jump::{jump_from_click, jump_from_cursor, Jump};
pub use self::tooltip::{tooltip, Tooltip};
use std::fmt::Write;
use ecow::{eco_format, EcoString};
use typst::font::{FontInfo, FontStyle};
use self::analyze::*;
use crate::font::{FontInfo, FontStyle};
/// Extract the first sentence of plain text of a piece of documentation.
///
@ -80,8 +78,7 @@ fn summarize_font_family<'a>(variants: impl Iterator<Item = &'a FontInfo>) -> Ec
}
let count = infos.len();
let s = if count == 1 { "" } else { "s" };
let mut detail = eco_format!("{count} variant{s}.");
let mut detail = eco_format!("{count} variant{}.", if count == 1 { "" } else { "s" });
if min_weight == max_weight {
write!(detail, " Weight {min_weight}.").unwrap();

View File

@ -1,18 +1,17 @@
use std::fmt::Write;
use ecow::{eco_format, EcoString};
use if_chain::if_chain;
use typst::doc::Frame;
use typst::eval::{CapturesVisitor, CastInfo, Tracer, Value};
use typst::geom::{round_2, Length, Numeric};
use typst::syntax::ast::{self, AstNode};
use typst::syntax::{LinkedNode, Source, SyntaxKind};
use typst::util::{pretty_comma_list, separated_list};
use typst::World;
use super::analyze::analyze_labels;
use super::{analyze_expr, plain_docs_sentence, summarize_font_family};
use crate::doc::Frame;
use crate::eval::{CapturesVisitor, CastInfo, Tracer, Value};
use crate::geom::{round_2, Length, Numeric};
use crate::syntax::ast::{self, AstNode};
use crate::syntax::{LinkedNode, Source, SyntaxKind};
use crate::util::{pretty_comma_list, separated_list};
use crate::World;
/// Describe the item under the cursor.
pub fn tooltip(

View File

@ -423,7 +423,7 @@ fn highlight_themed<F>(
for child in node.children() {
let mut scopes = scopes.clone();
if let Some(tag) = typst::ide::highlight(&child) {
if let Some(tag) = typst::syntax::highlight(&child) {
scopes.push(syntect::parsing::Scope::new(tag.tm_scope()).unwrap())
}
highlight_themed(&child, scopes, highlighter, f);

View File

@ -1,4 +1,4 @@
use crate::syntax::{ast, LinkedNode, SyntaxKind, SyntaxNode};
use crate::{ast, LinkedNode, SyntaxKind, SyntaxNode};
/// A syntax highlighting tag.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
@ -405,7 +405,6 @@ mod tests {
use std::ops::Range;
use super::*;
use crate::syntax::parse;
#[test]
fn test_highlighting() {
@ -414,7 +413,7 @@ mod tests {
#[track_caller]
fn test(text: &str, goal: &[(Range<usize>, Tag)]) {
let mut vec = vec![];
let root = parse(text);
let root = crate::parse(text);
highlight_tree(&mut vec, &LinkedNode::new(&root));
assert_eq!(vec, goal);
}

View File

@ -3,6 +3,7 @@
pub mod ast;
mod file;
mod highlight;
mod kind;
mod lexer;
mod node;
@ -12,6 +13,7 @@ mod source;
mod span;
pub use self::file::{FileId, PackageSpec, PackageVersion, VirtualPath};
pub use self::highlight::{highlight, highlight_html, Tag};
pub use self::kind::SyntaxKind;
pub use self::lexer::{is_id_continue, is_id_start, is_ident, is_newline};
pub use self::node::{LinkedChildren, LinkedNode, SyntaxError, SyntaxNode};

View File

@ -25,7 +25,6 @@ comemo = "0.3"
ecow = { version = "0.1.2", features = ["serde"] }
flate2 = "1"
fontdb = { version = "0.14", default-features = false }
if_chain = "1"
image = { version = "0.24", default-features = false, features = ["png", "jpeg", "gif"] }
indexmap = { version = "2", features = ["serde"] }
log = "0.4"

View File

@ -253,14 +253,12 @@ impl CastInfo {
msg.push_str(", found ");
write!(msg, "{}", found.ty()).unwrap();
}
if_chain::if_chain! {
if let Value::Int(i) = found;
if parts.iter().any(|p| p == "length");
if !matching_type;
then {
if let Value::Int(i) = found {
if parts.iter().any(|p| p == "length") && !matching_type {
write!(msg, ": a length needs a unit - did you mean {i}pt?").unwrap();
}
};
}
msg.into()
}

View File

@ -50,10 +50,12 @@ pub use self::cast::{
pub use self::datetime::Datetime;
pub use self::dict::{dict, Dict};
pub use self::duration::Duration;
pub use self::fields::fields_on;
pub use self::func::{
func, CapturesVisitor, Func, NativeFunc, NativeFuncData, ParamInfo,
};
pub use self::library::{set_lang_items, LangItems, Library};
pub use self::methods::mutable_methods_on;
pub use self::module::Module;
pub use self::none::NoneValue;
pub use self::plugin::Plugin;
@ -64,9 +66,6 @@ pub use self::tracer::Tracer;
pub use self::ty::{scope, ty, NativeType, NativeTypeData, Type};
pub use self::value::{Dynamic, Value};
pub(crate) use self::fields::fields_on;
pub(crate) use self::methods::mutable_methods_on;
use std::collections::HashSet;
use std::mem;
@ -1829,7 +1828,7 @@ impl Eval for ast::ModuleInclude<'_> {
}
/// Process an import of a module relative to the current location.
pub(crate) fn import(
pub fn import(
vm: &mut Vm,
source: Value,
span: Span,

View File

@ -46,7 +46,6 @@ pub mod doc;
pub mod export;
pub mod font;
pub mod geom;
pub mod ide;
pub mod image;
pub mod model;