Plugin Settings
#5485
Replies: 1 comment
-
W dniu 24.06.2024 o 18:02, nerix pisze:
[...]
### Alternatives
There are two main alternatives: having the settings in `info.json` and allowing declaration of settings in `init.lua` (i.e. in the main plugin code).
Being able to define the settings in `info.json` has the advantage of being static - no code needs to be executed. However, this comes at the cost of flexibility. To migrate settings, plugins would need to provide some entry point in `info.json` which is similar to the proposed `settings.lua`.
I don't think adding a new module that's loaded at a different time is
the solution to this.
Allowing plugins to be able to declare settings at runtime can get complicated with bookkeeping. For example, what would the following code that allows declaration at runtime (no `settings.lua`) output:
```lua
-- init.lua
c2.log(c2.LogLevel.Debug, "Initial setting: " .. c2.settings.raw["my-setting"])
c2.setting.declare({ name = "my-setting", --[[ ... ]] })
```
What is the actual problem with this? Assuming 'c2.settings.raw' is just
a mapping of setting keys to setting values, everything should be fine.
We do not need to have settings declared to be able to know what the
value of its key is in the file.
Another option is to not introduce this API at all and have plugins figure this out on their own, which would probably result in plugins keeping their settings in `data/` and having users change them with custom commands. While this works, it's not a nice user experience. Additionally, this might be a problem in case of typos. If some plugin had the command `!set-secret <secret>` and a user made a typo, this could be sent in the chat.
Another alternative to consider is to create a settings UI API instead.
This would give plugins the option to generate the UI elements for the
settings but Chatterino never needs to know about saving them explicitly
or any formats used.This would give plugins the freedom to save
settings, credentials and whatever where ever they like.
## Prior art
This design is loosely based on [Factorio's mod settings](https://wiki.factorio.com/Tutorial:Mod_settings). Factorio has a few more stages and allows mods to access settings of other mods, but the basic idea remains a `settings.lua`.
## Unresolved questions
- Which types should be supported initially? Currently, there are `string` and `boolean`. `int` and `enum` might be nice, although they can be emulated with `string`. See [Extensions to `string`](#extensions-to-string)
We currently have all enums in c2 lua namespace generated as strings.
- What about sensitive data? See [Sensitive Data](#sensitive-data)
We potentially should have an API that just loads/saves a map of
secrets.This should be another feature probably? I don't really want to
save them in the same files as the settings, saving secrets with
settings is not the best practice IMO.
- Should the table to provide the settings be named something other than `raw`? Using `c2.settings` isn't an option, because this table holds functions to manipulate/listen to settings.
Naming is a secondary issue, we don't need to worry about this just yet.
… ## Future possibilities
### Extensions to `string`
- `string` could be extended with a `sensitive` value which displays [a password mask](https://doc.qt.io/qt-6/qlineedit.html#EchoMode-enum).
- `string` could be extended with a `regex` value which validates input and past settings (next question: which value should be used when invalid settings are encountered?).
### Sensitive Data
It will be common for plugins that send HTTP requests to have some sort of token/api-key setting. Ideally, this shouldn't be saved in cleartext (although it's done with the credentials today). `string` settings could have a `sensitive` value which causes them to be saved separately (on Unix via QtKeychain and on Windows with `CryptProtectData`).
This will add complexity to the implementation (settings need to be merged when reading and split when writing).
### Search for Settings
It shouldn't be a priority right now to be able to search for settings of plugins, but as the feature gets adopted, there will be a need for a search.
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I don't intend to implement this, but want to open a discussion about a possible API for settings instead of having that discussion on a PR that has done all the work already.
Summary
Plugins can declare their own settings in a file called
settings.lua
.Motivation
Some plugins want/need to have user specific configuration. An example would be a plugin that can interact with an API of some bot on behalf of the user.
To be able to do this, the plugin needs to be able to send authenticated requests (or messages) which need some form of token/password specific to the user. Other plugins might want to have a toggle.
Explanation
Plugins can include a
settings.lua
that gets loaded before the main plugin, which sets up settings:In
settings.lua
, the plugin declares its settings:Additionally, a plugin can access its previous raw settings and update them:
If there aren't any previous settings,
c2.settings.raw
will be empty.In
settings.lua
, no APIs except the ones from above and logging are available. Other files can be imported (e.g. to share code).At runtime, a plugin can access the settings through
c2.settings.raw
as well. However, there, the settings will be fully resolved. Settings are read-only.Since settings can be changed by the user, there's a function to receive updates from settings:
The following changes are made to
plugin-meta.lua
:Internally, settings are stored as JSON in the plugin directory as
settings.json
.Settings for each plugin are displayed in the "Plugins" category in the section for each plugin.
Drawbacks
Settings add a layer of complexity to the already complex plugin system, but the advantages of both DX (for plugin devs) and UX will outweigh the complexity.
Having the settings display in the "Plugins" category requires a bit more effort to make them searchable (see Future Possibilities).
Rationale
Goals
Alternatives
There are two main alternatives: having the settings in
info.json
and allowing declaration of settings ininit.lua
(i.e. in the main plugin code).Being able to define the settings in
info.json
has the advantage of being static - no code needs to be executed. However, this comes at the cost of flexibility. To migrate settings, plugins would need to provide some entry point ininfo.json
which is similar to the proposedsettings.lua
.Allowing plugins to be able to declare settings at runtime can get complicated with bookkeeping. For example, what would the following code that allows declaration at runtime (no
settings.lua
) output:Another option is to not introduce this API at all and have plugins figure this out on their own, which would probably result in plugins keeping their settings in
data/
and having users change them with custom commands. While this works, it's not a nice user experience. Additionally, this might be a problem in case of typos. If some plugin had the command!set-secret <secret>
and a user made a typo, this could be sent in the chat.Prior art
This design is loosely based on Factorio's mod settings. Factorio has a few more stages and allows mods to access settings of other mods, but the basic idea remains a
settings.lua
.Unresolved questions
string
andboolean
.int
andenum
might be nice, although they can be emulated withstring
. See Extensions tostring
raw
? Usingc2.settings
isn't an option, because this table holds functions to manipulate/listen to settings.Future possibilities
Extensions to
string
string
could be extended with asensitive
value which displays a password mask.string
could be extended with aregex
value which validates input and past settings (next question: which value should be used when invalid settings are encountered?).Sensitive Data
It will be common for plugins that send HTTP requests to have some sort of token/api-key setting. Ideally, this shouldn't be saved in cleartext (although it's done with the credentials today).
string
settings could have asensitive
value which causes them to be saved separately (on Unix via QtKeychain and on Windows withCryptProtectData
).This will add complexity to the implementation (settings need to be merged when reading and split when writing).
Search for Settings
It shouldn't be a priority right now to be able to search for settings of plugins, but as the feature gets adopted, there will be a need for a search.
Beta Was this translation helpful? Give feedback.
All reactions