clip

package module
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2023 License: Apache-2.0 Imports: 10 Imported by: 3

README

clip

Yet another Go “Command Line Interface Parser”.

Docs: https://pkg.go.dev/github.com/mark-summerfield/clip

License

Apache-2.0


Documentation

Overview

Package clip “command line interface parser” provides yet another Go command line argument parser.

Overview

clip can handle flags, single argument options, multiple argument options, and positional arguments.

Although there's no direct support for subcommands, they can easily be achieved (see `eg/subcommands/subcommands.go` for an example).

Flags

A flag is either present or absent.

Examples:

myapp -v
myapp --verbose

If the flag is present, the option's value is true; otherwise it is false.

Flags support short and long names. For example, a flag name of "version" can be set with `--version` or `-v`. If you don't want a short name, or want a different one (e.g., `-V`), use [Option.SetShortName].

parser := NewParserVersion("1.0.0") # AppName is strings.TrimSuffix(os.Base(os.Args[0]), ".exe")
verboseOpt := parser.Flag("verbose", "whether to show more output")
parser.ParseLine("")
verbose := verboseOpt.Value() // verbose == false
// -or-
verbose = verboseOpt.Given() // verbose == false

parser.ParseLine("-v")
verbose = verboseOpt.Value() // verbose == true
// -or-
verbose = verboseOpt.Given() // verbose == true

If you want the user to be able to optionally specify how verbose to be then use an Int value option: see Parser.Int.

Multiple flags can be grouped together if their short names are used, e.g., given flags `-v`, `-x`, and `-c`, they can be set individually, or together, i.e., `-v -x -c` or `-vxc`. The last option in such a group may be a single- or multi-value option. For example, if option `o` takes a string argument, we could write any of these:

myapp -v -x -c -o outfile.dat
myapp -v -x -c -o=outfile.dat
myapp -vxcooutfile.dat
myapp -vxco outfile.dat
myapp -vxco=outfile.dat

And if we are happy with `-o`'s default value, we can use these:

myapp -v -x -c -o
myapp -v -x -c
myapp -vxco
myapp -vxc

All of which set the `v`, `x`, and `c` flags as before and set the `-o` option to its default value.

Single Value Options

A single value option is either present—either with a value or without (in which case its default is used)—or absent, in which case its default is its value.

Examples:

myapp
myapp -v
myapp --verbose
myapp -v1
myapp -v=2
myapp -v 3
myapp --verbose=4
myapp --verbose 5

If the option is absent, the option's value is the default that was set. If the option is present, the option's value is the default if no value is given, otherwise the given value.

If you need to distinguish between whether a value was given at all (i.e., between the first two examples, assuming the default was set to 1), then use [Option.Given].

parser := NewParser()
verboseOpt := parser.Int("verbose", "how much output to show", 1)
verboseOpt.AllowImplicit = true // implicitly use the default so -v → -v1
parser.ParseLine("")
verbose := 0 // assume no verbosity
if verboseOpt.Given() {
	verbose = verboseOpt.Value()
}

