aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_include.py (unfollow)
Commit message (Collapse)Author
2026-08-17sl0ppty: ruff format the Pythonuser
The bumpy one, again. Every `.py` outside `vendor/` plus the three `contrib/` scripts that are Python with no extension: 60 files, 6,714 lines rewritten, no behaviour changed. Nothing here is worth reading -- the next commit adds it to `.git-blame-ignore-revs` so `git blame` walks past it. It is a bigger reformat than the C was, 60% of the lines against 17%, and for a reason worth writing down rather than tuning away: ruff and black break a call that does not fit onto one argument per line, where this code aligned the continuation under the opening paren. The test suite is thousands of `check("some prose", cond, detail)` calls, so nearly every one of them changed shape and the suite grew 3,308 lines. Line length was the one lever that moved it -- 120 columns would have been a 40% reformat and no growth at all -- and it was left at 88, because picking an unusual width to dodge a one-time diff is paying forever to avoid paying once. Import sorting came with it. Two files had `import os, pty, uuid, select, struct, sys, termios, time, fcntl, signal` on one line and now have ten. Verified after, not before, because a formatter that alters behaviour would be worse than none: - `make retest`, 1801 checks green -- and this reformats the suite that does the checking, including `harness.py`, which every one of those files imports. - `make test-live`, the tty tests the fast suite skips. They matter here more than usual: `live_input.py` and `live_m0.py` are two of the files whose comma-imports were split, and nothing in the fast suite would have noticed if that broke them. - All 60 files still compile, `make fmt` twice in a row changes nothing the second time, and `ruff check --select I` has nothing left to say.
2026-08-15sl0ppty: say what the config could not honouruser
A config that half-applied said nothing. An unknown shader, a binding that does not parse, an include that is not there: the file loaded, that line did not, and the session announced "config reloaded" as though nothing had happened. Every one of those messages was already being produced -- config_load has filled `err` on a successful load since it was written -- and then dropped on the floor by every caller, because a non-zero return meant "fine". So the complaint from the last load is kept, and the front end says it where it would have said "config reloaded". Once at startup too: a config that loaded with a complaint still started the session, and the stderr line goes where nobody attached can read it. The `reload` control verb answers `{"ok":true,"warning":"..."}` -- ok, because the file did apply, with the reason attached for a script that cares. Two things fell out of writing the test for it. An include's complaint was reported by nobody when the file in the middle was fine. apply_includes only looked at the return value, so a theme that loaded while *its* include was missing swallowed the message: the child returned true, and true meant there was nothing to say. The complaint now travels up whether or not the include itself loaded. And a complaint now carries the name of the file it happened in, exactly once -- added by the file that produced it, never by the files that included it, because prefixing at every level builds a chain that truncates before the part that matters. So: t.kdl: unknown shader: bloom keys.kdl: line 2: unknown action fly b.kdl: includes nested too deep (a cycle?) cannot open /home/you/.config/sl0ppty/themes/nope.kdl which is enough to know which file to open, in a message that fits in a toast.
2026-08-15sl0ppty: a config can be made of filesuser
include "themes/amber.kdl" include "keys/vim.kdl" "shaders/crt.kdl" which is how you switch a theme by editing one line rather than pasting one in. Nothing about it is theme-specific: an include is another config file applied here, so the same line composes keys, shader chains, states or geometry, and contrib/themes stops being a directory you copy out of. A relative path is relative to *the file doing the including*, never to the directory the session was started from -- a config is a thing on disk that refers to its neighbours, and where you were standing is not part of what it means. A leading `~` is a home directory, an absolute path is itself, and an included file may include others. What you include is the base: the file with the `include` line in it wins wherever they disagree, and a later include wins over an earlier one. That holds wherever the line sits, because the loader reads a document by asking it for the keys it knows rather than walking it top to bottom -- so "here" is not a position it could honour, and "the file you are editing wins" is the rule worth having anyway. It is what makes a theme something you can put two lines on top of. A depth limit rather than a set of files already seen, because the two failures it has to stop are the same failure: a config that includes itself and a config eleven files deep are both a mistake, and the message says which one you have. A file that will not load is skipped and the rest of the config still applies (D9) -- losing your keybindings over a mistyped theme name would be the worse answer. The loader was already shaped for this: `config_load` applied one parsed root onto a config_t, so it becomes a recursive `load_into` that applies its includes first and then itself. Errors from an include get their own buffer, so a broken theme cannot overwrite a message the file that included it has already produced. tests/test_include.py covers the two rules that carry the weight -- the outer file winning either way round, and a nested include resolving against the file that wrote it -- plus multiple files on one line, `~`, a binding from an included file, a missing file, a cycle, switching theme through a reload, and every file in contrib/themes applying as an include, checked against each file's own frame_focus so it cannot pass by looking default. Not yet: an included file is not watched, so editing the theme itself does not reload the session. Editing the include line does.