diff options
| author | user <user@clank> | 2026-08-29 20:25:39 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-29 20:25:39 +0200 |
| commit | 31c32f9c20e3dd5045fa053fc8e7e606a8139397 (patch) | |
| tree | 007bf1dfe01b8beda4bd5d00642f060d759d519c /docs | |
| parent | arch: sign the packages and the database, and say whose key (diff) | |
| download | slosh-31c32f9c20e3dd5045fa053fc8e7e606a8139397.tar.gz slosh-31c32f9c20e3dd5045fa053fc8e7e606a8139397.tar.xz slosh-31c32f9c20e3dd5045fa053fc8e7e606a8139397.zip | |
docs: less wordy
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/config.md | 21 | ||||
| -rw-r--r-- | docs/design.md | 5 | ||||
| -rw-r--r-- | docs/index.md | 30 | ||||
| -rw-r--r-- | docs/keys.md | 5 | ||||
| -rw-r--r-- | docs/layouts.md | 73 | ||||
| -rw-r--r-- | docs/panes.md | 58 | ||||
| -rw-r--r-- | docs/scripting.md | 5 | ||||
| -rw-r--r-- | docs/shaders.md | 42 | ||||
| -rw-r--r-- | docs/windows.md | 15 | ||||
| -rw-r--r-- | docs/workspaces.md | 78 |
10 files changed, 125 insertions, 207 deletions
diff --git a/docs/config.md b/docs/config.md index 86cfc79..d768e3a 100644 --- a/docs/config.md +++ b/docs/config.md @@ -61,9 +61,8 @@ config that was never opened and a config with nothing wrong look identical. It is the loader, not a second implementation of it: the only checker that cannot drift from what a session does is the one a session uses. The single -difference is how many problems each reports: a session has one status line and -shows the first, and a linter that stopped at the first mistake would make you -run it once per mistake. +difference: a session's status line shows the first problem, the checker shows +them all. ## include @@ -136,10 +135,8 @@ padding 0 2 // vertical, horizontal padding 2 0 0 1 // top, right, bottom, left ``` -A number means the same thing however many of them you write, so `padding 1`, -`padding 1 1` and `padding 1 1 1 1` are one padding rather than three. Three -values is refused: CSS reads it as top/horizontal/bottom, and a line whose -meaning you have to look up is a line nobody can read. +Three values is refused: CSS reads it as top/horizontal/bottom, and a line +whose meaning you have to look up is a line nobody can read. ## Compact @@ -193,12 +190,10 @@ picks its own: 10,000 *bytes*, which measures at 622 lines of an 80-column pane, less than one `make` run. `scrollback` is that number replaced with the one every other multiplexer settled on. -The two limits work together because either can be reached first and neither can -see what the other depends on: a line count cannot know how wide your terminal is -or how many styles a program used, and a byte count cannot know how many lines -that bought. Whichever bites first wins. Both are estimates: history is pruned a -page at a time (a page is about 400KB of grid), so a pane keeps a little more -than it was told, never less. +Whichever limit bites first wins: a line count cannot know how wide your +terminal is, and a byte count cannot know how many lines it bought. Both are +estimates: history is pruned a page (about 400KB of grid) at a time, so a pane +keeps a little more than it was told, never less. What the ceiling costs, measured on a pane filled with styled output: diff --git a/docs/design.md b/docs/design.md index bf1d412..458858c 100644 --- a/docs/design.md +++ b/docs/design.md @@ -91,9 +91,8 @@ line breaks carry meaning: a paragraph, a list, a diagram of a pane. A comment that runs long is a thing for a person to fix. The Python is the opposite: left entirely at ruff's defaults. The C here was -hand-formatted into a house style worth arguing for; the Python was not, and a -formatter of that kind is only worth having when there is nothing left to argue -about. Every knob turned would be an argument to have again later. It cost a 60% +hand-formatted into a house style worth arguing for; the Python was not, and +every knob turned would be an argument to have again later. It cost a 60% reformat of the test suite, once. **Python imports are sorted and C includes are not**, which is not an diff --git a/docs/index.md b/docs/index.md index ad90c7f..960ebf7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -16,11 +16,9 @@ brew install slosh ### Linux -The same tap works under [Homebrew on -Linux](https://docs.brew.sh/Homebrew-on-Linux), or build from source. That -needs [zig](https://ziglang.org) 0.16 and nothing else: no cmake, no -autotools, no libraries. The result is one static binary that runs on any -distro. +Build from source. That needs [zig](https://ziglang.org) 0.16 and nothing +else: no cmake, no autotools, no libraries. The result is one static binary +that runs on any distro. ```bash make vendor # build the vendored terminal core (once, a couple of minutes) @@ -32,6 +30,28 @@ sudo make install (The source build works on a mac too; Homebrew is simply the shorter road there.) +#### Arch + +A pacman repository serves built, signed packages. Enroll the signing key +(fingerprint `0F67C909938CFFA8A76B59FD8D69B55A0E9056B9`; the same key is +`contrib/arch/slosh.asc` in git, so the two copies can be compared): + +```sh +curl -fsSLO https://slosh.foo/arch/slosh.asc +sudo pacman-key --add slosh.asc +sudo pacman-key --lsign-key 0F67C909938CFFA8A76B59FD8D69B55A0E9056B9 +``` + +then, in `/etc/pacman.conf`: + +```ini +[slosh] +Server = https://slosh.foo/arch/$arch +``` + +and `pacman -Sy slosh`. Details, and the PKGBUILD for building it yourself: +`contrib/arch/README.md` in the source tree. + ### Windows Windows 10/11, x86-64 and ARM64, as one `slosh.exe`. Panes are ConPTYs and diff --git a/docs/keys.md b/docs/keys.md index 5afc1b5..84422d1 100644 --- a/docs/keys.md +++ b/docs/keys.md @@ -49,9 +49,8 @@ it did not (`+7 more, in docs/keys.md`), which is the table below. **`x`/`X`, `p`/`P`, `w`/`W` and `f`/`F` are deliberately shifted pairs on one letter.** Close this pane / close this tab; run a command / tag this pane; go to a project / write this project down; float this pane / float a fresh one. -The shifted half is the same verb on a bigger thing, or the thing you reach -for within a moment of the other, so the shift is less to remember than a -second letter would have been. +The shifted half is the same verb on a bigger thing, so the shift is less to +remember than a second letter would have been. `X` says how many panes went with the tab, since most of them were not the one you were looking at. On the **last** tab it refuses and points at `q` instead: a key diff --git a/docs/layouts.md b/docs/layouts.md index a2d22b3..0e66f7b 100644 --- a/docs/layouts.md +++ b/docs/layouts.md @@ -21,26 +21,18 @@ slosh --layout project.layout ## What to call them -**`*.layout`**, and a project's is `slosh.layout`. The syntax is still the same -KDL subset the config uses, one parser reads both files, and for a while the -files were `*.layout.kdl` on the argument that the extension should say so. -The argument lost to a collision: zellij speaks the same syntax under that -same extension with a different schema, and to anyone arriving from there -`.kdl` said *whose* file it is, and naming the wrong owner is worse than not -naming the parser. The name says what the file is; `slosh --check` says how -it was read. (Point your editor's KDL highlighting at `*.layout`; it *is* -still KDL underneath.) The old spelling is still found by the project scan, -never written. +**`*.layout`**, and a project's is `slosh.layout`. The syntax is the same KDL +subset the config uses — one parser reads both files — but the extension is +not `.kdl`: zellij speaks KDL layouts with a different schema, and naming the +wrong owner is worse than not naming the parser. Point your editor's KDL +highlighting at `*.layout`. The old `*.layout.kdl` spelling is still found by +the project scan, never written. A filename cannot enforce anything, so **the document decides which schema it is held to, not the flag that read it**. `slosh --check` reads what is in front of -it: a file with `layout` or `tab` at the top of it is checked as a layout, and a -config handed to the same flag is still checked as a config. A file too broken to -parse at all is judged by its name, because by then there is nothing else left to -read. One flag rather than a `--check-layout` beside it: naming the schema is the -part you wanted the checker to do, and the answer it used to give (`this is a -layout, not a config`) replied to a question about a file with the name of -another flag. +it: a file with `layout` or `tab` at the top is checked as a layout, a config +handed to the same flag is still checked as a config, and a file too broken to +parse at all is judged by its name, there being nothing else left to read. ``` $ slosh --check project.layout @@ -64,12 +56,9 @@ $ slosh --check broken.layout broken.layout: 6 problems ``` -Those are the mistakes a layout can make that still parses: a property no pane -has, a `split=` that is neither direction, a `weight=` that is not a number the -engine will honour, a `true`/`false` written some other way, a `purpose=` on a -split (which would tag nothing, because a split runs nothing) and a child node -that is not a `pane`. Last comes `this layout declares no tabs`, reported at the -end rather than first so it reads as the summary it is. +Those are the mistakes a layout can make that still parses. `this layout +declares no tabs` comes last rather than first, so it reads as the summary it +is. Loading is the other half of the same answer: @@ -79,9 +68,7 @@ slosh: config.kdl: this is a config, not a layout: `gap` is a setting ``` A config handed to `--layout` is named for what it is instead of refused for -having no tabs, which is true of it in the least useful way. Both answers come -from the same list of settings the loader reads, so the two cannot disagree about -which file is which. +having no tabs, which is true of it in the least useful way. ## The shape @@ -105,10 +92,9 @@ which file is which. - `purpose=`: a label for tooling; see below. **A relative `cwd=` in a layout *file* resolves against that file's own -directory**, never against the directory you started the session from. It is the -rule [`include`](config.md#include) already follows for configs, applied to the -other half of the same syntax: the two documents share a parser, so they should -not disagree about what a relative path is. A layout with no `cwd=` anywhere +directory**, never against the directory you started the session from. It is +the rule [`include`](config.md#include) already follows, applied to the other +half of the same syntax. A layout with no `cwd=` anywhere starts in the file's directory too, so the common case needs no `cwd=` at all. An absolute path is unchanged, and `~` is still your home directory. @@ -129,14 +115,11 @@ layout { ``` Clone that repo somewhere else and the tab still opens on the checkout, with the -pane that said `src` still in the checkout's `src`. The alternative (absolute -paths, or a `$PROJECT` of our own to expand) makes the file personal to one -machine, or makes you learn a variable to say "here". +pane that said `src` still in the checkout's `src`. -A layout that arrives as *text* over the socket has no file, and so no directory -to be relative to. Relative paths in it keep the meaning they had before there -was a base: relative to wherever the session is. Inventing one for text would -mean guessing on behalf of whoever sent it. +A layout that arrives as *text* over the socket has no file, and so no +directory to be relative to; relative paths in it resolve against wherever the +session is. A full annotated example is `config/example.layout`. @@ -214,9 +197,7 @@ empty document, because an empty layout is a plausible answer for a tab you clos a minute ago and a silent one for a typo in an id. A dump records `focus=true` in **every** tab, not only the one you were looking -at. It used to ask the session's current tab which pane was focused whichever tab -it was writing, so restoring a six-tab session put you back where you were in one -tab and wherever the file happened to begin in the other five. +at, so restoring a six-tab session puts you back where you were in all six. ## Applying one to a running session @@ -259,17 +240,13 @@ the layout rather than from whatever the program decides to print. `C-a P` gives the focused pane one from the keyboard (see [keys](keys.md#defaults)) and **a purpose an operator typed counts as declared, -so it locks like one from a file**. The lock is not about which door the label -came through, it is about the label coming from outside the pane at all: you named -that pane `service:web` on purpose, and the shell in it printing a title is not an -argument for renaming it. +so it locks like one from a file**: you named that pane `service:web` on +purpose, and the shell in it printing a title is not an argument for renaming +it. **Setting a purpose to nothing unlocks it**, from a layout, the API or `C-a P` with the field cleared, and hands the label back to the program to describe -itself again. Before that, a lock held over an empty string was the one state -nothing could get out of: the pane carried no label, and the lock was what kept -the program from supplying one. It is the same shape as clearing a pane's name, -and worth more than a second verb whose whole job is taking a lock off. +itself again — the same shape as clearing a pane's name. The [finder](panes.md#finding-a-pane) matches on purposes as well as titles, and `{"cmd":"panes"}` reports them. diff --git a/docs/panes.md b/docs/panes.md index 4161d2f..04127bd 100644 --- a/docs/panes.md +++ b/docs/panes.md @@ -12,11 +12,9 @@ looking at is drawn. Splitting the same direction again gives three equal shares rather than 1/2 + 1/4 + 1/4. - **A new pane starts in the directory the pane it came out of is in**, not where - the session was started. Splitting inside a project to run one more thing and - landing in whatever directory the server was launched from is wrong on its own; - it was wrong on disk as well, because a saved - [project layout](workspaces.md) then carried an absolute `cwd=` pointing at - somewhere else entirely. + the session was started. Landing somewhere else is wrong on screen and worse + on disk: a saved [project layout](workspaces.md) would carry an absolute + `cwd=` pointing somewhere else entirely. - **Resize** with `C-a H J K L`: the boundary moves the way you press, whichever side of it you are on. Sizes are *weights*, so a resized layout survives the window changing size. @@ -29,15 +27,14 @@ looking at is drawn. A turn that would squeeze a pane under the floor is refused with a word. - **`C-a z`** fills the tab with one pane and back; **`C-a m`** puts one away into a strip along the bottom, still running. Each put-away pane sits there - as a **miniature pane frame** (a frame is what a pane looks like here, so - a shrunken one reads as exactly what it is) and clicking it anywhere - brings the pane back: + as a **miniature pane frame**, and clicking it anywhere brings the pane + back: - ``` - ╭────────────╮ ╭─────────────────╮ - │ ▬ server │ │ ▬ agent [!] │ - ╰────────────╯ ╰─────────────────╯ - ``` +``` +╭────────────╮ ╭─────────────────╮ +│ ▬ server │ │ ▬ agent [!] │ +╰────────────╯ ╰─────────────────╯ +``` ## The mouse @@ -55,9 +52,9 @@ nothing you click can disagree with what is on screen. land. The rest of the edge does nothing when clicked. - **The top row is the drag handle, and its handle splits upward.** Clicking a pane's header to focus it never splits it. Its handle goes as near the middle - of the row as the row allows: centred when the row is empty, and against the - title when the title is holding the middle, since the title keeps its own cells - for the double-click rename. Arming an edge leaves the name, the buttons and a + of the row as the row allows: centred when the row is empty, beside the title + when the title holds the middle (the title keeps its cells for the + double-click rename). Arming an edge leaves the name, the buttons and a dead pane's epitaph legible: the heavy rule goes round them. - **Drag the gap between panes** to move that boundary. Where two gaps cross, drag the crossing to move both at once. With `gap 0` there is no gap to @@ -101,11 +98,8 @@ nothing you click can disagree with what is on screen. rather than dropping it at the end. - Click a tab to switch, `+` to open one, a pane to focus it, and the marks in a frame's corner to minimise (`▬`), zoom (`□`) or close (`✕`) it. -- **A tab in the strip has no `✕`** and closes with `C-a X` instead. A mark per tab - would cost two columns of every tab on every frame, forever, for a verb pressed - rarely, the same arithmetic that took the per-pane `+` away. A pane's marks - earn their cells because there is one set of them and it is where you are - looking. +- **A tab in the strip has no `✕`** and closes with `C-a X` instead: a mark per + tab would cost two columns of every tab, forever, for a verb pressed rarely. - Hovering anything says what it does, in a word, in the status line. ## Floating a pane @@ -129,9 +123,8 @@ like any shell, and un-floating lands it beside the pane it was opened over. - **`C-a H J K L` move a focused float** instead of moving a boundary, since a float has no boundary to move. **`=` (or `+`) grows it and `-` shrinks it** about its own centre, so it stays under your eyes; on a tiled pane - `-` still splits. Equalize lives on `0` for this reason: `+` arrives as a - bare `=` on terminals that do not report shift for punctuation, and two - verbs on one key survive only until that happens. + `-` still splits. Equalize lives on `0` because `+` arrives as a bare `=` + on terminals that do not report shift for punctuation. - **It casts a shadow** on what it covers, which is how you tell a float from a tile at a glance. `float_shadow 0` in the config turns it off, and a `states { floating { … } }` chain colours floats on top of that. @@ -203,16 +196,15 @@ with two lines saying what ran and how it ended, and two buttons: ``` **The command is written down because `[re-run]` is one button.** Without it, -pressing it is a guess, most of all in a tab that a [project's -layout](workspaces.md) built, where the command was never typed into that pane to -be scrolled back to. A pane running the session's shell has no command to name -and gets the exit line alone. +pressing it is a guess — most of all in a tab a [project's +layout](workspaces.md) built, where the command was never typed to be scrolled +back to. A pane running the session's shell has no command to name and gets the +exit line alone. -`[re-run]` (or `C-a r`) runs the same command again in the same pane, keeping the -previous run above it in the scrollback. So the two notes turn a pane you re-run -into a log of what ran rather than a pile of identical epitaphs, and a command -that failed while you were looking elsewhere still has its error message when you -get back, while a mistyped command in a fresh session no longer closes it. +`[re-run]` (or `C-a r`) runs the same command again in the same pane, keeping +the previous run above it in the scrollback: a pane you re-run becomes a log of +what ran, and a command that failed while you were looking elsewhere still has +its error message when you get back. Which panes stay is one setting, `keep_dead`: `commands` (the default), `all`, or `none`. diff --git a/docs/scripting.md b/docs/scripting.md index d03184d..54c41ce 100644 --- a/docs/scripting.md +++ b/docs/scripting.md @@ -30,13 +30,12 @@ Panes and tabs are addressed by **id**, so a background tab is scriptable. | `focus` | `id` | | `close` `rerun` | `id`, or 0 for the focused pane | | `clear-shaders` | `id`, or 0 for the focused pane; answers `cleared:0\|1`. The way back from a pane that painted itself unreadable | -| `new-tab` `select-tab` `close-tab` `move-tab` `set-name` | tabs, by `id` or `index` | -| `set-name target="pane"` | a pane's name, which outranks the title its program sets | +| `new-tab` `select-tab` `close-tab` `move-tab` | tabs, by `id` or `index` | | `move-pane` | `id` of the pane, `tab` id to move it into (`0` for a tab of its own, with an optional `name`), `dir:"cols"\|"rows"`. The pane keeps running: same pty, same scrollback | | `float` | bare: toggle a pane [floating](panes.md#floating-a-pane) (`id`, or 0 for the focused one). With any of `x` `y` `w` `h` it *places*: floats first when tiled, re-places when floating, never un-floats; omitted fields keep their value | | `new-float` | a fresh floating shell over the current tab, centred, in the focused pane's directory; answers `id` | | `set-name` | `target:"tab"` (the default, because that is what this verb has always meant) or `"pane"`, `id`, `name`. A pane accepts 0 for the focused one. A pane's name wins over the title the program sets, so this is how a program that keeps announcing something stale gets overruled; an empty `name` clears it and hands the label back. Refusals say `no such pane` or `no such tab`, so a mistyped target is visible in the reply | -| `set-purpose` | `target:"pane"\|"tab"`, `id` (or 0 for the focused pane, and the tab you are in), `purpose`. An empty `purpose` clears the slot *and* unlocks it, handing the label back to the program, because a lock held over an empty string was a state nothing could get out of | +| `set-purpose` | `target:"pane"\|"tab"`, `id` (or 0 for the focused pane, and the tab you are in), `purpose`. An empty `purpose` clears the slot *and* unlocks it, handing the label back to the program | | `dump-layout` `apply-layout` | see [layouts](layouts.md). `dump-layout` takes `tab` (0 for every tab), `relative_to` to write every `cwd=` under that directory instead of absolute, and `suspend` (`as-is` `none` `commands` `all`); it answers `kdl` `panes` `suspended`, and an unknown `tab` is an error rather than an empty document | | `workspaces` | the projects on disk and which of them are open: `roots` says whether any are configured at all, and each entry has `name` `path` `purpose` `layout` (a file path, or "") `mtime` `tab` (0 when closed). See [workspaces](workspaces.md) | | `open-workspace` | `name` or `path`, and `suspended`; answers `tab` `purpose` `path` `created` `tabs` `honoured`. Already open means focused, with `created:false` | diff --git a/docs/shaders.md b/docs/shaders.md index d06aa3c..8be513a 100644 --- a/docs/shaders.md +++ b/docs/shaders.md @@ -74,10 +74,9 @@ shaders { `PI` being a half turn is what makes a radian-shaped formula port across as written: `sin(TAU * x / cols)` is one cycle over the pane's width, `PI / 2` is a quarter turn, `PI / 6` is thirty degrees. It is also *more* exact than radians -could be in a language with no fractions: a sixth of a turn is 30 whole degrees, -where `3.14159 / 6` in integers is 0. For the same reason there is no `deg2rad` -or `rad2deg`: there is one angle unit, and a conversion could only lose the angle -or invent a second scale to disagree with. +could be in a language with no fractions: a sixth of a turn is 30 whole +degrees, where `3.14159 / 6` in integers is 0. There is one angle unit, so +there is no `deg2rad` or `rad2deg`. There are no loops and no recursion, on purpose: a config cannot spin and there is nothing to sandbox. An expression that does not compile drops that one shader @@ -149,29 +148,22 @@ chrome> include "contrib/chrome/shine.kdl" a file, the way a config includes chrome> :load shine the same, for the presets that ship with it ``` -`:paste` prints the document back as a `shaders { }` block with `where=` on every -entry, and that block can be typed straight back in, which is the point of -borrowing the syntax rather than inventing one. A test reads it off the screen, -clears the pane, types it back and compares the cells. +`:paste` prints the document back as a `shaders { }` block with `where=` on +every entry, and that block can be typed straight back in, which is the point +of borrowing the syntax rather than inventing one. The reply counts +(`1 chrome, 1 content`) say where the passes went, which is the only way to see +that an entry's `where=` did what you meant. -The text is a **document**: what it says replaces both chains, the way naming -`shaders { }` in a config replaces the block rather than adding to it. The reply -counts (`1 chrome, 1 content`) say where the passes went, which is the only way to -see that an entry's `where=` did what you meant. +Nothing in the prompt parses KDL: a file goes over by path and a pasted block +via a temporary file, because the session already has the parser and a second +reader would be a second opinion. -Nothing in the prompt parses KDL. A file goes over by path and a pasted block via a -temporary file, because the session already has the parser, and a second reader of -a config file would be a second opinion about what it says, exactly where comments -meet quoted strings. - -It is a readline prompt, so editing, up/down and ctrl-r work as they do in a shell, -and history is kept between runs in `$XDG_DATA_HOME/slosh/shader-repl.history`. -The chains only, since `:quit` is not something you want to press up past. Tab -completes the commands, the shader names, the property keys, the expression -language's own variables, constants and functions, and filenames after `:load`. -`:help` prints the same list at once. A test checks that list against -`src/shader.c` and `src/expr.c`, because a completion list that has gone stale -reads as "that is all there is". +It is a readline prompt: editing, up/down and ctrl-r work as in a shell, and +history is kept between runs in `$XDG_DATA_HOME/slosh/shader-repl.history` +(the chains only, since `:quit` is not something you want to press up past). +Tab completes the commands, the shader names, the property keys, the +expression language's variables, constants and functions, and filenames after +`:load`; `:help` prints the same list at once. **Off by default.** It needs `in_band_shaders true`, because a program that can restyle the session it happens to be running in is a hazard first and a diff --git a/docs/windows.md b/docs/windows.md index c1901cd..2f076da 100644 --- a/docs/windows.md +++ b/docs/windows.md @@ -145,14 +145,11 @@ the session on the one program that misbehaves. Whoever finishes last frees. something on it is not an EOF anywhere. - **No editor is guaranteed.** `C-a e` prefers whichever console editor is actually installed — `nvim`, `vim`, `vi`, `nano`, `micro`, `hx`, `edit` — - because the obvious fallback is the wrong shape: `notepad` is a GUI program, - so a pane running it draws nothing and looks broken. Microsoft Edit (`edit`) - is a console program, so it fills a pane like any other editor: from Windows - 11 24H2 there is a usable editor without installing one. It comes last of the - console editors because it arrives on its own, and so says nothing about what - you want, where having fetched nvim does. Older Windows does not ship it, so - if nothing is found slosh still opens notepad, and says so, rather than - leaving you an empty pane to puzzle over. `EDITOR` and the config's `editor` - are honoured ahead of the search. + because `notepad` is a GUI program: a pane running it draws nothing and looks + broken. Microsoft Edit (`edit`) ships from Windows 11 24H2 and fills a pane + like any other editor; it comes last because it arrives on its own, and so + says nothing about what you want. If nothing is found, slosh still opens + notepad, and says so, rather than leaving an empty pane to puzzle over. + `EDITOR` and the config's `editor` are honoured ahead of the search. - **`--check`, `--dump-config`, layouts, workspaces and shaders** are unaffected: they never touched a pty or a socket. diff --git a/docs/workspaces.md b/docs/workspaces.md index 2dbce4d..134b8b2 100644 --- a/docs/workspaces.md +++ b/docs/workspaces.md @@ -1,40 +1,12 @@ # Workspaces -A **project** is a directory on disk. A **workspace** is the tab it occupies in a -session. Two words rather than one because the two have different lifetimes: the -project outlives every session and is checked into git, the workspace lasts until -you close the tab. +slosh has the concept of **workspaces**. Essentially a workspace is a +pane layout that represents a project. slosh will scan your config's `project_roots` +folder(s) for two kinds of sub folders: ones that have a `slosh.layout` file, and +ones that have a `.git` but no `slosh.layout`. in the latter case our project picker +can still pick it up and help you provision a new `slosh.layout`. -[Finding a pane](panes.md#finding-a-pane) starts from the complaint this answers: -tabs stop being navigation somewhere around six projects. The finder answers -*where is that pane*; this answers the question before it: which of the things you -work on is this tab about, and what does opening one mean. `C-a w`, a name, enter, -and the tab arrives arranged, because the project itself said how. - -## What counts as a project - -A subdirectory of a configured root with one of two markers in it: - -| marker | what it is | -|---|---| -| `slosh.layout` | a *declared* project: it says what it needs open | -| `.git` | an *inferred* one: you work here, but you have not said how | - -Anything else is not a project, and nothing is guessed from what is inside it. - -**`.git` counts because otherwise the list is empty on the day you configure the -feature.** A picker that only knows declared projects shows nothing until you have -written a layout, and there is nowhere to write one from: you would need the -picker to get there. The inferred half is also the invitation: such a project reads -`.git · no layout` in the picker, and `C-a W` is how it stops being one. - -**A directory that is a project is never descended into.** That is what keeps the -scan out of `node_modules`, a vendored checkout or a submodule without a rule about -any of their names: they are under a project, so the walk stops above them. A skip -list is a list of the directories that were fashionable when it was written; this -holds for the ones nobody has invented yet. - -## Where they live +## Configuration options Two settings, both in your [config](config.md): @@ -45,29 +17,7 @@ project_layout "~/.config/slosh/project.layout" `project_roots` takes more than one directory because people have more than one (work in one tree, everything else in another), and `depth` is how many levels below -each root to look, 2 by default, 1 to 8. Two is `~/dev/thing` and -`~/dev/org/thing`, which is where checkouts actually sit. - -**No roots configured and the feature is dormant.** Nothing is scanned, `C-a w` -says which setting is missing rather than opening an empty picker, and `workspaces` -answers `roots: false`, because "you have no projects" and "you never said where -they are" are different facts, and a tool that cannot tell them apart reports the -wrong one. - -`project_layout` is what a project with no file of its own opens as. **Relative -paths in it bind to the project being opened, not to the directory the file lives -in**, deliberately the opposite of the rule for a layout you name yourself, where -a relative `cwd=` is relative to that file ([layouts](layouts.md#the-shape)). The -whole point of one shared layout is that `cwd="."` means *this* project; bound to -itself it would open every project in `~/.config/slosh`. Unset, a project opens -as one pane running your shell in it. - -**Nothing sniffs `package.json` or `Cargo.toml` to guess what to run.** A table -mapping manifests to commands is wrong for somebody the day it ships (the repo -with two package managers, the one whose dev server is behind a make target) and -stale for everybody a year later. `project_layout` is that table with your name on -it, covering the projects you have rather than the ones a heuristic imagined, and a -project that disagrees with it carries its own file. +each root to look, 2 by default, 1 to 8. ## From the keyboard @@ -145,11 +95,9 @@ otherwise: a shell's history and an editor's buffers are not in it. **Over the API, writing over a layout that is already there is refused without `force`; from the keyboard `C-a W` replaces it and the toast says `replaced`.** -That asymmetry is not an oversight in either direction. A key cannot pass a flag, -and the operator pressing it is looking at the tab being written; the file is -committed text, so the diff is the confirmation and the replacement stays -reviewable after the fact. A script has none of that (no witness, no glance at -the screen) so it says so in the request. +The asymmetry is deliberate: the operator pressing the key is looking at the +tab being written, and the file is committed text, so the diff is the +confirmation. A script has no witness, so it says so in the request. `save-workspace` also takes `path`, for a tab that is not a workspace yet: that is how a hand-arranged tab becomes a project's layout without opening it through the @@ -218,9 +166,9 @@ Every one of them is in the bare dispatcher too, so `slosh -s work cmd workspaces` and `slosh -s work cmd open-workspace api` do the same from a shell without quoting JSON ([scripting](scripting.md#the-control-socket)). -`open-workspace` is idempotent, which is the property that makes it safe to call -from a script that does not know whether it ran already: asking twice focuses the -tab rather than building a second one. `suspended:true` opens the layout with every +`open-workspace` is idempotent: asking twice focuses the tab rather than +building a second one, so a script that does not know whether it already ran is +safe. `suspended:true` opens the layout with every pane suspended whatever the file said: the *open ten projects, run zero processes* case, which is a different question from the one the project answered about which of its own panes are expensive. |
