# Attach and send keys

Source: https://libtmux.org/en/swift/latest/examples/attach-and-send-keys/

> Get a session handle, send a command to a pane, and capture output.

Get a session handle, send a command to a pane, and capture output. These
examples use libtmux from your program; to attach your terminal interactively,
see [Attaching to tmux](https://libtmux.org/en/swift/latest/guides/attaching-to-tmux/).

The examples include setup, error handling, and cleanup. [Source and
verification](https://libtmux.org/en/swift/latest/examples/attach-and-send-keys/#where-this-comes-from) identifies their files and checks.

```swift file="Examples/Sources/ExampleCode/Changing.swift"
// The examples in the README's "Change what is there" section.

import LibTmux

public func buildASessionByHand(_ server: Server) async throws -> Pane {
    let session = try await server.newSession(named: "work", windowName: "editor")
    _ = try await server.setOption("@purpose", to: "development", scope: .session(session))
    let logs = try await server.newWindow(in: session, named: "logs").window
    let pane = try await server.splitWindow(logs, direction: .right)
    try await server.run("tail -f /tmp/build.log", in: pane)
    return pane
}

public func readBackWhatAPanePrinted(_ server: Server, _ pane: Pane) async throws -> [String] {
    let lines = try await server.capture(pane)
    print(lines.suffix(5).joined(separator: "\n"))
    return lines
}

public func spendOneProcessOnAllOfIt(_ server: Server) async throws {
    var plan = TmuxCommandList()
    for name in ["edit", "test", "logs"] {
        plan = plan.then("new-window", ["-d", "-n", name])
    }
    _ = try await server.run(plan)
}
```

## Finding an existing session instead

For a script that runs repeatedly, look up a session before creating it.
[Attaching to
tmux](https://libtmux.org/en/swift/latest/guides/attaching-to-tmux/#finding-a-session-instead-of-always-creating-one)
shows that pattern, and [Filtering and querying, in
practice](https://libtmux.org/en/swift/latest/guides/querying-and-filtering/) covers absent and ambiguous matches.

## Where this comes from

**Source:** [`Examples/Sources/ExampleCode/Changing.swift`](<https://github.com/libtmux/libtmux-swift/blob/6b51d1408b55b8583825c6595405d08e728674bf/Examples/Sources/ExampleCode/Changing.swift>)

**In this page:** read whole from the file

**Checked by:** matched against the README's "Change what is there" section by
[`Scripts/check_examples.py`](<https://github.com/libtmux/libtmux-swift/blob/6b51d1408b55b8583825c6595405d08e728674bf/Scripts/check_examples.py>); compiled and run through the package's public
products by `swift test --package-path Examples`

### Source inclusion

A `file="..."` fence reads the named source during the site build. Hand-quoted
excerpts are copies; their source files and regions are listed above.
