diff --git a/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Pane.kt b/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Pane.kt index 2b9de3952..8fbcf3114 100644 --- a/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Pane.kt +++ b/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Pane.kt @@ -22,6 +22,93 @@ import io.github.libtmux.Pane as JavaPane * Holds the Java handle privately, so a member here always wins over a same-named catalog-generated * extension in `PaneOperations.kt`. [Companion] hosts the generated query field namespace * (`Pane.command`, `Pane.active`, ...). + * + * A property or a plain function here reads the capture this handle came from and issues no command. + * Every `suspend` function asks tmux now, dispatched through the [Server]'s policy, except the waits, + * which run on their own dispatcher. + * + * # What is on here + * + * The members fall into a few groups: + * + * **Reading the capture.** [id], [index], [active], [currentCommand], [floating], [size], [position], + * [edges], [title], [currentPath] and [pid] read what this capture stored about the pane, and + * [window] and [server] are what it sits in. The id is stable and the index is state, since panes + * renumber as neighbours come and go. [floating] is null when the running tmux cannot say, which + * before 3.7 is always, and [pid] is null when tmux reported no process. [currentPath] throws when + * this JVM cannot represent the directory's name. + * + * [id], [index], [active], [currentCommand], [floating], [size], [position], [edges], [title], + * [currentPath], [pid], [window], [server] and [asJava] + * + * **Sending input.** [send][Pane.send] types keys without pressing Enter and + * [sendLine][Pane.sendLine] presses it, which is how a command gets run. [sendKeys][Pane.sendKeys] + * resolves each entry through tmux's key table and types an unknown name as text; + * [sendLiteral][Pane.sendLiteral] types every entry as the characters it spells, so `C-c` is three + * characters. [paste][Pane.paste] delivers text as one block through a private buffer that is + * removed afterwards, and it throws for text containing NUL and before tmux 3.4. + * [noteTyped][Pane.noteTyped] tells a later wait about text that reached the pane without passing + * through this handle. + * + * [send][Pane.send], [sendLine][Pane.sendLine], [sendKeys][Pane.sendKeys], + * [sendLiteral][Pane.sendLiteral], [paste][Pane.paste], [pasteBuffer][Pane.pasteBuffer] and + * [noteTyped][Pane.noteTyped] + * + * **Reading output.** [capture][Pane.capture] returns the visible content, one element per line, read + * from tmux now rather than from the capture. Give it a `CaptureSpec` to read part of the history; it + * throws when the spec asks for something this server does not have. [pipeTo][Pane.pipeTo] sends + * everything the pane prints to a shell command until [stopPiping][Pane.stopPiping], and + * [clearHistory][Pane.clearHistory] discards the scrollback. + * + * [capture][Pane.capture], [pipeTo][Pane.pipeTo], [stopPiping][Pane.stopPiping] and + * [clearHistory][Pane.clearHistory] + * + * **Running and waiting.** [run] runs a shell command to its end and answers with its exit status and + * output, and throws when the pane is not running a POSIX shell. Reach for it first when the command + * is yours. When it is not, [awaitText] and [await] poll the screen or the pane's state on a timer + * and answer with why they ended; a pane killed mid-wait ends [awaitText] as `TextOutcome.PANE_GONE` + * rather than an exception. Cancelling the coroutine interrupts a wait and is not a timeout. + * [dead][Pane.dead] reads fresh whether the pane's process has exited, and throws when the pane is + * gone from a server that still answers. + * + * [run], [awaitText], [await] and [dead][Pane.dead] + * + * **Splitting and arranging.** [split][Pane.split] divides this pane in half, or as a `SplitSpec` + * describes, and returns the pane that appeared. [breakOut][Pane.breakOut] moves the pane into a + * window of its own, [joinTo][Pane.joinTo] into another window, and [swapWith][Pane.swapWith] swaps + * it with another pane. [resize][Pane.resize] grows it by cells in one direction, + * [resizeTo][Pane.resizeTo] sets exact dimensions, and [select][Pane.select] makes it the active + * pane. An unnamed [breakOut][Pane.breakOut] throws on exact tmux 3.7, which a named break or 3.7a + * avoids. + * + * [split][Pane.split], [breakOut][Pane.breakOut], [joinTo][Pane.joinTo], [swapWith][Pane.swapWith], + * [resize][Pane.resize], [resizeTo][Pane.resizeTo] and [select][Pane.select] + * + * **Modes.** [copyMode][Pane.copyMode] puts the pane into copy mode, [mode][Pane.mode] reads live + * which mode it is in, null when it is showing its program, and [exitMode][Pane.exitMode] leaves + * whichever mode it is in. + * + * [copyMode][Pane.copyMode], [mode][Pane.mode] and [exitMode][Pane.exitMode] + * + * **Changing the pane.** [retitle][Pane.retitle] returns a replacement capture, because this handle + * keeps its original state. [respawn][Pane.respawn] kills what runs here and starts the pane's + * default command or one you give, [respawnIn][Pane.respawnIn] does so in a directory, and + * [kill][Pane.kill] closes the pane. + * + * [retitle][Pane.retitle], [respawn][Pane.respawn], [respawnIn][Pane.respawnIn] and + * [kill][Pane.kill] + * + * **Options and hooks.** [options] and [hooks] reach what is set on this pane alone. + * + * [options] and [hooks] + * + * **Formats and refreshing.** [expand][Pane.expand] expands a tmux format, and + * [variables][Pane.variables] reads several named variables, in this pane's context. + * [refresh][Pane.refresh] takes a new capture to see the pane as it is now. It leaves this handle + * unchanged and returns the new one, and throws if the pane is gone from a server that still + * answers. + * + * [expand][Pane.expand], [variables][Pane.variables] and [refresh][Pane.refresh] */ public class Pane internal constructor(internal val java: JavaPane, public val server: Server) { diff --git a/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Session.kt b/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Session.kt index 4e4ef8532..0a6e86ea5 100644 --- a/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Session.kt +++ b/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Session.kt @@ -9,6 +9,54 @@ import io.github.libtmux.Session as JavaSession * Holds the Java handle privately, so a member here always wins over a same-named catalog-generated * extension in `SessionOperations.kt`. [Companion] hosts the generated query field namespace * (`Session.name`, `Session.attached`, ...). + * + * A property or a plain function here reads the capture this handle came from and issues no command. + * Every `suspend` extension asks tmux now, dispatched through the [Server]'s policy. + * + * # What is on here + * + * The members fall into a few groups: + * + * **Reading the capture.** [id], [name] and [attached] read what this capture stored about the + * session, and [server] is the [Server] it lives on. The id is stable, the name is state a user may + * change at any time, and a rename or an attach after the capture does not show in it. + * + * [id], [name], [attached], [server] and [asJava] + * + * **Windows and panes.** [windows] lists the session's windows in tmux's order, and [activeWindow] + * and [activePane] are the window tmux had active and the active pane of that window, each null when + * the capture holds none. All three are pure reads and issue no command. [selectWindow][Session.selectWindow] + * makes a window the active one, [nextWindow][Session.nextWindow] and + * [previousWindow][Session.previousWindow] step to a neighbour with wrap-around, and + * [lastWindow][Session.lastWindow] goes back to the one that was active before. + * + * [windows], [activeWindow], [activePane], [selectWindow][Session.selectWindow], + * [nextWindow][Session.nextWindow], [previousWindow][Session.previousWindow] and + * [lastWindow][Session.lastWindow] + * + * **Changing the session.** [newWindow][Session.newWindow] creates a window from a name or a + * `WindowSpec` and returns the window tmux made. [rename][Session.rename] returns a replacement + * capture, because this handle keeps its original state. [setHistoryLimit][Session.setHistoryLimit] + * sets the scrollback retained by panes created in this session afterwards. + * [detachClients][Session.detachClients] leaves the session running, and [kill][Session.kill] takes + * every window with it. + * + * [newWindow][Session.newWindow], [rename][Session.rename], [setHistoryLimit][Session.setHistoryLimit], + * [detachClients][Session.detachClients] and [kill][Session.kill] + * + * **Options, environment, and hooks.** These reach what is set on this session alone: its own + * options, its own environment, which a process started in it is given on top of the server's, and + * its own hooks. The [Server] holds the global ones, which a session inherits. Each returns a + * wrapper whose own operations are `suspend`. + * + * [options], [environment] and [hooks] + * + * **Formats and refreshing.** [expand][Session.expand] expands a tmux format in this session's + * context, and [refresh][Session.refresh] takes a new capture to see the session as it is now. It + * leaves this handle unchanged and returns the new one, and throws if the session is gone from a + * server that still answers. + * + * [expand][Session.expand] and [refresh][Session.refresh] */ public class Session internal constructor(internal val java: JavaSession, public val server: Server) { diff --git a/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Window.kt b/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Window.kt index 566b9cd67..9e978dcdf 100644 --- a/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Window.kt +++ b/libtmux-kotlin/src/main/kotlin/io/github/libtmux/kotlin/Window.kt @@ -12,6 +12,72 @@ import io.github.libtmux.Window as JavaWindow * * Holds the Java handle privately, so a member here always wins over a same-named catalog-generated * extension in `WindowOperations.kt`. [Companion] hosts the generated query field namespace. + * + * A property or a plain function here reads the capture this handle came from and issues no command. + * Every `suspend` extension asks tmux now, dispatched through the [Server]'s policy. + * + * # What is on here + * + * The members fall into a few groups: + * + * **Reading the capture.** [id], [index], [context], [name], [active], [linked], [size] and [layout] + * read what this capture stored about the window, and [server] and [session] are the [Server] and + * [Session] it sits in. The id names the underlying window and the index names this link, so a window + * linked into two sessions has one id and two handles. A rename or a resize after the capture does + * not show in it. + * + * [id], [index], [context], [name], [active], [linked], [size], [layout], [server], [session] and + * [asJava] + * + * **Panes.** [panes] lists this link's panes in tmux's order and [activePane] is the one tmux had + * active, null when the capture holds none; both are pure reads. [split][Window.split] divides the + * active pane in half, or as a `SplitSpec` describes, and returns the pane that appeared. It throws + * when the spec asks for something this server does not have. + * + * [panes], [activePane] and [split][Window.split] + * + * **Layout and size.** [selectLayout][Window.selectLayout] rearranges the panes into one of tmux's + * built-in layouts, [nextLayout][Window.nextLayout] and [previousLayout][Window.previousLayout] step + * to a neighbour, and [rotate][Window.rotate] rotates the panes. Read the arrangement from [layout] + * and hand it back to [applyLayout][Window.applyLayout], which checks a string before tmux sees it. + * [resizeTo][Window.resizeTo] takes terminal cells. [synchronizePanes][Window.synchronizePanes] + * copies input typed into one pane into every pane of the window until + * [stopSynchronizingPanes][Window.stopSynchronizingPanes]. + * + * [selectLayout][Window.selectLayout], [nextLayout][Window.nextLayout], + * [previousLayout][Window.previousLayout], [applyLayout][Window.applyLayout], + * [rotate][Window.rotate], [resizeTo][Window.resizeTo], + * [synchronizePanes][Window.synchronizePanes] and + * [stopSynchronizingPanes][Window.stopSynchronizingPanes] + * + * **Moving and linking.** [select][Window.select] makes the window the active one in its session. + * [linkTo][Window.linkTo] links it into another session so one window sits in both, + * [moveTo][Window.moveTo] moves it to another session or to an exact index there, and + * [unlink][Window.unlink] removes one link and throws when it is the window's only one, which tmux + * refuses to remove. + * + * [select][Window.select], [linkTo][Window.linkTo], [moveTo][Window.moveTo] and + * [unlink][Window.unlink] + * + * **Changing the window.** [rename][Window.rename] returns a replacement capture, because this handle + * keeps its original state. [respawn][Window.respawn] kills what is running in the window and starts + * it again, [displayPopup][Window.displayPopup] shows a popup over it and needs an attached client, + * and [kill][Window.kill] closes it. + * + * [rename][Window.rename], [respawn][Window.respawn], [displayPopup][Window.displayPopup] and + * [kill][Window.kill] + * + * **Options and hooks.** [options] and [hooks] reach what is set on this window alone, and every link + * to the window shares them. + * + * [options] and [hooks] + * + * **Formats and refreshing.** [expand][Window.expand] expands a tmux format in this window's + * context, and [refresh][Window.refresh] takes a new capture to see the window as it is now. It + * leaves this handle unchanged and returns the new one, and throws if the window is no longer linked + * here, from a server that still answers. + * + * [expand][Window.expand] and [refresh][Window.refresh] */ public class Window internal constructor(internal val java: JavaWindow, public val server: Server) { diff --git a/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Pane.scala b/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Pane.scala index 9a89e3c78..e95ac475a 100644 --- a/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Pane.scala +++ b/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Pane.scala @@ -9,6 +9,104 @@ import scala.jdk.DurationConverters._ * identifies the physical pane; every operation beyond that is an extension, * generated from the operation catalog or handwritten where the catalog marks * it `WAIT`, `STREAM` or `LIFECYCLE`. + * + * A pure read of the capture issues no command; every other operation asks tmux + * now, blocking the calling thread. + * + * # What is on here + * + * The operations fall into a few groups: + * + * **Reading the capture.** [[Pane.id]], [[Pane.index]], [[Pane.active]], + * [[Pane.currentCommand]], [[Pane.floating]], [[Pane.size]], [[Pane.position]], + * [[Pane.edges]], [[Pane.title]], [[Pane.currentPath]], + * [[Pane.currentPathText]] and [[Pane.pid]] read what this capture stored about + * the pane, and [[Pane.window]] and [[Pane.server]] are what it sits in. The id + * is stable and the index is state, since panes renumber as neighbours come and + * go. [[Pane.floating]] is empty when the running tmux cannot say, which before + * 3.7 is always, and [[Pane.pid]] is empty when tmux reported no process. + * [[Pane.currentPath]] throws when this JVM cannot represent the directory's + * name; [[Pane.currentPathText]] is what tmux reported and never throws. + * + * [[Pane.info]], [[Pane.id]], [[Pane.index]], [[Pane.active]], + * [[Pane.currentCommand]], [[Pane.floating]], [[Pane.size]], [[Pane.position]], + * [[Pane.edges]], [[Pane.title]], [[Pane.currentPath]], + * [[Pane.currentPathText]], [[Pane.pid]], [[Pane.window]], [[Pane.server]] and + * [[Pane.asJava]] + * + * **Sending input.** [[Pane.send]] types keys without pressing Enter and + * [[Pane.sendLine]] presses it, which is how a command gets run. + * [[Pane.sendKeys]] resolves each entry through tmux's key table and types an + * unknown name as text; [[Pane.sendLiteral]] types every entry as the + * characters it spells, so `C-c` is three characters. [[Pane.paste]] delivers + * text as one block through a private buffer that is removed afterwards, and it + * throws for text containing NUL and before tmux 3.4. [[Pane.noteTyped]] tells + * a later wait about text that reached the pane without passing through this + * handle. + * + * [[Pane.send]], [[Pane.sendLine]], [[Pane.sendKeys]], [[Pane.sendLiteral]], + * [[Pane.paste]], [[Pane.pasteBuffer]] and [[Pane.noteTyped]] + * + * **Reading output.** [[Pane.capture]] returns the visible content as a + * `Vector` with one element per line, read from tmux now rather than from the + * capture. Give it a callback on a builder or a `CaptureSpec` to read part of + * the history; it throws when the spec asks for something this server does not + * have. [[Pane.pipeTo]] sends everything the pane prints to a shell command + * until [[Pane.stopPiping]], and [[Pane.clearHistory]] discards the scrollback. + * + * [[Pane.capture]], [[Pane.pipeTo]], [[Pane.stopPiping]] and + * [[Pane.clearHistory]] + * + * **Running and waiting.** [[Pane.run]] runs a shell command to its end and + * answers with its exit status and output, and throws when the pane is not + * running a POSIX shell. Reach for it first when the command is yours. When it + * is not, [[Pane.awaitText]] and [[Pane.await]] poll the screen or the pane's + * state on a timer and answer with why they ended; a pane killed mid-wait ends + * [[Pane.awaitText]] as `TextOutcome.PANE_GONE` rather than an exception. Each + * wait blocks its thread, and interrupting the thread cancels it with + * `InterruptedException`. [[Pane.dead]] reads fresh whether the pane's process + * has exited, and throws when the pane is gone from a server that still + * answers. + * + * [[Pane.run]], [[Pane.awaitText]], [[Pane.await]] and [[Pane.dead]] + * + * **Splitting and arranging.** [[Pane.split]] divides this pane in half, from a + * callback on a builder or a `SplitSpec`, and returns the pane that appeared. + * [[Pane.breakOut]] moves the pane into a window of its own, [[Pane.joinTo]] + * into another window, and [[Pane.swapWith]] swaps it with another pane. + * [[Pane.resize]] grows it by cells in one direction, [[Pane.resizeTo]] sets + * exact dimensions, and [[Pane.select]] makes it the active pane. An unnamed + * [[Pane.breakOut]] throws on exact tmux 3.7, which a named break or 3.7a + * avoids. + * + * [[Pane.split]], [[Pane.breakOut]], [[Pane.joinTo]], [[Pane.swapWith]], + * [[Pane.resize]], [[Pane.resizeTo]] and [[Pane.select]] + * + * **Modes.** [[Pane.copyMode]] puts the pane into copy mode, [[Pane.mode]] + * reads live which mode it is in, empty when it is showing its program, and + * [[Pane.exitMode]] leaves whichever mode it is in. + * + * [[Pane.copyMode]], [[Pane.mode]] and [[Pane.exitMode]] + * + * **Changing the pane.** [[Pane.retitle]] returns a replacement capture, + * because this handle keeps its original state. [[Pane.respawn]] kills what + * runs here and starts the pane's default command or one you give, + * [[Pane.respawnIn]] does so in a directory, and [[Pane.kill]] closes the pane. + * + * [[Pane.retitle]], [[Pane.respawn]], [[Pane.respawnIn]] and [[Pane.kill]] + * + * **Options and hooks.** [[Pane.options]] and [[Pane.hooks]] reach what is set + * on this pane alone. + * + * [[Pane.options]] and [[Pane.hooks]] + * + * **Formats and refreshing.** [[Pane.expand]] expands a tmux format, and + * [[Pane.variables]] reads several named variables, in this pane's context. + * [[Pane.refresh]] takes a new capture to see the pane as it is now. It leaves + * this handle unchanged and returns the new one, and throws if the pane is gone + * from a server that still answers. + * + * [[Pane.expand]], [[Pane.variables]] and [[Pane.refresh]] */ opaque type Pane = JavaPane diff --git a/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Session.scala b/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Session.scala index 26e7899dd..7ec9c1911 100644 --- a/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Session.scala +++ b/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Session.scala @@ -6,6 +6,59 @@ import io.github.libtmux.scaladsl.query.Expr /** A captured session, opaque over the Java handle; every operation beyond * equality is an extension, generated from the operation catalog or * handwritten where the catalog marks it `WAIT`, `STREAM` or `LIFECYCLE`. + * + * A pure read of the capture issues no command; every other operation asks tmux + * now, blocking the calling thread. + * + * # What is on here + * + * The operations fall into a few groups: + * + * **Reading the capture.** [[Session.id]], [[Session.name]] and + * [[Session.attached]] read what this capture stored about the session, and + * [[Session.server]] is the [[Server]] it lives on. The id is stable, the name + * is state a user may change at any time, and a rename or an attach after the + * capture does not show in it. + * + * [[Session.info]], [[Session.id]], [[Session.name]], [[Session.attached]], + * [[Session.server]] and [[Session.asJava]] + * + * **Windows and panes.** [[Session.windows]] lists the session's windows in + * tmux's order as a `Vector`, and [[Session.activeWindow]] and + * [[Session.activePane]] are the window tmux had active and the active pane of + * that window, each an `Option`. All three are pure reads. + * [[Session.selectWindow]] makes a window the active one, + * [[Session.nextWindow]] and [[Session.previousWindow]] step to a neighbour + * with wrap-around, and [[Session.lastWindow]] goes back to the one that was + * active before. + * + * [[Session.windows]], [[Session.activeWindow]], [[Session.activePane]], + * [[Session.selectWindow]], [[Session.nextWindow]], [[Session.previousWindow]] + * and [[Session.lastWindow]] + * + * **Changing the session.** [[Session.newWindow]] creates a window from a name, + * a callback on a builder, or a `WindowSpec`, and returns the window tmux made. + * [[Session.rename]] returns a replacement capture, because this handle keeps + * its original state. [[Session.setHistoryLimit]] sets the scrollback retained + * by panes created in this session afterwards. [[Session.detachClients]] leaves + * the session running, and [[Session.kill]] takes every window with it. + * + * [[Session.newWindow]], [[Session.rename]], [[Session.setHistoryLimit]], + * [[Session.detachClients]] and [[Session.kill]] + * + * **Options, environment, and hooks.** These reach what is set on this session + * alone: its own options, its own environment, which a process started in it is + * given on top of the server's, and its own hooks. The [[Server]] holds the + * global ones, which a session inherits. + * + * [[Session.options]], [[Session.environment]] and [[Session.hooks]] + * + * **Formats and refreshing.** [[Session.expand]] expands a tmux format in this + * session's context, and [[Session.refresh]] takes a new capture to see the + * session as it is now. It leaves this handle unchanged and returns the new + * one, and throws if the session is gone from a server that still answers. + * + * [[Session.expand]] and [[Session.refresh]] */ opaque type Session = JavaSession diff --git a/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Window.scala b/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Window.scala index 55b237969..b28c573dc 100644 --- a/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Window.scala +++ b/libtmux-scala/src/main/scala/io/github/libtmux/scaladsl/Window.scala @@ -8,6 +8,76 @@ import io.github.libtmux.scaladsl.query.Expr * session has more than one placement. Every operation beyond equality is an * extension, generated from the operation catalog or handwritten where the * catalog marks it `WAIT`, `STREAM` or `LIFECYCLE`. + * + * A pure read of the capture issues no command; every other operation asks tmux + * now, blocking the calling thread. + * + * # What is on here + * + * The operations fall into a few groups: + * + * **Reading the capture.** [[Window.id]], [[Window.index]], [[Window.context]], + * [[Window.name]], [[Window.active]], [[Window.linked]], [[Window.size]] and + * [[Window.layout]] read what this capture stored about the window, and + * [[Window.server]] and [[Window.session]] are the [[Server]] and [[Session]] + * it sits in. The id names the underlying window and the index names this link, + * so a window linked into two sessions has one id and two handles. A rename or + * a resize after the capture does not show in it. + * + * [[Window.info]], [[Window.id]], [[Window.index]], [[Window.context]], + * [[Window.name]], [[Window.active]], [[Window.linked]], [[Window.size]], + * [[Window.layout]], [[Window.server]], [[Window.session]] and + * [[Window.asJava]] + * + * **Panes.** [[Window.panes]] lists this link's panes in tmux's order as a + * `Vector`, and [[Window.activePane]] is the one tmux had active, an `Option`; + * both are pure reads. [[Window.split]] divides the active pane in half, from a + * callback on a builder or a `SplitSpec`, and returns the pane that appeared. + * It throws when the spec asks for something this server does not have. + * + * [[Window.panes]], [[Window.activePane]] and [[Window.split]] + * + * **Layout and size.** [[Window.selectLayout]] rearranges the panes into one of + * tmux's built-in layouts, [[Window.nextLayout]] and [[Window.previousLayout]] + * step to a neighbour, and [[Window.rotate]] rotates the panes. Read the + * arrangement from [[Window.layout]] and hand it back to + * [[Window.applyLayout]], which checks a string before tmux sees it. + * [[Window.resizeTo]] takes terminal cells. [[Window.synchronizePanes]] copies + * input typed into one pane into every pane of the window until + * [[Window.stopSynchronizingPanes]]. + * + * [[Window.selectLayout]], [[Window.nextLayout]], [[Window.previousLayout]], + * [[Window.applyLayout]], [[Window.rotate]], [[Window.resizeTo]], + * [[Window.synchronizePanes]] and [[Window.stopSynchronizingPanes]] + * + * **Moving and linking.** [[Window.select]] makes the window the active one in + * its session. [[Window.linkTo]] links it into another session so one window + * sits in both, [[Window.moveTo]] moves it to another session or to an exact + * index there, and [[Window.unlink]] removes one link and throws when it is the + * window's only one, which tmux refuses to remove. + * + * [[Window.select]], [[Window.linkTo]], [[Window.moveTo]] and [[Window.unlink]] + * + * **Changing the window.** [[Window.rename]] returns a replacement capture, + * because this handle keeps its original state. [[Window.respawn]] kills what + * is running in the window and starts it again, [[Window.displayPopup]] shows a + * popup over it and needs an attached client, and [[Window.kill]] closes it. + * + * [[Window.rename]], [[Window.respawn]], [[Window.displayPopup]] and + * [[Window.kill]] + * + * **Options and hooks.** [[Window.options]] and [[Window.hooks]] reach what is + * set on this window alone, and every link to the window shares them. + * + * [[Window.options]] and [[Window.hooks]] + * + * **Formats and refreshing.** [[Window.expand]] expands a tmux format in this + * window's context, and [[Window.refresh]] takes a new capture to see the + * window as it is now. It leaves this handle unchanged and returns the new one, + * and throws if the window is no longer linked here, from a server that still + * answers. + * + * [[Window.expand]] and [[Window.refresh]] */ opaque type Window = JavaWindow diff --git a/libtmux/src/main/java/io/github/libtmux/Pane.java b/libtmux/src/main/java/io/github/libtmux/Pane.java index 5356fc9ca..a40b3c12d 100644 --- a/libtmux/src/main/java/io/github/libtmux/Pane.java +++ b/libtmux/src/main/java/io/github/libtmux/Pane.java @@ -40,6 +40,95 @@ * *

