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

format.register({
	name = "Plan 9 Mkfile",
	shortname = "mkfile",
	author = "liqube",

	filenames = { "mkfile" },

	comment = "#",

	patterns = {
		-- Escaped comment marker
		{ pattern = "\\#", type = "normal" },

		-- Comments
		{ pattern = "#[^\r\n]*", type = "comment", not_preceded_by = "\\" },

		-- Generated include
		{
			pattern = " *(<|)([^\r\n#]+)",
			type = { "preprocessor", "string" },
			line_start = true,
		},

		-- Include
		{
			pattern = " *(<)([^|\r\n#]+)",
			type = { "preprocessor", "string" },
			line_start = true,
		},

		-- Backquoted rc command substitution
		{ pattern = { "`%{", "%}" }, type = "meta" },

		-- Double quoted shell text
		{ pattern = { '"', '"', "\\" }, type = "string" },

		-- Single quoted shell text
		{ pattern = { "'", "'" }, type = "string" },

		-- Line continuation backslash
		{ pattern = "[ \t]*(\\)[ \t]*\n", type = { "meta" } },

		-- Variable assignment with update attribute
		{
			pattern = " *([^%s:=#][^=#\r\n]-)(=)(U)(=)",
			type = { "variable", "operator", "keyword2", "operator" },
			line_start = true,
		},

		-- Variable assignment
		{
			pattern = " *([^%s:=#][^=#\r\n]-)(=)",
			type = { "variable", "operator" },
			line_start = true,
		},

		-- Rule with one or more attributes
		{
			pattern = " *([^#%s:=][^#:=\r\n]-)(:)([DENnPQRUV][^:%s\r\n]*)(:)",
			type = { "function", "operator", "keyword2", "operator" },
			line_start = true,
		},

		-- Rule without attributes
		{
			pattern = " *([^#%s:=][^#:=\r\n]-)(:)",
			type = { "function", "operator" },
			line_start = true,
		},

		-- Braced variable reference
		{ pattern = "%${[^}\r\n]-}", type = "variable" },

		-- Simple variable reference
		{ pattern = "%$[%a_][%w_]*", type = "variable" },

		-- Single-character variable reference
		{ pattern = "%$[%w%*%@%#%?%$]", type = "variable" },

		-- Regular expression meta-rule back reference
		{ pattern = "\\%d", type = "variable" },

		-- Decimal number
		{ pattern = "%f[%w_]%d+%.?%d*%f[^%w_]", type = "number" },

		-- Command line option
		{ pattern = "%f[%S]%-[%w%-_%.=,/]+", type = "function" },

		-- Meta-rule wildcard
		{ pattern = "[%%&]", type = "operator" },

		-- Rule and shell punctuation
		{ pattern = "[%(%){},;:@|<>%*%+%-=%%%!%?%^%[%]/]", type = "operator" },

		-- Plain words
		{ pattern = "[%.%a_][%w_%.%-]*", type = "normal" },
	},

	outline_patterns = {
		{ pattern = " *<|[^\r\n#]+", line_start = true }, -- Generated include
		{ pattern = " *<[^|\r\n#]+", line_start = true }, -- Include
		{ pattern = " *[^%s:=#][^=#\r\n]-=", line_start = true }, -- Variable assignment
		{ pattern = " *[^#%s:=][^#:=\r\n]-:[DENnPQRUV][^:%s\r\n]*:", line_start = true }, -- Rule with attributes
		{ pattern = " *[^#%s:=][^#:=\r\n]-:", line_start = true }, -- Rule
	},

	symbols = {
		-- Rule attributes
		["D"] = "keyword2",
		["E"] = "keyword2",
		["N"] = "keyword2",
		["n"] = "keyword2",
		["Q"] = "keyword2",
		["R"] = "keyword2",
		["U"] = "keyword2",
		["V"] = "keyword2",

		-- Common mk variables
		["objtype"] = "variable",
		["O"] = "variable",
		["OS"] = "variable",
		["CC"] = "variable",
		["CFLAGS"] = "variable",
		["LD"] = "variable",
		["LDFLAGS"] = "variable",
		["AR"] = "variable",
		["YACC"] = "variable",
		["NPROC"] = "variable",
		["MKSHELL"] = "variable",
		["MKFLAGS"] = "variable",
		["MKARGS"] = "variable",

		-- Recipe mk variables
		["alltarget"] = "variable",
		["newprereq"] = "variable",
		["newmember"] = "variable",
		["nproc"] = "variable",
		["pid"] = "variable",
		["prereq"] = "variable",
		["stem"] = "variable",
		["stem0"] = "variable",
		["stem1"] = "variable",
		["stem2"] = "variable",
		["stem3"] = "variable",
		["stem4"] = "variable",
		["stem5"] = "variable",
		["stem6"] = "variable",
		["stem7"] = "variable",
		["stem8"] = "variable",
		["stem9"] = "variable",
		["target"] = "variable",

		-- Common Plan 9 recipe commands
		["sed"] = "keyword2",
		["rm"] = "keyword2",
		["cp"] = "keyword2",
		["cmp"] = "keyword2",
		["ar"] = "keyword2",
		["echo"] = "keyword2",

		-- Common rc control words
		["for"] = "keyword",
		["if"] = "keyword",
		["switch"] = "keyword",
		["while"] = "keyword",
		["in"] = "keyword",
		["fn"] = "keyword",
	},
})