diff options
Diffstat (limited to 'docs')
27 files changed, 629 insertions, 16 deletions
diff --git a/docs/config.md b/docs/config.md index 0a6765b8..79a5e631 100644 --- a/docs/config.md +++ b/docs/config.md @@ -23,7 +23,7 @@ which `Config` reports as `no per-user config path`. `Config` (`SPC f c`, or the word executed anywhere) opens one refreshable `+Config` pane. It reports the startup path and every live config-like value: -theme, colors, wrapping, tag position, debug mode, the requested shell and the +theme, colors, focus tint, syntax weight, wrapping, tag position, debug mode, the requested shell and the executable actually resolved at the last spawn, requested/effective GUI font and size, tagline scale, panel transition, scene effects, hover delay, platform, native-image support, and (on SDL) whether @@ -65,7 +65,7 @@ The format is one existing builtin command per line, using the same spelling and argument parsing as commands executed inside pardes: ```text -Theme acme +Theme orchard Font DejaVuSansMono-Regular TaglineSize 82 Shell zsh @@ -83,7 +83,7 @@ everything after the name as the argument. On a native build that is `Theme`, (`Peek`, `Poke`, `Hexdump` and `Gpio` take one too, but they exist only where `builtins.Board.enabled` holds, and that build has no config file.) -`Theme <name>` wants one of the 228 names in the ring. Do not derive the +`Theme <name>` wants one of the names in the compiled ring. Do not derive the spelling — read it off `ThemeSel` (`SPC t t`), which lists every one as the exact `Theme <name>` line that selects it. `slug` in `tools/gen_themes.zig` lowercases, folds punctuation runs to a single `_` and then TRIMS leading and @@ -94,6 +94,28 @@ and `ayu_mirage` is helix's `ayu_mirage.toml`. The suffix goes on all of them rather than only the eight that clash today, so a name cannot move when either project gains or loses a file. A name that is not in the ring is ignored. +The fifteen [native Pardes themes](themes.md) lead the ring: `orchard` (the +default), `dusk`, `ink`, `paper`, `daybreak`, `atelier`, `forge`, `lagoon`, +`solarium`, `spectrum`, `harvest`, `clay`, `forge_black`, `forge_soft`, and +`orchard_black`. `ThemeSel` lists them first under Pardes themes, followed by +a separate legacy/imported section. They add coordinated +focus, search, diagnostic and terminal colors; `ink` and `daybreak` are high +contrast dark and light options. The original `helix`, `dark` and `acme` +themes and all imported names remain available. + +`FocusTint` toggles the focused pane and column tag tints; it is on by default. +Workspace, column and pane command text can be edited directly; see +[editable tags](tags.md) for naming and saved-workspace behavior. +`ColumnTags` toggles the column command row in both GUI and TTY; it is on by +default. Add `ColumnTags` to startup configuration to reclaim that row on a +compact screen. Hiding it preserves your custom column commands. +`SyntaxBold` toggles bold syntax keywords; it is off by default. These +settings are shared by GUI and TTY, and `Config` reports their current +states. Like `Colors` and `Wrap`, these commands take no argument and invert +the current value. A `FocusTint` line in a fresh startup configuration disables +the tint; a `SyntaxBold` line enables the stronger keyword weight. Those two +appearance controls leave focus, selections and editing behavior unchanged. + ## Crash records A panic appends to `crashes` in that same directory, beside `init`, and only @@ -172,8 +194,14 @@ format, and it is `pardes.Theme` serialised by `std.zon.stringify`: the theme name, thirteen required RGB roles (`sel_bg`, `sel_fg`, `tag_bg`, `tag_fg`, `box`, `box_dim`, `kw`, `str`, `num`, `comment`, `lineno`, `scroll_track`, `scroll_thumb`), nullable `bg`/`fg`, and either a 16-color RGB `palette` or -`null`. RGB values are three-byte arrays, and hex literals are accepted. There -is no inheritance or partial override layer. +`null`. Nine optional nullable RGB roles extend this format: +`tag_active_bg`, `tag_active_fg`, `border`, `search_bg`, `search_fg`, +`diagnostic_error`, `diagnostic_warning`, `diagnostic_info`, and +`diagnostic_hint`. Missing new roles use backward-compatible defaults, so +previously exported files remain valid. [Theme customization](themes.md) +describes each role and its fallback. RGB values are three-byte arrays, and +hex literals are accepted. The original fields remain required; there is no +inheritance or partial override layer. `Filter` in a terminal's tag projects that pane's ANSI colors through the active theme, and does it in two stages. The default foreground and background @@ -202,8 +230,24 @@ terminal's font belongs to its emulator and a browser's to the page — so a resolve the name by walking the font directories on every lookup, so a face installed a moment ago is findable. +Use `Font <name>:<size>` to change face and size together, for example +`Font MartianMono-NrRg:18` in the startup file or an editable tag. Fractional +sizes such as `:18.5` are supported; the accepted range is 8–72 (pixels in SDL, +points on macOS). `Font <name>` without a suffix preserves the current size. +Invalid sizes or unknown faces leave the current font unchanged. + +The SDL GUI also has a tiny optional workspace-tag companion: `Pet cat`, +`Pet frog`, or `Pet off` (the default). Its original pixel sprite walks and +idles in the trailing blank area of the global tag only. It hides while that +tag is being edited, when the tag is full, or when the font leaves too little +room; it never replaces text, receives clicks, or appears in pane/column tags. +Animation runs at ten steps per second, uses theme ink, and requires no image +assets or shaders. Put `Pet cat` in the startup configuration to keep it; +`Pet off` disables the companion and its animation. Other hosts ignore the +startup command. `Config` reports the current choice in SDL. + `Font` is asynchronous at the renderer boundary. `Config` therefore keeps -requested name/path, pending state, and the effective face/point-or-pixel size +requested name/path/size, pending state, and the effective face/point-or-pixel size as separate facts; a failed request never gets reported as the face on screen. Taglines use a distinct face size in both native GUI renderers. Execute `TaglineSize <percent>` to change it live, for example `TaglineSize 70`; the @@ -221,7 +265,8 @@ same compiled percentage to its DOM glyphs but has no runtime setter. Both native GUIs join the reduced-height global and pane tagline bands with `gui_topbar_pane_border_px` physical pixels. Set it to zero for a direct join. `gui_topbar_pane_border_rgb` can pin an RGB color; its default `null` follows -the active theme's scrollbar-track color. With `Tagbottom` enabled, a tagline +the theme's `border` role in SDL (falling back to `scroll_track` for older +themes), and `scroll_track` in the macOS shell. With `Tagbottom` enabled, a tagline on the final grid row is bottom-aligned so the same unused half-band does not show beneath it. The rule itself lives in the core (`pardes.taglineBandOffset`), and the macOS shell reaches it over the C ABI @@ -270,7 +315,14 @@ PanelScramble PanelType ``` -All panel transitions start off. Slide uses cubic ease-out and zoom uses an +All panel transitions start off. To disable one, execute its builtin again: +`PanelDissolve` turns off an active dissolve, and `PanelAscii` turns off an +active ASCII transition. `Config` shows the active command under +`Panel transition`. Remove that command from your startup configuration to +keep it off after restarting. Executing a different transition enables that +one instead; these commands are toggles, not an unconditional animation-off command. + +Slide uses cubic ease-out and zoom uses an overshooting ease-out-back. Dissolve and ASCII compare the last successfully presented grid with the new one. Dissolve switches visually changed cells at stable noise thresholds. diff --git a/docs/design.typ b/docs/design.typ index 8a5b9381..88bb49d6 100644 --- a/docs/design.typ +++ b/docs/design.typ @@ -1920,17 +1920,24 @@ system clipboard, which is helix's five words — `SPC y/Y/p/P/R`, out via cannot clobber what the desktop was holding. A paste from an outer terminal arrives bracketed, as one `paste` event. -*Tag.* Live prefix (mode indicator, cwd or path) + editable tail with the -full modal editor. Save leads the tail of every pane holding text of its own: -`Save New Newtty Del` for a file or an output buffer, -`Save New Newtty Del Filter` for a terminal, and the plain `New Newtty Del` -for an image or a PDF, with `*` after an unsaved file's name; an image tag +*Tag.* Compact name/status prefix + editable command tail. File names support +staged edits: Enter commits a new buffer save target, Escape cancels, and no +disk rename or write happens until explicit Save. Terminal cwd and image/PDF +status stay generated. Save leads the tail of every pane holding text of its own: +`Save Tty Del Collapse` for a file or an output buffer, +`Save Tty Del Togglettymode Filter Collapse` for a terminal, and `Tty Del Collapse` +for an image. PDFs use `Tty Del PdfSections PdfTint Collapse`, without tint status text. +`Collapse` toggles a pane between its tagline alone and its expanded height; +hidden body contents and running terminals are retained. +An unsaved file has `*` after its name; an image tag reports `img petscii:<on|off> palette:<commodore|terminal> ascii:<on|off> <path>` before the ordinary tail (its renderer toggles are builtins under `SPC t p/l/a`). Topbar: -`New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill` — -execute-only (left click inert); +`Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill` — +editable by left click, with keyboard command navigation and Exec/Look gestures. +An additional editable tag in each column supplies local New, Tty, Find, +Grep and Joincol commands. ColumnTags hides that row when space is tight; Colors and Crt left it for their leader paths. *Panes.* Terminal: ghostty-vt, 16 MiB scrollback, OSC 133 prompt semantics, diff --git a/docs/helix-keys.md b/docs/helix-keys.md index dcd5b7cb..b999a25c 100644 --- a/docs/helix-keys.md +++ b/docs/helix-keys.md @@ -118,7 +118,7 @@ language-backend queries, and the shell pipe. | `Enter` (normal) | acme **look** chord: EXPLICIT selection, else file-ish word under cursor | pardes-specific, keep (helix normal-mode Enter unbound). Covers helix `gf`. Implicit motion residue falls back to the cursor word | pardes-specific | | `Tab` (normal) | acme **execute** chord | pardes-specific, keep; explicit-selection rule as Enter | pardes-specific | | `:` (normal, body) | focuses the pane's OWN tag as a one-line editor in **normal** mode, parked at the first EDITABLE column: motions (`w` `b` `e` `W` `B` `E`, `0` `$` `^`, arrows, `Home`/`End`) walk the whole rendered tag, `y` yanks the selection, `Enter`/`Tab` look/execute it (else the file-ish word under the cursor), `i`/`a`/`I`/`A` enter insert, `Esc` hands the body back. `h`/`j`/`k`/`l` are NOT motion here — a tagline is a place in the LAYOUT, so they run the same `Left`/`Down`/`Up`/`Right` builtins and land on the neighbouring pane's TAGLINE, still in normal mode (nothing that way = stay put, EXCEPT `k` off the topmost tagline — see the next row); the arrows keep the in-tag motion | helix `:` is command mode (section C); pardes' commands are acme words that live in the tag. `tag_col`/`tag_anchor` are columns of the RENDERED tag (prefix ++ tail) — one coordinate space, so the live mode+path prefix is selectable, yankable and executable, while every edit op (typing, `Backspace`, `i`/`a`/`I`/`A`) measures from the first editable column and is inert inside it | pardes-specific | -| `k` (tag normal, topmost tagline) | focuses the TOPBAR — row 0, the global tagline (`config.topbar_str`, today `New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill`, plus `Restore <path>` once a dump exists). It is its own one-line normal mode: `h`/`l` and the arrows by grapheme (row 0 has no window left or right to walk to), `w`/`b`/`e`/`W`/`B`/`E` and `0`/`$`/`^` by word, `Enter`/`Tab` runs the word under the cursor through the same dispatch a MIDDLE click on it uses, `j` drops back onto the topmost pane's tagline, `Esc` leaves. No insert mode and no selection — the bar is chrome with no tail to own | pardes-specific. The topbar is not a pane, so `focusDir` can never reach it: this is a fallback on the `.Up` branch of the tagline hop, from a TAGLINE only (a body's `SPC w k`/`Ctrl-w k` keep their pane-to-pane meaning). Its whole state is one global `topbar_col: ?u16` (row 0 has no pane to hang it on), cleared by any mouse press and BEFORE the chord dispatch, because `Kill` up here frees the session the way `Del` frees a pane. The motion vocabulary is literally the tag's — both call `lineMotion` | pardes-specific | +| `k` (tag normal, topmost tagline) | focuses the column tag, then another `k` reaches the workspace tag at row 0 (`Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill`, plus `Restore <path>` once a dump exists). With `ColumnTags` disabled it goes directly to the workspace. `j` walks back down. Header arrows and `h`/`l` move by grapheme; word motions and `0`/`$`/`^` work too. In normal mode `Enter`/`Tab` executes; `i`/`a`/`I`/`A` enter editing, where Enter is Look and Tab is Exec. Left-click, drag selection, typing, and paste edit either header; Esc leaves | Column commands target that column's active pane, or its first pane when coming from elsewhere. Workspace and column text are independently editable and persist in dumps. See [editable tags](tags.md) | pardes-specific | | `Ctrl-w` + `h/j/k/l`/arrows | directional pane focus prefix — normal/tty modes only | pardes' own window handling (helix window mode skipped, section C). Runs the SAME `Left`/`Down`/`Up`/`Right` builtins `SPC w h/j/k/l` runs; kept alongside the leader because a pane in raw **tty** mode never sees `SPC` (the shell owns it), so this is the only keyboard way out of one. Insert mode owns `Ctrl-w` = delete-word-back, so a tag being TYPED into swallows it; from a tag in normal mode (`:`) it moves focus to the neighbour's BODY, while the bare letters `h/j/k/l` there move to its TAGLINE (next row) | pardes-specific | | `Alt-n` | new terminal below (any mode) | shadows helix `Alt-n` TS sibling-select — skipped anyway (tree-sitter) | pardes-specific | | `Alt-c` | move active terminal to a fresh column (any mode) | helix `Alt-c` is change-noyank; the pardes window op wins (do-not-touch contract). `Alt-d` + `i` covers the behavior | waived (`alt-c-window-op`) | diff --git a/docs/screenshots/agave-lsp.txt b/docs/screenshots/agave-lsp.txt new file mode 100644 index 00000000..9a46b911 --- /dev/null +++ b/docs/screenshots/agave-lsp.txt @@ -0,0 +1,38 @@ +backend: zls-inproc+lsp-client +zls: 0.16.1-dev+3e0d0820 (compiled in — no server process, no JSON-RPC) +zig lib dir: /usr/lib/zig [OK] +offsets: utf-8 walk caps: 512 files, 2000 rows + +dependency imports gd can follow (8): + zls /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/zls-0.16.1-dev-rmm5ftfOJgAzIdWUGVB08ycFbud2O3viKnGF1HZgfKZJ/src/zls.zig + tree-sitter /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/tree_sitter-0.26.0-8heIf3CaAQB4SSumoGzq3gLSz2rkvXxcKFyskRWqDGBz/src/root.zig + zstbi /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/zstbi-0.11.0-dev-L0Ea_3GWBwAh7m54XX055vwLKPTPij5hyqyeq92MXPE2/src/zstbi.zig + mvzr /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/mvzr-0.3.9-ZSOky6t2AQCA7efmm5EYbPb5sOdbXa4EFsUgYbQ6hZv9/src/mvzr.zig + mupdf /home/goblin/00-projects/0x4200.cafe/02-pardes-code/src/pdf.zig + ghostty-vt /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/ghostty-1.3.2-dev-5UdBCzeJJQXw_vG5Hsfx0DYUmF7Exs_9yctijqOIfp7W/src/lib_vt.zig + vaxis /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/vaxis-0.6.0-BWNV_CrbCQCscGpzsAlR402rYQ_tV3aAl081c2iRRkka/src/main.zig + uucode /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/uucode-0.2.0-ZZjBPlK5VADj7fdoq7G8LIHzD5o6FSkcBXXrRWr4jnrA/src/root.zig +asked from: /home/goblin/00-projects/00-solana/agave/02-upstream/gossip/src/crds_value.rs + +answers: definition, declaration, type_definition, implementation, references, hover, document_symbols, workspace_symbols, diagnostics, workspace_diagnostics, rename, code_action, format, select_refs, completion +refuses: incoming_calls, outgoing_calls, supertypes, subtypes + +last queries (0 total, keeping 24): + (none yet — press gd somewhere, then ask again) + +protocol servers (lsp-client): + rust-analyzer ready root /home/goblin/00-projects/00-solana/agave/02-upstream utf8 pull-diags call-hier docs 1 diag-files 0 [PARDES_LSP_RS=/home/goblin/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rust-analyzer] + .rs + clangd off [PARDES_LSP_C=(disabled)] + .c .h .cc .cpp .hpp .cxx .hxx + gopls off [PARDES_LSP_GO=(disabled)] + .go + typescript-language-server off [PARDES_LSP_TS=(disabled)] + .ts .tsx .js .jsx .mjs .cjs + pyright off [PARDES_LSP_PY=(disabled)] + .py + +client queries (3 total, keeping 24): + document_symbols rust-analyzer crds_value.rs 52 row(s) + hover rust-analyzer crds_value.rs 0 row(s) + definition rust-analyzer crds_value.rs 1 row(s) diff --git a/docs/screenshots/atelier.png b/docs/screenshots/atelier.png Binary files differnew file mode 100644 index 00000000..f889647a --- /dev/null +++ b/docs/screenshots/atelier.png diff --git a/docs/screenshots/before.png b/docs/screenshots/before.png Binary files differnew file mode 100644 index 00000000..f2e3d506 --- /dev/null +++ b/docs/screenshots/before.png diff --git a/docs/screenshots/classic-gallery.json b/docs/screenshots/classic-gallery.json new file mode 100644 index 00000000..0b1092dd --- /dev/null +++ b/docs/screenshots/classic-gallery.json @@ -0,0 +1,21 @@ +{ + "themes": [ + "forge", + "lagoon", + "solarium", + "spectrum", + "harvest", + "clay" + ], + "pets": [ + "cat", + "frog", + "off" + ], + "os_windows": [ + "20971567" + ], + "font_effective_pixels": 18, + "tagline_percent": 80, + "source_unchanged": true +}
\ No newline at end of file diff --git a/docs/screenshots/classic-themes.png b/docs/screenshots/classic-themes.png Binary files differnew file mode 100644 index 00000000..f0fe4089 --- /dev/null +++ b/docs/screenshots/classic-themes.png diff --git a/docs/screenshots/columns-atelier.png b/docs/screenshots/columns-atelier.png Binary files differnew file mode 100644 index 00000000..2727df2f --- /dev/null +++ b/docs/screenshots/columns-atelier.png diff --git a/docs/screenshots/columns-orchard.png b/docs/screenshots/columns-orchard.png Binary files differnew file mode 100644 index 00000000..0fa179a5 --- /dev/null +++ b/docs/screenshots/columns-orchard.png diff --git a/docs/screenshots/columns-parity.json b/docs/screenshots/columns-parity.json new file mode 100644 index 00000000..9e18f2d4 --- /dev/null +++ b/docs/screenshots/columns-parity.json @@ -0,0 +1,37 @@ +{ + "commands": [ + "python3 -B test/column_tags.py zig-out/column-review/bin/pardes-gui /home/goblin/.cache/ct-sdl --project /home/goblin/00-projects/00-solana/agave/02-upstream", + "python3 -B test/column_tags.py zig-out/column-review/bin/pardes /home/goblin/.cache/ct-tty --project /home/goblin/00-projects/00-solana/agave/02-upstream --tty" + ], + "checks_per_host": 11, + "input": "Real keyboard and SGR mouse bytes through each host PTY parser; 9P state observation", + "comparison": "Core grid text and foreground/background colors; owned output directory names normalized ct-sdl/ct-tty to ct-run", + "limitations": [ + "SDL captures are native GPU PNGs; TTY captures are core grids, not independent terminal-emulator screenshots.", + "This helper does not automate SDL pixel-coordinate mouse events.", + "Unicode editing and persistence are verified separately; presentation tags use ASCII because selected font lacks CJK glyph coverage." + ], + "frames": { + "columns-orchard": { + "cols": 150, "rows": 48, + "matching_color_cells": 7200, "total_cells": 7200, + "matching_text_rows": 48, + "cursor_sdl": {"x": 82, "y": 3, "bar": false}, + "cursor_tty": {"x": 82, "y": 3, "bar": false} + }, + "columns-atelier": { + "cols": 150, "rows": 48, + "matching_color_cells": 7200, "total_cells": 7200, + "matching_text_rows": 48, + "cursor_sdl": {"x": 82, "y": 3, "bar": false}, + "cursor_tty": {"x": 82, "y": 3, "bar": false} + }, + "columns-tag-reveal": { + "cols": 150, "rows": 48, + "matching_color_cells": 7200, "total_cells": 7200, + "matching_text_rows": 48, + "cursor_sdl": {"x": 74, "y": 2, "bar": true}, + "cursor_tty": {"x": 74, "y": 2, "bar": true} + } + } +} diff --git a/docs/screenshots/columns-tag-reveal.png b/docs/screenshots/columns-tag-reveal.png Binary files differnew file mode 100644 index 00000000..ce55adbc --- /dev/null +++ b/docs/screenshots/columns-tag-reveal.png diff --git a/docs/screenshots/compact-columns.png b/docs/screenshots/compact-columns.png Binary files differnew file mode 100644 index 00000000..61b07ad7 --- /dev/null +++ b/docs/screenshots/compact-columns.png diff --git a/docs/screenshots/daybreak.png b/docs/screenshots/daybreak.png Binary files differnew file mode 100644 index 00000000..09cba567 --- /dev/null +++ b/docs/screenshots/daybreak.png diff --git a/docs/screenshots/dusk.png b/docs/screenshots/dusk.png Binary files differnew file mode 100644 index 00000000..53c55313 --- /dev/null +++ b/docs/screenshots/dusk.png diff --git a/docs/screenshots/ink.png b/docs/screenshots/ink.png Binary files differnew file mode 100644 index 00000000..171c6427 --- /dev/null +++ b/docs/screenshots/ink.png diff --git a/docs/screenshots/orchard.png b/docs/screenshots/orchard.png Binary files differnew file mode 100644 index 00000000..66057fa5 --- /dev/null +++ b/docs/screenshots/orchard.png diff --git a/docs/screenshots/paper.png b/docs/screenshots/paper.png Binary files differnew file mode 100644 index 00000000..7294869f --- /dev/null +++ b/docs/screenshots/paper.png diff --git a/docs/screenshots/parity.json b/docs/screenshots/parity.json new file mode 100644 index 00000000..c2e636e3 --- /dev/null +++ b/docs/screenshots/parity.json @@ -0,0 +1,20 @@ +{ + "comparison": "Every row-major cell resolved to (grapheme, foreground color, background color), using each capture's own style table; indices are not compared.", + "gui_artifacts": "/home/goblin/.cache/pardes-ui-review-final", + "tty_artifacts": "/home/goblin/.cache/pardes-ui-review-final-tty", + "capture_files": "theme-<name>.json", + "gui_command": "python3 -B test/ui_review.py zig-out/ui-review/bin/pardes-gui /home/goblin/.cache/pardes-ui-review-final --project /home/goblin/00-projects/00-solana/agave/02-upstream --skip-lsp --theme orchard --themes orchard dusk ink paper daybreak atelier", + "tty_command": "python3 -B test/ui_review.py zig-out/ui-review/bin/pardes /home/goblin/.cache/pardes-ui-review-final-tty --project /home/goblin/00-projects/00-solana/agave/02-upstream --tty --skip-lsp --theme orchard --themes orchard dusk ink paper daybreak atelier", + "themes": [ + {"name": "orchard", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200}, + {"name": "dusk", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200}, + {"name": "ink", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200}, + {"name": "paper", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200}, + {"name": "daybreak", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200}, + {"name": "atelier", "cols": 150, "rows": 48, "compared_cells": 7200, "matching_cells": 7200} + ], + "limitations": [ + "TTY evidence is the real core grid and styles, not an independently rendered emulator screenshot.", + "Comparisons exclude SDL pixel decorations, rasterization, font-role metadata and terminal-emulator rendering." + ] +} diff --git a/docs/screenshots/pdf-and-tty-tags.png b/docs/screenshots/pdf-and-tty-tags.png Binary files differnew file mode 100644 index 00000000..66c3a008 --- /dev/null +++ b/docs/screenshots/pdf-and-tty-tags.png diff --git a/docs/screenshots/pets.png b/docs/screenshots/pets.png Binary files differnew file mode 100644 index 00000000..b9a83d66 --- /dev/null +++ b/docs/screenshots/pets.png diff --git a/docs/screenshots/theme-preferences-forge.png b/docs/screenshots/theme-preferences-forge.png Binary files differnew file mode 100644 index 00000000..3497c291 --- /dev/null +++ b/docs/screenshots/theme-preferences-forge.png diff --git a/docs/screenshots/theme-preferences.png b/docs/screenshots/theme-preferences.png Binary files differnew file mode 100644 index 00000000..48bb0d57 --- /dev/null +++ b/docs/screenshots/theme-preferences.png diff --git a/docs/screenshots/theme-selector.png b/docs/screenshots/theme-selector.png Binary files differnew file mode 100644 index 00000000..883a2801 --- /dev/null +++ b/docs/screenshots/theme-selector.png diff --git a/docs/tags.md b/docs/tags.md new file mode 100644 index 00000000..87cee2ff --- /dev/null +++ b/docs/tags.md @@ -0,0 +1,84 @@ +# Editable tags + +Pardes has three levels of command text: the workspace tag, one tag per +column, and each pane's tag. Column commands run in that column's active +pane (or its first pane when focus comes from another column). This makes +`New`, `Tty`, `Find`, and `Grep` available beside the work they act on. +`New` appears only in the column tag by default; pane tags keep their own +save, terminal, close, and collapse commands. `Tty` opens a new embedded terminal. +Column command text starts flush with the column's left edge, just like the +workspace tag; pane bodies retain their scrollbars and line-number gutters. + +When Look opens the first document and its source column is too narrow for +a new column, it splits below the originating pane, just like `Tty`, instead +of inserting at the top of the leftmost column. The originating terminal is +kept. As with `Tty`, a tagline-only source uses a roomier split parent. + +`Collapse` reduces a pane to just its tagline, giving all its body space to +the nearest expanded pane above, or below if none is above. Other panes keep +their heights. Execute it again to reclaim its former height from that one +neighbor, as far as available space allows. If every pane is collapsed, the +unused area stays blank. +Its text and terminal process are kept; +the command stays available in the visible tag. Every default pane tag includes +`Collapse`, including file, terminal, image, and PDF panes. + +Left-click a tag to place its caret; drag to select text, then type to +replace it. Arrow keys, Home, End, Backspace and Delete edit the line. +Tags reveal the caret horizontally when text is wider than their column. +Escape returns to the body, keeping command-text edits. The existing Exec +and Look gestures still apply; the workspace tag is no longer an inert +left-click target. Pasted text goes to the focused tag, not to the file or +embedded shell beneath it. + +Normal tag navigation now visits pane, column, and workspace tags in order: +from the top pane's `:` tag, `k` reaches the column and another `k` reaches +the workspace; `j` walks back down. Enter or Tab on a header command in +normal mode executes it, as before. `i`/`a`/`I`/`A` switch to editing the +header. In insert mode, Enter is Look and Tab is Exec, as in pane tags. + +Pane filenames and commands now have a single separator space rather than +generated right-alignment padding. Intentionally customized spacing is kept. + +## File names + +Editing a file pane's name creates a draft. Enter confirms the new buffer +name; Escape or leaving the tag cancels the draft. Confirmation changes the +buffer's save target and marks it unsaved. It does **not** rename, create or +overwrite a disk file. A subsequent explicit `Save` writes the buffer to its +committed name. Executing a pane-tag command confirms a valid name draft +first, so a visible draft cannot silently save to the previous name. + +Terminal working directories and generated image/PDF status remain managed +by their corresponding commands. Their command tails are editable just like +file command tails. + +PDF tags follow the same filename-first layout: `manual.pdf [1/12] Tty Del +PdfSections PdfTint Collapse`. Sections and tint commands remain in the editable +tail, without displaying the current tint state. `PdfFit` (`SPC t z`) remains +available, as do the shortcuts for `PdfTint` (`SPC t i`) and `PdfSections` +(`SPC t s`, or `f` on a PDF). + +Terminal tags include `Togglettymode`, which toggles between normal editor mode and raw +terminal input using the same transition as Ctrl-B. It also works while editing +the tag: the command leaves tag editing and toggles the parked body mode. +Executing it on a non-terminal pane does nothing. + +## Saved workspaces + +`Dump` and `Restore` preserve customized workspace and column tags, including +intentionally empty tags. New columns start with the standard column tag. +Closing a column keeps surviving columns' tags; `Joincol` keeps the destination +column's tag. Old dumps without these optional fields retain the defaults. +The automatic `Restore` shortcut does not overwrite a customized workspace +tag. + +The column row stays above panes with `TagBottom` enabled. On screens shorter +than three rows it is omitted so a pane still has room. SDL and TTY share the +same tag text, editing and layout; SDL additionally uses compact font sizing +and subtle pixel separators. + +`ColumnTags` toggles the column row (on by default) without deleting its text. +`FocusTint` controls active-column and active-pane emphasis. SDL also honors +the shared bold, underline, and strikethrough attributes, including diagnostic +underlines and the optional `SyntaxBold` keyword weight. diff --git a/docs/themes.md b/docs/themes.md new file mode 100644 index 00000000..7d71d0dd --- /dev/null +++ b/docs/themes.md @@ -0,0 +1,124 @@ +# Pardes themes + +Pardes ships fifteen native palettes: six originals, six classic-inspired +adaptations and three contrast variants, designed for tags, text, search, diagnostics and embedded +terminals together. `orchard` is the initial theme. +Execute `Theme <name>` anywhere, or open `ThemeSel` with `SPC t t` and select +a theme's command. Put the same command in your [startup configuration](config.md) +to keep a preference. `NextColor` cycles through the native themes first, +then the retained `helix`, `dark` and `acme` themes and imported palettes. +`ThemeSel` groups the new palettes under `Pardes themes`, followed by +`Legacy and imported themes`; its navigation skips the section headings. +See the [Agave visual review](ui-review.md) for the original six-palette gallery. + +| Theme | Character | Page | Accent | +| --- | --- | --- | --- | +| `orchard` | Near-black evergreen; bright leaf comments and plum syntax | `#0d1410` | `#adcc91` | +| `dusk` | Soft plum charcoal; copper comments and gentle text | `#39323b` | `#e4b39b` | +| `ink` | Pure black; bright, distinct signals and ice-blue comments | `#000000` | `#86d8ff` | +| `paper` | Neutral uncoated paper; graphite and teal | `#f5f3ed` | `#3c6b56` | +| `daybreak` | High contrast light; white and deep blue ink | `#ffffff` | `#075f91` | +| `atelier` | Acme homage; butter-yellow paper and blue-green tags | `#fffdeb` | `#3e7a68` | +| `forge` | Dark Plus-inspired near-black, blue and peach; slate-blue tags | `#0c0c0e` | `#a5c4ee` | +| `lagoon` | Softer Material-inspired slate; vivid sea-glass comments | `#34464c` | `#89c7b4` | +| `solarium` | Softer Solarized-inspired blue-green; golden comments and teal tags | `#173e45` | `#d5bc72` | +| `spectrum` | Monokai-inspired near-black and candy colors; golden comments | `#100e11` | `#ffd866` | +| `harvest` | Autumn-inspired near-black earth, ember and leaf green | `#100e0b` | `#cfba8b` | +| `clay` | Gruvbox-inspired near-black and earthy brights; amber comments | `#10100e` | `#8ec07c` | +| `forge_black` | Pure-black Forge; luminous text and cool slate tags | `#000000` | `#a5c4ee` | +| `forge_soft` | Neutral-slate Forge; gentler text, still vivid blue comments | `#35383e` | `#a5c4ee` | +| `orchard_black` | Pure-black Orchard; luminous garden ink and bright leaf comments | `#000000` | `#adcc91` | + +The six adaptations retain recognizable classic syntax identities, but are +not exact ports. Their Acme influence is deliberate: quiet command strips, +thin boundaries, and a search surface +distinct from selection. Forge uses cool-neutral chrome instead of green +tints. Active pane and column tags use a restrained tone-on-tone shift, not +a light/dark inversion: dark palettes keep dark tags, and light palettes +keep light tags. A slight text lift and the focus marker retain the cue +without turning the entire command strip into a highlight. +Comments are colorful first-class text, while line numbers stay quiet; +the current line number gets a small color emphasis and bold weight, never a bright tag-colored +block. These are appearance changes only; +tag editing, commands and terminal interaction are unchanged. + +Dark backgrounds make an explicit choice: near-black with bright text, or +the gentler slate/plum/blue-green of `forge_soft`, `dusk`, `lagoon` and +`solarium`. The softer group keeps body text around 5.5–6.7:1 contrast; the +near-black group exceeds 14:1. Try `Theme forge_black` and `Theme forge_soft` +back-to-back to compare the extremes without changing the syntax identity. +Light paper and the Acme homage remain available. + +Their local references are `vendor/themes/dark_plus.toml`, +`material_oceanic.toml` (and its `material_deep_ocean.toml` parent), +`solarized_dark.toml`, `monokai_pro.toml`, `autumn.toml`, and the Gruvbox Dark +entry in `gruvbox.json`. The original imported themes remain selectable under +their existing names; the adaptations have distinct Pardes names and do not +claim upstream affiliation. Existing vendor provenance and licenses remain +with those sources. + +All fifteen palettes specify their own ANSI colors, so indexed terminal output +belongs to the same palette as the editor. Explicit true-color output can +still carry an application's own colors; the existing terminal `Filter` +command projects those colors through the theme. The older `dark` palette +continues to inherit the surrounding terminal's default background and text. + +The native palettes keep normal text, syntax colors, comments, +diagnostics and ANSI foregrounds at a calculated sRGB contrast ratio of at +least 4.5:1 against the page. `ink` and `daybreak` raise that floor to 7:1. +Comments additionally stay above 5:1. Decorative line numbers sit between +2.5:1 and 4:1, with current numbers capped at 4.5:1; they deliberately do not +compete with source text. ANSI bright black is independent of the comment +color, so making comments vivid does not recolor gray terminal output. +Tag, active-tag, selection and search text are checked against their respective +surfaces at the same thresholds. Active/inactive tag backgrounds differ by +no more than 1.6:1, keeping focus changes quiet. ANSI black is exempt because applications +also use it as a background. These are palette checks, not a guarantee about +arbitrary terminal escape sequences, reversed colors or shader effects. + +## Make a theme your own + +Run `DumpThemes` to export complete `.zon` files below the configuration +directory's `themes/builtin/`. Copy a native file to `themes/mine.zon`, change +its `.name`, and run: + +```text +ThemeFile themes/mine.zon +``` + +On hosts with live document reload, saving a valid theme file updates it +immediately. An incomplete save keeps the last valid version. Selecting a +built-in theme stops the custom theme watch. + +Pardes roles extend the original editor palette with independent choices +for its UI. Each value is an RGB triple, for example +`.search_bg = .{ 0x57, 0x47, 0x2a }`. New roles are optional and accept `null`, +so existing exported themes remain valid. + +| Optional role | Purpose | When absent | +| --- | --- | --- | +| `tag_active_bg`, `tag_active_fg` | Focused pane tag surface and text | `tag_bg`, `tag_fg` | +| `border` | Quiet separators | `scroll_track` | +| `lineno_active` | Restrained current line number foreground | `lineno` | +| `search_bg`, `search_fg` | Search matches, independent of selection | `sel_bg`, `sel_fg` | +| `diagnostic_error` | Error text | `fg`, or `tag_fg` for an inherited foreground | +| `diagnostic_warning` | Warning text | Same foreground fallback | +| `diagnostic_info` | Informational diagnostic text | Same foreground fallback | +| `diagnostic_hint` | Hint text | Same foreground fallback | + +These colors are shared by the GUI and TTY. Tags and their active tint retain +the same text, command execution, drag targets and focus behavior. Selection +and search have separate palette roles because they communicate different +states. Theme changes use the existing chrome transition; body and terminal +colors switch directly so syntax and ANSI content stay coherent. + +`FocusTint` toggles the focused pane's tag tint, which is on by default. +`SyntaxBold` toggles bold syntax keywords, which are off by default. Both +commands take no argument, work in GUI and TTY, and report their states in +`Config`. Use them in the startup configuration to reverse the defaults. + +The original required roles remain unchanged: nullable `bg` and `fg`, +`sel_bg`, `sel_fg`, `tag_bg`, `tag_fg`, `box`, `box_dim`, `kw`, `str`, `num`, +`comment`, `lineno`, `scroll_track`, `scroll_thumb`, and a nullable 16-entry +`palette`. `ThemeFile` loads a complete theme, with no inheritance or partial +override syntax. The exported native files are the easiest starting point. diff --git a/docs/ui-review.md b/docs/ui-review.md new file mode 100644 index 00000000..e43ef9b7 --- /dev/null +++ b/docs/ui-review.md @@ -0,0 +1,230 @@ +# Visual review + +## Contrast choices and local collapse + +The fifteen native palettes now give comments vivid color and keep line +numbers subdued. The current number uses muted ink and bold weight instead +of a tag-colored background block, in SDL and TTY. Active pane and column +tags use a small tonal shift without reversing their light/dark polarity. +Column tag text starts at the column edge without the former two-cell inset. +Forge has neutral coal +and silver-blue chrome. `forge_black` and `orchard_black` use pure black; +`forge_soft` joins `dusk`, `lagoon` and `solarium` as deliberately softer +alternatives. Light and Acme-inspired choices remain available. + +`ThemeSel` opens with the native collection, followed by a separate legacy +and imported section. Keyboard navigation skips both section headings. + +`Collapse` now transfers all released rows to one expanded pane, preferring +the nearest one above and falling back below. Unrelated pane heights stay +unchanged. Expansion borrows from one neighbor too, limited by its available +body space. Tests cover exact unchanged sibling rectangles, repeated inverse +toggles, already-folded neighbors, tiny resizes, drag expansion and Dump/Restore. + +The refreshed builds pass 791 TTY and 822 SDL unit tests, with one skipped +in each suite, plus all 98 interaction snapshots. Snapshot review found only +the intended style changes, the expanded grouped theme picker, and flush-left +column text/carets (including newly visible text in one- and two-cell columns). + +The isolated 9P harness `test/collapse_layout.py` passes seven collapse/expand +pairs on each host, checking rendered tag boundaries and unchanged contents. +The live OS gallery checks all fifteen native themes for bold current-line +numbers, unchanged gutter backgrounds and no active-tag polarity inversion. +Both hosts pass all twelve column input checks, including first-cell execution, +editing and caret reveal. Agave source bytes stay unchanged and no input is +sent to the user's session. + +- [Six contrast studies, OS screenshot crops](screenshots/theme-preferences.png) +- [Neutral Forge, full workspace](screenshots/theme-preferences-forge.png) +- [Native-first ThemeSel, full workspace](screenshots/theme-selector.png) + +## Compact rails, classic palettes and workspace pets + +`New` now belongs to column tags only. Pane tags keep their local save, +terminal and close actions: `Tty` opens a terminal, and `Togglettymode` +switches editor/raw input using the same transition as Ctrl-B. Historical +default pane tails upgrade during Restore; explicitly customized text remains +owned by the user. + +SDL paints adjacent tag backgrounds to their full row height, leaving only +the thin separator. Square scroll markers share the column's left edge, and +a one-pixel continuous line joins its column tag, pane tags and bodies. +Pointer targets and the TTY grid are unchanged. + +`Font MartianMono-NrRg:18` now applies both face and size. The isolated +`test/font_size.py` checks startup sizing, fractional sizing, retaining the +size when omitted, and rejecting invalid requests without partial changes. + +Six [classic-inspired themes](themes.md) add `forge`, `lagoon`, `solarium`, +`spectrum`, `harvest` and `clay`. ANSI colors retain their terminal meanings +instead of borrowing a similarly positioned syntax color. Optional SDL +`Pet cat` and `Pet frog` companions walk, idle and reverse in the unused +workspace tag; `Pet off` is the default. Editing that tag hides the pet. +The original pixel sprites use no external assets or input handlers. + +`test/appearance_gallery.py` recreates a two-column Agave review with stacked +right-hand panes, an embedded terminal, Font 18 and TaglineSize 80. It checks +all six new themes, font and pet reports, changing pet frames, and unchanged +Agave source bytes. Its `--live-window` mode captures the owned SDL window +through the OS, identified by its child PID. It never resizes or sends input +to the user's existing Pardes window. + +- [Compact columns, native OS capture](screenshots/compact-columns.png) +- [Six classic adaptations, screenshot contact sheet](screenshots/classic-themes.png) +- [Cat and frog, enlarged nearest-neighbor screenshot crops](screenshots/pets.png) +- [Gallery checks](screenshots/classic-gallery.json) + +The full suites passed 807 SDL and 776 TTY tests, with one skipped in each; +all 97 interaction snapshots passed. A private mount namespace redirected +test-only `/tmp` writes after the host's temporary-file quota was exhausted, +without deleting files or changing the user's `/tmp`. These counts include +the pet/geometry/font/command changes; palette corrections additionally pass +the native contrast tests. + +## PDF and terminal tag cleanup + +PDFs now use `filename.pdf [page/total] Tty Del PdfSections PdfTint Collapse`, +keeping sections and tint commands visible without the long generated +control/status prefix. Terminal tags add `Togglettymode`, sharing Ctrl-B's actual mode +transition, including when invoked from an edited tag. + +`test/tag_cleanup.py` verifies the compact PDF tag, middle-click `Togglettymode`, Ctrl-B, +and tag-edit/Tab execution through real host input and 9P observations on both +SDL and TTY. The PDF source stays unchanged. The full unit suites pass 773 TTY +tests and 797 SDL tests; SDL image/PDF and Kitty PDF rendering harnesses pass. + +[Native PDF and terminal screenshot](screenshots/pdf-and-tty-tags.png). + +## Column and editable-tag follow-up + +The follow-up adds editable workspace and column command rows, compact pane +tags, staged buffer-name edits, caret reveal for long tags, and `ColumnTags` +to reclaim the extra row when needed. See [editable tags](tags.md) for the +exact interaction and save-target rules. + +`test/column_tags.py` exercises isolated SDL and TTY sessions against the same +Agave source. It sends actual host input bytes while observing through 9P: +header typing and selection replacement, UTF-8 deletion, inactive-column +`New`/`Tty`, pane-tail edits, filename cancellation, terminal input, and +custom-tag Dump/Restore. Source bytes remain unchanged. Input goes through +the host PTY parser; compact SDL pixel coordinates are covered separately by +round-trip mapping tests, not claimed as physical SDL mouse automation. +All 11 live checks passed on each frontend. All 7,200 foreground/background +cells and 48 text rows matched for the three final frames after normalizing +only the isolated `ct-sdl`/`ct-tty` directory names. + +The screenshots below are native GPU captures, after removing test-only +Unicode markers through normal tag editing. The tested CJK text has correct +grid/editing behavior, but the selected font lacks its glyph; this is not +claimed as complete font-fallback coverage. + +- [Two-column Orchard workspace](screenshots/columns-orchard.png) +- [Two-column Atelier workspace](screenshots/columns-atelier.png) +- [Long tag revealing its actions and caret](screenshots/columns-tag-reveal.png) +- [Final SDL/TTY parity evidence](screenshots/columns-parity.json) + +The final unit suites passed 771 TTY tests and 795 SDL tests. Native image and PDF harnesses +passed, including continuous PDF layout and reload. The PDF fixture gains one +screen row to preserve its original document area; its pixel assertions are +unchanged. + +Existing terminal snapshots were migrated by adding one screen row and moving +pane mouse coordinates down one row, preserving their original body area. +Raw SGR mouse sequences were migrated too. The tag-padding/name/navigation +fixtures were explicitly rewritten for the new behavior. Review found 86 +fixtures with identical text tokens after removing the new column row and +normalizing spacing; the remaining differences were reviewed for tag edits, +nested editor chrome, resize handles, and debug overlays. All 97 scripts +passed both when regenerating the reviewed goldens and in a subsequent +independent run with retries disabled. + +## Initial palette pass + +The UI pass was exercised against Agave's real `gossip/src/crds_value.rs`, +using isolated named Pardes sessions and the existing Python 9P client. +The workflow opened Find and Grep results, ran harmless commands in an +embedded terminal, requested Rust document symbols and hover, and sent `gd` +through the host's actual terminal input parser. Agave source bytes were +checked unchanged after the session. + +Native SDL screenshots use the GPU capture path. TTY captures contain the +real core grid and its styles; they are not screenshots of an independent +terminal emulator. Resolving cells to their grapheme, foreground and +background yielded **7,200 of 7,200 matching cells** at 150 × 48 for each of +`orchard`, `dusk`, `ink`, `paper`, `daybreak`, and `atelier`. + +Rust-analyzer returned 52 document-symbol rows and one definition result. +The initial baseline hover timed out; the updated run returned no hover +text for the declaration. No hover popup is claimed as verified. Agave's +gossip crate is feature-gated, and workspace loading was still substantial; +the exact cause of that empty result was not established. + +## Reproduce + +Run from the Pardes checkout, using an existing SDL binary and an Agave +checkout. The output directory is private and also holds isolated startup +configuration. ImageMagick and an X11 display are required for PNG captures; +the LSP pass additionally needs rust-analyzer (located through rustup unless +`--rust-analyzer` is supplied). + +```sh +python3 -B test/ui_review.py zig-out/ui-review/bin/pardes-gui \ + /tmp/pardes-ui-review --project /path/to/agave \ + --theme orchard --themes orchard dusk ink paper daybreak atelier +``` + +For subsequent palette captures, add `--skip-lsp`. To repeat LSP work without +rebuilding dependencies, use `--cargo-target /path/to/previous/cargo-target`. +Cargo runs offline and stores build output in that isolated directory. +For the TTY pass, use the TTY binary and add `--tty`. The script requires +Find/Grep results and observed terminal output, fails missing or malformed +SDL captures, and writes `report.json` with the actual outcomes. LSP absence +or failure is recorded separately rather than passing as a successful popup. + +Review artifacts from this pass: + +- [Baseline workspace](screenshots/before.png) +- [Orchard: mild dark](screenshots/orchard.png) +- [Dusk: warm dark](screenshots/dusk.png) +- [Ink: high contrast dark](screenshots/ink.png) +- [Paper: mild light](screenshots/paper.png) +- [Daybreak: high contrast light](screenshots/daybreak.png) +- [Atelier: Acme homage](screenshots/atelier.png) +- [Cell parity evidence](screenshots/parity.json) +- [Actual Rust LSP responses](screenshots/agave-lsp.txt) + + + +## Regression checks + +Both native binaries built in ReleaseFast. The full TTY and SDL unit suites +passed with the inherited nesting variables `PARDES_FORWARD_LOOK`, `PARDES_9P` +and `PARDES_PANE` removed from the test process. Those variables exposed an +existing environment-ownership issue in native subprocess tests: libc's +environment was changed while the Zig test I/O retained the old slice. This +pass does not change that environment code or skip the affected tests. + +The appearance checks cover native palette contrast, old ThemeFile documents, +wrapped search matches, selection precedence, immediate body colors during +theme fades, light-theme carets and both quiet and bold syntax preferences. +The 9P walkthrough also verifies `FocusTint` and `SyntaxBold` through `Config`. + +All 97 terminal snapshot scripts passed without retries after reviewing and +refreshing 32 appearance goldens. Of those, 27 preserve identical visible text, +cursor positions and grid geometry; the remaining five contain the new default +theme name or the expanded theme list. SDL image and PDF harnesses also passed, +including continuous PDF layout and idle document reload. The PDF color fixture +explicitly selects legacy `helix` to preserve its fixed pixel expectations. + +## Possible interaction follow-ups + +These were not needed for the appearance pass: + +- A way to reveal an abbreviated pane path on demand could recover title + space in deep workspaces. The full path should remain selectable and + available to Look; replacing it outright would weaken an existing workflow. +- Show a query's busy state until its response arrives, and distinguish an + empty answer from a timeout. The first full-workspace Rust hover provided + little visible feedback while indexing; explicit status would tell users + whether to wait or change their selection. This needs clear cancellation + and stale-response behavior before changing the interaction. |
