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

format.register({
	name = "Meson Build",
	shortname = "Meson",
	author = "liqube",

	filenames = {
		"meson.build",
		"meson.options",
		"meson_options.txt",
	},

	comment = "#",

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

		-- Triple quoted multiline strings do not use backslash escaping
		{ pattern = { "'''", "'''" }, type = "string" },

		-- Single quoted strings
		{ pattern = { "'", "'", "\\" }, type = "string" },

		-- Backslash line continuation
		{ pattern = "\\[ \t]*\r?\n", type = "meta" },

		-- Foreach declaration with two loop variables
		{
			pattern = "%s*(foreach)(%s+)([%a_][%w_]*)(%s*,%s*)([%a_][%w_]*)(%s*)(:)",
			type = {
				"control",
				"normal",
				"variable",
				"operator",
				"variable",
				"normal",
				"operator",
			},
			line_start = true,
		},

		-- Foreach declaration with one loop variable
		{
			pattern = "%s*(foreach)(%s+)([%a_][%w_]*)(%s*)(:)",
			type = {
				"control",
				"normal",
				"variable",
				"normal",
				"operator",
			},
			line_start = true,
		},

		-- Append assignment
		{
			pattern = "%s*([%a_][%w_]*)(%s*)(%+=)",
			type = { "variable", "normal", "operator" },
			line_start = true,
		},

		-- Plain assignment
		{
			pattern = "%s*([%a_][%w_]*)(%s*)(=)",
			type = { "variable", "normal", "operator" },
			line_start = true,
		},

		-- Method call after member-access dot
		{
			pattern = "(%.)([%a_][%w_]*)(%s*)%f[(]",
			type = { "operator", "function", "normal" },
		},

		-- Function call
		{
			pattern = "([%a_][%w_]*)(%s*)%f[(]",
			type = { "function", "normal" },
		},

		-- Keyword argument and dictionary identifier key
		{
			pattern = "([%a_][%w_]*)(%s*)(:)",
			type = { "keyword2", "normal", "operator" },
		},

		-- Membership operator phrase
		{ pattern = "%f[%a]not%s+in%f[^%w_]", type = "operator" },

		-- Comparison operators
		{ pattern = "[=!<>]=", type = "operator" },

		-- Decimal integer
		{ pattern = "%f[%w_]%d[%d_]*%f[^%w_]", type = "number" },

		-- Operators and delimiters
		{ pattern = "[%+%-%*/%%<>=%.:,;%?%(%)%[%]{}]", type = "operator" },

		-- Identifiers for exact symbol recoloring
		{ pattern = "[%a_][%w_]*", type = "symbol" },
	},

	outline_patterns = {
		{ pattern = "%s*project%s*%(", line_start = true }, -- Project declaration
		{ pattern = "%s*executable%s*%(", line_start = true }, -- Executable target
		{ pattern = "%s*library%s*%(", line_start = true }, -- Library target
		{ pattern = "%s*shared_library%s*%(", line_start = true }, -- Shared library target
		{ pattern = "%s*static_library%s*%(", line_start = true }, -- Static library target
		{ pattern = "%s*both_libraries%s*%(", line_start = true }, -- Dual library target
		{ pattern = "%s*custom_target%s*%(", line_start = true }, -- Custom target
		{ pattern = "%s*run_target%s*%(", line_start = true }, -- Run target
		{ pattern = "%s*generator%s*%(", line_start = true }, -- Generator declaration
		{ pattern = "%s*test%s*%(", line_start = true }, -- Test declaration
		{ pattern = "%s*benchmark%s*%(", line_start = true }, -- Benchmark declaration
		{ pattern = "%s*option%s*%(", line_start = true }, -- Build option
		{ pattern = "%s*subdir%s*%(", line_start = true }, -- Subdirectory inclusion
		{ pattern = "%s*if%s+", line_start = true }, -- Conditional block
		{ pattern = "%s*foreach%s+", line_start = true }, -- Loop block
	},

	quotes = {
		primary = "single",
		profiles = {
			single = quotes.profile.c_style_single(),
		},
	},

	symbols = {
		-- Conditional and loop control
		["if"] = "control",
		["elif"] = "control",
		["else"] = "control",
		["endif"] = "control",
		["foreach"] = "control",
		["endforeach"] = "control",
		["break"] = "control",
		["continue"] = "control",

		-- Logical and membership operators
		["and"] = "operator",
		["or"] = "operator",
		["not"] = "operator",
		["in"] = "operator",

		-- Boolean literals
		["true"] = "literal",
		["false"] = "literal",

		-- Built-in objects
		["meson"] = "variable",
		["build_machine"] = "variable",
		["host_machine"] = "variable",
		["target_machine"] = "variable",

		-- Project and target functions
		["project"] = "function",
		["executable"] = "function",
		["library"] = "function",
		["shared_library"] = "function",
		["static_library"] = "function",
		["both_libraries"] = "function",
		["custom_target"] = "function",
		["run_target"] = "function",
		["generator"] = "function",

		-- Dependency and program discovery
		["dependency"] = "function",
		["find_program"] = "function",
		["find_library"] = "function",
		["disabler"] = "function",

		-- Source and include handling
		["files"] = "function",
		["include_directories"] = "function",
		["configure_file"] = "function",
		["vcs_tag"] = "function",

		-- Dependency declarations
		["declare_dependency"] = "function",
		["override_dependency"] = "function",
		["override_find_program"] = "function",

		-- Project composition
		["subproject"] = "function",
		["subdir"] = "function",
		["import"] = "function",

		-- Installation functions
		["install_data"] = "function",
		["install_emptydir"] = "function",
		["install_headers"] = "function",
		["install_man"] = "function",
		["install_subdir"] = "function",
		["install_symlink"] = "function",

		-- Test functions
		["test"] = "function",
		["benchmark"] = "function",
		["add_test_setup"] = "function",

		-- Configuration and option functions
		["configuration_data"] = "function",
		["get_option"] = "function",
		["option"] = "function",

		-- Output and validation functions
		["summary"] = "function",
		["message"] = "function",
		["debug"] = "function",
		["warning"] = "warning",
		["error"] = "error",
		["assert"] = "function",

		-- Command execution
		["run_command"] = "function",

		-- Option types
		["string"] = "keyword2",
		["boolean"] = "keyword2",
		["combo"] = "keyword2",
		["integer"] = "keyword2",
		["array"] = "keyword2",
		["feature"] = "keyword2",

		-- Feature option states
		["enabled"] = "literal",
		["disabled"] = "literal",
		["auto"] = "literal",
	},

	defaults = {
		word_wrap = false,
	},
})
