use std::sync::{Arc, LazyLock};
use crate::{Lang, LangInner};
#[derive(Debug, Clone)]
pub struct LangInfo {
pub name: &'static str,
pub aliases: &'static [&'static str],
pub extensions: &'static [&'static str],
}
macro_rules! define_langs {
(
$(
$fn_name:ident => {
feature: $feature:literal,
name: $name:literal,
ts_lang: $ts_lang:expr,
lang_key: $lang_key:literal,
names: [$($alias:literal),* $(,)?],
extensions: [$($ext:literal),* $(,)?] $(,)?
}
),* $(,)?
) => {
$(
#[cfg(feature = $feature)]
pub fn $fn_name() -> Lang {
paste::paste! {
static LANG: LazyLock<Lang> = LazyLock::new(|| {
static NODE_TYPES_BYTES: &[u8] = include_bytes!(env!(
concat!("PLOTNIK_NODE_TYPES_", $lang_key)
));
static GRAMMAR_BYTES: &[u8] = include_bytes!(env!(
concat!("PLOTNIK_GRAMMAR_", $lang_key)
));
let raw_nodes: Vec<plotnik_core::RawNode> =
postcard::from_bytes(NODE_TYPES_BYTES)
.expect("invalid embedded node types");
let grammar = plotnik_core::grammar::Grammar::from_binary(GRAMMAR_BYTES)
.expect("invalid embedded grammar");
Arc::new(LangInner::new(
$name,
$ts_lang.into(),
raw_nodes,
grammar,
))
});
}
Arc::clone(&LANG)
}
)*
pub fn from_name(s: &str) -> Option<Lang> {
match s.to_ascii_lowercase().as_str() {
$(
#[cfg(feature = $feature)]
$($alias)|* => Some($fn_name()),
)*
_ => None,
}
}
#[allow(unreachable_patterns)]
pub fn from_ext(ext: &str) -> Option<Lang> {
match ext.to_ascii_lowercase().as_str() {
$(
#[cfg(feature = $feature)]
$($ext)|* => Some($fn_name()),
)*
_ => None,
}
}
pub fn all() -> Vec<Lang> {
vec![
$(
#[cfg(feature = $feature)]
$fn_name(),
)*
]
}
pub fn all_info() -> Vec<LangInfo> {
vec![
$(
#[cfg(feature = $feature)]
LangInfo {
name: $name,
aliases: &[$($alias),*],
extensions: &[$($ext),*],
},
)*
]
}
};
}
define_langs! {
ada => {
feature: "lang-ada",
name: "ada",
ts_lang: arborium_ada::language(),
lang_key: "ADA",
names: ["ada"],
extensions: ["ada", "adb", "ads"],
},
agda => {
feature: "lang-agda",
name: "agda",
ts_lang: arborium_agda::language(),
lang_key: "AGDA",
names: ["agda"],
extensions: ["agda"],
},
asciidoc => {
feature: "lang-asciidoc",
name: "asciidoc",
ts_lang: arborium_asciidoc::language(),
lang_key: "ASCIIDOC",
names: ["asciidoc", "adoc"],
extensions: ["adoc", "asciidoc", "asc"],
},
asm => {
feature: "lang-asm",
name: "asm",
ts_lang: arborium_asm::language(),
lang_key: "ASM",
names: ["asm", "assembly"],
extensions: ["asm", "s"],
},
awk => {
feature: "lang-awk",
name: "awk",
ts_lang: arborium_awk::language(),
lang_key: "AWK",
names: ["awk", "gawk", "mawk", "nawk"],
extensions: ["awk"],
},
bash => {
feature: "lang-bash",
name: "bash",
ts_lang: arborium_bash::language(),
lang_key: "BASH",
names: ["bash", "sh", "shell"],
extensions: ["sh", "bash"],
},
batch => {
feature: "lang-batch",
name: "batch",
ts_lang: arborium_batch::language(),
lang_key: "BATCH",
names: ["batch", "bat", "cmd"],
extensions: ["bat", "cmd"],
},
c => {
feature: "lang-c",
name: "c",
ts_lang: arborium_c::language(),
lang_key: "C",
names: ["c"],
extensions: ["c", "h"],
},
caddy => {
feature: "lang-caddy",
name: "caddy",
ts_lang: arborium_caddy::language(),
lang_key: "CADDY",
names: ["caddy", "caddyfile"],
extensions: ["caddyfile"],
},
capnp => {
feature: "lang-capnp",
name: "capnp",
ts_lang: arborium_capnp::language(),
lang_key: "CAPNP",
names: ["capnp", "capnproto"],
extensions: ["capnp"],
},
cedar => {
feature: "lang-cedar",
name: "cedar",
ts_lang: arborium_cedar::language(),
lang_key: "CEDAR",
names: ["cedar"],
extensions: ["cedar"],
},
cedarschema => {
feature: "lang-cedarschema",
name: "cedarschema",
ts_lang: arborium_cedarschema::language(),
lang_key: "CEDARSCHEMA",
names: ["cedarschema"],
extensions: ["cedarschema"],
},
clojure => {
feature: "lang-clojure",
name: "clojure",
ts_lang: arborium_clojure::language(),
lang_key: "CLOJURE",
names: ["clojure", "clj"],
extensions: ["clj", "cljs", "cljc", "edn"],
},
cmake => {
feature: "lang-cmake",
name: "cmake",
ts_lang: arborium_cmake::language(),
lang_key: "CMAKE",
names: ["cmake"],
extensions: ["cmake"],
},
cobol => {
feature: "lang-cobol",
name: "cobol",
ts_lang: arborium_cobol::language(),
lang_key: "COBOL",
names: ["cobol", "cob"],
extensions: ["cob", "cbl", "cpy"],
},
commonlisp => {
feature: "lang-commonlisp",
name: "commonlisp",
ts_lang: arborium_commonlisp::language(),
lang_key: "COMMONLISP",
names: ["commonlisp", "common-lisp", "lisp", "cl"],
extensions: ["lisp", "lsp", "cl"],
},
cpp => {
feature: "lang-cpp",
name: "cpp",
ts_lang: arborium_cpp::language(),
lang_key: "CPP",
names: ["cpp", "c++", "cxx", "cc"],
extensions: ["cpp", "cc", "cxx", "hpp", "hh", "hxx", "h++", "c++"],
},
csharp => {
feature: "lang-c-sharp",
name: "c_sharp",
ts_lang: arborium_c_sharp::language(),
lang_key: "C_SHARP",
names: ["csharp", "c#", "cs", "c_sharp"],
extensions: ["cs"],
},
css => {
feature: "lang-css",
name: "css",
ts_lang: arborium_css::language(),
lang_key: "CSS",
names: ["css"],
extensions: ["css"],
},
d => {
feature: "lang-d",
name: "d",
ts_lang: arborium_d::language(),
lang_key: "D",
names: ["d", "dlang"],
extensions: ["d"],
},
dart => {
feature: "lang-dart",
name: "dart",
ts_lang: arborium_dart::language(),
lang_key: "DART",
names: ["dart"],
extensions: ["dart"],
},
devicetree => {
feature: "lang-devicetree",
name: "devicetree",
ts_lang: arborium_devicetree::language(),
lang_key: "DEVICETREE",
names: ["devicetree", "dts"],
extensions: ["dts", "dtsi"],
},
diff => {
feature: "lang-diff",
name: "diff",
ts_lang: arborium_diff::language(),
lang_key: "DIFF",
names: ["diff", "patch"],
extensions: ["diff", "patch"],
},
dockerfile => {
feature: "lang-dockerfile",
name: "dockerfile",
ts_lang: arborium_dockerfile::language(),
lang_key: "DOCKERFILE",
names: ["dockerfile", "docker"],
extensions: ["dockerfile"],
},
dot => {
feature: "lang-dot",
name: "dot",
ts_lang: arborium_dot::language(),
lang_key: "DOT",
names: ["dot", "graphviz"],
extensions: ["dot", "gv"],
},
elisp => {
feature: "lang-elisp",
name: "elisp",
ts_lang: arborium_elisp::language(),
lang_key: "ELISP",
names: ["elisp", "emacs-lisp"],
extensions: ["el"],
},
elixir => {
feature: "lang-elixir",
name: "elixir",
ts_lang: arborium_elixir::language(),
lang_key: "ELIXIR",
names: ["elixir", "ex"],
extensions: ["ex", "exs"],
},
elm => {
feature: "lang-elm",
name: "elm",
ts_lang: arborium_elm::language(),
lang_key: "ELM",
names: ["elm"],
extensions: ["elm"],
},
erlang => {
feature: "lang-erlang",
name: "erlang",
ts_lang: arborium_erlang::language(),
lang_key: "ERLANG",
names: ["erlang", "erl"],
extensions: ["erl", "hrl"],
},
fish => {
feature: "lang-fish",
name: "fish",
ts_lang: arborium_fish::language(),
lang_key: "FISH",
names: ["fish"],
extensions: ["fish"],
},
fsharp => {
feature: "lang-fsharp",
name: "fsharp",
ts_lang: arborium_fsharp::language(),
lang_key: "FSHARP",
names: ["fsharp", "f#", "fs"],
extensions: ["fs", "fsi", "fsx"],
},
gleam => {
feature: "lang-gleam",
name: "gleam",
ts_lang: arborium_gleam::language(),
lang_key: "GLEAM",
names: ["gleam"],
extensions: ["gleam"],
},
glsl => {
feature: "lang-glsl",
name: "glsl",
ts_lang: arborium_glsl::language(),
lang_key: "GLSL",
names: ["glsl"],
extensions: ["glsl", "vert", "frag", "geom", "tesc", "tese", "comp"],
},
go => {
feature: "lang-go",
name: "go",
ts_lang: arborium_go::language(),
lang_key: "GO",
names: ["go", "golang"],
extensions: ["go"],
},
graphql => {
feature: "lang-graphql",
name: "graphql",
ts_lang: arborium_graphql::language(),
lang_key: "GRAPHQL",
names: ["graphql", "gql"],
extensions: ["graphql", "gql"],
},
groovy => {
feature: "lang-groovy",
name: "groovy",
ts_lang: arborium_groovy::language(),
lang_key: "GROOVY",
names: ["groovy", "gradle"],
extensions: ["groovy", "gradle", "gvy", "gy", "gsh"],
},
haskell => {
feature: "lang-haskell",
name: "haskell",
ts_lang: arborium_haskell::language(),
lang_key: "HASKELL",
names: ["haskell", "hs"],
extensions: ["hs", "lhs"],
},
hcl => {
feature: "lang-hcl",
name: "hcl",
ts_lang: arborium_hcl::language(),
lang_key: "HCL",
names: ["hcl", "terraform", "tf"],
extensions: ["hcl", "tf", "tfvars"],
},
hlsl => {
feature: "lang-hlsl",
name: "hlsl",
ts_lang: arborium_hlsl::language(),
lang_key: "HLSL",
names: ["hlsl"],
extensions: ["hlsl", "hlsli", "fx"],
},
html => {
feature: "lang-html",
name: "html",
ts_lang: arborium_html::language(),
lang_key: "HTML",
names: ["html", "htm"],
extensions: ["html", "htm"],
},
idris => {
feature: "lang-idris",
name: "idris",
ts_lang: arborium_idris::language(),
lang_key: "IDRIS",
names: ["idris"],
extensions: ["idr"],
},
ini => {
feature: "lang-ini",
name: "ini",
ts_lang: arborium_ini::language(),
lang_key: "INI",
names: ["ini"],
extensions: ["ini", "cfg", "conf"],
},
java => {
feature: "lang-java",
name: "java",
ts_lang: arborium_java::language(),
lang_key: "JAVA",
names: ["java"],
extensions: ["java"],
},
javascript => {
feature: "lang-javascript",
name: "javascript",
ts_lang: arborium_javascript::language(),
lang_key: "JAVASCRIPT",
names: ["javascript", "js", "jsx", "ecmascript", "es"],
extensions: ["js", "mjs", "cjs", "jsx"],
},
jinja2 => {
feature: "lang-jinja2",
name: "jinja2",
ts_lang: arborium_jinja2::language(),
lang_key: "JINJA2",
names: ["jinja2", "jinja"],
extensions: ["j2", "jinja", "jinja2"],
},
jq => {
feature: "lang-jq",
name: "jq",
ts_lang: arborium_jq::language(),
lang_key: "JQ",
names: ["jq"],
extensions: ["jq"],
},
json => {
feature: "lang-json",
name: "json",
ts_lang: arborium_json::language(),
lang_key: "JSON",
names: ["json"],
extensions: ["json"],
},
julia => {
feature: "lang-julia",
name: "julia",
ts_lang: arborium_julia::language(),
lang_key: "JULIA",
names: ["julia", "jl"],
extensions: ["jl"],
},
kotlin => {
feature: "lang-kotlin",
name: "kotlin",
ts_lang: arborium_kotlin::language(),
lang_key: "KOTLIN",
names: ["kotlin", "kt"],
extensions: ["kt", "kts"],
},
lean => {
feature: "lang-lean",
name: "lean",
ts_lang: arborium_lean::language(),
lang_key: "LEAN",
names: ["lean", "lean4"],
extensions: ["lean"],
},
lua => {
feature: "lang-lua",
name: "lua",
ts_lang: arborium_lua::language(),
lang_key: "LUA",
names: ["lua"],
extensions: ["lua"],
},
markdown => {
feature: "lang-markdown",
name: "markdown",
ts_lang: arborium_markdown::language(),
lang_key: "MARKDOWN",
names: ["markdown", "md"],
extensions: ["md", "markdown"],
},
matlab => {
feature: "lang-matlab",
name: "matlab",
ts_lang: arborium_matlab::language(),
lang_key: "MATLAB",
names: ["matlab", "octave"],
extensions: ["m"],
},
meson => {
feature: "lang-meson",
name: "meson",
ts_lang: arborium_meson::language(),
lang_key: "MESON",
names: ["meson"],
extensions: ["meson"],
},
nginx => {
feature: "lang-nginx",
name: "nginx",
ts_lang: arborium_nginx::language(),
lang_key: "NGINX",
names: ["nginx"],
extensions: ["nginx"],
},
ninja => {
feature: "lang-ninja",
name: "ninja",
ts_lang: arborium_ninja::language(),
lang_key: "NINJA",
names: ["ninja"],
extensions: ["ninja"],
},
nix => {
feature: "lang-nix",
name: "nix",
ts_lang: arborium_nix::language(),
lang_key: "NIX",
names: ["nix"],
extensions: ["nix"],
},
objc => {
feature: "lang-objc",
name: "objc",
ts_lang: arborium_objc::language(),
lang_key: "OBJC",
names: ["objc", "objective-c", "objectivec"],
extensions: ["m", "mm"],
},
ocaml => {
feature: "lang-ocaml",
name: "ocaml",
ts_lang: arborium_ocaml::language(),
lang_key: "OCAML",
names: ["ocaml", "ml"],
extensions: ["ml", "mli"],
},
perl => {
feature: "lang-perl",
name: "perl",
ts_lang: arborium_perl::language(),
lang_key: "PERL",
names: ["perl", "pl"],
extensions: ["pl", "pm"],
},
php => {
feature: "lang-php",
name: "php",
ts_lang: arborium_php::language(),
lang_key: "PHP",
names: ["php"],
extensions: ["php"],
},
postscript => {
feature: "lang-postscript",
name: "postscript",
ts_lang: arborium_postscript::language(),
lang_key: "POSTSCRIPT",
names: ["postscript", "ps"],
extensions: ["ps", "eps"],
},
powershell => {
feature: "lang-powershell",
name: "powershell",
ts_lang: arborium_powershell::language(),
lang_key: "POWERSHELL",
names: ["powershell", "pwsh", "ps1"],
extensions: ["ps1", "psm1", "psd1"],
},
prolog => {
feature: "lang-prolog",
name: "prolog",
ts_lang: arborium_prolog::language(),
lang_key: "PROLOG",
names: ["prolog"],
extensions: ["pl", "pro"],
},
python => {
feature: "lang-python",
name: "python",
ts_lang: arborium_python::language(),
lang_key: "PYTHON",
names: ["python", "py"],
extensions: ["py", "pyi", "pyw"],
},
query => {
feature: "lang-query",
name: "query",
ts_lang: arborium_query::language(),
lang_key: "QUERY",
names: ["query", "scm"],
extensions: ["scm"],
},
r => {
feature: "lang-r",
name: "r",
ts_lang: arborium_r::language(),
lang_key: "R",
names: ["r", "rlang"],
extensions: ["r", "R"],
},
rescript => {
feature: "lang-rescript",
name: "rescript",
ts_lang: arborium_rescript::language(),
lang_key: "RESCRIPT",
names: ["rescript", "res"],
extensions: ["res", "resi"],
},
ron => {
feature: "lang-ron",
name: "ron",
ts_lang: arborium_ron::language(),
lang_key: "RON",
names: ["ron"],
extensions: ["ron"],
},
ruby => {
feature: "lang-ruby",
name: "ruby",
ts_lang: arborium_ruby::language(),
lang_key: "RUBY",
names: ["ruby", "rb"],
extensions: ["rb", "rake", "gemspec"],
},
rust => {
feature: "lang-rust",
name: "rust",
ts_lang: arborium_rust::language(),
lang_key: "RUST",
names: ["rust", "rs"],
extensions: ["rs"],
},
scala => {
feature: "lang-scala",
name: "scala",
ts_lang: arborium_scala::language(),
lang_key: "SCALA",
names: ["scala"],
extensions: ["scala", "sc"],
},
scheme => {
feature: "lang-scheme",
name: "scheme",
ts_lang: arborium_scheme::language(),
lang_key: "SCHEME",
names: ["scheme", "racket"],
extensions: ["scm", "ss", "rkt"],
},
scss => {
feature: "lang-scss",
name: "scss",
ts_lang: arborium_scss::language(),
lang_key: "SCSS",
names: ["scss", "sass"],
extensions: ["scss", "sass"],
},
solidity => {
feature: "lang-solidity",
name: "solidity",
ts_lang: arborium_solidity::language(),
lang_key: "SOLIDITY",
names: ["solidity", "sol"],
extensions: ["sol"],
},
sparql => {
feature: "lang-sparql",
name: "sparql",
ts_lang: arborium_sparql::language(),
lang_key: "SPARQL",
names: ["sparql"],
extensions: ["sparql", "rq"],
},
sql => {
feature: "lang-sql",
name: "sql",
ts_lang: arborium_sql::language(),
lang_key: "SQL",
names: ["sql"],
extensions: ["sql"],
},
ssh_config => {
feature: "lang-ssh-config",
name: "ssh_config",
ts_lang: arborium_ssh_config::language(),
lang_key: "SSH_CONFIG",
names: ["ssh-config", "ssh_config", "sshconfig"],
extensions: ["ssh_config"],
},
starlark => {
feature: "lang-starlark",
name: "starlark",
ts_lang: arborium_starlark::language(),
lang_key: "STARLARK",
names: ["starlark", "bazel", "bzl"],
extensions: ["bzl", "bazel"],
},
svelte => {
feature: "lang-svelte",
name: "svelte",
ts_lang: arborium_svelte::language(),
lang_key: "SVELTE",
names: ["svelte"],
extensions: ["svelte"],
},
swift => {
feature: "lang-swift",
name: "swift",
ts_lang: arborium_swift::language(),
lang_key: "SWIFT",
names: ["swift"],
extensions: ["swift"],
},
textproto => {
feature: "lang-textproto",
name: "textproto",
ts_lang: arborium_textproto::language(),
lang_key: "TEXTPROTO",
names: ["textproto", "pbtxt"],
extensions: ["textproto", "pbtxt"],
},
thrift => {
feature: "lang-thrift",
name: "thrift",
ts_lang: arborium_thrift::language(),
lang_key: "THRIFT",
names: ["thrift"],
extensions: ["thrift"],
},
tlaplus => {
feature: "lang-tlaplus",
name: "tlaplus",
ts_lang: arborium_tlaplus::language(),
lang_key: "TLAPLUS",
names: ["tlaplus", "tla+", "tla"],
extensions: ["tla"],
},
toml => {
feature: "lang-toml",
name: "toml",
ts_lang: arborium_toml::language(),
lang_key: "TOML",
names: ["toml"],
extensions: ["toml"],
},
tsx => {
feature: "lang-tsx",
name: "tsx",
ts_lang: arborium_tsx::language(),
lang_key: "TSX",
names: ["tsx"],
extensions: ["tsx"],
},
typescript => {
feature: "lang-typescript",
name: "typescript",
ts_lang: arborium_typescript::language(),
lang_key: "TYPESCRIPT",
names: ["typescript", "ts"],
extensions: ["ts", "mts", "cts"],
},
typst => {
feature: "lang-typst",
name: "typst",
ts_lang: arborium_typst::language(),
lang_key: "TYPST",
names: ["typst"],
extensions: ["typ"],
},
uiua => {
feature: "lang-uiua",
name: "uiua",
ts_lang: arborium_uiua::language(),
lang_key: "UIUA",
names: ["uiua"],
extensions: ["ua"],
},
vb => {
feature: "lang-vb",
name: "vb",
ts_lang: arborium_vb::language(),
lang_key: "VB",
names: ["vb", "vbnet", "visualbasic"],
extensions: ["vb"],
},
verilog => {
feature: "lang-verilog",
name: "verilog",
ts_lang: arborium_verilog::language(),
lang_key: "VERILOG",
names: ["verilog", "v"],
extensions: ["v", "sv"],
},
vhdl => {
feature: "lang-vhdl",
name: "vhdl",
ts_lang: arborium_vhdl::language(),
lang_key: "VHDL",
names: ["vhdl"],
extensions: ["vhd", "vhdl"],
},
vim => {
feature: "lang-vim",
name: "vim",
ts_lang: arborium_vim::language(),
lang_key: "VIM",
names: ["vim", "vimscript"],
extensions: ["vim"],
},
vue => {
feature: "lang-vue",
name: "vue",
ts_lang: arborium_vue::language(),
lang_key: "VUE",
names: ["vue"],
extensions: ["vue"],
},
wit => {
feature: "lang-wit",
name: "wit",
ts_lang: arborium_wit::language(),
lang_key: "WIT",
names: ["wit"],
extensions: ["wit"],
},
x86asm => {
feature: "lang-x86asm",
name: "x86asm",
ts_lang: arborium_x86asm::language(),
lang_key: "X86ASM",
names: ["x86asm", "x86"],
extensions: ["asm"],
},
xml => {
feature: "lang-xml",
name: "xml",
ts_lang: arborium_xml::language(),
lang_key: "XML",
names: ["xml"],
extensions: ["xml", "xsl", "xslt", "xsd", "svg"],
},
yaml => {
feature: "lang-yaml",
name: "yaml",
ts_lang: arborium_yaml::language(),
lang_key: "YAML",
names: ["yaml", "yml"],
extensions: ["yaml", "yml"],
},
yuri => {
feature: "lang-yuri",
name: "yuri",
ts_lang: arborium_yuri::language(),
lang_key: "YURI",
names: ["yuri"],
extensions: ["yuri"],
},
zig => {
feature: "lang-zig",
name: "zig",
ts_lang: arborium_zig::language(),
lang_key: "ZIG",
names: ["zig"],
extensions: ["zig"],
},
zsh => {
feature: "lang-zsh",
name: "zsh",
ts_lang: arborium_zsh::language(),
lang_key: "ZSH",
names: ["zsh"],
extensions: ["zsh"],
},
}