feat: add Typst syntax and Tinymist defaults

This commit is contained in:
2026-10-22 09:30:22 +02:00
parent ea7c240eb6
commit 03931496bf
14 changed files with 104 additions and 4 deletions
+1
View File
@@ -14,6 +14,7 @@ pub fn resolve(value: Value) -> Result<Vec<ServerConfig>, String> {
crate::syntax::RUST_ID => Some((&[&["rust-analyzer"]], "rs")),
crate::syntax::PYTHON_ID => Some((&[&["ty", "server"], &["ruff", "server"]], "py")),
crate::syntax::RUBY_ID => Some((&[&["solargraph", "stdio"]], "rb")),
crate::syntax::TYPST_ID => Some((&[&["tinymist", "lsp"]], "typ")),
_ => None,
};
let mut options = match value {
+1
View File
@@ -125,6 +125,7 @@ Set VAMP_RUBY to choose the Ruby executable.
Native LSP is disabled by default: config.lsp[\"rust\"] = true enables a preset
Presets: rust -> rust-analyzer, python -> ty server + ruff server, ruby -> solargraph stdio
typst -> tinymist lsp
Custom languages: config.lsp[\"my-language\"] = { command: [...], extensions: [...] }
Server stacks: config.lsp[\"python\"] = { servers: [{ command: [...] }, { command: [...] }] }
LSP commands: :lsp.definition, :lsp.diagnostics, :lsp.hover
+1
View File
@@ -13,6 +13,7 @@ use languages::LanguageSpec;
pub(crate) const RUST_ID: &str = "rust";
pub(crate) const RUBY_ID: &str = "ruby";
pub(crate) const PYTHON_ID: &str = "python";
pub(crate) const TYPST_ID: &str = "typst";
// Full trees and their indexes are optional; editing remains available beyond these budgets.
const MAX_SYNTAX_BYTES: usize = 1024 * 1024;
+37 -1
View File
@@ -90,6 +90,32 @@ const CPP_INJECTIONS: &str = "
(raw_string_content) @injection.content)
";
// The Typst crate exports its grammar but not queries. Use its AST nodes with
// Vamp's supported capture roles, and standard captures for raw-code injections.
const TYPST_HIGHLIGHTS: &str = r#"
(comment) @comment
(string) @string
(number) @number
[(bool) (none) (auto)] @keyword
[
"let" "if" "else" "while" "for" "in" "import" "as" "include"
"show" "set" "return" "break" "continue" "context" "and" "or" "not"
] @keyword
(call item: (ident) @function)
(call item: (field field: (ident) @function))
[
(heading) (emph) (strong) (url) (label) (ref) (symbol)
(raw_blck) (raw_span)
] @markup
(item "-" @markup.list)
(term ["/" ":"] @markup.list)
"#;
const TYPST_INJECTIONS: &str = "
(raw_blck
lang: (ident) @injection.language
(blob) @injection.content)
";
fn javascript_injections() -> &'static str {
// The trailing upstream hbs/@glimmer rule uses a nonstandard #offset! directive,
// not injection.* captures. Glimmer is outside the selected language set;
@@ -118,7 +144,7 @@ fn spec(
}
}
static LANGUAGES: LazyLock<[LanguageSpec; 20]> = LazyLock::new(|| {
static LANGUAGES: LazyLock<[LanguageSpec; 21]> = LazyLock::new(|| {
[
spec(
super::RUST_ID,
@@ -280,6 +306,14 @@ static LANGUAGES: LazyLock<[LanguageSpec; 20]> = LazyLock::new(|| {
"",
"",
),
spec(
super::TYPST_ID,
"Typst",
tree_sitter_typst::LANGUAGE.into(),
TYPST_HIGHLIGHTS,
TYPST_INJECTIONS,
"",
),
]
});
@@ -320,6 +354,7 @@ pub(super) fn by_name(name: &str) -> Option<&'static LanguageSpec> {
("golang", "Go"),
("hon", "Honey"),
("honeylang", "Honey"),
("typ", "Typst"),
];
let name = ALIASES
.iter()
@@ -376,6 +411,7 @@ fn detect_path(path: &Path) -> Option<&'static LanguageSpec> {
"go" => "Go",
"zig" => "Zig",
"hon" => "Honey",
"typ" => "Typst",
_ => return None,
}
}