# Editable tags Pardes has three levels of command text: the workspace tag, one tag per column, and each pane's tag. Column commands act on that column and run in its active pane (or its first pane when focus comes from another column); a column with no pane is described under [empty columns](#empty-columns). 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. In a terminal's own tag the word names the shell it runs, `Tty+fish`, tinted with the tag's name colour: `Tty+arg` is one word a tag can hold for `Tty arg`, so clicking it opens another terminal on that shell, as `Tty fish` would. Only a builtin that declares `plus_arg` reads a `+` so; `Tty` is the one, since other arguments (a dump's name) may contain `+`. A command pane's tag reads ` () running` or `exit N` and offers `Kill`. `Repl python` in a terminal's tag binds it as Python's REPL, its id, `python-a`, beside the Tty word: a middle click or the execute key on a `.py` body then types the text into it rather than running it, and several bound ask which. The tag's own words, `Exec ` by name and a command word @`cmd` still run as commands (docs/fs.md). Pane and column command text leave a small gap after their aligned drag grips. GUI pane mode symbols are centered by their visible ink; changing the font or its size refreshes the cached measurements. The column grip has a different color from a pane grip. It stays blank and muted even when its column is active, and lights in its full accent while it is held. Drag it past a neighbour's middle to move the whole column there; dropped short of that, it moves the column's left edge instead, as a border drag would. While it is held, a dashed rail in the grip's accent stands where the column's left edge will land, beside the rule as a border drag's rail does. Only columns between the old and new positions shift. Each column keeps its width, panes and command text. Two panes in a column are resized as acme's windows are, by the grip: drag a pane's grip up or down its own column and its top follows, the pane above taking or giving the rows, either one down to its tag alone (acme's coldragwin keeps a window its tag line); drop it in another column and the pane moves there. In the GUI the 2 px rule between two panes also drags their seam. No row of text is a handle: a pane's last row takes a click like any other, and a terminal, which draws no rule, resizes by the grip. A column's right edge still drags its width. 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. `Edit` is acme's: the rest of the line is sam's command language, run on the pane's body (`Edit ,x/foo/c/bar/` renames every `foo`), from a tag, a pane's `ctl` or `exec`. Addresses are the `addr` file's, `line:col` included; the commands are `x y g v c a i d s p = m t`, `u` alone, and `{ }` with a command per line. All its changes are one undo step, applied only if every command ran; an error says why in acme's words and changes nothing. `p` and `=` print to the directory's `+Errors`. Left out: the file commands `b B D e r w f X Y`, the pipes `< | >`, and `\1`-`\9` in `s`, since mvzr keeps no submatches; acme applies changes that come out of sequence with a warning, pardes refuses the Edit. In `s`, `&` in the replacement is the matched text (`\&` a plain `&`); in `c`, `a` and `i` an `&` is only an `&`, as in sam. A pattern that finds nothing says so with the pattern (`no match for regexp /nomatch/`), and an `s` on an empty dot says `no substitution: dot is empty`. `Undo` and `Redo` are acme's: typed or clicked in a pane's tag, or written to its `ctl`, they step the body back and forward through its edits, as the `u` and `U` keys do. They are not in the default tags. `Del` closes a pane and gives its rows to one neighbor; the rest of the column keeps its heights. A pane with unsaved text is refused once, as acme's Del warns (exec.c del, wind.c winclean): `: Modified (Del again to discard)`, and the same `Del` again, nothing edited since, closes it and throws the text away; `Delcol` refuses a column holding such a pane the same way (exec.c delcol). Each word warns on its own, from a key, a tag, `exec` or a ctl, where the refusal fails the write with EIO. `Del k` (or `DelAbove`) gives them to the nearest expanded pane above, `Del j` (or `DelBelow`) to the one below, each falling back to the other side. Bare `Del` from the keyboard (`SPC d`, or Enter on the word) on a pane with expanded panes both above and below asks on the pane's notice band: `k` or Up gives the rows above, `j` or Down below, and any other key keeps the pane. A click, a 9P write or a startup line never asks; there bare `Del` gives the rows to the nearest document above, as it always has. A collapsed pane is never asked about, and collapsed neighbors are passed over: they only keep a weight for later. A tag is a text like a pane's body: pane tags, column tags and the workspace tag all edit with the body's own normal and insert modes, undo included. A pane's tag may hold more than one line, and a line wider than the pane wraps onto more rows, as acme's tag does: it takes a row per shown line, up to eight, and leaves its body at least one row. A line exactly as wide as the pane stays one row, its caret at the tag's edge past the last character, as acme's tick is (in a terminal, on the last cell). A word the wrap breaks across rows is still one word to a click. A collapsed pane shows only the first row. A pane tag starts expanded, showing all its rows, and can be collapsed to one row, as acme's Tagup does. In the tag's insert mode Up on its first row collapses it and Down on its last row expands it; Alt-Up and Alt-Down do the same in either mode. acme expands or collapses on any arrow key typed in the tag (Up collapses, the others expand); here arrows keep moving the cursor, and only these keys at the tag's edges change its height. The column and workspace tags are one line, as acme's (cols.c:244 gives a column tag one font height): a newline typed, pasted or written into one becomes a space, and a dump that holds a column or workspace tag of several lines, from before, comes back with its lines joined by spaces. The path and a PDF's page at the start of a pane tag are computed, never stored, and read-only. The keyboard reaches them as the mouse does: `0` goes to the line's start, the path's, as in acme, and motions select and yank across the path and the commands. An edit that would change them is refused and leaves the cursor where it was; typing into a file's path instead drafts a new name, as clicking it does. When they grow or shrink (a rename, a PDF's page) the cursor keeps its place in the text after them. Left-click a tag or a header to type into it at the click, in insert mode. A pane tag wraps instead of scrolling sideways; a column or workspace tag reveals the caret horizontally when its text is wider than its column. Esc is normal mode, where everything a body's normal mode does works. There Tab executes the word under the cursor (or an explicit selection), and Enter looks it up in a pane's tag but runs it in a column or workspace tag, whose words are all commands; in insert mode Enter is a new line. Executing gives the keyboard back to the body first, so `Del`, `Kill` and `Restore` never return into a tag that is gone. Pasted text goes to the focused tag, not to the file or embedded shell beneath it. `:` is the one key a tag and a body do not share: in the body's normal mode it focuses the pane's tag in normal mode, and in the tag's normal mode it goes back to the body; in a column or workspace tag it goes back to the active pane. Each pane, column and workspace tag remembers its own cursor during the session; the first `:` into a pane tag starts on its `Save`. A tag's text changing under it (a 9P write, a shorter tag) pulls the cursor back inside it. Moving between tags is the window keys' job, as it is between bodies (`Ctrl-w` or `SPC w` with `h/j/k/l`): they move to the neighbouring pane's body. Up from a pane with nothing above it reaches its column's tag, then the workspace's; Down comes back the same way, and Left and Right walk the column tags. Search (`/`), `s`/`S`, pipe (`|`) and Save's path prompt are not typed into the tag: each gets a line of its own on the pane's notice band, with the body's insert-mode keys. Pressed in a tag, `s`, `S` and `|` answer for the tag's own text, as they do for a body, and a header's go on the active pane's band; `/` searches the body wherever it is pressed, as acme's Look from a tag does. Pane filenames and commands now have a single separator space rather than generated right-alignment padding. Intentionally customized spacing is kept. ## File names Clicking a file pane's name, or typing into it from the tag, starts a draft of it, typed into where it was clicked or typed. Enter or Tab confirms the new buffer name; Escape or leaving the pane 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 `Mode`, which cycles through raw terminal input, normal editor mode, insert mode, and back to terminal input. On files and text output panes, `Mode` cycles between normal and insert mode; it is available as a command but does not appear in their default tags. Images and PDFs keep their normal mode. Executing `Mode` from a tag leaves the tag and advances the parked body mode. Ctrl-B keeps its terminal/editor toggle. Existing custom tags can still use `Togglettymode` for that two-way terminal toggle. Old default terminal tags upgrade to `Mode`; customized command text is preserved. ## Saved workspaces `Dump` and `Restore` preserve customized workspace and column tags, including intentionally empty tags, and columns that hold no pane. 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. The column row is always shown. An old `ColumnTags` line in an init file is ignored, with a message saying so. `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. Unsaved text shows on the pane's grip button, as acme's modbutton does, not in the tag: the tag names the file and nothing more. In a terminal the grip is two cells: the second is `*` while the pane holds unsaved text, and the first is the pane's mode: blank in normal mode, `^` in insert, `$` when the keyboard goes to a terminal's program (tty mode). The `dirty` file and `index`'s flag say the same to a script. ## Empty columns A column can hold no pane, as acme's can: its tag stands over blank space in the theme's `empty_col` colour, white in the acme theme as acme paints it (cols.c:186-188), and the frame's border fill in themes that do not set it. `Newcol` makes an empty column right of the keyboard's and gives its tag the keyboard. Closing a column's last pane (`Del`, `Del k`/`Del j`, a shell exiting, a drag to another column) leaves the column empty where it was, and the keyboard goes to its tag if it was on that pane. Only `Delcol` and `Joincol` take a column away. `Delcol` and `Joincol` from a column's tag act on that column; `Delcol` written to a pane's ctl closes that pane's column. A pane dragged onto an empty column fills it. ## Where new panes go Every new pane goes through one placement, chosen by the `Placement` setting: `acme` (the default) or `pardes`. `Placement pardes` or `Placement acme` sets it, in an init file, a tag or the root ctl; bare `Placement` flips it; `SPC c p` is its leader path, and `Config` reports it. `Placement acme` is acme's makenewwindow (util.c:449-495). The core keeps acme's *active column* (activecol, dat.c:37): the column last typed in (acme.c:487), clicked in with the select button (acme.c:659), dropped into by a grip (acme.c:640), whose tag was given the keyboard (`Newcol`, an emptied column, `Ctrl-w k`), or that was given the last new pane (util.c:467). A Look click moves the keyboard but not the active column, as button 3 does not in acme. A new pane goes into the column a command's tag belongs to when it came from a column tag, else the active column, else the keyboard's pane's, and never into a new column: - an empty column it takes whole (util.c:468-469); - from a tag, or 9P's `pane/new` (acme's `t->w == nil`), it takes the bottom half of the column's last pane (coladd, cols.c:62-65); - from a pane's text (a Look, `Tty`, `Alt-n`, a Grep or Find listing), it goes right under the text of the pane with the most blank rows when that is more than 15 rows, or more than 3 and more than half the biggest pane (util.c:482-486); otherwise it halves the biggest pane, or the asking pane when that is in the column and not much smaller (util.c:487-491); - `New` goes into its own column, the bottom half of its last pane (look.c:921-923); - a command pane or a `+Errors` pane goes to the last column, the bottom half of its last pane (util.c:94-98). `Placement pardes` is what pardes did before: an empty column whose tag asked, or has the keyboard, is filled; a scratch goes right under the pane that asked; a shell under it or the nearest pane with room; a document beside the last one read, or in a column of its own on the left when there is none and the column is at least 200 cells wide; a command pane at the foot of the last column. `BootShell replace` brings back one more placeholder: a document dragged into the left column closes the column's lone shell if nobody has typed into it. `BootShell keep`, the default, never closes a pane for another one. Down from an empty column's tag stays there, and the pane-to-pane keys pass over an empty column; Left and Right from a tag walk every column's tag. One divergence from acme: acme keeps running when its last window closes, every column empty. Pardes quits when the session's last pane closes, as `Delcol` of the last column always has. A key, a prompt or a command in pardes runs in a pane, so a session without one would have nothing to run them in.