feat: improve style of hover param docs (#813)

* feat: improve style of hover param docs

* feat: give value example in parameter docs
This commit is contained in:
Myriad-Dreamin 2024-11-14 20:49:14 +08:00 committed by GitHub
parent c128f633d4
commit 808da99092
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 103 additions and 81 deletions

View file

@ -388,7 +388,7 @@ mod type_describe_tests {
description => format!("Check on {text:?} ({pos:?})"), description => format!("Check on {text:?} ({pos:?})"),
}, { }, {
let literal_type = literal_type.and_then(|e| e.describe()) let literal_type = literal_type.and_then(|e| e.describe())
.unwrap_or_else(|| "<nil>".to_string()); .unwrap_or_else(|| "<nil>".into());
assert_snapshot!(literal_type); assert_snapshot!(literal_type);
}) })
}); });

View file

@ -2,7 +2,7 @@ use core::fmt;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::sync::OnceLock; use std::sync::OnceLock;
use ecow::EcoString; use ecow::{eco_format, EcoString};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use typst::syntax::Span; use typst::syntax::Span;
@ -14,9 +14,9 @@ use crate::ty::{DocSource, Interned};
use crate::upstream::plain_docs_sentence; use crate::upstream::plain_docs_sentence;
type TypeRepr = Option<( type TypeRepr = Option<(
/* short */ String, /* short */ EcoString,
/* long */ String, /* long */ EcoString,
/* value */ String, /* value */ EcoString,
)>; )>;
/// Documentation about a definition (without type information). /// Documentation about a definition (without type information).
@ -100,41 +100,57 @@ impl fmt::Display for SigHoverDocs<'_> {
let docs = self.0; let docs = self.0;
let base_docs = docs.docs.trim(); let base_docs = docs.docs.trim();
let has_params_docs = !docs.pos.is_empty() || !docs.named.is_empty() || docs.rest.is_some();
if !base_docs.is_empty() { if !base_docs.is_empty() {
f.write_str(base_docs)?; f.write_str(base_docs)?;
}
if has_params_docs { fn write_param_docs(
f.write_str("\n\n")?; f: &mut fmt::Formatter<'_>,
p: &ParamDocsT<TypeRepr>,
kind: &str,
is_first: &mut bool,
) -> fmt::Result {
if *is_first {
*is_first = false;
write!(f, "\n\n## {}\n\n", p.name)?;
} else {
write!(f, "\n\n## {} ({kind})\n\n", p.name)?;
}
// p.cano_type.0
if let Some(t) = &p.cano_type {
write!(f, "```typc\ntype: {}\n```\n\n", t.2)?;
}
f.write_str(p.docs.trim())?;
Ok(())
}
if !docs.pos.is_empty() {
f.write_str("\n\n# Positional Parameters")?;
let mut is_first = true;
for p in &docs.pos {
write_param_docs(f, p, "positional", &mut is_first)?;
} }
} }
if has_params_docs { if docs.rest.is_some() {
f.write_str("## Parameters")?; f.write_str("\n\n# Rest Parameters")?;
for p in &docs.pos {
write!(f, "\n\n@positional `{}`", p.name)?;
if !p.docs.is_empty() {
f.write_str("")?;
f.write_str(&p.docs)?;
}
}
for (name, p) in &docs.named {
write!(f, "\n\n@named `{name}`")?;
if !p.docs.is_empty() {
f.write_str("")?;
f.write_str(&p.docs)?;
}
}
let mut is_first = true;
if let Some(rest) = &docs.rest { if let Some(rest) = &docs.rest {
write!(f, "\n\n@rest `{}`", rest.name)?; write_param_docs(f, rest, "spread right", &mut is_first)?;
if !rest.docs.is_empty() { }
f.write_str("")?; }
f.write_str(&rest.docs)?;
} if !docs.named.is_empty() {
f.write_str("\n\n# Named Parameters")?;
let mut is_first = true;
for p in docs.named.values() {
write_param_docs(f, p, "named", &mut is_first)?;
} }
} }
@ -219,7 +235,7 @@ impl SignatureDocs {
/// Documentation about a variable (without type information). /// Documentation about a variable (without type information).
pub type UntypedVarDocs = VarDocsT<()>; pub type UntypedVarDocs = VarDocsT<()>;
/// Documentation about a variable. /// Documentation about a variable.
pub type VarDocs = VarDocsT<Option<(String, String, String)>>; pub type VarDocs = VarDocsT<Option<(EcoString, EcoString, EcoString)>>;
/// Describes a primary pattern binding. /// Describes a primary pattern binding.
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@ -276,9 +292,9 @@ impl ParamDocs {
fn format_ty(ty: Option<&Ty>) -> TypeRepr { fn format_ty(ty: Option<&Ty>) -> TypeRepr {
let ty = ty?; let ty = ty?;
let short = ty.repr().unwrap_or_else(|| "any".to_owned()); let short = ty.repr().unwrap_or_else(|| "any".into());
let long = format!("{ty:?}"); let long = eco_format!("{ty:?}");
let value = ty.value_repr().unwrap_or_else(|| "".to_owned()); let value = ty.value_repr().unwrap_or_else(|| "".into());
Some((short, long, value)) Some((short, long, value))
} }

View file

@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
input_file: crates/tinymist-query/src/fixtures/hover/annotate_docs_error.typ input_file: crates/tinymist-query/src/fixtures/hover/annotate_docs_error.typ
--- ---
{ {
"contents": "```typc\nlet speaker-note(\n note: any,\n mode: str = \"typ\",\n setting: (any) => any = Closure(..),\n) = none;\n```\n\n---\nSpeaker notes are a way to add additional information to your slides that is not visible to the audience. This can be useful for providing additional context or reminders to yourself.\n\n ## Example\n\n ```typ\n#speaker-note[This is a speaker note]\n\n```\n```\nRender Error\ncompiling node: error: unknown variable: speaker-note at \"/__render__.typ\":201..213\nHint: if you meant to use subtraction, try adding spaces around the minus sign: \\`speaker - note\\`\n\n```\n\n## Parameters\n\n@positional `note`\n\n@named `mode`\n\n@named `setting`", "contents": "```typc\nlet speaker-note(\n note: any,\n mode: str = \"typ\",\n setting: (any) => any = Closure(..),\n) = none;\n```\n\n---\nSpeaker notes are a way to add additional information to your slides that is not visible to the audience. This can be useful for providing additional context or reminders to yourself.\n\n ## Example\n\n ```typ\n#speaker-note[This is a speaker note]\n\n```\n```\nRender Error\ncompiling node: error: unknown variable: speaker-note at \"/__render__.typ\":201..213\nHint: if you meant to use subtraction, try adding spaces around the minus sign: \\`speaker - note\\`\n\n```\n\n# Positional Parameters\n\n## note\n\n```typc\ntype: \n```\n\n\n\n# Named Parameters\n\n## mode\n\n```typc\ntype: \"typ\"\n```\n\n\n\n## setting (named)\n\n```typc\ntype: (any) => any\n```\n\n",
"range": "11:20:11:32" "range": "11:20:11:32"
} }

View file

@ -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(\n fn: (..: any) => 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`.", "contents": "```typc\nlet touying-fn-wrapper(\n fn: (..: any) => any | function,\n ..args: arguments,\n max-repetitions: int | none = none,\n repetitions: int | none = none,\n) = none;\n```\n\n---\n\n\n# Positional Parameters\n\n## fn\n\n```typc\ntype: (..: any) => any | function\n```\n\nThe `fn`.\n\n# Rest Parameters\n\n## args\n\n```typc\ntype: arguments\n```\n\nThe `args`.\n\n# Named Parameters\n\n## max-repetitions\n\n```typc\ntype: int | none\n```\n\nThe `max-repetitions`.\n\n## repetitions (named)\n\n```typc\ntype: int | none\n```\n\nThe `repetitions`.",
"range": "8:20:8:38" "range": "8:20:8:38"
} }

View file

@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
input_file: crates/tinymist-query/src/fixtures/hover/annotate_ret.typ input_file: crates/tinymist-query/src/fixtures/hover/annotate_ret.typ
--- ---
{ {
"contents": "```typc\nlet _delayed-wrapper(\n body: any,\n) = content;\n```\n\n---\n## Parameters\n\n@positional `body`", "contents": "```typc\nlet _delayed-wrapper(\n body: any,\n) = content;\n```\n\n---\n\n\n# Positional Parameters\n\n## body\n\n```typc\ntype: \n```\n\n",
"range": "6:20:6:36" "range": "6:20:6:36"
} }

File diff suppressed because one or more lines are too long

View file

@ -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(\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/)", "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# Named Parameters\n\n## to\n\n```typc\ntype: \"even\" | \"odd\" | none\n```\n\nIf 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## weak (named)\n\n```typc\ntype: bool\n```\n\nIf `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"
} }

View file

@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
input_file: crates/tinymist-query/src/fixtures/hover/value_repr.typ input_file: crates/tinymist-query/src/fixtures/hover/value_repr.typ
--- ---
{ {
"contents": "```typc\nlet f(\n x: any,\n y: any,\n z: any,\n w01: int = 1,\n w02: str = \"test\",\n w03: any = 1 + 2,\n w04: any = Label(test),\n w05: function = box,\n w06: any = list.item,\n w07: content = Expr(..),\n w08: any = Expr(..),\n w09: any = 1 + 2,\n w10: array = (\n 1,\n 2,\n ),\n w11: array = (),\n w12: dict = (:),\n w13: dict = (a: 1),\n w14: dict = (a: box),\n w15: dict = (a: list.item),\n) = int;\n```\n\n---\n## Parameters\n\n@positional `x`\n\n@positional `y`\n\n@positional `z`\n\n@named `w01`\n\n@named `w02`\n\n@named `w03`\n\n@named `w04`\n\n@named `w05`\n\n@named `w06`\n\n@named `w07`\n\n@named `w08`\n\n@named `w09`\n\n@named `w10`\n\n@named `w11`\n\n@named `w12`\n\n@named `w13`\n\n@named `w14`\n\n@named `w15`", "contents": "```typc\nlet f(\n x: any,\n y: any,\n z: any,\n w01: int = 1,\n w02: str = \"test\",\n w03: any = 1 + 2,\n w04: any = Label(test),\n w05: function = box,\n w06: any = list.item,\n w07: content = Expr(..),\n w08: any = Expr(..),\n w09: any = 1 + 2,\n w10: array = (\n 1,\n 2,\n ),\n w11: array = (),\n w12: dict = (:),\n w13: dict = (a: 1),\n w14: dict = (a: box),\n w15: dict = (a: list.item),\n) = int;\n```\n\n---\n\n\n# Positional Parameters\n\n## x\n\n```typc\ntype: \n```\n\n\n\n## y (positional)\n\n```typc\ntype: \n```\n\n\n\n## z (positional)\n\n```typc\ntype: \n```\n\n\n\n# Named Parameters\n\n## w01\n\n```typc\ntype: 1\n```\n\n\n\n## w02 (named)\n\n```typc\ntype: \"test\"\n```\n\n\n\n## w03 (named)\n\n```typc\ntype: any\n```\n\n\n\n## w04 (named)\n\n```typc\ntype: \n```\n\n\n\n## w05 (named)\n\n```typc\ntype: box\n```\n\n\n\n## w06 (named)\n\n```typc\ntype: any\n```\n\n\n\n## w07 (named)\n\n```typc\ntype: content\n```\n\n\n\n## w08 (named)\n\n```typc\ntype: any\n```\n\n\n\n## w09 (named)\n\n```typc\ntype: any\n```\n\n\n\n## w10 (named)\n\n```typc\ntype: array\n```\n\n\n\n## w11 (named)\n\n```typc\ntype: array\n```\n\n\n\n## w12 (named)\n\n```typc\ntype: dict\n```\n\n\n\n## w13 (named)\n\n```typc\ntype: dict\n```\n\n\n\n## w14 (named)\n\n```typc\ntype: dict\n```\n\n\n\n## w15 (named)\n\n```typc\ntype: dict\n```\n\n",
"range": "23:20:23:21" "range": "23:20:23:21"
} }

View file

@ -272,7 +272,11 @@ fn link_tooltip(
Some(HoverContents::Array(results)) Some(HoverContents::Array(results))
} }
fn push_result_ty(name: &str, ty_repr: Option<&(String, String, String)>, type_doc: &mut String) { fn push_result_ty(
name: &str,
ty_repr: Option<&(EcoString, EcoString, EcoString)>,
type_doc: &mut String,
) {
let Some((short, _, _)) = ty_repr else { let Some((short, _, _)) = ty_repr else {
return; return;
}; };

View file

@ -1,5 +1,6 @@
use core::fmt; use core::fmt;
use ecow::{eco_format, EcoString};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use regex::RegexSet; use regex::RegexSet;
use strum::{EnumIter, IntoEnumIterator}; use strum::{EnumIter, IntoEnumIterator};
@ -312,7 +313,7 @@ impl BuiltinTy {
BuiltinTy::Type(builtin).literally() BuiltinTy::Type(builtin).literally()
} }
pub(crate) fn describe(&self) -> String { pub(crate) fn describe(&self) -> EcoString {
let res = match self { let res = match self {
BuiltinTy::Clause => "any", BuiltinTy::Clause => "any",
BuiltinTy::Undef => "any", BuiltinTy::Undef => "any",
@ -347,9 +348,9 @@ impl BuiltinTy {
BuiltinTy::Tag(tag) => { BuiltinTy::Tag(tag) => {
let (name, id) = tag.as_ref(); let (name, id) = tag.as_ref();
return if let Some(id) = id { return if let Some(id) = id {
format!("tag {name} of {id:?}") eco_format!("tag {name} of {id:?}")
} else { } else {
format!("tag {name}") eco_format!("tag {name}")
}; };
} }
BuiltinTy::Path(s) => match s { BuiltinTy::Path(s) => match s {
@ -369,7 +370,7 @@ impl BuiltinTy {
}, },
}; };
res.to_string() res.into()
} }
} }

View file

@ -1,11 +1,12 @@
use ecow::{eco_format, EcoString};
use reflexo::hash::hash128; use reflexo::hash::hash128;
use typst::foundations::Repr; use typst::foundations::Repr;
use crate::ty::prelude::*; use crate::{ty::prelude::*, upstream::truncated_repr_};
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<EcoString> {
let mut worker: TypeDescriber = TypeDescriber::default(); let mut worker: TypeDescriber = TypeDescriber::default();
worker.describe_root(ty) worker.describe_root(ty)
} }
@ -13,7 +14,7 @@ impl TypeScheme {
impl Ty { impl Ty {
/// Describe the given type. /// Describe the given type.
pub fn repr(&self) -> Option<String> { pub fn repr(&self) -> Option<EcoString> {
let mut worker = TypeDescriber { let mut worker = TypeDescriber {
repr: true, repr: true,
..Default::default() ..Default::default()
@ -22,16 +23,17 @@ impl Ty {
} }
/// Describe available value instances of the given type. /// Describe available value instances of the given type.
pub fn value_repr(&self) -> Option<String> { pub fn value_repr(&self) -> Option<EcoString> {
let mut worker = TypeDescriber { let mut worker = TypeDescriber {
repr: true, repr: true,
value: true,
..Default::default() ..Default::default()
}; };
worker.describe_root(self) worker.describe_root(self)
} }
/// Describe the given type. /// Describe the given type.
pub fn describe(&self) -> Option<String> { pub fn describe(&self) -> Option<EcoString> {
let mut worker = TypeDescriber::default(); let mut worker = TypeDescriber::default();
worker.describe_root(self) worker.describe_root(self)
} }
@ -55,13 +57,14 @@ impl Ty {
#[derive(Default)] #[derive(Default)]
struct TypeDescriber { struct TypeDescriber {
repr: bool, repr: bool,
described: HashMap<u128, String>, value: bool,
results: HashSet<String>, described: HashMap<u128, EcoString>,
results: HashSet<EcoString>,
functions: Vec<Interned<SigTy>>, functions: Vec<Interned<SigTy>>,
} }
impl TypeDescriber { impl TypeDescriber {
fn describe_root(&mut self, ty: &Ty) -> Option<String> { fn describe_root(&mut self, ty: &Ty) -> Option<EcoString> {
let _ = TypeDescriber::describe_iter; let _ = TypeDescriber::describe_iter;
// recursive structure // recursive structure
if let Some(t) = self.described.get(&hash128(ty)) { if let Some(t) = self.described.get(&hash128(ty)) {
@ -72,7 +75,7 @@ impl TypeDescriber {
if !res.is_empty() { if !res.is_empty() {
return Some(res); return Some(res);
} }
self.described.insert(hash128(ty), "$self".to_string()); self.described.insert(hash128(ty), "$self".into());
let mut results = std::mem::take(&mut self.results) let mut results = std::mem::take(&mut self.results)
.into_iter() .into_iter()
@ -83,7 +86,7 @@ impl TypeDescriber {
// only first function is described // only first function is described
let f = functions[0].clone(); let f = functions[0].clone();
let mut res = String::new(); let mut res = EcoString::new();
res.push('('); res.push('(');
let mut not_first = false; let mut not_first = false;
for ty in f.positional_params() { for ty in f.positional_params() {
@ -124,13 +127,13 @@ impl TypeDescriber {
} }
if results.is_empty() { if results.is_empty() {
self.described.insert(hash128(ty), "any".to_string()); self.described.insert(hash128(ty), "any".into());
return None; return None;
} }
results.sort(); results.sort();
results.dedup(); results.dedup();
let res = results.join(" | "); let res: EcoString = results.join(" | ").into();
self.described.insert(hash128(ty), res.clone()); self.described.insert(hash128(ty), res.clone());
Some(res) Some(res)
} }
@ -144,7 +147,7 @@ impl TypeDescriber {
} }
} }
fn describe(&mut self, ty: &Ty) -> String { fn describe(&mut self, ty: &Ty) -> EcoString {
match ty { match ty {
Ty::Var(..) => {} Ty::Var(..) => {}
Ty::Union(tys) => { Ty::Union(tys) => {
@ -158,57 +161,56 @@ impl TypeDescriber {
self.functions.push(f.clone()); self.functions.push(f.clone());
} }
Ty::Dict(..) => { Ty::Dict(..) => {
return "dict".to_string(); return "dict".into();
} }
Ty::Tuple(..) => { Ty::Tuple(..) => {
return "array".to_string(); return "array".into();
} }
Ty::Array(..) => { Ty::Array(..) => {
return "array".to_string(); return "array".into();
} }
// todo: sig with // todo: sig with
Ty::With(w) => { Ty::With(w) => {
return self.describe(&w.sig); return self.describe(&w.sig);
} }
Ty::Builtin(BuiltinTy::Content | BuiltinTy::Space) => { Ty::Builtin(BuiltinTy::Content | BuiltinTy::Space) => {
return "content".to_string(); return "content".into();
} }
// Doesn't provide any information, hence we doesn't describe it intermediately here. // Doesn't provide any information, hence we doesn't describe it intermediately here.
Ty::Any | Ty::Builtin(BuiltinTy::Clause | BuiltinTy::Undef | BuiltinTy::Infer) => {} Ty::Any | Ty::Builtin(BuiltinTy::Clause | BuiltinTy::Undef | BuiltinTy::Infer) => {}
Ty::Builtin(BuiltinTy::FlowNone | BuiltinTy::None) => { Ty::Builtin(BuiltinTy::FlowNone | BuiltinTy::None) => {
return "none".to_string(); return "none".into();
} }
Ty::Builtin(BuiltinTy::Auto) => { Ty::Builtin(BuiltinTy::Auto) => {
return "auto".to_string(); return "auto".into();
} }
Ty::Boolean(..) if self.repr => { Ty::Boolean(..) if self.repr => {
return "bool".to_string(); return "bool".into();
} }
Ty::Boolean(None) => { Ty::Boolean(None) => {
return "bool".to_string(); return "bool".into();
} }
Ty::Boolean(Some(b)) => { Ty::Boolean(Some(b)) => {
return b.to_string(); return eco_format!("{b}");
} }
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) if self.value => return truncated_repr_::<181>(&v.val),
Ty::Value(v) => return v.val.repr().to_string(), Ty::Value(v) if self.repr => return v.val.ty().short_name().into(),
Ty::Value(v) => return v.val.repr(),
Ty::Field(..) => { Ty::Field(..) => {
return "field".to_string(); return "field".into();
} }
Ty::Args(..) => { Ty::Args(..) => {
return "arguments".to_string(); return "arguments".into();
} }
Ty::Pattern(..) => { Ty::Pattern(..) => {
return "pattern".to_string(); return "pattern".into();
}
Ty::Select(..) | Ty::Unary(..) | Ty::Binary(..) | Ty::If(..) => {
return "any".to_string()
} }
Ty::Select(..) | Ty::Unary(..) | Ty::Binary(..) | Ty::If(..) => return "any".into(),
} }
String::new() EcoString::new()
} }
} }

View file

@ -469,7 +469,6 @@ fn describe_value(ctx: &mut LocalContext, v: &Value) -> EcoString {
.ty() .ty()
.describe() .describe()
.unwrap_or_else(|| "function".into()) .unwrap_or_else(|| "function".into())
.into()
} }
Value::Module(m) => { Value::Module(m) => {
if let Some(fid) = m.file_id() { if let Some(fid) = m.file_id() {

View file

@ -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:513716cde1f43609375d257774bdddd9"); insta::assert_snapshot!(hash, @"siphash128_13:37db2c66ca1b5a0cdec20f531c15d5");
} }
{ {
@ -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:5fc968f2227784be47aac5beca4ef369"); insta::assert_snapshot!(hash, @"siphash128_13:338a3a6f7c14c355579c3a4a99f47b30");
} }
} }