-- lx syntax
local syntax = require("core.syntax")

syntax.add({
	name = "CSharp Source",
	shortname = "C#",
	extensions = {
		"cs",	-- C# source
		"csx",	-- C# script
	},
	comment = "//",

	patterns = {
		{ pattern = "//.-\n", type = "comment" },
		{ pattern = { "/%*", "%*/" }, type = "comment" },
		{ pattern = { '"', '"', "\\" }, type = "string" },
		{ pattern = { '[%$%@]?"', '"', "\\" }, type = "string" }, -- string interpolation and verbatim
		{ pattern = "'\\x%x?%x?%x?%x'", type = "string" }, -- character hexadecimal escape sequence
		{ pattern = "'\\u%x%x%x%x'", type = "string" }, -- character unicode escape sequence
		{ pattern = "'\\?.'", type = "string" }, -- character literal
		{ pattern = "-?0x%x+", type = "number" },
		{ pattern = "-?%d+[%d%.eE]*f?", type = "number" },
		{ pattern = "-?%.?%d+f?", type = "number" },
		{ pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
		{ pattern = "%?%?", type = "operator" }, -- ?? null-coalescing
		{ pattern = "%?%.", type = "operator" }, -- ?. null-conditional
		{ pattern = "[%a_][%w_]*%f[(]", type = "function" },
		{ pattern = "[%a_][%w_]*", type = "symbol" },
	},

	block_comment = {
		block_open = "/*",
		block_close = "*/",
		block_line_prefix = " * ",
		close_line_prefix = " ",
		open_on_own_line = false,
		close_on_own_line = true,
		strip_line_prefix = "^%s*%*%s?",
		allow_nested = false,
	},

	guard_comment = {
		guard_open = { "#if false", "#if 0" },
		guard_close = "#endif",
		guard_align_to_indent = false,
		allow_nested = true,
	},

	symbols = {
		-- keywords
		["abstract"] = "keyword",
		["add"] = "keyword",
		["alias"] = "keyword",
		["ascending"] = "keyword",
		["as"] = "keyword",
		["await"] = "keyword",
		["base"] = "keyword",
		["break"] = "conrol",
		["by"] = "keyword",
		["case"] = "keyword",
		["catch"] = "keyword",
		["checked"] = "keyword",
		["class"] = "keyword",
		["const"] = "keyword",
		["continue"] = "control",
		["default"] = "keyword",
		["delegate"] = "keyword",
		["descending"] = "keyword",
		["do"] = "keyword",
		["dynamic"] = "keyword",
		["else"] = "keyword",
		["equals"] = "keyword",
		["enum"] = "keyword",
		["event"] = "keyword",
		["explicit"] = "keyword",
		["extern"] = "keyword",
		["file"] = "keyword",
		["finally"] = "keyword",
		["fixed"] = "keyword",
		["for"] = "keyword",
		["foreach"] = "keyword",
		["from"] = "keyword",
		["get"] = "keyword",
		["global"] = "keyword",
		["goto"] = "control",
		["group"] = "keyword",
		["if"] = "keyword",
		["implicit"] = "keyword",
		["in"] = "keyword",
		["init"] = "keyword",
		["into"] = "keyword",
		["interface"] = "keyword",
		["internal"] = "keyword",
		["is"] = "keyword",
		["join"] = "keyword",
		["let"] = "keyword",
		["lock"] = "keyword",
		["namespace"] = "keyword",
		["nameof"] = "keyword",
		["new"] = "keyword",
		["not"] = "keyword",
		["on"] = "keyword",
		["operator"] = "keyword",
		["orderby"] = "keyword",
		["out"] = "keyword",
		["override"] = "keyword",
		["partial"] = "keyword",
		["params"] = "keyword",
		["private"] = "keyword",
		["protected"] = "keyword",
		["public"] = "keyword",
		["record"] = "keyword",
		["readonly"] = "keyword",
		["ref"] = "keyword",
		["remove"] = "keyword",
		["required"] = "keyword",
		["return"] = "control",
		["scoped"] = "keyword",
		["select"] = "keyword",
		["sealed"] = "keyword",
		["set"] = "keyword",
		["sizeof"] = "keyword",
		["stackalloc"] = "keyword",
		["static"] = "keyword",
		["struct"] = "keyword",
		["switch"] = "keyword",
		["this"] = "keyword",
		["throw"] = "keyword",
		["try"] = "keyword",
		["typeof"] = "keyword",
		["unchecked"] = "keyword",
		["unmanaged"] = "keyword",
		["unsafe"] = "keyword",
		["using"] = "keyword",
		["value"] = "keyword",
		["var"] = "keyword",
		["virtual"] = "keyword",
		["void"] = "keyword",
		["volatile"] = "keyword",
		["when"] = "keyword",
		["where"] = "keyword",
		["while"] = "keyword",
		["with"] = "keyword",
		["yield"] = "keyword",
		-- types
		["bool"] = "keyword2",
		["byte"] = "keyword2",
		["char"] = "keyword2",
		["decimal"] = "keyword2",
		["double"] = "keyword2",
		["float"] = "keyword2",
		["int"] = "keyword2",
		["long"] = "keyword2",
		["nint"] = "keyword2",
		["nuint"] = "keyword2",
		["object"] = "keyword2",
		["sbyte"] = "keyword2",
		["short"] = "keyword2",
		["string"] = "keyword2",
		["uint"] = "keyword2",
		["ulong"] = "keyword2",
		["ushort"] = "keyword2",
		-- literals
		["true"] = "literal",
		["false"] = "literal",
		["null"] = "literal",
	},
})