Here, verbose == 0 (since we started at 0 and checked whether it was given and it wasn't)

// first three lines as before
parser.ParseLine("-v")
verbose := 0 // assume no verbosity
if verboseOpt.Given() {
	verbose = verboseOpt.Value()
}

Here, verbose == 1 (since it was given with no value, but due to AllowImplicit, the default was used for its value)

// first three lines as before
parser.ParseLine("-v2")
verbose := 0 // assume no verbosity
if verboseOpt.Given() {
	verbose = verboseOpt.Value()
}

Here, verbose == 2 (as given)

Hidden Options

An option can be hidden by calling Hide on it. Such options work normally but don't show up in -h or --help texts.

Validators

To create an IntOption or RealOption whose values must be within a given (inclusive) range, use Parser.IntInRange or Parser.RealInRange.

To create a StrOption that only accepts one of a specific set of choices, use Parser.Choice.

Alternatively, create a plain option and set a custom [Validator].

A validator function takes two string arguments: the option name and value, and must return two strings, either a valid value and an empty string, or an empty string and an error message string.

parser := NewParser()
formatsOpt := parser.Strs("format", "The format(s) to output")
formatsOpt.Validator = func(name, value string) (string, string) {
	value = strings.ToLower(value)
	for _, valid := range []string{"csv", "jsn", "json", "xml"} {
		if value == valid {
			return value, ""
		}
	}
	return "", fmt.Sprintf("invalid format: %q", value)
}

Mutli-Value Options

For ints, reals, and strings it is possible to set multi-value options, that is options that accept one or more. See Parser.Ints, Parser.Reals, and Parser.Strs.

It is often more convenient to use a single-value option with multiple values comma separated. For example:

--pages 21,36,42,43
-f csv,json,xml

Post-Parsing Validation

If some post-parsing validation finds invalid data it is possible to treat it as a parser error by calling Parser.OnError with a message string.

Required Options

This is a contradiction in terms, but if we really want to require an option then handle it like this:

parser := NewParser() // below: name, help, minimum, maximum, default
countOpt := parser.IntInRange("count", "how many are wanted", 0, 100, 0)
parser.ParseLine("")
if !countOpt.Given() {
	parser.OnMissing(countOpt) // won't return (calls os.Exit)
}
count := countOpt.Value() // if we got here the user set it

Examples

See the `eg` folder for examples of use.

Index

Constants

View Source
const NoShortName = 0 // Use this for options that don't have short names

Variables

View Source
var Version string // This module's version

Functions

func ArgHelp added in v0.3.3

func ArgHelp(argWidth, width int, desc string) string

ArgHelp is used internally by clip, but made public because it can be useful for implementing subcommands (see `eg/subcommands/subcommands.go`).

func Bold deprecated added in v0.4.0

func Bold(s string) string

Bold returns bold text.

Deprecated: Use Strong instead.

func Emph added in v0.4.0

func Emph(s string) string

Empth returns the given string contained within terminal escape codes to make it italic on linux and underlined on windows (providing os.Stdout is a TTY).

func GetWidth added in v0.3.3

func GetWidth() int

GetWidth returns the terminal width; it is used internally by clip, but made public because it can be useful for implementing subcommands (see `eg/subcommands/subcommands.go`).

func Hint added in v0.4.0

func Hint(s string) string

Hint returns the given string contained within terminal escape codes to make it underlined on linux and italic on windows (although I've never known italics to actually work on windows) (providing os.Stdout is a TTY).

func Strong added in v1.0.0

func Strong(s string) string

Strong returns the given string contained within terminal escape codes to make it bold on linux and bold or colored on windows (providing os.Stdout is a TTY).

Types

type FlagOption

type FlagOption struct {
	// contains filtered or unexported fields
}

FlagOption is an option for a flag (i.e., an option that is either present or absent).

func (FlagOption) Given

func (me FlagOption) Given() bool

Given returns true if (after the parse) the option was given; otherwise returns false.

func (FlagOption) Help

func (me FlagOption) Help() string

Help returns the option's help text.

func (FlagOption) Hide added in v0.4.0

func (me FlagOption) Hide()

Hide sets the option to be hidden: the user can use it normally, but it won't show up when -h or --help is given.

func (FlagOption) LongName

func (me FlagOption) LongName() string

LongName returns the option's long name.

func (FlagOption) MustSetVarName added in v0.9.0

func (me FlagOption) MustSetVarName(name string)

MustSetVarName is used to set the option's variable name. Panics on error. See also [SetVarName]

func (FlagOption) SetShortName

func (me FlagOption) SetShortName(c rune)

SetShortName sets the option's short name—or clears it if NoShortName is passed.

func (FlagOption) SetVarName

func (me FlagOption) SetVarName(name string) error

SetVarName is used to set the option's variable name. [See also MustSetVarName].

func (FlagOption) ShortName

func (me FlagOption) ShortName() rune

ShortName returns the option's short name which could be 0 (NoShortName).

func (FlagOption) Value

func (me FlagOption) Value() bool

Value returns true if the flag was given; otherwise false.

func (FlagOption) VarName

func (me FlagOption) VarName() string

VarName returns the name used for the option's variables: by default the option's long name uppercased. (This is never used by FlagOptions.)

type IntOption

type IntOption struct {
	TheDefault    int          // The options default value.
	AllowImplicit bool         // If true, giving the option with no value means use the default.
	Validator     IntValidator // A validation function.
	// contains filtered or unexported fields
}

IntOption is an option for accepting a single int.

func (IntOption) Given

func (me IntOption) Given() bool

Given returns true if (after the parse) the option was given; otherwise returns false.

func (IntOption) Help

func (me IntOption) Help() string

Help returns the option's help text.

func (IntOption) Hide added in v0.4.0

func (me IntOption) Hide()

Hide sets the option to be hidden: the user can use it normally, but it won't show up when -h or --help is given.

func (IntOption) LongName

func (me IntOption) LongName() string

LongName returns the option's long name.

func (IntOption) MustSetVarName added in v0.9.0

func (me IntOption) MustSetVarName(name string)

MustSetVarName is used to set the option's variable name. Panics on error. See also [SetVarName]

func (IntOption) SetShortName

func (me IntOption) SetShortName(c rune)

SetShortName sets the option's short name—or clears it if NoShortName is passed.

func (IntOption) SetVarName

func (me IntOption) SetVarName(name string) error

SetVarName is used to set the option's variable name. [See also MustSetVarName].

func (IntOption) ShortName

func (me IntOption) ShortName() rune

ShortName returns the option's short name which could be 0 (NoShortName).

func (IntOption) Value

func (me IntOption) Value() int

Value returns the given value or if the option wasn't given, the default value.

func (IntOption) VarName

func (me IntOption) VarName() string

VarName returns the name used for the option's variables: by default the option's long name uppercased. (This is never used by FlagOptions.)

type IntValidator

type IntValidator func(string, string) (int, string)

These take an option's name and the given string value and return a valid value and "" or the type's zero value and an error message.

type IntsOption

type IntsOption struct {
	ValueCount ValueCount   // How many ints are wanted.
	Validator  IntValidator // A validation function.
	// contains filtered or unexported fields
}

IntsOption is an option for accepting a one or more ints.

func (IntsOption) Given

func (me IntsOption) Given() bool

Given returns true if (after the parse) the option was given; otherwise returns false.

func (IntsOption) Help

func (me IntsOption) Help() string

Help returns the option's help text.

func (IntsOption) Hide added in v0.4.0

func (me IntsOption) Hide()

Hide sets the option to be hidden: the user can use it normally, but it won't show up when -h or --help is given.

func (IntsOption) LongName

func (me IntsOption) LongName() string

LongName returns the option's long name.

func (IntsOption) MustSetVarName added in v0.9.0

func (me IntsOption) MustSetVarName(name string)

MustSetVarName is used to set the option's variable name. Panics on error. See also [SetVarName]

func (IntsOption) SetShortName

func (me IntsOption) SetShortName(c rune)

SetShortName sets the option's short name—or clears it if NoShortName is passed.

func (IntsOption) SetVarName

func (me IntsOption) SetVarName(name string) error

SetVarName is used to set the option's variable name. [See also MustSetVarName].

func (IntsOption) ShortName

func (me IntsOption) ShortName() rune

ShortName returns the option's short name which could be 0 (NoShortName).

func (IntsOption) Value

func (me IntsOption) Value() []int

Value returns the given value(s) or nil.

func (IntsOption) VarName

func (me IntsOption) VarName() string

VarName returns the name used for the option's variables: by default the option's long name uppercased. (This is never used by FlagOptions.)

type Parser

type Parser struct {
	ShortDesc   string // Text that goes before the usage line.
	LongDesc    string // Text between the usage line and arguments.
	EndDesc     string // Text at the end.
	VersionName string // Default "version".
	HelpName    string // Default "help"; recommend leaving as-is.

	Positionals     []string        // The positionals (after parsing).
	PositionalCount PositionalCount // How many positionals are wanted.
	PositionalHelp  string          // The positionals help text.
	// contains filtered or unexported fields
}

For applications with fairly simple CLIs, only the LongDesc is used.

func NewParser

func NewParser() Parser

NewParser creates a new command line parser. It uses the executable's basename for the AppName and has no version option. See also NewParserVersion and NewParserUser.

func NewParserUser

func NewParserUser(appname, version string) Parser

NewParserUser creates a new command line parser. If appname == "" the executable's basename will be used. If version == "" no version option will be available. See also NewParser and NewParserVersion.

func NewParserVersion

func NewParserVersion(version string) Parser

NewParserVersion creates a new command line parser. It uses the executable's basename for the AppName and a version option with the given version. See also NewParser and NewParserUser.

func (*Parser) AppName

func (me *Parser) AppName() string

AppName returns the name used for the application when displaying help.

func (*Parser) Choice

func (me *Parser) Choice(name, help string, choices []string,
	theDefault string) *StrOption

Create and return new StrOption, --name or -n (where n is the first rune in name), help is the option's help text, choices are the valid choices from which the option's value must be chosen, and theDefault is the option's default.

func (*Parser) Flag

func (me *Parser) Flag(name, help string) *FlagOption

Create and return new FlagOption, --name or -n (where n is the first rune in name) and help is the option's help text.

func (*Parser) Int

func (me *Parser) Int(name, help string, theDefault int) *IntOption

Create and return new IntOption, --name or -n (where n is the first rune in name), help is the option's help text, and theDefault is the option's default.

func (*Parser) IntInRange

func (me *Parser) IntInRange(name, help string, minimum, maximum,
	theDefault int) *IntOption

Create and return new IntOption, --name or -n (where n is the first rune in name), help is the option's help text, the minimum and maximum are inclusive limits, and theDefault is the option's default.

func (*Parser) Ints

func (me *Parser) Ints(name, help string) *IntsOption

Create and return new IntsOption, --name or -n (where n is the first rune in name) and help is the option's help text. By default this option accepts OneOrMoreValues (see ValueCount).

func (*Parser) MustSetPositionalVarName added in v0.9.0

func (me *Parser) MustSetPositionalVarName(name string)

Sets the variable name for positional arguments; the default is FILE. Panics on error. See also [SetPositionalVarName].

func (*Parser) OnError

func (me *Parser) OnError(err error)

OnError is useful for post parsing validation: use it to display an error in clip's style and quit with exit code 2.

func (*Parser) OnHelp added in v1.3.1

func (me *Parser) OnHelp()

OnHelp shows the help text and quits.

func (*Parser) OnMissing

func (me *Parser) OnMissing(option optioner) error

OnMissing is for use with options that—contradictoraly—are required.

For example, if the user _must_ use the "count" option:

parser := NewParser() // below: name, help, minimum, maximum, default
countOpt := parser.IntInRange("count", "how many are wanted", 0, 100, 0)
parser.ParseLine("")
if !countOpt.Given() { // countOpt is required
	parser.OnMissing(countOpt) // won't return (calls os.Exit)
}
count := countOpt.Value() // if we got here the user set it

func (*Parser) Parse

func (me *Parser) Parse() error

Parses the arguments in os.Args[1:]. Each option is assigned the given value or its default (if any), and the Parser.Positionals is filled with the remaining arguments (depending on the Parser.PositionalCount (see PositionalCount. See also Parser.ParseLine and Parser.ParseArgs.

func (*Parser) ParseArgs

func (me *Parser) ParseArgs(args []string) error

Parses the arguments in the given slice of strings. Each option is assigned the given value or its default (if any), and the Parser.Positionals is filled with the remaining arguments (depending on the Parser.PositionalCount (see PositionalCount. See also Parser.Parse and Parser.ParseLine.

func (*Parser) ParseLine

func (me *Parser) ParseLine(line string) error

Parses the arguments in the given line. Each option is assigned the given value or its default (if any), and the Parser.Positionals is filled with the remaining arguments (depending on the Parser.PositionalCount (see PositionalCount. See also Parser.Parse and Parser.ParseArgs.

func (*Parser) Real

func (me *Parser) Real(name, help string,
	theDefault float64) *RealOption

Create and return new RealOption, --name or -n (where n is the first rune in name), help is the option's help text, and theDefault is the option's default.

func (*Parser) RealInRange

func (me *Parser) RealInRange(name, help string, minimum, maximum,
	theDefault float64) *RealOption

Create and return new RealOption, --name or -n (where n is the first rune in name), help is the option's help text, the minimum and maximum are inclusive limits, and theDefault is the option's default.

func (*Parser) Reals

func (me *Parser) Reals(name, help string) *RealsOption

Create and return new RealsOption, --name or -n (where n is the first rune in name) and help is the option's help text. By default this option accepts OneOrMoreValues (see ValueCount).

func (*Parser) SetAppName added in v0.3.3

func (me *Parser) SetAppName(appName string)

SetAppName can be used to override the default application name; the default is strings.TrimSuffix(path.Base(os.Args[0]), ".exe").

func (*Parser) SetPositionalVarName

func (me *Parser) SetPositionalVarName(name string) error

Sets the variable name for positional arguments; the default is FILE. See also [MustSetPositionalVarName].

func (*Parser) Str

func (me *Parser) Str(name, help, theDefault string) *StrOption

Create and return new StrOption, --name or -n (where n is the first rune in name), help is the option's help text, and theDefault is the option's default.

func (*Parser) Strs

func (me *Parser) Strs(name, help string) *StrsOption

Create and return new StrsOption, --name or -n (where n is the first rune in name) and help is the option's help text. By default this option accepts OneOrMoreValues (see ValueCount).

func (*Parser) Version

func (me *Parser) Version() string

Returns the version string (which could be empty).

type PositionalCount

type PositionalCount uint8

This specifies how many positionals *must* be present.

const (
	ZeroPositionals PositionalCount = iota
	ZeroOrOnePositionals
	ZeroToTwoPositionals
	ZeroOrMorePositionals
	OnePositional
	TwoPositionals
	TwoOrThreePositionals
	ThreePositionals
	FourPositionals
	OneOrTwoPositionals
	OneToThreePositionals
	OneOrMorePositionals
)

func (PositionalCount) String

func (me PositionalCount) String() string

type RealOption

type RealOption struct {
	TheDefault    float64       // The options default value.
	AllowImplicit bool          // If true, giving the option with no value means use the default.
	Validator     RealValidator // A validation function.
	// contains filtered or unexported fields
}

RealOption is an option for accepting a single real.

func (RealOption) Given

func (me RealOption) Given() bool

Given returns true if (after the parse) the option was given; otherwise returns false.

func (RealOption) Help

func (me RealOption) Help() string

Help returns the option's help text.

func (RealOption) Hide added in v0.4.0

func (me RealOption) Hide()

Hide sets the option to be hidden: the user can use it normally, but it won't show up when -h or --help is given.

func (RealOption) LongName

func (me RealOption) LongName() string

LongName returns the option's long name.

func (RealOption) MustSetVarName added in v0.9.0

func (me RealOption) MustSetVarName(name string)

MustSetVarName is used to set the option's variable name. Panics on error. See also [SetVarName]

func (RealOption) SetShortName

func (me RealOption) SetShortName(c rune)

SetShortName sets the option's short name—or clears it if NoShortName is passed.

func (RealOption) SetVarName

func (me RealOption) SetVarName(name string) error

SetVarName is used to set the option's variable name. [See also MustSetVarName].

func (RealOption) ShortName

func (me RealOption) ShortName() rune

ShortName returns the option's short name which could be 0 (NoShortName).

func (RealOption) Value

func (me RealOption) Value() float64

Value returns the given value or if the option wasn't given, the default value.

func (RealOption) VarName

func (me RealOption) VarName() string

VarName returns the name used for the option's variables: by default the option's long name uppercased. (This is never used by FlagOptions.)

type RealValidator

type RealValidator func(string, string) (float64, string)

type RealsOption

type RealsOption struct {
	ValueCount ValueCount    // How many strings are wanted.
	Validator  RealValidator // A validation function.
	// contains filtered or unexported fields
}

RealsOption is an option for accepting a one or more reals.

func (RealsOption) Given

func (me RealsOption) Given() bool

Given returns true if (after the parse) the option was given; otherwise returns false.

func (RealsOption) Help

func (me RealsOption) Help() string

Help returns the option's help text.

func (RealsOption) Hide added in v0.4.0

func (me RealsOption) Hide()

Hide sets the option to be hidden: the user can use it normally, but it won't show up when -h or --help is given.

func (RealsOption) LongName

func (me RealsOption) LongName() string

LongName returns the option's long name.

func (RealsOption) MustSetVarName added in v0.9.0

func (me RealsOption) MustSetVarName(name string)

MustSetVarName is used to set the option's variable name. Panics on error. See also [SetVarName]

func (RealsOption) SetShortName

func (me RealsOption) SetShortName(c rune)

SetShortName sets the option's short name—or clears it if NoShortName is passed.

func (RealsOption) SetVarName

func (me RealsOption) SetVarName(name string) error

SetVarName is used to set the option's variable name. [See also MustSetVarName].

func (RealsOption) ShortName

func (me RealsOption) ShortName() rune

ShortName returns the option's short name which could be 0 (NoShortName).

func (RealsOption) Value

func (me RealsOption) Value() []float64

Value returns the given value(s) or nil.

func (RealsOption) VarName

func (me RealsOption) VarName() string

VarName returns the name used for the option's variables: by default the option's long name uppercased. (This is never used by FlagOptions.)

type StrOption

type StrOption struct {
	TheDefault    string       // The options default value.
	AllowImplicit bool         // If true, giving the option with no value means use the default.
	Validator     StrValidator // A validation function.
	// contains filtered or unexported fields
}

StrOption is an option for accepting a single string.

func (StrOption) Given

func (me StrOption) Given() bool

Given returns true if (after the parse) the option was given; otherwise returns false.

func (StrOption) Help

func (me StrOption) Help() string

Help returns the option's help text.

func (StrOption) Hide added in v0.4.0

func (me StrOption) Hide()

Hide sets the option to be hidden: the user can use it normally, but it won't show up when -h or --help is given.

func (StrOption) LongName

func (me StrOption) LongName() string

LongName returns the option's long name.

func (StrOption) MustSetVarName added in v0.9.0

func (me StrOption) MustSetVarName(name string)

MustSetVarName is used to set the option's variable name. Panics on error. See also [SetVarName]

func (StrOption) SetShortName

func (me StrOption) SetShortName(c rune)

SetShortName sets the option's short name—or clears it if NoShortName is passed.

func (StrOption) SetVarName

func (me StrOption) SetVarName(name string) error

SetVarName is used to set the option's variable name. [See also MustSetVarName].

func (StrOption) ShortName

func (me StrOption) ShortName() rune

ShortName returns the option's short name which could be 0 (NoShortName).

func (StrOption) Value

func (me StrOption) Value() string

Value returns the given value or if the option wasn't given, the default value.

func (StrOption) VarName

func (me StrOption) VarName() string

VarName returns the name used for the option's variables: by default the option's long name uppercased. (This is never used by FlagOptions.)

type StrValidator

type StrValidator func(string, string) (string, string)

type StrsOption

type StrsOption struct {
	ValueCount ValueCount   // How many strings are wanted.
	Validator  StrValidator // A validation function.
	// contains filtered or unexported fields
}

StrsOption is an option for accepting a one or more strings.

func (StrsOption) Given

func (me StrsOption) Given() bool

Given returns true if (after the parse) the option was given; otherwise returns false.

func (StrsOption) Help

func (me StrsOption) Help() string

Help returns the option's help text.

func (StrsOption) Hide added in v0.4.0

func (me StrsOption) Hide()

Hide sets the option to be hidden: the user can use it normally, but it won't show up when -h or --help is given.

func (StrsOption) LongName

func (me StrsOption) LongName() string

LongName returns the option's long name.

func (StrsOption) MustSetVarName added in v0.9.0

func (me StrsOption) MustSetVarName(name string)

MustSetVarName is used to set the option's variable name. Panics on error. See also [SetVarName]

func (StrsOption) SetShortName

func (me StrsOption) SetShortName(c rune)

SetShortName sets the option's short name—or clears it if NoShortName is passed.

func (StrsOption) SetVarName

func (me StrsOption) SetVarName(name string) error

SetVarName is used to set the option's variable name. [See also MustSetVarName].

func (StrsOption) ShortName

func (me StrsOption) ShortName() rune

ShortName returns the option's short name which could be 0 (NoShortName).

func (StrsOption) Value

func (me StrsOption) Value() []string

Value returns the given value(s) or nil.

func (StrsOption) VarName

func (me StrsOption) VarName() string

VarName returns the name used for the option's variables: by default the option's long name uppercased. (This is never used by FlagOptions.)

type ValueCount

type ValueCount uint8

This specifies how many value *must* be present—if the option is given at all. So even if the ValueCount is TwoValues, if the option isn't given the option's Value will be empty. But if it _is_ given, then either it will have exactly two values, or there will be a Parser error.

const (
	OneOrMoreValues ValueCount = iota
	TwoValues
	ThreeValues
	FourValues
)

func (ValueCount) String

func (me ValueCount) String() string

Directories

Path Synopsis
eg
eg1
eg2
eg3
eg4

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL