Property definitions

config $ Config :: defaultinit
# Basic configuration class
#
# ~~~
# import config
#
# class MyConfig
#	super Config
#
#	var opt_my = new OptionString("My option", "--my")
#
#	init do
#		super
#		tool_description = "Usage: MyExample [OPTION]... [ARGS]..."
#		opts.add_option(opt_my)
#	end
#
#	fun my: String do return opt_my.value or else "Default value"
# end
#
# var config = new MyConfig
# config.parse_options(["--my", "hello", "arg1", "arg2"])
# assert config.my == "hello"
# assert config.args == ["arg1", "arg2"]
# ~~~
class Config

	# Context used to store and parse options
	var opts = new OptionContext

	# Help option
	var opt_help = new OptionBool("Show this help message", "-h", "-?", "--help")

	# Option --stub-man
	var opt_stub_man = new OptionBool("Generate a stub manpage in markdown format", "--stub-man")

	# Redefine this init to add your options
	init do
		add_option(opt_help, opt_stub_man)
		opt_stub_man.hidden = true
	end

	# Add an option to `self`
	#
	# Shortcut to `opts.add_option`.
	fun add_option(opt: Option...) do opts.add_option(opt...)

	# Initialize `self` options from `args`
	fun parse_options(args: Collection[String]) do
		opts.parse(args)

		if opt_stub_man.value then
			stub_man_options
			exit 0
		end
	end

	# Return the remaining args once options are parsed by `from_args`
	fun args: Array[String] do return opts.rest

	# Name, usage and synopsis of the tool.
	# It is mainly used in `usage`.
	# Should be correctly set by the client before calling `usage`
	# A multi-line string is recommended.
	#
	# eg. `"Usage: tool [OPTION]... [FILE]...\nDo some things."`
	var tool_description: String = "Usage: [OPTION]... [ARG]..." is writable

	# Was the `--help` option requested?
	fun help: Bool do return opt_help.value

	# Display `tool_description` and options usage in console
	fun usage do
		print tool_description
		print "\nOptions:"
		opts.usage
	end

	# Generate a manpage stub from `self`
	fun stub_man_options do
		var lines = tool_description.split("\n")
		var name = sys.program_name.basename
		var syn = lines.shift
		print "# NAME"
		print ""
		if lines.not_empty then
			printn "{name} - "
			print lines.join("\n")
			print ""
		end
		print "# SYNOPSIS"
		print ""
		print syn.replace("Usage: ", "")
		print ""
		print "# OPTIONS"
		for o in opts.options do
			if o.hidden then continue

			var first = true
			print ""
			printn "### "
			for n in o.names do
				if first then first = false else printn ", "
				printn "`{n}`"
			end
			print ""
			print "{o.helptext}."
		end
		exit 0
	end
end
lib/config/config.nit:159,1--268,3