Extract IDE crate
This commit is contained in:
parent
0d39fa021f
commit
d7928a8ea3
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -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"
|
||||
|
@ -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()));
|
||||
}
|
||||
|
@ -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,
|
||||
|
25
crates/typst-ide/Cargo.toml
Normal file
25
crates/typst-ide/Cargo.toml
Normal 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"
|
@ -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)
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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)]
|
@ -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();
|
@ -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(
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
@ -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};
|
||||
|
@ -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"
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user