const std = @import("std"); const Allocator = std.mem.Allocator; pub const KeywordCase = enum { sensitive, ascii_insensitive,}; pub const BlockComment = struct { start: []const u8, end: []const u8,}; pub const Detection = enum { none, typescript_assertion, json, shell_shebang, python_header, sql_select, dockerfile_from, go_package, rust_function,}; pub const Profile = struct { label: []const u8, aliases: []const []const u8, line_comments: []const []const u8 = &.{}, block_comment: ?BlockComment = null, quotes: []const u8 = &.{}, keywords: []const []const u8 = &.{}, literals: []const []const u8 = &.{}, keyword_case: KeywordCase = .sensitive, detection: Detection = .none,}; const double_quote = &[_]u8{'"'};const double_single_quotes = &[_]u8{ '"', '\'' };const shell_quotes = &[_]u8{ '"', '\'', '`' }; const profiles = [_]Profile{ .{ .label = "zig", .aliases = &.{"zig"}, .line_comments = &.{"//"}, .quotes = double_quote, .keywords = &.{ "const", "var", "fn", "pub", "return", "if", "else", "while", "for", "struct", "enum", "union", "try", "catch", "comptime", "defer", "errdefer", "async", "await", "anytype", "void" }, }, .{ .label = "ts", .aliases = &.{ "js", "jsx", "javascript", "ts", "tsx", "typescript" }, .line_comments = &.{"//"}, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = shell_quotes, .keywords = &.{ "const", "let", "var", "function", "class", "interface", "type", "export", "import", "from", "return", "if", "else", "for", "while", "async", "await", "new", "extends", "implements", "public", "private", "readonly" }, .literals = &.{ "true", "false", "null", "undefined" }, .detection = .typescript_assertion, }, .{ .label = "json", .aliases = &.{"json"}, .quotes = double_quote, .literals = &.{ "true", "false", "null" }, .detection = .json, }, .{ .label = "sh", .aliases = &.{ "sh", "bash", "zsh", "shell" }, .line_comments = &.{"#"}, .quotes = shell_quotes, .keywords = &.{ "if", "then", "fi", "for", "do", "done", "in", "case", "esac", "function", "local", "export", "readonly", "return" }, .literals = &.{ "true", "false", "null" }, .detection = .shell_shebang, }, .{ .label = "python", .aliases = &.{ "python", "py" }, .line_comments = &.{"#"}, .quotes = double_single_quotes, .keywords = &.{ "def", "class", "return", "if", "elif", "else", "for", "while", "in", "import", "from", "as", "try", "except", "with", "lambda", "async", "await", "pass", "raise", "yield", "match", "case" }, .literals = &.{ "True", "False", "None" }, .detection = .python_header, }, .{ .label = "yaml", .aliases = &.{ "yaml", "yml" }, .line_comments = &.{"#"}, .quotes = double_single_quotes, .literals = &.{ "true", "false", "null", "yes", "no", "on", "off" }, }, .{ .label = "toml", .aliases = &.{"toml"}, .line_comments = &.{"#"}, .quotes = double_single_quotes, .literals = &.{ "true", "false" }, }, .{ .label = "sql", .aliases = &.{"sql"}, .line_comments = &.{"--"}, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = double_single_quotes, .keywords = &.{ "select", "from", "where", "join", "left", "right", "inner", "outer", "on", "insert", "into", "values", "update", "set", "delete", "create", "alter", "drop", "table", "index", "group", "by", "order", "having", "limit", "as", "and", "or", "not", "distinct", "union" }, .literals = &.{ "true", "false", "null" }, .keyword_case = .ascii_insensitive, .detection = .sql_select, }, .{ .label = "dockerfile", .aliases = &.{ "dockerfile", "docker" }, .line_comments = &.{"#"}, .quotes = double_single_quotes, .keywords = &.{ "from", "run", "cmd", "entrypoint", "copy", "add", "workdir", "env", "arg", "expose", "volume", "user", "label", "onbuild", "stopsignal", "healthcheck", "shell", "maintainer" }, .keyword_case = .ascii_insensitive, .detection = .dockerfile_from, }, .{ .label = "rust", .aliases = &.{ "rust", "rs" }, .line_comments = &.{"//"}, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = double_single_quotes, .keywords = &.{ "fn", "let", "mut", "pub", "struct", "enum", "impl", "trait", "use", "mod", "crate", "return", "if", "else", "match", "for", "while", "loop", "async", "await", "move", "where", "self", "super" }, .literals = &.{ "true", "false", "None", "Some" }, .detection = .rust_function, }, .{ .label = "go", .aliases = &.{"go"}, .line_comments = &.{"//"}, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = &[_]u8{ '"', '`' }, .keywords = &.{ "package", "import", "func", "var", "const", "type", "struct", "interface", "return", "if", "else", "for", "range", "switch", "case", "go", "defer", "select", "chan", "map" }, .literals = &.{ "true", "false", "nil" }, .detection = .go_package, }, .{ .label = "c", .aliases = &.{ "c", "h" }, .line_comments = &.{"//"}, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = double_single_quotes, .keywords = &.{ "auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while" }, .literals = &.{ "true", "false", "NULL" }, }, .{ .label = "cpp", .aliases = &.{ "cpp", "c++", "cc", "cxx", "hpp" }, .line_comments = &.{"//"}, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = double_single_quotes, .keywords = &.{ "auto", "bool", "class", "const", "constexpr", "decltype", "delete", "enum", "explicit", "friend", "inline", "namespace", "new", "nullptr", "private", "protected", "public", "template", "this", "typename", "using", "virtual", "void" }, .literals = &.{ "true", "false", "nullptr", "NULL" }, }, .{ .label = "csharp", .aliases = &.{ "csharp", "cs" }, .line_comments = &.{"//"}, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = double_single_quotes, .keywords = &.{ "class", "namespace", "using", "public", "private", "protected", "internal", "static", "void", "string", "int", "var", "new", "return", "if", "else", "for", "foreach", "while", "async", "await", "interface", "record", "get", "set" }, .literals = &.{ "true", "false", "null" }, }, .{ .label = "java", .aliases = &.{"java"}, .line_comments = &.{"//"}, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = double_single_quotes, .keywords = &.{ "class", "interface", "package", "import", "public", "private", "protected", "static", "final", "void", "new", "return", "if", "else", "for", "while", "try", "catch", "throws", "extends", "implements", "record", "var" }, .literals = &.{ "true", "false", "null" }, }, .{ .label = "kotlin", .aliases = &.{ "kotlin", "kt", "kts" }, .line_comments = &.{"//"}, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = double_single_quotes, .keywords = &.{ "fun", "val", "var", "class", "object", "interface", "package", "import", "public", "private", "return", "if", "else", "when", "for", "while", "try", "catch", "data", "sealed", "suspend" }, .literals = &.{ "true", "false", "null" }, }, .{ .label = "php", .aliases = &.{"php"}, .line_comments = &.{ "//", "#" }, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = double_single_quotes, .keywords = &.{ "function", "class", "public", "private", "protected", "namespace", "use", "return", "if", "else", "foreach", "for", "while", "try", "catch", "new", "static", "const", "echo", "yield" }, .literals = &.{ "true", "false", "null" }, }, .{ .label = "ruby", .aliases = &.{ "ruby", "rb" }, .line_comments = &.{"#"}, .quotes = double_single_quotes, .keywords = &.{ "def", "class", "module", "end", "return", "if", "elsif", "else", "unless", "case", "when", "do", "while", "for", "in", "begin", "rescue", "require", "attr_reader" }, .literals = &.{ "true", "false", "nil" }, }, .{ .label = "swift", .aliases = &.{"swift"}, .line_comments = &.{"//"}, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = double_single_quotes, .keywords = &.{ "func", "let", "var", "class", "struct", "enum", "protocol", "extension", "import", "public", "private", "return", "if", "else", "guard", "for", "while", "switch", "case", "async", "await", "throws", "try" }, .literals = &.{ "true", "false", "nil" }, }, .{ .label = "powershell", .aliases = &.{ "powershell", "ps1", "pwsh", "ps" }, .line_comments = &.{"#"}, .block_comment = .{ .start = "<#", .end = "#>" }, .quotes = double_single_quotes, .keywords = &.{ "function", "param", "if", "else", "elseif", "foreach", "for", "while", "switch", "return", "throw", "try", "catch", "finally", "begin", "process", "end", "filter", "class", "enum" }, .literals = &.{ "true", "false", "null" }, .keyword_case = .ascii_insensitive, }, .{ .label = "lua", .aliases = &.{"lua"}, .line_comments = &.{"--"}, .block_comment = .{ .start = "--[[", .end = "]]" }, .quotes = double_single_quotes, .keywords = &.{ "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while" }, .literals = &.{ "true", "false", "nil" }, }, .{ .label = "html", .aliases = &.{ "html", "htm" }, .block_comment = .{ .start = "<!--", .end = "-->" }, .quotes = double_single_quotes, .keywords = &.{ "html", "head", "body", "main", "header", "footer", "section", "article", "div", "span", "a", "p", "script", "style", "link", "meta", "title", "button", "input", "form", "img", "ul", "li" }, }, .{ .label = "xml", .aliases = &.{"xml"}, .block_comment = .{ .start = "<!--", .end = "-->" }, .quotes = double_single_quotes, .keywords = &.{ "xml", "version", "encoding", "DOCTYPE", "CDATA" }, }, .{ .label = "css", .aliases = &.{"css"}, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = double_single_quotes, .keywords = &.{ "color", "background", "display", "position", "margin", "padding", "border", "font", "width", "height", "flex", "grid", "align", "justify", "transition", "transform", "animation", "media" }, }, .{ .label = "hcl", .aliases = &.{ "hcl", "terraform", "tf" }, .line_comments = &.{ "#", "//" }, .block_comment = .{ .start = "/*", .end = "*/" }, .quotes = double_single_quotes, .keywords = &.{ "resource", "module", "variable", "output", "provider", "terraform", "locals", "data", "dynamic", "for_each", "count" }, .literals = &.{ "true", "false", "null" }, },}; pub fn resolve(label: []const u8) ?*const Profile { for (&profiles) |*profile| { for (profile.aliases) |alias| { if (std.ascii.eqlIgnoreCase(label, alias)) return profile; } } return null;} pub fn infer(alloc: Allocator, source: []const u8) ?*const Profile { for (&profiles) |*profile| { if (matchesDetection(alloc, profile.detection, source)) return profile; } return null;} fn matchesDetection(alloc: Allocator, detection: Detection, source: []const u8) bool { return switch (detection) { .none => false, .typescript_assertion => matchesTypeScriptAssertion(source), .json => isValidJson(alloc, source), .shell_shebang => matchesShellShebang(source), .python_header => matchesPythonHeader(source), .sql_select => matchesSqlSelect(source), .dockerfile_from => startsWithIgnoreCase(firstNonblankLine(source), "from "), .go_package => startsWith(firstNonblankLine(source), "package ") and containsLineStart(source, "func "), .rust_function => matchesRustFunction(source), };} fn matchesTypeScriptAssertion(source: []const u8) bool { var start: usize = 0; while (std.mem.indexOfPos(u8, source, start, "} as ")) |assertion_start| { const type_start = assertion_start + "} as ".len; if (type_start < source.len and std.ascii.isUpper(source[type_start])) return true; start = type_start; } return false;} fn isValidJson(alloc: Allocator, source: []const u8) bool { const trimmed = std.mem.trim(u8, source, " \t\r\n"); if (trimmed.len == 0 or (trimmed[0] != '{' and trimmed[0] != '[')) return false; var parsed = std.json.parseFromSlice(std.json.Value, alloc, trimmed, .{}) catch return false; defer parsed.deinit(); return parsed.value == .object or parsed.value == .array;} fn matchesShellShebang(source: []const u8) bool { const line = firstNonblankLine(source); return std.mem.startsWith(u8, line, "#!") and (std.mem.indexOf(u8, line, "bash") != null or std.mem.indexOf(u8, line, "zsh") != null or std.mem.indexOf(u8, line, "/sh") != null);} fn matchesPythonHeader(source: []const u8) bool { const line = firstNonblankLine(source); return (std.mem.startsWith(u8, line, "def ") or std.mem.startsWith(u8, line, "class ")) and std.mem.endsWith(u8, line, ":");} fn matchesSqlSelect(source: []const u8) bool { const line = firstNonblankLine(source); return startsWithIgnoreCase(line, "select ") and containsWordIgnoreCase(source, "from");} fn matchesRustFunction(source: []const u8) bool { const line = firstNonblankLine(source); if (!std.mem.startsWith(u8, line, "fn ") and !std.mem.startsWith(u8, line, "pub fn ")) return false; return std.mem.indexOf(u8, source, "let ") != null or std.mem.indexOf(u8, source, "println!") != null or std.mem.indexOf(u8, line, "->") != null;} fn firstNonblankLine(source: []const u8) []const u8 { var lines = std.mem.splitScalar(u8, source, '\n'); while (lines.next()) |line| { const trimmed = std.mem.trim(u8, line, " \t\r"); if (trimmed.len > 0) return trimmed; } return "";} fn containsLineStart(source: []const u8, prefix: []const u8) bool { if (std.mem.startsWith(u8, source, prefix)) return true; var start: usize = 0; while (std.mem.indexOfPos(u8, source, start, "\n")) |newline| { const line_start = newline + 1; if (std.mem.startsWith(u8, source[line_start..], prefix)) return true; start = line_start; } return false;} fn startsWith(text: []const u8, prefix: []const u8) bool { return text.len >= prefix.len and std.mem.eql(u8, text[0..prefix.len], prefix);} fn startsWithIgnoreCase(text: []const u8, prefix: []const u8) bool { return text.len >= prefix.len and std.ascii.eqlIgnoreCase(text[0..prefix.len], prefix);} fn containsWordIgnoreCase(source: []const u8, word: []const u8) bool { if (word.len > source.len) return false; var index: usize = 0; while (index + word.len <= source.len) : (index += 1) { const end = index + word.len; if (std.ascii.eqlIgnoreCase(source[index..end], word) and (index == 0 or !isWordByte(source[index - 1])) and (end == source.len or !isWordByte(source[end]))) return true; } return false;} fn isWordByte(byte: u8) bool { return std.ascii.isAlphanumeric(byte) or byte == '_';} test "TypeScript assertions infer the canonical TypeScript label" { const source = "const hook = await resumeHook(token, { cleanup: true } as CleanupSignal);"; try std.testing.expectEqualStrings("ts", infer(std.testing.allocator, source).?.label); try std.testing.expect(infer(std.testing.allocator, "const value = 1;") == null); try std.testing.expect(infer(std.testing.allocator, "const value = {} as cleanupSignal;") == null);} test "supported code fence labels resolve case insensitively" { const cases = [_]struct { label: []const u8, profile: []const u8 }{ .{ .label = "Zig", .profile = "zig" }, .{ .label = "js", .profile = "ts" }, .{ .label = "JSX", .profile = "ts" }, .{ .label = "javascript", .profile = "ts" }, .{ .label = "TS", .profile = "ts" }, .{ .label = "tsx", .profile = "ts" }, .{ .label = "TypeScript", .profile = "ts" }, .{ .label = "JSON", .profile = "json" }, .{ .label = "sh", .profile = "sh" }, .{ .label = "BASH", .profile = "sh" }, .{ .label = "zsh", .profile = "sh" }, .{ .label = "Shell", .profile = "sh" }, }; for (cases) |case| try std.testing.expectEqualStrings(case.profile, resolve(case.label).?.label); try std.testing.expect(resolve("") == null); try std.testing.expect(resolve("text") == null);} test "expanded code fence labels resolve through the language registry" { const cases = [_]struct { label: []const u8, profile: []const u8 }{ .{ .label = "python", .profile = "python" }, .{ .label = "py", .profile = "python" }, .{ .label = "yaml", .profile = "yaml" }, .{ .label = "yml", .profile = "yaml" }, .{ .label = "toml", .profile = "toml" }, .{ .label = "sql", .profile = "sql" }, .{ .label = "dockerfile", .profile = "dockerfile" }, .{ .label = "rust", .profile = "rust" }, .{ .label = "rs", .profile = "rust" }, .{ .label = "go", .profile = "go" }, .{ .label = "c", .profile = "c" }, .{ .label = "cpp", .profile = "cpp" }, .{ .label = "c++", .profile = "cpp" }, .{ .label = "csharp", .profile = "csharp" }, .{ .label = "cs", .profile = "csharp" }, .{ .label = "java", .profile = "java" }, .{ .label = "kotlin", .profile = "kotlin" }, .{ .label = "php", .profile = "php" }, .{ .label = "ruby", .profile = "ruby" }, .{ .label = "swift", .profile = "swift" }, .{ .label = "powershell", .profile = "powershell" }, .{ .label = "ps1", .profile = "powershell" }, .{ .label = "lua", .profile = "lua" }, .{ .label = "html", .profile = "html" }, .{ .label = "xml", .profile = "xml" }, .{ .label = "css", .profile = "css" }, .{ .label = "hcl", .profile = "hcl" }, .{ .label = "terraform", .profile = "hcl" }, .{ .label = "tf", .profile = "hcl" }, }; for (cases) |case| try std.testing.expectEqualStrings(case.profile, resolve(case.label).?.label);} test "high-confidence source shapes infer registered profiles" { const alloc = std.testing.allocator; const cases = [_]struct { source: []const u8, profile: []const u8 }{ .{ .source = "{\"ready\": true}", .profile = "json" }, .{ .source = "#!/usr/bin/env bash\necho ready", .profile = "sh" }, .{ .source = "def render(value):\n return value", .profile = "python" }, .{ .source = "SELECT id FROM users", .profile = "sql" }, .{ .source = "FROM alpine:3.20\nRUN echo ready", .profile = "dockerfile" }, .{ .source = "package main\nfunc main() {}", .profile = "go" }, .{ .source = "fn main() { println!(\"ready\"); }", .profile = "rust" }, }; for (cases) |case| try std.testing.expectEqualStrings(case.profile, infer(alloc, case.source).?.label); try std.testing.expect(infer(alloc, "const value = 1;") == null); try std.testing.expect(infer(alloc, "title: ready") == null);} test "aliases do not collide across profiles" { for (profiles, 0..) |profile, profile_index| { for (profile.aliases) |alias| { for (profiles[profile_index + 1 ..]) |other| { for (other.aliases) |other_alias| { try std.testing.expect(!std.ascii.eqlIgnoreCase(alias, other_alias)); } } } }}
const std = @import("std");
const Allocator = std.mem.Allocator;
pub const KeywordCase = enum {
sensitive,
ascii_insensitive,
};
pub const BlockComment = struct {
start: []const u8,
end: []const u8,
};
pub const Detection = enum {
none,
typescript_assertion,
json,
shell_shebang,
python_header,
sql_select,
dockerfile_from,
go_package,
rust_function,
};
pub const Profile = struct {
label: []const u8,
aliases: []const []const u8,
line_comments: []const []const u8 = &.{},
block_comment: ?BlockComment = null,
quotes: []const u8 = &.{},
keywords: []const []const u8 = &.{},
literals: []const []const u8 = &.{},
keyword_case: KeywordCase = .sensitive,
detection: Detection = .none,
};
const double_quote = &[_]u8{'"'};
const double_single_quotes = &[_]u8{ '"', '\'' };
const shell_quotes = &[_]u8{ '"', '\'', '`' };
const profiles = [_]Profile{
.{
.label = "zig",
.aliases = &.{"zig"},
.line_comments = &.{"//"},
.quotes = double_quote,
.keywords = &.{ "const", "var", "fn", "pub", "return", "if", "else", "while", "for", "struct", "enum", "union", "try", "catch", "comptime", "defer", "errdefer", "async", "await", "anytype", "void" },
},
.{
.label = "ts",
.aliases = &.{ "js", "jsx", "javascript", "ts", "tsx", "typescript" },
.line_comments = &.{"//"},
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = shell_quotes,
.keywords = &.{ "const", "let", "var", "function", "class", "interface", "type", "export", "import", "from", "return", "if", "else", "for", "while", "async", "await", "new", "extends", "implements", "public", "private", "readonly" },
.literals = &.{ "true", "false", "null", "undefined" },
.detection = .typescript_assertion,
},
.{
.label = "json",
.aliases = &.{"json"},
.quotes = double_quote,
.literals = &.{ "true", "false", "null" },
.detection = .json,
},
.{
.label = "sh",
.aliases = &.{ "sh", "bash", "zsh", "shell" },
.line_comments = &.{"#"},
.quotes = shell_quotes,
.keywords = &.{ "if", "then", "fi", "for", "do", "done", "in", "case", "esac", "function", "local", "export", "readonly", "return" },
.literals = &.{ "true", "false", "null" },
.detection = .shell_shebang,
},
.{
.label = "python",
.aliases = &.{ "python", "py" },
.line_comments = &.{"#"},
.quotes = double_single_quotes,
.keywords = &.{ "def", "class", "return", "if", "elif", "else", "for", "while", "in", "import", "from", "as", "try", "except", "with", "lambda", "async", "await", "pass", "raise", "yield", "match", "case" },
.literals = &.{ "True", "False", "None" },
.detection = .python_header,
},
.{
.label = "yaml",
.aliases = &.{ "yaml", "yml" },
.line_comments = &.{"#"},
.quotes = double_single_quotes,
.literals = &.{ "true", "false", "null", "yes", "no", "on", "off" },
},
.{
.label = "toml",
.aliases = &.{"toml"},
.line_comments = &.{"#"},
.quotes = double_single_quotes,
.literals = &.{ "true", "false" },
},
.{
.label = "sql",
.aliases = &.{"sql"},
.line_comments = &.{"--"},
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = double_single_quotes,
.keywords = &.{ "select", "from", "where", "join", "left", "right", "inner", "outer", "on", "insert", "into", "values", "update", "set", "delete", "create", "alter", "drop", "table", "index", "group", "by", "order", "having", "limit", "as", "and", "or", "not", "distinct", "union" },
.literals = &.{ "true", "false", "null" },
.keyword_case = .ascii_insensitive,
.detection = .sql_select,
},
.{
.label = "dockerfile",
.aliases = &.{ "dockerfile", "docker" },
.line_comments = &.{"#"},
.quotes = double_single_quotes,
.keywords = &.{ "from", "run", "cmd", "entrypoint", "copy", "add", "workdir", "env", "arg", "expose", "volume", "user", "label", "onbuild", "stopsignal", "healthcheck", "shell", "maintainer" },
.keyword_case = .ascii_insensitive,
.detection = .dockerfile_from,
},
.{
.label = "rust",
.aliases = &.{ "rust", "rs" },
.line_comments = &.{"//"},
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = double_single_quotes,
.keywords = &.{ "fn", "let", "mut", "pub", "struct", "enum", "impl", "trait", "use", "mod", "crate", "return", "if", "else", "match", "for", "while", "loop", "async", "await", "move", "where", "self", "super" },
.literals = &.{ "true", "false", "None", "Some" },
.detection = .rust_function,
},
.{
.label = "go",
.aliases = &.{"go"},
.line_comments = &.{"//"},
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = &[_]u8{ '"', '`' },
.keywords = &.{ "package", "import", "func", "var", "const", "type", "struct", "interface", "return", "if", "else", "for", "range", "switch", "case", "go", "defer", "select", "chan", "map" },
.literals = &.{ "true", "false", "nil" },
.detection = .go_package,
},
.{
.label = "c",
.aliases = &.{ "c", "h" },
.line_comments = &.{"//"},
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = double_single_quotes,
.keywords = &.{ "auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while" },
.literals = &.{ "true", "false", "NULL" },
},
.{
.label = "cpp",
.aliases = &.{ "cpp", "c++", "cc", "cxx", "hpp" },
.line_comments = &.{"//"},
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = double_single_quotes,
.keywords = &.{ "auto", "bool", "class", "const", "constexpr", "decltype", "delete", "enum", "explicit", "friend", "inline", "namespace", "new", "nullptr", "private", "protected", "public", "template", "this", "typename", "using", "virtual", "void" },
.literals = &.{ "true", "false", "nullptr", "NULL" },
},
.{
.label = "csharp",
.aliases = &.{ "csharp", "cs" },
.line_comments = &.{"//"},
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = double_single_quotes,
.keywords = &.{ "class", "namespace", "using", "public", "private", "protected", "internal", "static", "void", "string", "int", "var", "new", "return", "if", "else", "for", "foreach", "while", "async", "await", "interface", "record", "get", "set" },
.literals = &.{ "true", "false", "null" },
},
.{
.label = "java",
.aliases = &.{"java"},
.line_comments = &.{"//"},
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = double_single_quotes,
.keywords = &.{ "class", "interface", "package", "import", "public", "private", "protected", "static", "final", "void", "new", "return", "if", "else", "for", "while", "try", "catch", "throws", "extends", "implements", "record", "var" },
.literals = &.{ "true", "false", "null" },
},
.{
.label = "kotlin",
.aliases = &.{ "kotlin", "kt", "kts" },
.line_comments = &.{"//"},
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = double_single_quotes,
.keywords = &.{ "fun", "val", "var", "class", "object", "interface", "package", "import", "public", "private", "return", "if", "else", "when", "for", "while", "try", "catch", "data", "sealed", "suspend" },
.literals = &.{ "true", "false", "null" },
},
.{
.label = "php",
.aliases = &.{"php"},
.line_comments = &.{ "//", "#" },
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = double_single_quotes,
.keywords = &.{ "function", "class", "public", "private", "protected", "namespace", "use", "return", "if", "else", "foreach", "for", "while", "try", "catch", "new", "static", "const", "echo", "yield" },
.literals = &.{ "true", "false", "null" },
},
.{
.label = "ruby",
.aliases = &.{ "ruby", "rb" },
.line_comments = &.{"#"},
.quotes = double_single_quotes,
.keywords = &.{ "def", "class", "module", "end", "return", "if", "elsif", "else", "unless", "case", "when", "do", "while", "for", "in", "begin", "rescue", "require", "attr_reader" },
.literals = &.{ "true", "false", "nil" },
},
.{
.label = "swift",
.aliases = &.{"swift"},
.line_comments = &.{"//"},
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = double_single_quotes,
.keywords = &.{ "func", "let", "var", "class", "struct", "enum", "protocol", "extension", "import", "public", "private", "return", "if", "else", "guard", "for", "while", "switch", "case", "async", "await", "throws", "try" },
.literals = &.{ "true", "false", "nil" },
},
.{
.label = "powershell",
.aliases = &.{ "powershell", "ps1", "pwsh", "ps" },
.line_comments = &.{"#"},
.block_comment = .{ .start = "<#", .end = "#>" },
.quotes = double_single_quotes,
.keywords = &.{ "function", "param", "if", "else", "elseif", "foreach", "for", "while", "switch", "return", "throw", "try", "catch", "finally", "begin", "process", "end", "filter", "class", "enum" },
.literals = &.{ "true", "false", "null" },
.keyword_case = .ascii_insensitive,
},
.{
.label = "lua",
.aliases = &.{"lua"},
.line_comments = &.{"--"},
.block_comment = .{ .start = "--[[", .end = "]]" },
.quotes = double_single_quotes,
.keywords = &.{ "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while" },
.literals = &.{ "true", "false", "nil" },
},
.{
.label = "html",
.aliases = &.{ "html", "htm" },
.block_comment = .{ .start = "<!--", .end = "-->" },
.quotes = double_single_quotes,
.keywords = &.{ "html", "head", "body", "main", "header", "footer", "section", "article", "div", "span", "a", "p", "script", "style", "link", "meta", "title", "button", "input", "form", "img", "ul", "li" },
},
.{
.label = "xml",
.aliases = &.{"xml"},
.block_comment = .{ .start = "<!--", .end = "-->" },
.quotes = double_single_quotes,
.keywords = &.{ "xml", "version", "encoding", "DOCTYPE", "CDATA" },
},
.{
.label = "css",
.aliases = &.{"css"},
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = double_single_quotes,
.keywords = &.{ "color", "background", "display", "position", "margin", "padding", "border", "font", "width", "height", "flex", "grid", "align", "justify", "transition", "transform", "animation", "media" },
},
.{
.label = "hcl",
.aliases = &.{ "hcl", "terraform", "tf" },
.line_comments = &.{ "#", "//" },
.block_comment = .{ .start = "/*", .end = "*/" },
.quotes = double_single_quotes,
.keywords = &.{ "resource", "module", "variable", "output", "provider", "terraform", "locals", "data", "dynamic", "for_each", "count" },
.literals = &.{ "true", "false", "null" },
},
};
pub fn resolve(label: []const u8) ?*const Profile {
for (&profiles) |*profile| {
for (profile.aliases) |alias| {
if (std.ascii.eqlIgnoreCase(label, alias)) return profile;
}
}
return null;
}
pub fn infer(alloc: Allocator, source: []const u8) ?*const Profile {
for (&profiles) |*profile| {
if (matchesDetection(alloc, profile.detection, source)) return profile;
}
return null;
}
fn matchesDetection(alloc: Allocator, detection: Detection, source: []const u8) bool {
return switch (detection) {
.none => false,
.typescript_assertion => matchesTypeScriptAssertion(source),
.json => isValidJson(alloc, source),
.shell_shebang => matchesShellShebang(source),
.python_header => matchesPythonHeader(source),
.sql_select => matchesSqlSelect(source),
.dockerfile_from => startsWithIgnoreCase(firstNonblankLine(source), "from "),
.go_package => startsWith(firstNonblankLine(source), "package ") and containsLineStart(source, "func "),
.rust_function => matchesRustFunction(source),
};
}
fn matchesTypeScriptAssertion(source: []const u8) bool {
var start: usize = 0;
while (std.mem.indexOfPos(u8, source, start, "} as ")) |assertion_start| {
const type_start = assertion_start + "} as ".len;
if (type_start < source.len and std.ascii.isUpper(source[type_start])) return true;
start = type_start;
}
return false;
}
fn isValidJson(alloc: Allocator, source: []const u8) bool {
const trimmed = std.mem.trim(u8, source, " \t\r\n");
if (trimmed.len == 0 or (trimmed[0] != '{' and trimmed[0] != '[')) return false;
var parsed = std.json.parseFromSlice(std.json.Value, alloc, trimmed, .{}) catch return false;
defer parsed.deinit();
return parsed.value == .object or parsed.value == .array;
}
fn matchesShellShebang(source: []const u8) bool {
const line = firstNonblankLine(source);
return std.mem.startsWith(u8, line, "#!") and
(std.mem.indexOf(u8, line, "bash") != null or std.mem.indexOf(u8, line, "zsh") != null or std.mem.indexOf(u8, line, "/sh") != null);
}
fn matchesPythonHeader(source: []const u8) bool {
const line = firstNonblankLine(source);
return (std.mem.startsWith(u8, line, "def ") or std.mem.startsWith(u8, line, "class ")) and std.mem.endsWith(u8, line, ":");
}
fn matchesSqlSelect(source: []const u8) bool {
const line = firstNonblankLine(source);
return startsWithIgnoreCase(line, "select ") and containsWordIgnoreCase(source, "from");
}
fn matchesRustFunction(source: []const u8) bool {
const line = firstNonblankLine(source);
if (!std.mem.startsWith(u8, line, "fn ") and !std.mem.startsWith(u8, line, "pub fn ")) return false;
return std.mem.indexOf(u8, source, "let ") != null or std.mem.indexOf(u8, source, "println!") != null or std.mem.indexOf(u8, line, "->") != null;
}
fn firstNonblankLine(source: []const u8) []const u8 {
var lines = std.mem.splitScalar(u8, source, '\n');
while (lines.next()) |line| {
const trimmed = std.mem.trim(u8, line, " \t\r");
if (trimmed.len > 0) return trimmed;
}
return "";
}
fn containsLineStart(source: []const u8, prefix: []const u8) bool {
if (std.mem.startsWith(u8, source, prefix)) return true;
var start: usize = 0;
while (std.mem.indexOfPos(u8, source, start, "\n")) |newline| {
const line_start = newline + 1;
if (std.mem.startsWith(u8, source[line_start..], prefix)) return true;
start = line_start;
}
return false;
}
fn startsWith(text: []const u8, prefix: []const u8) bool {
return text.len >= prefix.len and std.mem.eql(u8, text[0..prefix.len], prefix);
}
fn startsWithIgnoreCase(text: []const u8, prefix: []const u8) bool {
return text.len >= prefix.len and std.ascii.eqlIgnoreCase(text[0..prefix.len], prefix);
}
fn containsWordIgnoreCase(source: []const u8, word: []const u8) bool {
if (word.len > source.len) return false;
var index: usize = 0;
while (index + word.len <= source.len) : (index += 1) {
const end = index + word.len;
if (std.ascii.eqlIgnoreCase(source[index..end], word) and
(index == 0 or !isWordByte(source[index - 1])) and
(end == source.len or !isWordByte(source[end]))) return true;
}
return false;
}
fn isWordByte(byte: u8) bool {
return std.ascii.isAlphanumeric(byte) or byte == '_';
}
test "TypeScript assertions infer the canonical TypeScript label" {
const source =
"const hook = await resumeHook(token, { cleanup: true } as CleanupSignal);";
try std.testing.expectEqualStrings("ts", infer(std.testing.allocator, source).?.label);
try std.testing.expect(infer(std.testing.allocator, "const value = 1;") == null);
try std.testing.expect(infer(std.testing.allocator, "const value = {} as cleanupSignal;") == null);
}
test "supported code fence labels resolve case insensitively" {
const cases = [_]struct { label: []const u8, profile: []const u8 }{
.{ .label = "Zig", .profile = "zig" },
.{ .label = "js", .profile = "ts" },
.{ .label = "JSX", .profile = "ts" },
.{ .label = "javascript", .profile = "ts" },
.{ .label = "TS", .profile = "ts" },
.{ .label = "tsx", .profile = "ts" },
.{ .label = "TypeScript", .profile = "ts" },
.{ .label = "JSON", .profile = "json" },
.{ .label = "sh", .profile = "sh" },
.{ .label = "BASH", .profile = "sh" },
.{ .label = "zsh", .profile = "sh" },
.{ .label = "Shell", .profile = "sh" },
};
for (cases) |case| try std.testing.expectEqualStrings(case.profile, resolve(case.label).?.label);
try std.testing.expect(resolve("") == null);
try std.testing.expect(resolve("text") == null);
}
test "expanded code fence labels resolve through the language registry" {
const cases = [_]struct { label: []const u8, profile: []const u8 }{
.{ .label = "python", .profile = "python" }, .{ .label = "py", .profile = "python" },
.{ .label = "yaml", .profile = "yaml" }, .{ .label = "yml", .profile = "yaml" },
.{ .label = "toml", .profile = "toml" }, .{ .label = "sql", .profile = "sql" },
.{ .label = "dockerfile", .profile = "dockerfile" }, .{ .label = "rust", .profile = "rust" },
.{ .label = "rs", .profile = "rust" }, .{ .label = "go", .profile = "go" },
.{ .label = "c", .profile = "c" }, .{ .label = "cpp", .profile = "cpp" },
.{ .label = "c++", .profile = "cpp" }, .{ .label = "csharp", .profile = "csharp" },
.{ .label = "cs", .profile = "csharp" }, .{ .label = "java", .profile = "java" },
.{ .label = "kotlin", .profile = "kotlin" }, .{ .label = "php", .profile = "php" },
.{ .label = "ruby", .profile = "ruby" }, .{ .label = "swift", .profile = "swift" },
.{ .label = "powershell", .profile = "powershell" }, .{ .label = "ps1", .profile = "powershell" },
.{ .label = "lua", .profile = "lua" }, .{ .label = "html", .profile = "html" },
.{ .label = "xml", .profile = "xml" }, .{ .label = "css", .profile = "css" },
.{ .label = "hcl", .profile = "hcl" }, .{ .label = "terraform", .profile = "hcl" },
.{ .label = "tf", .profile = "hcl" },
};
for (cases) |case| try std.testing.expectEqualStrings(case.profile, resolve(case.label).?.label);
}
test "high-confidence source shapes infer registered profiles" {
const alloc = std.testing.allocator;
const cases = [_]struct { source: []const u8, profile: []const u8 }{
.{ .source = "{\"ready\": true}", .profile = "json" },
.{ .source = "#!/usr/bin/env bash\necho ready", .profile = "sh" },
.{ .source = "def render(value):\n return value", .profile = "python" },
.{ .source = "SELECT id FROM users", .profile = "sql" },
.{ .source = "FROM alpine:3.20\nRUN echo ready", .profile = "dockerfile" },
.{ .source = "package main\nfunc main() {}", .profile = "go" },
.{ .source = "fn main() { println!(\"ready\"); }", .profile = "rust" },
};
for (cases) |case| try std.testing.expectEqualStrings(case.profile, infer(alloc, case.source).?.label);
try std.testing.expect(infer(alloc, "const value = 1;") == null);
try std.testing.expect(infer(alloc, "title: ready") == null);
}
test "aliases do not collide across profiles" {
for (profiles, 0..) |profile, profile_index| {
for (profile.aliases) |alias| {
for (profiles[profile_index + 1 ..]) |other| {
for (other.aliases) |other_alias| {
try std.testing.expect(!std.ascii.eqlIgnoreCase(alias, other_alias));
}
}
}
}
}