# config: {…}

The config: field lists feature- or application-level settings. It's often multiline:

# config:
#    { name: linky, type: bool, description: autolink urls }
#    { name: xy.title, type: str, value: "blog title" }
#    { name: perm, type: select, select: 3=USER|2=EX|1=SUP|0=KERN }

PMD is about uniform feature lookup and configurability. To keep it brief but support enough variation, each entry is a JSOL-dictionary.

{

name: associates some variable/constant/expression to a setting.
type: A few common types may cover 90% of configuration needs.
bool would render as checkbox often.
str for plain textual content.
int verifies the value to be numeric.
select defining a predefined list of defaults.
select: With select: "aaa┃bbb┃ccc" being the alternatives attribute for combobox options.
description: holds some elaboration on the key name.
value: just sets a default

}

select: alternatives

The syntax for select: is

  • preferrably "alt|alt|alt"
  • or with optional title "1=title|2=alternative|3=…".
  • Though implementations may allow to use , comma, ; semicolon or | dash as separator.
  • Or allow both : and = to separate keys+values. (Too much flexibility makes it ambigious however.)

Custom types

Apart from providing aliases for the base types, a plugin API might provide its own custom set of setting types:

type alias usage
int integer / numeric numbers
bool boolean / checkbox true/false
str string / numeric string
select multi / dropdown see select: alternatives
text textarea / long longer string type (= renders as textarea)
color rgb graphical color picker
file filechooser setting should be a valid filename
table csv / list for supporting more complex (Excel-style) setting lists.
dict hashtable complex dictionary (Excel-style) setting field.

Again, supporting base type aliases (str=string) is very advisable. But complex types (table/dict) often cause too much effort for basic plugin/config systems. There's no need to cram in support for rarely used features.

Other fields

Other per-config {…} attributes migh encompass

category: grouping config options (else inherited from plugin)
class: either decoration or additional type qualifier
arg: declares a commandline argument instead of global app setting
param: plugin invocation argument instead of global app flag

There's some paritiy with the main plugin meta fields. Except that config entries should not have a nested config: attribute, of course^^

Storage and key name:

Notably this scheme just defines a list of available options. It does not prescribe if they're stored in an .ini, .json, xml or code file, or a database perhaps.
Applications might utilize different stores even, and dispatch depending on the name: syntax

  • For example name: ALL_UPPERCASE might become a code constant,
  • While name: sectioned.feature.option indicated an INI setting,
  • Or name: "$cfg.plugins[after][]" even a literal code target.

So names can be somewhat free-form. I'd avoid including the $ sigil however, or spaces obviously. Mostly-alphunumeric and dotted keys are certainly most versatile.

Regex tokenizer

You can get by with a somewhat simple regex extractor for this config scheme. It's simply finding {…} pairs, then splitting key-value pairs, and handling optional quoting.

  • Which allows syntax alternatives [:=>]+ for key-value pairs.

  • Same as shortened/aliased type names add some user-friendliness.

Of course a stringent JSON-parser could be used. But that's obstructing maintanability, and buys little performance-wise. (Plugin or option management is rarely done during runtime; but confined to some admin or installer UI.)

Purpose

Once config options are easily parseable, it quickly pays off to implement a centralized option/admin UI. And it sometimes can be combined with plugin configuration itself. Which is why plugin meta data defines this simple scheme.