// The guide: pardes day to day, the path a newcomer reads once. Edge cases // live in the reference, the pager and the language servers in setup, the // keys on the cheatsheet. #import "style.typ": key, keys, btn, chord, word, tag, addr, file, cmd, doc, pairs, glossary, annotated, clip, mode-box Two clicks carry pardes: #word("Look") (right-click) opens `src/bar.c:12`, and #word("Exec") (middle-click) runs `make`. #annotated("/docs/site/media/themes/orchard.png", (640, 513), alt: "a pardes window: workspace tag, column tag, a file pane, a terminal and a diff", ([the workspace tag: words for the whole session], -22, 11), ([a column's tag], 400, 34), ([a pane's tag: its path, then its words], 560, 58), ([the box: the pane's mode, and the handle to drag it], 8, 58), ([the body: here a file, below it a terminal], 200, 104), ([the scrollbar: how much of the body is in view], 8, 160), ) #glossary("Words you'll see", , [the pane with the keyboard], [where your keys go; one pane at a time], [the session's directory], [where pardes started, or the directory `pardes DIR` named; workspace and column tags run there], [active column], [where the next new pane goes (below)], [command pane], [a terminal that runs one command line and shows its output], [`+` names], [panes pardes makes, named in their directory: `+New` a scratch (text with no file yet), `+Search` a listing of places, `+Pager` paged text, `+Errors` output, `+Unsaved` the panes holding unsaved text], [serial], [a pane's number, never reused: the `3` in `@p3:12` and in 9P paths], [message row], [the line where pardes says what happened, and asks: answer a prompt (a search, #word("Save")'s path) with #key("Enter"), cancel it with #key("Esc")], ) = Modes Each pane keeps its own mode. The box left of its tag shows it. #pairs( [#mode-box(" ") normal], [keys move and select; an edit acts on the selection. File and PDF panes start here, and so does a terminal from #key("Alt-n").], [#mode-box("^") insert], [keys type. #keys("i", "a", "o") and the rest enter it.], [#mode-box("$") raw, terminals only], [keys go to the program. A terminal from #word("Tty"), the shell a bare `pardes` starts with, and a command pane start here.], ) #key("Ctrl-b") switches a terminal between raw and normal. In normal, its text is a page to move over and copy from. #word("Mode") in the tag steps raw, normal, insert. #pairs( [#mode-box(" ") normal], [#key("Esc"): back to the previous pane (#word("Last")), unlike helix. #key("Shift-Esc"): the same.], [#mode-box("^") insert], [#key("Esc"): back to normal. #key("Shift-Esc"): out of insert and back to the previous pane.], [#mode-box("$") raw], [#key("Esc"): to the program, except at a shell prompt with nothing typed on it, where it goes back to the previous pane. #key("Shift-Esc"): always back. Either way the terminal stays raw.], [a PDF], [#key("Esc"): clears the selection and the search highlights. #key("Shift-Esc"): back to the previous pane.], ) #key("Shift-Esc") needs the kitty keyboard protocol or the GUI. Elsewhere it is a plain Esc. The previous pane is the last one you jumped from, else the next pane down the column. #pairs( [#key("Ctrl-w") #key("h")], [the keyboard to the pane on the left; #key("j") below, #key("k") above, #key("l") right], [#keys("Ctrl-o", "Ctrl-i")], [back and forward through the places you jumped to (the jump list)], ) Raw mode sends almost every key to the program. Leave it (#key("Ctrl-b")) before #key("Ctrl-w") or #key("Alt-n"). = The mouse #pairs( btn("B1"), [select; a click puts the cursor there and gives the pane the keyboard. In a tag it starts typing, in insert mode. A double click selects the word; at a line's start or end, the line; just inside a bracket or quote, up to its match.], btn("B2"), [#word("Exec"): a builtin word runs, anything else is a shell line.], btn("B3"), [#word("Look"): open the file, address, directory or URL, else find the word's next place.], chord("B1", "B2"), [cut the selection], chord("B1", "B3"), [paste over it], chord("B1", "B2", "B3"), [copy], [Alt-click (Option)], [#btn("B2"), sweeps too, for one button or a trackpad; in a terminal too], [Super-click (Cmd)], [#btn("B3"); not in a terminal, which never passes Super], [Ctrl-click], [the language server's definition], ) #clip("chords") A program that takes the mouse gets the plain click. #btn("B3") on `src/bar.c:12:5:` in a compiler's error opens `src/bar.c` at line 12, column 5. A click takes the word under it: letters, digits and `. - + / : @ _ ~`, less a trailing `:`. Drag to take exactly what you swept. In normal mode #key("Enter") is #word("Look") and #key("Tab") is #word("Exec"). A builtin's argument: sweep `Find conf` with #btn("B2"), or select `conf`, then #chord("B2", "B1") on `Find`. #key("x") #key("y") then #key("p") copies a line below. Every pane shares the registers. #key("SPC y") and #key("SPC p") use the system clipboard. = Tags #tag("Newcol Joincol Find Grep Help Changelog Tutor Dump Themes Config Debug Exit") #tag("New Tty Find Grep Joincol Delcol") #tag("Save Tty Collapse Del", path: "/home/me/notes.txt") A tag is text with undo. Type `make` into one and #word("Exec") it, or delete the words you never use. Any word runs from any tag: #word("Exit") in a pane's tag quits too. #pairs( [#key(":")], [the keyboard to the tag, on #word("Save") the first time; #key("Tab") runs it, #key(":") comes back], [edit the path, #key("Enter")], [the next #word("Save") writes to the new path], [#word("Collapse")], [folds the pane to its tag], [drag the box], [up or down resizes; onto another column moves the pane], ) = Where commands run and panes go #btn("B2") on `make` runs it with the #word("Shell") setting's `-c`. Where it runs depends on where you clicked: // TODO(clip: where-commands-run) #pairs( [a terminal's text or tag, at a prompt with nothing typed], [typed into that shell, in its current directory], [any other pane's text or tag], [a command pane in that pane's directory, in the last column], [a column's tag], [a command pane in the session's directory, in that column], [the workspace tag], [a command pane in the session's directory, in the last column], ) A file's text and tag run in its directory: `make` from `README` at the project root is right, from `src/main.c` it is not. The keyboard stays where it was. The command pane's tag ends in `running`, then `exit N`: #tag("Kill Save Collapse Del", path: "/home/me/src (make) exit 0") Click into the command pane: #key("n") selects the next `file:line`, #key("Enter") opens it, and #key("n") from there goes on to the next error. A finished command pane is in normal mode, so #key("x") #key("y") copy from it at once. The next command for that directory reuses it. #word("Kill") `make` stops the commands pardes started with `make`. #word("Save") or #word("Del") in a column tag acts on that column's pane with the keyboard, else its first. Every other new pane goes into the *active column*: where you last typed or left-clicked, or where the last new pane went. The new pane takes the keyboard. A listing is the exception: it opens below the pane that asked, which keeps the keyboard, so #keys("n", "N") walk the listing. #btn("B3") on a file open in another column jumps there, but the next new pane still lands in the old column. #word("Placement") `pardes` picks other rules (#doc("reference", section: "placement")). To open beside: #word("Newcol"), then #word("Look") a file name typed in its tag opens it there; #key("Alt-c") moves a pane into a new column. // TODO(clip: columns) Closing a column's last pane leaves it empty; #word("Delcol") and #word("Joincol") take columns away. Closing the session's last pane quits pardes. = Look #pairs( addr("notes.txt"), [opens it, or goes to the pane already showing it], addr("notes.txt:12"), [line 12], addr("notes.txt:/TODO/"), [the next match of `TODO`], addr("src/"), [`ls` typed into a terminal idle there, else a new terminal there], addr("https://ziglang.org"), [the browser], ) #key("Enter") does the same from the keyboard; the other address forms are on the cheatsheet. A relative path is found in the directory of the pane the #word("Look") came from, then of each pane on the jump list, most recent first. #pairs( [#key("/") `TODO` #key("Enter")], [a `+Search` of the lines holding `TODO`, the cursor on the first; #keys("n", "N") step through], [#word("Find") `conf`], [a `+Search` of the files below the pane's directory with `conf` in their names], [#word("Grep") `TODO`], [a `+Search` of the lines holding `TODO`, literally, under every pane's directory], ) // TODO(clip: search) = Unsaved panes #word("Del") on a pane with unsaved text, its box filled (#mode-box(" ", unsaved: true); a `*` in a terminal), refuses once, saying `1 unsaved pane — Del again to discard`, and lists the pane in `+Unsaved`; #word("Del") again discards it. #word("Exit") (or #key("SPC q")), #word("Restore") and #word("Delcol") refuse once the same way. #key("SPC d") between two panes also asks which takes the rows: #key("k") above, #key("j") below. = Terminals #tag("Tty+bash Save Mode Filter Collapse Del", path: "/home/me/src") - #word("Tty") opens a terminal in the pane's directory, #key("Alt-n") one in the session's directory; #word("Tty+bash") picks the shell. - #word("Del") closes a terminal and its shell at once, running or not, and a shell that exits closes its pane. - #word("Save") writes the scrollback to a path it asks for. - #word("Filter") maps the program's colours through the theme. - #word("Petscii") draws a program's images as glyph art instead of pixels. - In raw mode Ctrl-V types what you yanked, Ctrl-Shift-V the clipboard. - A program that tracks the mouse gets #btn("B1") and the wheel; #btn("B2") and #btn("B3") stay pardes's. Hold Shift to swap. - #word("Repl") `python` in its tag makes #btn("B2") on a `.py` pane send the text to that REPL. - `git log` and `man` open in a `+Pager` pane (#doc("setup", section: "pager")). = Reviewing diffs `git diff` run as a command, or a `.diff` or `.patch` opened, is drawn as a diff, each hunk in its file's language. #btn("B3") on: #pairs( [`diff --git`, `---`, `+++`], [the file], [`@@ -3,7 +3,8 @@`], [the hunk's first new line], [a line's `+`, `-` or space], [that line in the new file], ) = `pardes FILE` and `--wait` In a pane's shell: ``` pardes notes.txt open it here and return at once (acme's B) pardes --wait notes.txt return when that pane closes (acme's E) ``` A file not there yet opens empty, and #word("Save") creates it. `--wait` makes pardes an `EDITOR` (#doc("setup", section: "editor-setup")); refusals and `--nested` are in the reference. = Keys #pairs( [#key("w") #key("d")], [select a word, delete it: motions select, edits act on the selection], [#key("x"), #key("v"), #key(";")], [select the line; extend; collapse to the cursor], [#key("s")], [a cursor per regex match; every edit acts at each], [#key("/"), #keys("n", "N")], [substring search; step through everything #word("Look") would open, across panes], [#key("g l")], [line end], [`12G`], [line 12; a bare #key("G") does nothing], [#key("SPC ?")], [#word("Help"): every builtin, with its leader path and keys; `SPC w ?` only the paths under `SPC w`; #word("Tutor") (#key("SPC h t")) practises them], [#keys("g d", "g r"), `SPC l`], [the language keys, once a server is installed (#doc("setup", section: "language-servers"))], ) The keys are helix's, and helix's #link("https://docs.helix-editor.com/keymap.html")[keymap] is their full reference. Where pardes differs (#key("Esc") leaving the pane, the #key("SPC") paths, #key("Ctrl-w"), #key("Ctrl-b")), this guide and the cheatsheet (#doc("cheatsheet")) say so. = Sessions ``` pardes --detach=work & a session with no screen of its own pardes --attach=work show it here ``` The session owns the panes, shells and files; frontends come and go, and all of them see the same screen. #word("Attach") `work` (#key("SPC s a")) switches this window to it; #word("Detach") (#key("SPC s D")) leaves it running. = Config #word("Config") (#key("SPC f c")) opens the startup file, `~/.config/pardes/init`: one builtin a line, run at start, `#` a comment. ``` Theme atelier Shell zsh # Placement acme is the default; Placement pardes picks the other rules ``` #word("DumpConfig") opens every live setting as the line that sets it. #word("Dump") saves the workspace and #word("Restore") brings it back (what a dump keeps is in the reference). Keys are compile-time, in `src/config.zig`. = Questions / Why not helix and tmux, or acme?: helix and tmux edit and run shells well, but their text is inert. acme makes text the interface, without modal keys, a terminal emulator or PDFs. pardes puts text as the interface, helix's keys, terminals, PDFs and a scriptable session in one program. / Does it run inside tmux?: Yes, as in any terminal. Where tmux does not pass kitty's protocols, #key("Shift-Esc") is a plain Esc and images draw as glyph art. / Does my helix config carry over?: No. The keys are compiled in (`src/config.zig`); `~/.config/helix` is not read. / How do I quit?: #key("SPC q"), or #word("Exit") in any tag. / What does "pardes" mean?: The name of the four levels of reading a text in rabbinical exegesis (#link("https://en.wikipedia.org/wiki/Pardes_(exegesis)")[Wikipedia]).