Documentation
¶
Overview ¶
Package config is 012's settings file: a Ghostty-style list of "key = value" lines in <user config dir>/012/config, with # comments and config-file includes. One registry (Options) says what every option is called, its type, default, environment variable, flag and meaning; the parser, `012 config`, docs/config.md and the in-app Settings all come from it.
Settings are process-wide. Settings that belong to a workbook (decimal arithmetic) stay in the workbook's file. Secrets never go here: the JEV API key lives in the OS credential store (see internal/keyring).
Index ¶
- Constants
- Variables
- func CheckBaseURL(v string) error
- func DefaultFile() string
- func DefaultPath() (string, error)
- func Dir() (string, error)
- func Editor(path string, getenv func(string) string) (*exec.Cmd, error)
- func EnsureFile(path string) error
- func FlagUsage() string
- func IsLocalhost(host string) bool
- func Names() []string
- func ParseFlags(args []string) (map[string]string, []string, error)
- func Reference() string
- func SetInFile(path, key, value string) error
- func SplitCommand(s string) ([]string, error)
- func ThemesDir() string
- func Tilde(path string) string
- type Config
- func (c *Config) Bool(name string) bool
- func (c *Config) Duration(name string) time.Duration
- func (c *Config) Get(name string) Value
- func (c *Config) Int(name string) int
- func (c *Config) List(name string) []Value
- func (c *Config) Override(name, value, why string) error
- func (c *Config) Show() string
- func (c *Config) String(name string) string
- func (c *Config) Theme() ThemeChoice
- type Kind
- type Option
- type Source
- type SourceKind
- type ThemeChoice
- type Value
- type Warning
Constants ¶
const ( GroupAppearance = "Appearance" GroupJEV = "JEV functions" GroupTelemetry = "Telemetry" GroupServe = "012 serve" GroupData = "Data" GroupFiles = "Config files" )
Group names, in the order docs list them.
const DocsMarker = "<!-- Generated from internal/config/registry.go by `go test ./internal/config -update-docs`. Don't edit below. -->"
DocsMarker divides docs/config.md: the introduction above it is written by hand, the reference below it is Reference's output.
Variables ¶
var Groups = []string{GroupAppearance, GroupData, GroupJEV, GroupTelemetry, GroupServe, GroupFiles}
Groups is the order groups are listed in.
var Options = []Option{ {Name: "theme", Group: GroupAppearance, Default: "terminal", Env: []string{"O12_THEME"}, Flag: "--theme", Live: true, Desc: "Colors. `terminal` uses the terminal's own 16-color palette. Any other name is a " + "terminal color scheme, built in (`012 config themes` lists them) or a file in the themes " + "directory, drawn in its own colors with solid menu and status bars. " + "`light:NAME,dark:NAME` picks one by the terminal's background and follows it when it changes.", Check: checkTheme}, {Name: "chart-images", Kind: Bool, Group: GroupAppearance, Default: "true", Env: []string{"O12_CHART_IMAGES"}, Live: true, Desc: "Draw charts as images on terminals with kitty graphics (kitty, Ghostty, WezTerm). " + "When false, charts are always text."}, {Name: "notifications", Kind: Bool, Group: GroupAppearance, Default: "true", Env: []string{"O12_NOTIFICATIONS"}, Live: true, Desc: "Send a desktop notification (OSC 9) when JEV answers or an import finishes while the " + "terminal window is in the background."}, {Name: "keymap", Kind: Enum, Group: GroupAppearance, Default: "default", Values: []string{"default", "vim"}, Env: []string{"O12_KEYMAP"}, Live: true, Desc: "Keys in the grid. `default` works like Google Sheets; `vim` adds hjkl, counts, operators, " + "visual selection and a : command line (File > Settings > Vim keys)."}, {Name: "max-cells", Kind: Int, Group: GroupData, Default: "2000000", Env: []string{"O12_MAX_CELLS"}, Live: true, Desc: "The most cells an import keeps, and a paste or fill writes at once. A sheet takes about " + "300 bytes a cell, so the default of two million is about 600 MB. Imports keep whole rows " + "up to the budget and say how many they left out; larger pastes and fills are refused. " + "The grid itself is 1,048,576 rows by 16,384 columns (A to XFD) whatever this is."}, {Name: "jev-api-key-command", Kind: Command, Group: GroupJEV, Desc: "A command that prints the TypeSafe API key, used when TYPESAFE_API_KEY isn't set and the " + "credential store has no key, e.g. `op read op://Private/TypeSafe/credential` or " + "`pass show typesafe`. It runs the first time a sheet asks JEV something, without a shell, for up to 10 seconds, and its first line of output is the key; for pipes, write " + "`sh -c '...'` yourself. The key itself never goes in this file."}, {Name: "jev-credential-store", Kind: Bool, Group: GroupJEV, Default: "true", Env: []string{"O12_JEV_CREDENTIAL_STORE"}, Desc: "Look for the API key in the OS credential store (macOS Keychain, Windows Credential Manager, " + "the Secret Service on Linux), where `012 config set-key` and Settings put it."}, {Name: "jev-base-url", Kind: URL, Group: GroupJEV, Env: []string{"TYPESAFE_BASE_URL"}, Desc: "The TypeSafe service to ask; the SDK's default when empty. Must be https, except on localhost.", Check: CheckBaseURL, Redact: redactURL}, {Name: "jev-model", Group: GroupJEV, Env: []string{"TYPESAFE_DEFAULT_MODEL"}, Desc: "The JEV model to ask; the service's default when empty."}, {Name: "log-file", Kind: Path, Group: GroupTelemetry, Env: []string{"O12_LOG"}, Flag: "--log", Desc: "Append telemetry events to this JSON log file. See docs/observability.md."}, {Name: "log-level", Kind: Enum, Group: GroupTelemetry, Default: "info", Values: []string{"debug", "info", "warn", "error"}, Env: []string{"O12_LOG_LEVEL"}, Desc: "The least severe telemetry event recorded; debug adds every frame and command."}, {Name: "otlp-endpoint", Kind: URL, Group: GroupTelemetry, Env: []string{"OTEL_EXPORTER_OTLP_ENDPOINT"}, Flag: "--otlp", Desc: "Send telemetry to this OTLP/HTTP collector, e.g. http://localhost:4318. " + "The other OTEL_* variables still apply.", Redact: redactURL}, {Name: "serve-listen", Kind: Address, Group: GroupServe, Default: "127.0.0.1:2312", Desc: "The address 012 serve listens on. Anything but the loopback address lets other machines " + "reach it (with an authorized key). See docs/ssh.md."}, {Name: "serve-authorized-keys", Kind: Path, Group: GroupServe, Default: "~/.ssh/authorized_keys", Desc: "The public keys allowed to log in to 012 serve, in OpenSSH's authorized_keys format."}, {Name: "serve-host-key", Kind: Path, Group: GroupServe, Desc: "012 serve's private host key, generated when missing; " + "ssh_host_ed25519_key in the config directory when empty."}, {Name: "serve-idle-timeout", Kind: Duration, Group: GroupServe, Default: "30m", Desc: "End a 012 serve session that has had no input for this long; 0 never does."}, {Name: "serve-max-sessions", Kind: Int, Group: GroupServe, Default: "8", Desc: "How many 012 serve sessions may run at once; more are turned away."}, {Name: "config-file", Kind: Path, Group: GroupFiles, Repeat: true, Desc: "Read another config file after this one, relative to this file's directory. " + "A leading `?` makes it optional: no warning when it doesn't exist."}, }
Options is every setting. Add an option here and read it with Config.String, Bool or List; parsing, `012 config`, docs/config.md (go test ./internal/config -update-docs) and Settings follow.
Functions ¶
func CheckBaseURL ¶
CheckBaseURL accepts https URLs, and http only for this machine, so a config can't send the API key anywhere in the clear.
func DefaultFile ¶
func DefaultFile() string
DefaultFile is a config file with every option commented out at its default, each with its description: what `012 config default` prints and `012 config edit` starts a new file with.
func DefaultPath ¶
DefaultPath is the main config file, <Dir>/config.
func Dir ¶
Dir is 012's config directory: $XDG_CONFIG_HOME/012 when that's set (on every OS, so tests and dotfile setups can point it anywhere), otherwise os.UserConfigDir()/012 (~/.config/012 on Linux, ~/Library/Application Support/012 on macOS, %AppData%\012 on Windows).
func Editor ¶
Editor returns the command that opens path in the user's editor: $VISUAL, then $EDITOR (either may carry arguments, e.g. "code -w"), else vi, or notepad on Windows.
func EnsureFile ¶
EnsureFile creates the config file at path, with every option commented out at its default, when it doesn't exist yet.
func FlagUsage ¶
func FlagUsage() string
FlagUsage lists the flags for a usage line, e.g. "[--log file]".
func IsLocalhost ¶
IsLocalhost reports whether host names this machine.
func ParseFlags ¶
ParseFlags takes the options that have flags ("--log path" or "--log=path") out of args, returning their values by option name and the arguments left.
func Reference ¶
func Reference() string
Reference is the option reference in Markdown, one section per group.
func SetInFile ¶
SetInFile sets key to value in the config file at path: the last line setting key is replaced, or a line is added at the end. Comments and every other line are kept. The file and its directory are created if needed.
func SplitCommand ¶
SplitCommand splits a command line into words, as a shell would without expanding anything: spaces separate words, and single or double quotes keep spaces inside one (a backslash escapes the next character outside single quotes). No variables, globs or pipes.
Types ¶
type Config ¶
type Config struct {
// Path is the main config file, which may not exist.
Path string
Warnings []Warning
// contains filtered or unexported fields
}
Config is the effective configuration.
func Load ¶
Load reads the config file at path (a missing file is fine), then applies environment variables (from getenv) and flags, which win in that order: flags > environment > config file > defaults.
func (*Config) Override ¶
Override sets an option for the rest of the session, over every other source, e.g. a theme picked in Settings. why says who set it. An invalid value is ignored and returned as an error.
func (*Config) Show ¶
Show writes the effective configuration: every option with its value and where it came from, values that can hold secrets redacted.
type Option ¶
type Option struct {
Name string
Kind Kind
Group string // heading in docs/config.md and `012 config`
Default string // as it would be written in the file
Values []string // for Enum
Env []string // environment variables that set it, first set wins
Flag string // command-line flag, e.g. "--log"
Repeat bool // may be given more than once; each adds a value
Live bool // Reload config applies it without restarting
Desc string // what it does, one or more sentences
// Check validates a value beyond its kind. Invalid values are
// reported as warnings and the option keeps its previous value.
Check func(string) error
// Redact shows a value safely in `012 config`, e.g. without a URL's
// password.
Redact func(string) string
}
Option is one setting.
type Source ¶
type Source struct {
Kind SourceKind
Name string // the file, variable or flag
Line int // for files
}
Source is where a value came from: the default, a line of a config file, an environment variable or a flag.
type SourceKind ¶
type SourceKind int
SourceKind says where a value came from.
const ( FromDefault SourceKind = iota FromFile FromEnv FromFlag )
type ThemeChoice ¶
type ThemeChoice struct{ Light, Dark string }
ThemeChoice is the theme value: one theme, or one for each kind of terminal background.
func ParseThemeChoice ¶
func ParseThemeChoice(v string) (ThemeChoice, error)
ParseThemeChoice parses "name" or "light:A,dark:B" (either order).
func (ThemeChoice) Pick ¶
func (c ThemeChoice) Pick(dark bool) string
Pick returns the theme for a dark or light terminal.
func (ThemeChoice) String ¶
func (c ThemeChoice) String() string
String is the choice as written in the file.