razziel89 / mdslw

Prepare your markdown for easy diff'ing!
GNU General Public License v3.0
13 stars 1 forks source link

Support configuration files #15

Closed razziel89 closed 3 weeks ago

razziel89 commented 5 months ago

It would be desirable to support something similar to a .prettierrc file, maybe calling it mdslw.yaml, that can be used to configure mdslw in a hierarchical way. That is, each such file influences how mdslw behaves for all files below it in the file tree. If there are two config files above a markdown file, then the closer one will overwrite options in the one farther away. The precedence of config files lies above that of default values and below that of environment variables.

It would be useful if clap supported such layered/hierarchical config files, but it does not at the moment, cf. this discussion.

bugabinga commented 5 months ago

Are you thinking yaml because it already gets used in the context of Markdown with Frontmatter? In that case, it might be fun to allow configuration in a YAML metadata block as well? Similar to how pandoc does it.

Otherwise, maybe simpler format like TOML does the job?

razziel89 commented 5 months ago

Are you thinking yaml because it already gets used in the context of Markdown with Frontmatter?

In that case, it might be fun to allow configuration in a YAML metadata block as well?

Similar to how pandoc does it.

That's a pretty neat idea that I hadn't considered yet. Embedding a config file in the frontmatter would enable per-file configurations. It might be worth trying out just for the fun of it.

Otherwise, maybe simpler format like TOML does the job?

I am actually leaning towards TOML at the moment. Even if it's going to be YAML, the structure will be kept pretty basic and simple.

razziel89 commented 3 weeks ago

At the moment, YAML is out as a config file format because there does not appear to be a reliable and trustworthy library for parsing YAML in rust (cf. this discussion about the deprecation of serde_yaml, which is the package that I intended to use originally). Thus, per-file configurations in the frontmatter are out, too. Still, the recent refactoring of the code (not yet merged) should make adding that feature relatively easy in the future, once there is, again, an acceptable rust library for parsing YAML.

razziel89 commented 3 weeks ago

Since clap itself does not support config files, an implementation is not all too easy. At the moment, mdslw uses clap's derive features to derive the command line integration. Unfortunately, that integration provides no way to determine whether an argument has been set on the command line or whether the default value has been used instead.

Take the following example: there is a config file ~/.mdslw.toml in a user's home directory that sets max_width = 100, which differs from the default value. Then, the user executes mdslw --max-width=80, re-instating the default value for that particular invocation. At the moment, there is no way to find out where the value 80 comes from: from the default or the command line. We could parse the command line arguments ourselves, but that would remove the benefit of using clap, which is a no-go.

One option would be to wrap all those arguments that can be taken from config files in Options and not relying on clap for default values any longer. That would separate default values from the definition of the command line interface, though (and thereby also from the --help message), which is also a no-go in my view. One of the main benefits of using clap is that it keeps the command line interface cleanly defined in a single struct.

Furthermore, looking at the command line arguments, only the following ones make sense to define in a config file. All the others only affect how mdslw operates. For example, it would not make sense to hard-code the --report-mode or the number of parallel threads in a config file. In any event: these are the flags that could be set via a config file:

For now, users should use environment variables for system-wide and project-wide configurations. Tools such as direnv can help streamline that.