mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-24 05:05:00 +00:00
feat: improve signature formatting in docs (#750)
* feat: improve signature formatting in docs * test: update snapshot * fix: package docs formatting
This commit is contained in:
parent
b97907cde6
commit
ac97c34d0f
44 changed files with 129 additions and 60 deletions
|
@ -218,7 +218,7 @@ impl<'a> TypeChecker<'a> {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
docs: param_doc.docs.clone(),
|
docs: param_doc.docs.clone(),
|
||||||
cano_type: (),
|
cano_type: (),
|
||||||
default: Some(eco_format!("{exp}")),
|
default: Some(exp.repr()),
|
||||||
attrs: ParamAttrs::named(),
|
attrs: ParamAttrs::named(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -439,6 +439,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_pkgs() {
|
fn test_pkgs() {
|
||||||
snapshot_testing("completion-pkgs", &run(TestConfig { pkg_mode: true }));
|
snapshot_testing("pkgs", &run(TestConfig { pkg_mode: true }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,7 +221,9 @@ pub fn package_docs(ctx: &mut AnalysisContext, spec: &PackageInfo) -> StrResult<
|
||||||
if let Some(SymbolDocs::Function(sig)) = &sym.head.parsed_docs {
|
if let Some(SymbolDocs::Function(sig)) = &sym.head.parsed_docs {
|
||||||
let _ = writeln!(md, "<!-- begin:sig -->");
|
let _ = writeln!(md, "<!-- begin:sig -->");
|
||||||
let _ = writeln!(md, "```typc");
|
let _ = writeln!(md, "```typc");
|
||||||
let _ = writeln!(md, "let {name}({sig});", name = sym.head.name);
|
let _ = write!(md, "let {}", sym.head.name);
|
||||||
|
let _ = sig.print(&mut md);
|
||||||
|
let _ = writeln!(md, ";");
|
||||||
let _ = writeln!(md, "```");
|
let _ = writeln!(md, "```");
|
||||||
let _ = writeln!(md, "<!-- end:sig -->");
|
let _ = writeln!(md, "<!-- end:sig -->");
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,17 +207,19 @@ pub type UntypedSignatureDocs = SignatureDocsT<()>;
|
||||||
/// Documentation about a signature.
|
/// Documentation about a signature.
|
||||||
pub type SignatureDocs = SignatureDocsT<TypeRepr>;
|
pub type SignatureDocs = SignatureDocsT<TypeRepr>;
|
||||||
|
|
||||||
impl fmt::Display for SignatureDocs {
|
impl SignatureDocs {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
/// Get the markdown representation of the documentation.
|
||||||
|
pub fn print(&self, f: &mut impl std::fmt::Write) -> fmt::Result {
|
||||||
let mut is_first = true;
|
let mut is_first = true;
|
||||||
let mut write_sep = |f: &mut fmt::Formatter<'_>| {
|
let mut write_sep = |f: &mut dyn std::fmt::Write| {
|
||||||
if is_first {
|
if is_first {
|
||||||
is_first = false;
|
is_first = false;
|
||||||
return Ok(());
|
return f.write_str("\n ");
|
||||||
}
|
}
|
||||||
f.write_str(", ")
|
f.write_str(",\n ")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
f.write_char('(')?;
|
||||||
for p in &self.pos {
|
for p in &self.pos {
|
||||||
write_sep(f)?;
|
write_sep(f)?;
|
||||||
f.write_str(&p.name)?;
|
f.write_str(&p.name)?;
|
||||||
|
@ -246,7 +248,7 @@ impl fmt::Display for SignatureDocs {
|
||||||
let v = v.as_deref().unwrap_or("any");
|
let v = v.as_deref().unwrap_or("any");
|
||||||
let mut v = v.trim();
|
let mut v = v.trim();
|
||||||
if v.starts_with('{') && v.ends_with('}') && v.len() > 30 {
|
if v.starts_with('{') && v.ends_with('}') && v.len() > 30 {
|
||||||
v = "{ ... }"
|
v = "{ .. }"
|
||||||
}
|
}
|
||||||
if v.starts_with('`') && v.ends_with('`') && v.len() > 30 {
|
if v.starts_with('`') && v.ends_with('`') && v.len() > 30 {
|
||||||
v = "raw"
|
v = "raw"
|
||||||
|
@ -258,9 +260,17 @@ impl fmt::Display for SignatureDocs {
|
||||||
if let Some(t) = t {
|
if let Some(t) = t {
|
||||||
write!(f, ": {t}")?;
|
write!(f, ": {t}")?;
|
||||||
}
|
}
|
||||||
write!(f, " = {v}")?;
|
if v.contains('\n') {
|
||||||
|
write!(f, " = {}", v.replace("\n", "\n "))?;
|
||||||
|
} else {
|
||||||
|
write!(f, " = {v}")?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !is_first {
|
||||||
|
f.write_str(",\n")?;
|
||||||
|
}
|
||||||
|
f.write_char(')')?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -303,7 +313,7 @@ fn format_ty(ty: Option<&Ty>, doc_ty: Option<&mut ShowTypeRepr>) -> TypeRepr {
|
||||||
match doc_ty {
|
match doc_ty {
|
||||||
Some(doc_ty) => doc_ty(ty),
|
Some(doc_ty) => doc_ty(ty),
|
||||||
None => ty
|
None => ty
|
||||||
.and_then(|ty| ty.describe())
|
.and_then(|ty| ty.repr())
|
||||||
.map(|short| (short, format!("{ty:?}"))),
|
.map(|short| (short, format!("{ty:?}"))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||||
input_file: crates/tinymist-query/src/fixtures/hover/annotate_fn.typ
|
input_file: crates/tinymist-query/src/fixtures/hover/annotate_fn.typ
|
||||||
---
|
---
|
||||||
{
|
{
|
||||||
"contents": "```typc\nlet touying-fn-wrapper(fn: (..: []) => any | function, ..args: arguments, max-repetitions: int | none = none, repetitions: int | none = none) = none;\n```\n\n---\n## Parameters\n\n@positional `fn` — The `fn`.\n\n@named `max-repetitions` — The `max-repetitions`.\n\n@named `repetitions` — The `repetitions`.\n\n@rest `args` — The `args`.",
|
"contents": "```typc\nlet touying-fn-wrapper(\n fn: (..: []) => any | function,\n ..args: arguments,\n max-repetitions: int | none = none,\n repetitions: int | none = none,\n) = none;\n```\n\n---\n## Parameters\n\n@positional `fn` — The `fn`.\n\n@named `max-repetitions` — The `max-repetitions`.\n\n@named `repetitions` — The `repetitions`.\n\n@rest `args` — The `args`.",
|
||||||
"range": "8:20:8:38"
|
"range": "8:20:8:38"
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||||
input_file: crates/tinymist-query/src/fixtures/hover/pagebreak.typ
|
input_file: crates/tinymist-query/src/fixtures/hover/pagebreak.typ
|
||||||
---
|
---
|
||||||
{
|
{
|
||||||
"contents": "```typc\nlet pagebreak(to: \"even\" | \"odd\" | none = none, weak: bool = false);\n```\n\n---\nA manual page break.\n\nMust not be used inside any containers.\n\n# Example\n```typ\nThe next page contains\nmore details on compound theory.\n#pagebreak()\n\n== Compound Theory\nIn 1984, the first ...\n```\n\n## Parameters\n\n@named `to` — If given, ensures that the next page will be an even/odd page, with an\nempty page in between if necessary.\n\n```typ\n#set page(height: 30pt)\n\nFirst.\n#pagebreak(to: \"odd\")\nThird.\n```\n\n@named `weak` — If `true`, the page break is skipped if the current page is already\nempty.\n\n---\n[Open docs](https://typst.app/docs/reference/layout/pagebreak/)",
|
"contents": "```typc\nlet pagebreak(\n to: none | str = none,\n weak: bool = false,\n);\n```\n\n---\nA manual page break.\n\nMust not be used inside any containers.\n\n# Example\n```typ\nThe next page contains\nmore details on compound theory.\n#pagebreak()\n\n== Compound Theory\nIn 1984, the first ...\n```\n\n## Parameters\n\n@named `to` — If given, ensures that the next page will be an even/odd page, with an\nempty page in between if necessary.\n\n```typ\n#set page(height: 30pt)\n\nFirst.\n#pagebreak(to: \"odd\")\nThird.\n```\n\n@named `weak` — If `true`, the page break is skipped if the current page is already\nempty.\n\n---\n[Open docs](https://typst.app/docs/reference/layout/pagebreak/)",
|
||||||
"range": "0:20:0:29"
|
"range": "0:20:0:29"
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||||
input_file: crates/tinymist-query/src/fixtures/hover/user.typ
|
input_file: crates/tinymist-query/src/fixtures/hover/user.typ
|
||||||
---
|
---
|
||||||
{
|
{
|
||||||
"contents": "```typc\nlet f() = 1;\n```\n\n---\nTest",
|
"contents": "```typc\nlet f() = int;\n```\n\n---\nTest",
|
||||||
"range": "3:20:3:21"
|
"range": "3:20:3:21"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
source: crates/tinymist-query/src/hover.rs
|
||||||
|
expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
||||||
|
input_file: crates/tinymist-query/src/fixtures/hover/value_repr.typ
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"contents": "```typc\nlet reconstruct(\n it,\n ..new-body: arguments,\n body-name: str = \"body\",\n labeled: bool = true,\n max-depth: int = 9999,\n wrapper: () => box = Closure(..),\n) = none;\n```\n\n---\n## Parameters\n\n@positional `it`\n\n@named `body-name`\n\n@named `labeled`\n\n@named `max-depth`\n\n@named `wrapper`\n\n@rest `new-body`",
|
||||||
|
"range": "1:20:1:31"
|
||||||
|
}
|
2
crates/tinymist-query/src/fixtures/hover/value_repr.typ
Normal file
2
crates/tinymist-query/src/fixtures/hover/value_repr.typ
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#let reconstruct(body-name: "body", labeled: true, max-depth: 9999, wrapper: () => box(""), it, ..new-body) = { }
|
||||||
|
#(/* ident after */ reconstruct);
|
|
@ -4,4 +4,4 @@ description: "Check on \"(\" (17)"
|
||||||
expression: literal_type
|
expression: literal_type
|
||||||
input_file: crates/tinymist-query/src/fixtures/post_type_check/with_builtin.typ
|
input_file: crates/tinymist-query/src/fixtures/post_type_check/with_builtin.typ
|
||||||
---
|
---
|
||||||
( ⪯ (Type(integer) | Type(ratio)))
|
( ⪯ (Type(int) | Type(ratio)))
|
||||||
|
|
|
@ -7,7 +7,7 @@ input_file: crates/tinymist-query/src/fixtures/type_check/annotation_fn.typ
|
||||||
"fn" = Any
|
"fn" = Any
|
||||||
"max-repetitions" = None
|
"max-repetitions" = None
|
||||||
"repetitions" = None
|
"repetitions" = None
|
||||||
"touying-fn-wrapper" = ((( ⪯ Type(function)), "max-repetitions": ( ⪯ Type(integer)), "repetitions": ( ⪯ Type(integer)), ...: ( ⪯ Any)) => None).with(..("max-repetitions": None, "repetitions": None) => any)
|
"touying-fn-wrapper" = ((( ⪯ Type(function)), "max-repetitions": ( ⪯ Type(int)), "repetitions": ( ⪯ Type(int)), ...: ( ⪯ Any)) => None).with(..("max-repetitions": None, "repetitions": None) => any)
|
||||||
---
|
---
|
||||||
162..180 -> @touying-fn-wrapper
|
162..180 -> @touying-fn-wrapper
|
||||||
181..183 -> @fn
|
181..183 -> @fn
|
||||||
|
|
|
@ -4,7 +4,7 @@ expression: result
|
||||||
input_file: crates/tinymist-query/src/fixtures/type_check/annotation_sum.typ
|
input_file: crates/tinymist-query/src/fixtures/type_check/annotation_sum.typ
|
||||||
---
|
---
|
||||||
"args" = Args
|
"args" = Args
|
||||||
"sum" = (...: ( ⪯ Array<Type(integer)>)) => None
|
"sum" = (...: ( ⪯ Array<Type(int)>)) => None
|
||||||
---
|
---
|
||||||
65..68 -> @sum
|
65..68 -> @sum
|
||||||
71..75 -> @args
|
71..75 -> @args
|
||||||
|
|
|
@ -3,7 +3,7 @@ source: crates/tinymist-query/src/analysis.rs
|
||||||
expression: result
|
expression: result
|
||||||
input_file: crates/tinymist-query/src/fixtures/type_check/fn_named.typ
|
input_file: crates/tinymist-query/src/fixtures/type_check/fn_named.typ
|
||||||
---
|
---
|
||||||
"d" = ( ⪰ 3 | Type(integer))
|
"d" = ( ⪰ 3 | Type(int))
|
||||||
"foo" = (("d": Any) => Any).with(..("d": 3) => any)
|
"foo" = (("d": Any) => Any).with(..("d": 3) => any)
|
||||||
"x" = 3
|
"x" = 3
|
||||||
---
|
---
|
||||||
|
|
|
@ -6,7 +6,7 @@ input_file: crates/tinymist-query/src/fixtures/type_check/infer.typ
|
||||||
1..6 -> Func(image)
|
1..6 -> Func(image)
|
||||||
1..18 -> Element(image)
|
1..18 -> Element(image)
|
||||||
21..25 -> Func(read)
|
21..25 -> Func(read)
|
||||||
21..37 -> (Type(bytes) | Type(string))
|
21..37 -> (Type(bytes) | Type(str))
|
||||||
40..44 -> Func(json)
|
40..44 -> Func(json)
|
||||||
40..57 -> Any
|
40..57 -> Any
|
||||||
60..64 -> Func(yaml)
|
60..64 -> Func(yaml)
|
||||||
|
|
|
@ -7,7 +7,7 @@ input_file: crates/tinymist-query/src/fixtures/type_check/sig_template_set.typ
|
||||||
"class" = ( ⪰ "article" | "article" | "letter" | "article" | "letter")
|
"class" = ( ⪰ "article" | "article" | "letter" | "article" | "letter")
|
||||||
"content" = Any
|
"content" = Any
|
||||||
"font" = None
|
"font" = None
|
||||||
"tmpl" = ((Any, "authors": ( ⪯ (Type(array) | Type(string))), "class": Any, "font": ( ⪯ (TextFont | Array<TextFont>))) => Any).with(..("authors": (), "class": "article", "font": None) => any)
|
"tmpl" = ((Any, "authors": ( ⪯ (Type(array) | Type(str))), "class": Any, "font": ( ⪯ (TextFont | Array<TextFont>))) => Any).with(..("authors": (), "class": "article", "font": None) => any)
|
||||||
---
|
---
|
||||||
5..9 -> @tmpl
|
5..9 -> @tmpl
|
||||||
10..17 -> @content
|
10..17 -> @content
|
||||||
|
|
|
@ -3,10 +3,10 @@ source: crates/tinymist-query/src/analysis.rs
|
||||||
expression: result
|
expression: result
|
||||||
input_file: crates/tinymist-query/src/fixtures/type_check/tuple_map.typ
|
input_file: crates/tinymist-query/src/fixtures/type_check/tuple_map.typ
|
||||||
---
|
---
|
||||||
"" = (( ⪯ (Type(bytes) | Type(decimal) | Type(float) | Type(integer) | Type(label) | Type(string) | Type(type) | Type(version)))) => Type(string)
|
"" = (( ⪯ (Type(bytes) | Type(decimal) | Type(float) | Type(int) | Type(label) | Type(str) | Type(type) | Type(version)))) => Type(str)
|
||||||
"a" = (1, )
|
"a" = (1, )
|
||||||
"b" = (Type(string), )
|
"b" = (Type(str), )
|
||||||
"f" = (( ⪯ (Type(bytes) | Type(decimal) | Type(float) | Type(integer) | Type(label) | Type(string) | Type(type) | Type(version)))) => Type(string)
|
"f" = (( ⪯ (Type(bytes) | Type(decimal) | Type(float) | Type(int) | Type(label) | Type(str) | Type(type) | Type(version)))) => Type(str)
|
||||||
"x" = Any
|
"x" = Any
|
||||||
---
|
---
|
||||||
5..6 -> @a
|
5..6 -> @a
|
||||||
|
@ -14,9 +14,9 @@ input_file: crates/tinymist-query/src/fixtures/type_check/tuple_map.typ
|
||||||
24..25 -> @x
|
24..25 -> @x
|
||||||
24..35 -> @
|
24..35 -> @
|
||||||
29..32 -> Type(string)
|
29..32 -> Type(string)
|
||||||
29..35 -> Type(string)
|
29..35 -> Type(str)
|
||||||
33..34 -> @x
|
33..34 -> @x
|
||||||
42..43 -> @b
|
42..43 -> @b
|
||||||
46..47 -> @a
|
46..47 -> @a
|
||||||
46..54 -> (Type(string), )
|
46..54 -> (Type(str), )
|
||||||
52..53 -> @f
|
52..53 -> @f
|
||||||
|
|
|
@ -5,7 +5,7 @@ input_file: crates/tinymist-query/src/fixtures/type_check/with.typ
|
||||||
---
|
---
|
||||||
"f" = (Any) => Any
|
"f" = (Any) => Any
|
||||||
"g" = ((Any) => Any).with(..(1) => any)
|
"g" = ((Any) => Any).with(..(1) => any)
|
||||||
"x" = ( ⪰ Type(integer) | Type(integer))
|
"x" = ( ⪰ Type(int) | Type(int))
|
||||||
"x" = 1
|
"x" = 1
|
||||||
---
|
---
|
||||||
5..6 -> @f
|
5..6 -> @f
|
||||||
|
|
|
@ -256,7 +256,7 @@ fn def_tooltip(
|
||||||
results.push(MarkedString::LanguageString(LanguageString {
|
results.push(MarkedString::LanguageString(LanguageString {
|
||||||
language: "typc".to_owned(),
|
language: "typc".to_owned(),
|
||||||
value: format!(
|
value: format!(
|
||||||
"let {name}({params}){result};",
|
"let {name}{params}{result};",
|
||||||
name = def.name(),
|
name = def.name(),
|
||||||
params = ParamTooltip(sig.as_ref()),
|
params = ParamTooltip(sig.as_ref()),
|
||||||
result =
|
result =
|
||||||
|
@ -372,7 +372,7 @@ impl fmt::Display for ParamTooltip<'_> {
|
||||||
let Some(sig) = self.0 else {
|
let Some(sig) = self.0 else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
sig.fmt(f)
|
sig.print(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ impl Expr {
|
||||||
|
|
||||||
impl fmt::Display for Expr {
|
impl fmt::Display for Expr {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
ExprFormatter::new(f).write_expr(self)
|
ExprFormatter::new(f, false).write_expr(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +571,15 @@ pub enum Pattern {
|
||||||
|
|
||||||
impl fmt::Display for Pattern {
|
impl fmt::Display for Pattern {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
ExprFormatter::new(f).write_pattern(self)
|
ExprFormatter::new(f, false).write_pattern(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Pattern {
|
||||||
|
pub(crate) fn repr(&self) -> EcoString {
|
||||||
|
let mut s = EcoString::new();
|
||||||
|
let _ = ExprFormatter::new(&mut s, true).write_pattern(self);
|
||||||
|
s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -847,14 +855,15 @@ impl_internable!(
|
||||||
ApplyExpr,
|
ApplyExpr,
|
||||||
);
|
);
|
||||||
|
|
||||||
struct ExprFormatter<'a, 'b> {
|
struct ExprFormatter<'a, T: fmt::Write> {
|
||||||
f: &'a mut fmt::Formatter<'b>,
|
f: &'a mut T,
|
||||||
|
repr: bool,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> ExprFormatter<'a, 'b> {
|
impl<'a, T: fmt::Write> ExprFormatter<'a, T> {
|
||||||
fn new(f: &'a mut fmt::Formatter<'b>) -> Self {
|
fn new(f: &'a mut T, repr: bool) -> Self {
|
||||||
Self { f, indent: 0 }
|
Self { f, repr, indent: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_decl(&mut self, d: &Decl) -> fmt::Result {
|
fn write_decl(&mut self, d: &Decl) -> fmt::Result {
|
||||||
|
@ -1043,6 +1052,10 @@ impl<'a, 'b> ExprFormatter<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_func(&mut self, func: &Interned<FuncExpr>) -> fmt::Result {
|
fn write_func(&mut self, func: &Interned<FuncExpr>) -> fmt::Result {
|
||||||
|
if self.repr {
|
||||||
|
return self.write_decl(&func.decl);
|
||||||
|
}
|
||||||
|
|
||||||
write!(self.f, "func[{:?}](", func.decl)?;
|
write!(self.f, "func[{:?}](", func.decl)?;
|
||||||
self.write_pattern_sig(&func.params)?;
|
self.write_pattern_sig(&func.params)?;
|
||||||
write!(self.f, " = ")?;
|
write!(self.f, " = ")?;
|
||||||
|
@ -1130,12 +1143,20 @@ impl<'a, 'b> ExprFormatter<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_contextual(&mut self, c: &Interned<Expr>) -> fmt::Result {
|
fn write_contextual(&mut self, c: &Interned<Expr>) -> fmt::Result {
|
||||||
|
if self.repr {
|
||||||
|
return self.f.write_str("content");
|
||||||
|
}
|
||||||
|
|
||||||
self.f.write_str("contextual(")?;
|
self.f.write_str("contextual(")?;
|
||||||
self.write_expr(c)?;
|
self.write_expr(c)?;
|
||||||
self.f.write_str(")")
|
self.f.write_str(")")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_conditional(&mut self, c: &Interned<IfExpr>) -> fmt::Result {
|
fn write_conditional(&mut self, c: &Interned<IfExpr>) -> fmt::Result {
|
||||||
|
if self.repr {
|
||||||
|
return self.f.write_str("Expr(..)");
|
||||||
|
}
|
||||||
|
|
||||||
self.f.write_str("if(")?;
|
self.f.write_str("if(")?;
|
||||||
self.write_expr(&c.cond)?;
|
self.write_expr(&c.cond)?;
|
||||||
self.f.write_str(", then = ")?;
|
self.f.write_str(", then = ")?;
|
||||||
|
@ -1146,6 +1167,10 @@ impl<'a, 'b> ExprFormatter<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_while_loop(&mut self, w: &Interned<WhileExpr>) -> fmt::Result {
|
fn write_while_loop(&mut self, w: &Interned<WhileExpr>) -> fmt::Result {
|
||||||
|
if self.repr {
|
||||||
|
return self.f.write_str("Expr(..)");
|
||||||
|
}
|
||||||
|
|
||||||
self.f.write_str("while(")?;
|
self.f.write_str("while(")?;
|
||||||
self.write_expr(&w.cond)?;
|
self.write_expr(&w.cond)?;
|
||||||
self.f.write_str(", ")?;
|
self.f.write_str(", ")?;
|
||||||
|
@ -1154,6 +1179,10 @@ impl<'a, 'b> ExprFormatter<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_for_loop(&mut self, f: &Interned<ForExpr>) -> fmt::Result {
|
fn write_for_loop(&mut self, f: &Interned<ForExpr>) -> fmt::Result {
|
||||||
|
if self.repr {
|
||||||
|
return self.f.write_str("Expr(..)");
|
||||||
|
}
|
||||||
|
|
||||||
self.f.write_str("for(")?;
|
self.f.write_str("for(")?;
|
||||||
self.write_pattern(&f.pattern)?;
|
self.write_pattern(&f.pattern)?;
|
||||||
self.f.write_str(", ")?;
|
self.f.write_str(", ")?;
|
||||||
|
|
|
@ -263,7 +263,7 @@ impl fmt::Debug for BuiltinTy {
|
||||||
BuiltinTy::Inset => write!(f, "Inset"),
|
BuiltinTy::Inset => write!(f, "Inset"),
|
||||||
BuiltinTy::Outset => write!(f, "Outset"),
|
BuiltinTy::Outset => write!(f, "Outset"),
|
||||||
BuiltinTy::Radius => write!(f, "Radius"),
|
BuiltinTy::Radius => write!(f, "Radius"),
|
||||||
BuiltinTy::Type(ty) => write!(f, "Type({})", ty.long_name()),
|
BuiltinTy::Type(ty) => write!(f, "Type({})", ty.short_name()),
|
||||||
BuiltinTy::Element(e) => e.fmt(f),
|
BuiltinTy::Element(e) => e.fmt(f),
|
||||||
BuiltinTy::Tag(tag) => {
|
BuiltinTy::Tag(tag) => {
|
||||||
let (name, id) = tag.as_ref();
|
let (name, id) = tag.as_ref();
|
||||||
|
|
|
@ -6,12 +6,21 @@ use crate::ty::prelude::*;
|
||||||
impl TypeScheme {
|
impl TypeScheme {
|
||||||
/// Describe the given type with the given type scheme.
|
/// Describe the given type with the given type scheme.
|
||||||
pub fn describe(&self, ty: &Ty) -> Option<String> {
|
pub fn describe(&self, ty: &Ty) -> Option<String> {
|
||||||
let mut worker = TypeDescriber::default();
|
let mut worker: TypeDescriber = TypeDescriber::default();
|
||||||
worker.describe_root(ty)
|
worker.describe_root(ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ty {
|
impl Ty {
|
||||||
|
/// Describe the given type.
|
||||||
|
pub fn repr(&self) -> Option<String> {
|
||||||
|
let mut worker = TypeDescriber {
|
||||||
|
repr: true,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
worker.describe_root(self)
|
||||||
|
}
|
||||||
|
|
||||||
/// Describe the given type.
|
/// Describe the given type.
|
||||||
pub fn describe(&self) -> Option<String> {
|
pub fn describe(&self) -> Option<String> {
|
||||||
let mut worker = TypeDescriber::default();
|
let mut worker = TypeDescriber::default();
|
||||||
|
@ -21,6 +30,7 @@ impl Ty {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct TypeDescriber {
|
struct TypeDescriber {
|
||||||
|
repr: bool,
|
||||||
described: HashMap<u128, String>,
|
described: HashMap<u128, String>,
|
||||||
results: HashSet<String>,
|
results: HashSet<String>,
|
||||||
functions: Vec<Interned<SigTy>>,
|
functions: Vec<Interned<SigTy>>,
|
||||||
|
@ -148,8 +158,11 @@ impl TypeDescriber {
|
||||||
Ty::Builtin(BuiltinTy::Auto) => {
|
Ty::Builtin(BuiltinTy::Auto) => {
|
||||||
return "auto".to_string();
|
return "auto".to_string();
|
||||||
}
|
}
|
||||||
|
Ty::Boolean(..) if self.repr => {
|
||||||
|
return "bool".to_string();
|
||||||
|
}
|
||||||
Ty::Boolean(None) => {
|
Ty::Boolean(None) => {
|
||||||
return "boolean".to_string();
|
return "bool".to_string();
|
||||||
}
|
}
|
||||||
Ty::Boolean(Some(b)) => {
|
Ty::Boolean(Some(b)) => {
|
||||||
return b.to_string();
|
return b.to_string();
|
||||||
|
@ -157,27 +170,19 @@ impl TypeDescriber {
|
||||||
Ty::Builtin(b) => {
|
Ty::Builtin(b) => {
|
||||||
return b.describe();
|
return b.describe();
|
||||||
}
|
}
|
||||||
|
Ty::Value(v) if self.repr => return v.val.ty().short_name().to_string(),
|
||||||
Ty::Value(v) => return v.val.repr().to_string(),
|
Ty::Value(v) => return v.val.repr().to_string(),
|
||||||
Ty::Field(..) => {
|
Ty::Field(..) => {
|
||||||
return "field".to_string();
|
return "field".to_string();
|
||||||
}
|
}
|
||||||
Ty::Args(..) => {
|
Ty::Args(..) => {
|
||||||
return "args".to_string();
|
return "arguments".to_string();
|
||||||
}
|
}
|
||||||
Ty::Pattern(..) => {
|
Ty::Pattern(..) => {
|
||||||
return "pattern".to_string();
|
return "pattern".to_string();
|
||||||
}
|
}
|
||||||
Ty::Select(..) => {
|
Ty::Select(..) | Ty::Unary(..) | Ty::Binary(..) | Ty::If(..) => {
|
||||||
return "any".to_string();
|
return "any".to_string()
|
||||||
}
|
|
||||||
Ty::Unary(..) => {
|
|
||||||
return "any".to_string();
|
|
||||||
}
|
|
||||||
Ty::Binary(..) => {
|
|
||||||
return "any".to_string();
|
|
||||||
}
|
|
||||||
Ty::If(..) => {
|
|
||||||
return "any".to_string();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -909,7 +909,7 @@ fn type_completion(
|
||||||
} else {
|
} else {
|
||||||
ctx.completions.push(Completion {
|
ctx.completions.push(Completion {
|
||||||
kind: CompletionKind::Syntax,
|
kind: CompletionKind::Syntax,
|
||||||
label: ty.long_name().into(),
|
label: ty.short_name().into(),
|
||||||
apply: Some(eco_format!("${{{ty}}}")),
|
apply: Some(eco_format!("${{{ty}}}")),
|
||||||
detail: Some(eco_format!("A value of type {ty}.")),
|
detail: Some(eco_format!("A value of type {ty}.")),
|
||||||
..Completion::default()
|
..Completion::default()
|
||||||
|
|
|
@ -96,7 +96,7 @@ const primitiveFunctions = {
|
||||||
|
|
||||||
const primitiveTypes: textmate.PatternMatch = {
|
const primitiveTypes: textmate.PatternMatch = {
|
||||||
match:
|
match:
|
||||||
/\b(auto|any|none|false|true|str|int|float|bool|length|content)\b(?!-)/,
|
/\b(any|str|int|float|bool|length|content|array|dictionary|arguments)\b(?!-)/,
|
||||||
name: "entity.name.type.primitive.typst",
|
name: "entity.name.type.primitive.typst",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -380,7 +380,12 @@ const markupEnterCode: textmate.Pattern = {
|
||||||
),
|
),
|
||||||
enterExpression(
|
enterExpression(
|
||||||
"entity.name.type.primitive.hash.typst",
|
"entity.name.type.primitive.hash.typst",
|
||||||
/(?=(?:auto|any|none|false|true|str|int|float|bool|length|content)\b(?!-))/
|
/(?=(?:any|str|int|float|bool|length|content|array|dictionary|arguments)\b(?!-))/
|
||||||
|
),
|
||||||
|
enterExpression("keyword.other.none.hash.typst", /(?=(?:none)\b(?!-))/),
|
||||||
|
enterExpression(
|
||||||
|
"constant.language.boolean.hash.typst",
|
||||||
|
/(?=(?:false|true)\b(?!-))/
|
||||||
),
|
),
|
||||||
enterExpression(
|
enterExpression(
|
||||||
"entity.name.function.hash.typst",
|
"entity.name.function.hash.typst",
|
||||||
|
@ -421,20 +426,25 @@ const floatUnit = (unit: RegExp, canDotSuff: boolean) =>
|
||||||
FLOAT_OR_INT.source + (canDotSuff ? "" : "(?<!\\.)") + unit.source
|
FLOAT_OR_INT.source + (canDotSuff ? "" : "(?<!\\.)") + unit.source
|
||||||
);
|
);
|
||||||
|
|
||||||
const constants: textmate.Pattern = {
|
const keywordConstants: textmate.Pattern = {
|
||||||
patterns: [
|
patterns: [
|
||||||
{
|
{
|
||||||
name: "constant.language.none.typst",
|
name: "keyword.other.none.typst",
|
||||||
match: /(?<!\)|\]|\})\bnone\b(?!-)/,
|
match: /(?<!\)|\]|\})\bnone\b(?!-)/,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "constant.language.auto.typst",
|
name: "keyword.other.auto.typst",
|
||||||
match: /(?<!\)|\]|\})\bauto\b(?!-)/,
|
match: /(?<!\)|\]|\})\bauto\b(?!-)/,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "constant.language.boolean.typst",
|
name: "constant.language.boolean.typst",
|
||||||
match: /(?<!\)|\]|\})\b(true|false)\b(?!-)/,
|
match: /(?<!\)|\]|\})\b(false|true)\b(?!-)/,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const constants: textmate.Pattern = {
|
||||||
|
patterns: [
|
||||||
{
|
{
|
||||||
name: "constant.numeric.length.typst",
|
name: "constant.numeric.length.typst",
|
||||||
match: floatUnit(/(mm|pt|cm|in|em)($|\b)/, false),
|
match: floatUnit(/(mm|pt|cm|in|em)($|\b)/, false),
|
||||||
|
@ -522,6 +532,7 @@ const expressions = (): textmate.Grammar => {
|
||||||
{ include: "#primitiveFunctions" },
|
{ include: "#primitiveFunctions" },
|
||||||
{ include: "#primitiveTypes" },
|
{ include: "#primitiveTypes" },
|
||||||
// todo: enable if only if for completely right grammar
|
// todo: enable if only if for completely right grammar
|
||||||
|
{ include: "#keywordConstants" },
|
||||||
{ include: "#identifier" },
|
{ include: "#identifier" },
|
||||||
{ include: "#constants" },
|
{ include: "#constants" },
|
||||||
{
|
{
|
||||||
|
@ -1373,6 +1384,7 @@ export const typst: textmate.Grammar = {
|
||||||
markup,
|
markup,
|
||||||
markupEnterCode,
|
markupEnterCode,
|
||||||
code,
|
code,
|
||||||
|
keywordConstants,
|
||||||
constants,
|
constants,
|
||||||
|
|
||||||
primitiveColors,
|
primitiveColors,
|
||||||
|
|
|
@ -374,7 +374,7 @@ fn e2e() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let hash = replay_log(&tinymist_binary, &root.join("neovim"));
|
let hash = replay_log(&tinymist_binary, &root.join("neovim"));
|
||||||
insta::assert_snapshot!(hash, @"siphash128_13:65fa45388648e656b1ec7cc30c48ad85");
|
insta::assert_snapshot!(hash, @"siphash128_13:bafb35d07c168f6630fc455df6ba0a3");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -385,7 +385,7 @@ fn e2e() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let hash = replay_log(&tinymist_binary, &root.join("vscode"));
|
let hash = replay_log(&tinymist_binary, &root.join("vscode"));
|
||||||
insta::assert_snapshot!(hash, @"siphash128_13:79e7e3ea6fab006d0b4b510940e10ee9");
|
insta::assert_snapshot!(hash, @"siphash128_13:1cd09a6f0362384cafcbf632da1a1d0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue