aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_dump_config.py (follow)
Commit message (Collapse)AuthorAge
* slosh: rename the project from sl0pptyuser2026-08-18
| | | | | | | | | | | | | | | | | | | | | sl0p + pty was error-prone to type and the zero made it worse; slosh (slop + sh) is one syllable, impossible to typo, and slosh.foo is ours. Mechanical rename everywhere it appears: binary, env vars (SLOSH, SLOSH_SESSION, SLOSH_BIN, SLOSH_CONFIG), socket dir (/tmp/slosh-<uid>, $XDG_RUNTIME_DIR/slosh), config path (~/.config/slosh), header guards, src/sl0ppty.h -> src/slosh.h, contrib/sl0ppty-dev -> contrib/slosh-dev, the driving-slosh skill, docs and tests. The sl0ppi fork references and the sl0p theme stay: one is history, the other is the brand. The rename surfaced a latent bug in test_osc5577: the hello-reply answer always appeared on screen twice (ECHOCTL echo plus cat -v), but a seven-character implementation name happened to wrap the second copy across the 60-column boundary, so counting substrings in wrapped text found one and passed for the wrong reason. A five-character name moved the wrap and exposed it. The loop guard itself is correct -- with echo off before the request there is exactly one reply -- so the test now counts on de-wrapped text and tolerates the pane's own echo.
* sl0ppty: ruff format the Pythonuser2026-08-17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* sl0ppty: double-click a word to select ituser2026-08-17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `pane_select_word()` was written and never wired to anything: no declaration, no caller, no way to reach it. This is the rest of it -- the gesture, the setting, and the tests. **The word is defined by what it stops at, not by what it is made of.** Anything that is not blank and not a listed separator belongs to a word, so CJK, accented letters and emoji need no table and come out whole; whitespace always separates, listed or not, because a double-click that selected the line would be a different gesture arrived at by surprise. Wide glyphs continue the run they are in rather than each being their own word -- otherwise every CJK character is a word. `word_separators` defaults to `"'`()[]{}<>;,|`, and what it leaves *out* is the decision: `/ . - _ : = @ # % ? & + ~ $` stay inside words, so a path, a dotted name, a snake_case identifier, a key=value pair, a URL and `src/app.c:1234` are each one thing you double-clicked to copy whole. `:` is the difference between copying an error location and copying half of one, which is why kitty keeps it too. The gesture reuses what selecting already has: the press starts a selection at the cell -- which anchors a drag out of the double-click -- then widens it to the word, and the release path that already copies a drag copies this. So the word *is* the copy, in the one place that rule lives, and the highlight is the copied span rather than an approximation of it. Tracked per cell as well as per pane, so clicking two different words quickly selects the second rather than everything between them. A program that asked for the mouse still keeps its clicks, with shift as the escape hatch, exactly as the drag has it. **One thing this needed on the way: quoted values were dumped unescaped.** The default separator set opens with a quote, and `cb_add(&b, "key \"%s\"\n", ...)` wrote it raw -- so `--dump-config` produced a file that no longer parsed, breaking the property the dump exists for. The escaping loop already existed inside `cb_chord`, for the same reason and with the reasoning written down; it is now `cb_qval`/`cb_qstr` and every string setting goes through it: the marks, `shell`, `editor`, `shader_dir`, `project_roots`, `project_layout`. Latent for all of those, load-bearing for this one. **And `--dump-config` does not do what four comments and the docs said it did.** It calls `config_dump_defaults()`: every setting with its *default*, never the value your config gives it. The function name was the honest one. Corrected in `docs/config.md`, `config/config.kdl`, `main.c`, `config.c`, `app.c` and the test's own docstring, rather than changing what the flag does -- starting a config from it is the documented use, and `--check` is what reads yours. There is no way to ask for the effective config; that is a gap, not a lie, and it can be a flag when somebody wants it. Verified: 22 checks in `tests/test_clipboard.py`. An error location, an identifier stopping at a bracket, a URL, a word inside quotes and a run of CJK; the highlight being exactly as wide as the copy; a separator, a blank cell and a single click each leaving the clipboard alone; two clicks on different cells not being a double; two slow clicks not being one; the separator set honoured from a config, including a quote and a backslash carried through KDL escaping; a word in a scrolled pane coming from the row on screen; and a mouse-tracking program keeping its double-clicks until shift takes them back. Three of those failed first because the test asked for the answer twice -- a second `worded()` call is a second pair of clicks -- and one because it mapped string indices to columns without counting wide glyphs as two.
* sl0ppty: every complaint, and the chords that produced eleven of themuser2026-08-16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Reported as "C-a is not a valid prefix in my config.kdl", which it was not, and neither were ten other lines of the same file -- a file written by `sl0ppty --dump-config`. The loader now collects every complaint instead of keeping the first. Each one carries the file and the line it happened at, so "line 14: bad binding" became "config.kdl:116: bad key: ←", and a complaint from an included file names that file. `err` still means the first message, so a session's one status line behaves as before; the list is what a linter needs, and `--check` (next commit) is that linter. Both changes live in the same regions of config.c, which is why they are one commit. Then what the list found. `--dump-config` is documented as "a file you could have written", and `--dump-config > ~/.config/sl0ppty/config.kdl` as a supported way to start one. It wrote every chord in the *cheatsheet's* notation: prefix "C-a" bind "?" "help" bind "←" "focus-left" bind "S-tab" "prev-tab" and the parser only spoke the config's, so eleven of the file's own lines came back as complaints and the session ran on the defaults those lines were describing. Two sessions looked identical for the worst possible reason, which is why the test asserting exactly that never noticed. Both halves were wrong, so both are fixed. The parser accepts what the sheet prints: `C-` `M-` `S-` as well as `ctrl+ alt+ shift+`, the arrow glyphs as well as `left`/`right`, and a character that carries its own shift -- `?` is shift+slash, `H` is shift+h, `|` is shift+backslash. config.kdl has claimed for months that `?` and `S-slash` were both writable; only one of them was. A punctuation binding registers *both* encodings, because whether a terminal reports `?` as shift+slash or as a bare byte is up to the terminal and not to what the config meant. The shipped default has bound `?` twice by hand for exactly this reason since it was written; this is that, done once, in the one place that knows the character implied the shift. A capital letter needs no such thing -- the decoder reports `H` as shift+h everywhere. And the dumper writes the canonical config spelling: `ctrl+a`, `shift+slash`, `left`, `shift+tab`. `shift+` spelled out rather than folded back into `?` or `H`, because both are accepted on the way in and one spelling on the way out keeps a dump of a dump the same dump. A key with no spelling the parser would accept is written as an empty chord rather than as its display form: writing the display form is what caused this, and a dump that does not load is worse than a dump missing a line. The test that should have caught it now does: a session started from the dump is asked to reload and must have nothing to say. Looking at the screen was never going to find this, because the screen was right.
* sl0ppty: render the config instead of shipping a copy of ituser2026-08-15
`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.