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

format.register({
	name = "Windows Registry File",
	shortname = "Reg",
	author = "liqube",
	extensions = "reg",

	headers = "^Windows Registry Editor Version 5%.00",
	comment = ";",

	patterns = {
		-- Header line
		{ pattern = "Windows Registry Editor Version 5%.00", type = "meta", line_start = true },

		-- GUIDs
--    	patterns.guid_value(),
		-- TODO: Why does this only match when like this:
		--  {d04e05a6-594b-4fb6-a80d-01af5eed7d1d}
		-- But never when like this:
		--  "{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},1"="!VALUE"
		{ pattern = "{%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x}", type = "hex" },

		-- Semicolon starts a comment; rest of line is ignored
		{ pattern = ";.-\n", type = "comment" },

		-- Section removal marker: only the '-' in "[-...]" is red
		{ pattern = "%-", type = "error", line_prefix = "%s*%[" },

		-- Regular sections: exclude deletion form "[-...]" from full section highlight
		{ pattern = "%s*%[[^%-%]][^%]]*%]%s*", type = "function", line_start = true },

		-- Default value marker on key/value lines
		{ pattern = "%s*@", type = "keyword", line_start = true },

		-- Key token at line start for key=value entries (without consuming '=')
		{ pattern = "%s*[^=;\n]+%s*%f[=]", type = "normal", line_start = true },

		-- Value strings and escapes
		{ pattern = { '"', '"', "\\" }, type = "string" },
		{ pattern = [[\\.]], type = "string" },

		-- Registry value type tokens (reserved in value context)
		{ pattern = "hex%s*%(%x+%)%s*:", type = "keyword2", line_prefix = "[^=\n]*=%s*" },
		{ pattern = "hex%s*:", type = "keyword2", line_prefix = "[^=\n]*=%s*" },
		{ pattern = "dword%s*:", type = "keyword2", line_prefix = "[^=\n]*=%s*" },
		{ pattern = "qword%s*:", type = "keyword2", line_prefix = "[^=\n]*=%s*" },

		-- dword:bf800000
		{ pattern = "%x%x%x%x%x%x%x%x", type = "hex", preceded_by = "dword:" },
		{ pattern = "%x%x%x%x%x%x%x%x", type = "hex", preceded_by = "qword:" },

		-- Hex byte tokens part of a hex(n): block
		{ pattern = "[%da-fA-F][%da-fA-F]%f[,%s]", type = "hex" },

		-- Hex payload rules ('hex:' / 'hex(n):'):
		-- valid byte tokens are exactly two hex digits, case-insensitive
		{ pattern = "%f[%x]%x%x%f[^%x]", type = "number", line_start = true, line_prefix = "[^=\n]*=%s*hex%s*:%s*" },
		{
			pattern = "%f[%x]%x%x%f[^%x]",
			type = "number",
			line_start = true,
			line_prefix = "[^=\n]*=%s*hex%s*%(%d+%)%s*:%s*",
		},
		-- continuation marker requires trailing ',\\'
		{ pattern = [[,%s*\\%s*$]], type = "operator", line_start = true, line_prefix = "[^=\n]*=%s*hex%s*:%s*" },
		{
			pattern = [[,%s*\\%s*$]],
			type = "operator",
			line_start = true,
			line_prefix = "[^=\n]*=%s*hex%s*%(%d+%)%s*:%s*",
		},

		-- Value deletion marker in key/value pairs: only '-' in 'key=-' is red
		{ pattern = "%-", type = "error", line_prefix = "[^=\n]*=%s*" },

		-- Reserved character set to treat specially in REG grammar contexts
		{ pattern = '[%[%]\\\\=@",:%(%),%-]', type = "operator" },

		-- Numbers
		{ pattern = "0x%x+", type = "number" },
		{ pattern = "%f[%w]%d+%f[^%w]", type = "number" },
	},

	-- Outline jump points for each registry section
	outline_patterns = {
		{ pattern = "%s*%[[^%]]+%]%s*", line_start = true },
	},

	symbols = {
		-- Canonical root key names
		["HKEY_CLASSES_ROOT"] = "keyword",
		["HKEY_CURRENT_USER"] = "keyword",
		["HKEY_LOCAL_MACHINE"] = "keyword",
		["HKEY_USERS"] = "keyword",
		["HKEY_CURRENT_CONFIG"] = "keyword",

		-- Legacy / compatibility root keys
		["HKEY_DYN_DATA"] = "keyword2",
		["HKEY_PERFORMANCE_DATA"] = "keyword2",
		["HKEY_PERFORMANCE_TEXT"] = "keyword2",
		["HKEY_PERFORMANCE_NLSTEXT"] = "keyword2",
	},
})
