std/settings

An application's settings, as editors keep them: a JSON Schema says what each setting is; the user's settings file and the workspace's, each JSON with comments, lie over the schema's defaults; changes are told to whoever listens; and the settings model lists them for a settings page. For settings from the environment and files in any number of layers, see std/config.

import "std/settings"

Settings s = open_settings(schema, config_dir() + "/app/settings.json", ".app/settings.json")?
print(s.number("editor.fontSize"))
s.on_change("editor.fontSize", func(str key, Json value) do
    print(f"{key} is now {to_json(value)}")
end)
s.set("editor.fontSize", Json.NUMBER(16.0))?          // in the user's file

Settings have flat keys, as "editor.fontSize", in the schema's properties and in the files.

Function or method
open_settings(schema, user_file, workspace_file) the settings; a file that is not there has none
s.get(key), s.text(key), s.number(key), s.flag(key) a setting's value: the workspace's, the user's, or the schema's default
s.source(key) where it comes from: "workspace", "user", or "default"
s.set(key, value, layer) sets it in the "user" (the default) or "workspace" file; a value the schema does not allow is an ERROR of kind "invalid_setting". Only the setting's member of the file changes, so comments and layout stay
s.reset(key, layer) takes it out of a file, so the value below shows
s.on_change(key, changed) changed gets the key and the new value each time it changes; "" listens to every setting
s.reload(), s.watch_files(), s.stop_watching() reads the files again, now or each time they change while the event loop runs, and tells the listeners
s.model() a SettingInfo for each setting of the schema, then each the files give that it does not know: key, title (the schema's, or made from the key, as "Font Size"), description, type, default_value, value, source, choices, and problem
s.problems() what is wrong, as key: problem