A method named for a captured field returns what {@link #info()} holds and does no I/O; * {@link #refresh()} reads again. Every other method asks tmux now. + * + *

What is on here

+ * + *

The methods fall into a few groups: + * + *

Reading the capture. Read what this capture stored about the pane, and the + * {@link Server} and {@link Window} it sits in, with no call to tmux. The id is stable and the index + * is state, since panes renumber as neighbours come and go. {@link #floating} is empty when the + * running tmux cannot say, which before 3.7 is always, and {@link #pid} is empty when tmux reported no + * process. {@link #currentPath} throws {@link LibTmuxException} when this JVM cannot represent the + * directory's name; {@link #currentPathText} is what tmux reported and never throws. + * + *

{@link #info}, {@link #id}, {@link #index}, {@link #active}, {@link #currentCommand}, + * {@link #floating}, {@link #size}, {@link #position}, {@link #edges}, {@link #title}, + * {@link #currentPath}, {@link #currentPathText}, {@link #pid}, {@link #server()}, {@link #window()} + * + *

Sending input. {@link #send} types keys without pressing Enter and + * {@link #sendLine} presses it, which is how a command gets run. {@link #sendKeys} resolves each entry + * through tmux's key table and types an unknown name as text; {@link #sendLiteral} types every entry + * as the characters it spells, so {@code C-c} is three characters. {@link #paste} delivers text as one + * block through a private buffer that is removed afterwards, throws {@link IllegalArgumentException} + * for text containing NUL, and throws {@link io.github.libtmux.exception.UnsupportedFeatureException} + * before tmux 3.4. {@link #noteTyped} tells a later wait about text that reached the pane without + * passing through this handle. + * + *

+ * + *

Reading output. {@link #capture()} returns the visible content, one element per + * line, read from tmux now rather than from the capture. Hand it a builder callback or a + * {@link CaptureSpec}, which may be reused across panes, to read part of the history; that throws + * {@link io.github.libtmux.exception.UnsupportedFeatureException} when the spec asks for something + * this server does not have. {@link #pipeTo} sends everything the pane prints to a shell command + * until {@link #stopPiping}. + * + *

{@link #capture}, {@link #pipeTo}, {@link #stopPiping}, {@link #clearHistory} + * + *

Running and waiting. {@link #run} runs a shell command to its end and answers + * with its exit status and output, and throws {@link IllegalStateException} when the pane is not + * running a POSIX shell. Reach for it first when the command is yours. When it is not, the waits poll + * the screen or the pane's state on a timer and answer with why they ended, which tells text that + * appeared from text that was already there; a pane killed mid-wait ends {@link #watchText} as an + * answer rather than an exception. A signal on a {@link Server#channel} is the one exact wait. + * {@link #dead} reads fresh whether the pane's process has exited, and throws + * {@link TargetGoneException} when the pane is gone from a server that still answers. + * + *

+ * + *

Splitting and arranging. Splitting divides this pane in half, from a builder + * callback or a reusable {@link SplitSpec}, and returns the pane that appeared. Break the pane out + * into a window of its own, join it into another window, swap it with another pane, resize it by a + * number of cells in one direction or to exact dimensions, or make it the active pane. An unnamed + * {@link #breakOut()} throws {@link io.github.libtmux.exception.UnsupportedFeatureException} on exact + * tmux 3.7, which a named break or 3.7a avoids. + * + *

+ * + *

Modes. Put the pane into copy mode, read live which mode it is in, as an + * {@link Optional} that is empty when it is showing its program, or leave whichever mode it is in. + * + *

{@link #copyMode}, {@link #mode}, {@link #exitMode} + * + *

Changing the pane. Retitle it, which returns a replacement capture because this + * handle keeps its original state; kill what runs here and start the pane's default command, a + * command in a directory, or a command you give; or close it. + * + *

{@link #retitle}, {@link #respawn}, {@link #respawnIn}, {@link #kill} + * + *

Options and hooks. These reach what is set on this pane alone. + * + *

{@link #options}, {@link #hooks} + * + *

Formats and refreshing. Expand a tmux format, or read several named variables, + * in this pane's context; or take a new capture to see the pane as it is now. Refreshing leaves this + * handle unchanged and returns the new one, and throws {@link TargetGoneException} if the pane is + * gone from a server that still answers. + * + *

{@link #expand}, {@link #variables}, {@link #refresh} */ public final class Pane { diff --git a/libtmux/src/main/java/io/github/libtmux/Window.java b/libtmux/src/main/java/io/github/libtmux/Window.java index 204e8ca35..65609ba8c 100644 --- a/libtmux/src/main/java/io/github/libtmux/Window.java +++ b/libtmux/src/main/java/io/github/libtmux/Window.java @@ -27,6 +27,69 @@ * *

A method named for a captured field returns what {@link #info()} holds and does no I/O; * {@link #refresh()} reads again. Every other method asks tmux now. + * + *

What is on here

+ * + *

The methods fall into a few groups: + * + *

Reading the capture. Read what this capture stored about the window, and the + * {@link Server} and {@link Session} it sits in, with no call to tmux. The id names the underlying + * window and the index names this link, so a window linked into two sessions has one id and two + * handles. A rename or a resize after the capture does not show in it. + * + *

{@link #info}, {@link #id}, {@link #index}, {@link #context}, {@link #name}, {@link #active}, + * {@link #linked}, {@link #size}, {@link #layout}, {@link #server()}, {@link #session()} + * + *

Panes. List this link's panes in tmux's order, or ask for the one tmux had + * active, as an {@link Optional}; both are pure reads of the capture and issue no command. Splitting + * divides the active pane in half, from a callback that fills in a builder or from a + * {@link SplitSpec} that can be reused across windows, and returns the pane that appeared. It throws + * {@link io.github.libtmux.exception.UnsupportedFeatureException} when the spec asks for something + * this server does not have. + * + *

+ * + *

Layout and size. Rearrange the panes into one of tmux's built-in layouts, step + * to the next or previous one, or rotate them. Read the arrangement with {@link #layout()} and hand it + * back to {@link #applyLayout}, which checks the string before tmux sees it and throws + * {@link IllegalArgumentException} for one tmux did not write. Resizing takes terminal cells. + * Synchronizing panes copies input typed into one pane into every pane of the window until it is + * stopped. + * + *

+ * + *

Moving and linking. Make the window the active one in its session, link it + * into another session so one window sits in both, move it to another session or to an exact index + * there, or remove one link. {@link #unlink} throws {@link LibTmuxException} when this is the + * window's only link, which tmux refuses to remove. + * + *

{@link #select}, {@link #linkTo}, {@link #unlink}, {@link #moveTo} + * + *

Changing the window. Rename it, which returns a replacement capture because + * this handle keeps its original state; kill what is running in it and start it again; show a popup + * over it, which needs an attached client; or close it. + * + *

{@link #rename}, {@link #respawn}, {@link #displayPopup}, {@link #kill} + * + *

Options and hooks. These reach what is set on this window alone, and every link + * to the window shares them. + * + *

{@link #options}, {@link #hooks} + * + *

Formats and refreshing. Expand a tmux format in this window's context, or take + * a new capture to see the window as it is now. Refreshing leaves this handle unchanged and returns + * the new one, and throws {@link TargetGoneException} if the window is no longer linked here, from a + * server that still answers. + * + *

{@link #expand}, {@link #refresh} */ public final class Window {