diff options
| author | user <user@clank> | 2026-08-15 16:22:27 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-15 16:22:27 +0200 |
| commit | 95b9b0414a2a8a3b1ec8e91d530c8b7119901257 (patch) | |
| tree | 8c8929534ab94f1a3c53de41ea108216d69b66bc /src/path.c | |
| parent | sl0ppty: C-a e opens the config, in a pane, in your editor (diff) | |
| download | slosh-95b9b0414a2a8a3b1ec8e91d530c8b7119901257.tar.gz slosh-95b9b0414a2a8a3b1ec8e91d530c8b7119901257.tar.xz slosh-95b9b0414a2a8a3b1ec8e91d530c8b7119901257.zip | |
sl0ppty: render the config instead of shipping a copy of it
`C-a e` on a machine with no config opened an empty buffer, which tells you
nothing about what you can set. The obvious fix -- embed config/config.kdl and
write it out -- trades one problem for a worse one: a checked-in copy of the
defaults is a second source of truth, and it drifts. Ours already had. Four
theme colours existed in the code and not in that file, and nothing said so.
So the file is generated. `sl0ppty --dump-config` renders every setting with
the value it currently holds -- geometry, behaviour, all 48 theme colours, the
state shader chains, and every binding including the leader-less ones -- and
`C-a e` seeds a missing config with exactly that, creating the directories on
the way (a fresh container has no ~/.config either).
config/config.kdl stays, and is now explicitly the *prose*: what a setting is
for, what it cost to get right, which ones are opinions. Values are generated,
essays are written, and the file says so at the top.
Three things keep the two honest:
- the theme colours became one file-scope table that the parser and the
renderer both walk. 48 names that used to exist in one place and be typed
again in another now exist once.
- the dump must parse back to itself byte-for-byte. That is what caught
`bind \ split-cols` rendering unquoted -- valid-looking output that would
not have survived being read back.
- a test scans config.c for `kdl_child(root, "...")`, which is the parser's
own vocabulary, and fails if a key is missing from the dump. Add a knob,
forget to render it, and the suite tells you rather than a user.
It never overwrites a config that exists: fopen(..., "wx") loses the race
rather than an edit, and there is a test for that too, because it is the one
thing here that must never go wrong.
Diffstat (limited to 'src/path.c')
| -rw-r--r-- | src/path.c | 20 |
1 files changed, 20 insertions, 0 deletions
@@ -8,6 +8,9 @@ */ #include "sl0ppty.h" +#include <sys/stat.h> + +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -23,3 +26,20 @@ const char *path_expand(const char *path, char *buf, size_t cap) { snprintf(buf, cap, "%s%s", home, path + 1); return buf; } + +/* Create a directory and everything above it. `mkdir` of one level is enough + * on a machine where ~/.config already exists, which is most of them and not + * all of them -- a fresh container has neither, and "could not write your + * config" is a poor first impression. Existing directories are not an error. */ +bool path_mkdirs(const char *dir) { + if (!dir || !*dir) return false; + char buf[1024]; + snprintf(buf, sizeof buf, "%s", dir); + for (char *p = buf + 1; *p; p++) { + if (*p != '/') continue; + *p = 0; + if (mkdir(buf, 0700) != 0 && errno != EEXIST) return false; + *p = '/'; + } + return mkdir(buf, 0700) == 0 || errno == EEXIST; +} |
