# Tags and columns Pardes has three levels of command text: the workspace tag, a tag per column, and each pane's tag. A column tag's words act on that column and run in its active pane (its first pane when focus comes from another column). A command or `Tty` run from the workspace or a column tag starts in the session's directory (where pardes started), as acme's row and column tags have none of their own; one run from a pane's tag or text starts in that pane's directory. Over 9P the tags are `/tag`, `/col//tag` and `/pane//tag` ([fs.md](fs.md#columns-and-tags)). ## Default words - Workspace: `Newcol Joincol Find Grep Help Changelog Tutor Dump Themes Config Debug Exit`. - Column: `New Tty Find Grep Joincol Delcol`. - File pane: `Save Tty Collapse Del`; a source file with a grammar adds `TreeContext`, a result list `LocationsConfig`. PDF: `manual.pdf [1/12] Tty PdfSections PdfTint Collapse Del`. - Terminal: `Tty+bash Save Mode Filter Collapse Del`. `Tty+bash` is one word for `Tty bash`, opening another terminal on that shell (only `Tty` reads a `+` so). `Mode` cycles raw terminal input, normal mode and insert mode. - Command pane: ` () running`, then `exit N`, and `Kill`. `Undo`, `Redo` and `Mode` (on files) work typed or clicked though they are not in the default tags. Customized tags keep their text. A tag word runs as acme's does, in the pane's directory with no file named: `wc` alone waits on stdin. There is no `$%`; name the file (`wc notes.txt`), or select the name and middle-click `wc`, which takes a held selection as its argument. A program that tracks the mouse gets it; hold Shift for pardes's own. In raw terminal input, a program that asked for the mouse (xterm's 1000, 1002 or 1003: htop, vim with `mouse=a`, codex) gets the clicks, drags and wheel over its grid, reported in the format it chose and with its modifiers. Shift-click selects, executes and looks as ever, and Shift-wheel scrolls pardes's scrollback. A full-screen program that does not track the mouse gets the wheel as arrow keys (xterm's alternate scroll, 1007). Tags, grips and gutters stay pardes's. `Repl python` in a terminal's tag binds it as that language's REPL ([fs.md](fs.md#repls)). `Repl` takes the languages a code fence names: ada, bash, c, c_sharp, clojure, cpp, css, elixir, erlang, fortran, go, haskell, html, java, javascript, json, kotlin, ocaml, markdown, pascal, php, powershell, python, ruby, rust, scala, typst, zig, and aliases such as `py` and `sh`. ## Pane builtins `Collapse` folds a pane to its tagline, giving its rows to the nearest expanded pane above (else below); again, it takes them back. Its text and process are kept. `Del` closes a pane, giving its rows to one neighbour. `Del k` (`DelAbove`) gives them to the nearest expanded pane above, `Del j` (`DelBelow`) below, each falling back to the other side. Bare `Del` from the keyboard (`SPC d`), with expanded panes above and below, asks on the notice band (`k`/Up above, `j`/Down below, any other key keeps the pane); a click, a 9P write or an `init` line never asks and gives the rows above. A pane with unsaved text is refused once: a notice `1 unsaved pane — Del again to discard`, the pane listed in `+Unsaved`, and over 9P the write fails (EIO). The same `Del` again, nothing edited since, discards. `Delcol` refuses a column holding such a pane the same way, without opening `+Unsaved` or moving focus. `Exit` and `Restore` do the same over the whole session. A `+New` scratch under 100 bytes is never asked about. `Edit` runs sam's command language on the body ([fs.md](fs.md#edit)). `Undo` and `Redo` step the body through its last 256 edits, as `u` and `U`. Unsaved text shows on the pane's grip, as acme's modbutton, not in the tag. In a terminal the grip is two cells: the pane's mode (blank normal, `^` insert, `$` tty mode), then `*` while unsaved. ## Reviewing diffs Open a `.diff` or `.patch` file, or run `git diff` (or `git show`, `diff -u old new`) as a command from any tag: once the command has finished, output that starts as a diff does (a `diff --git` line, or a `--- ` line with `+++ ` and `@@` under it) is shown as one. Each hunk's code is coloured in the language of the file its section names (`+++ b/`, or `--- a/` for a deleted file), its old side (context and removed lines) and new side (context and added lines) each parsed as one text, so a string or comment across lines colours as it does in the file. Added and removed rows are tinted to the pane's edge, their `+`/`-` in the tint's hue (the theme's ANSI green and red where it has them); a file in no language pardes knows keeps the plain line colours. Only the hunks in view are parsed, a few dozen lines at a time, each once. Then right-click to jump; the look's hover shows what the click takes. On a `diff --git`, `---` or `+++` line, anywhere on it, markers included, that is the whole line, and it opens its file: `diff --git a/x b/y` and `+++` the new one, `---` the old one unless the `+++` under it names another (a rename, a new file, `diff -u old/x new/x`), since the old name is the one likely gone. On a `@@ -a,b +c,d @@` line it is the whole line again, and opens the new file at line c. On a hunk line, the `+`, `-` or space in its first column takes the whole line and opens the new file at that line; for a removed line, at the new line now standing where it was (the one after it, or the hunk's last when it went from the end of the file). The code after it is words, looked at as ever. A path is the repository's name for the file. In a git section (one with a `diff --git` line) git's side prefix is dropped when both paths on that line carry one, different ones: `a/`/`b/`, or with `diff.mnemonicPrefix` `c/`, `i/`, `w/`, `o/`. `--no-prefix` writes none, so there `a/x a/x` is a real directory `a`, kept. A plain `diff -u`'s names are used as written, past the timestamp. The file is looked for from the repository's root (pardes walks up from the diff's directory, a command pane's own, to a `.git` or `.jj`), else from that directory. A file that is not here (a branch not checked out) opens nothing and says so by that name: `Look: src/x.zig: no such file here`, or `deleted by this diff` for a deleted one. A 9P `look` of a whole line of the diff does the same. ## Editing tags A tag is text like a body, with the body's normal and insert modes and undo. A pane tag may hold several lines and wraps, taking a row per shown line up to eight and leaving its body at least one; a collapsed pane shows the first. Up on its first row in insert mode (or Alt-Up in either mode) folds a tag to one row, Down on its last (Alt-Down) unfolds it. Column and workspace tags are one line: a newline typed, pasted or written into one becomes a space. The path (and a PDF's page) at the start of a pane tag is computed and read-only; `0` goes to its start, and motions select and yank across it. Typing into a file's path, or clicking it, starts a draft of a new name: Enter or Tab confirms it, Escape or leaving the pane cancels. Confirming changes the buffer's save target and marks it unsaved; nothing on disk is renamed until `Save`. A pane-tag command confirms a valid draft first. Left-click a tag to type at the click, in insert mode. Esc is normal mode: there Tab executes the word under the cursor (or the selection); Enter looks it up in a pane's tag and runs it in a column or workspace tag. Executing gives the keyboard back to the body first. Paste goes to the focused tag. `:` in a body's normal mode focuses its tag (the first time, on `Save`); `:` in a tag goes back. The window keys (`Ctrl-w`, `SPC w` with `h/j/k/l`) move between panes; up from the top pane reaches its column's tag, then the workspace's, and Left/Right walk the column tags. Search, `s`/`S`, pipe and Save's path prompt get a line on the pane's notice band; in a tag `s`, `S` and `|` act on the tag's own text, while `/` searches the body. ## Moving and resizing Drag a pane's grip up or down its column and its top follows, the pane above giving or taking rows, down to its tag alone; drop it in another column and it moves there. In the GUI the 2 px rule between panes drags too. A column's right edge drags its width. Drag a column's grip past a neighbour's middle to move the whole column there; short of that it moves the column's left edge. A terminal keeps its tag and 2 body rows: no drag, squeeze or smaller window takes it below that, and `pty/ctl`'s `winsize` gives a pty 2 rows at least. A text pane can be dragged down to its tag. ## 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. `Newcol` makes one right of the keyboard's and gives its tag the keyboard. Closing a column's last pane leaves the column empty, the keyboard on its tag. Only `Delcol` and `Joincol` take a column away; `Joincol` keeps the right column's tag, its panes below. A pane dragged onto an empty column fills it. `Delcol` of the last column leaves the workspace tag alone; `Newcol` or `New` starts again. Unlike acme, pardes quits when the session's last pane closes. ## Where new panes go Every new pane goes through one placement, chosen by `Placement acme` (the default) or `Placement pardes` (bare flips it; `SPC c p`). No placement leaves a pane shorter than its tag and 2 body rows. Where the chosen place has not that room, the column's tallest pane is halved; where no one pane can give it but the column holds every pane's minimum with the new one's, the rows are shared out again; otherwise the pane is refused, `no space for a pane in that column: each keeps its tag and 2 rows` (ENOSPC over 9P). A pane alone in its column always fits. `Placement acme` is acme's makenewwindow. The active column is the one last typed or clicked in, dropped into, whose tag was given the keyboard, or that was given the last new pane; a Look moves the keyboard, not the active column. A new pane goes into the column whose tag the command came from, else the active column, never into a new column: - an empty column it takes whole; - from a tag, or 9P's `pane/new`, it takes the bottom half of the column's last pane; - from a pane's text (a Look, `Tty`, `Alt-n`, a Grep or Find listing), it goes 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; otherwise it halves the biggest pane, or the asking pane when that is in the column and not much smaller; - `New` goes to the bottom half of its own column's last pane; - a command pane or `+Errors` pane goes to the last column's last pane (a command from a column's tag to that column, reusing a finished command pane only there). With no room anywhere, `+Errors` text is logged as `msg` records. `Placement pardes`: an empty column whose tag asked, or has the keyboard, is filled; a scratch goes 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. ## Saved workspaces `Dump` and `Restore` keep workspace and column tags (empty ones too) and empty columns ([config.md](config.md#dumps)). The column row stays above the panes with `Tagbottom` on; on screens under three rows it is left out.