Core Library0.xAPI Reference

Choose documentation 3

latest

Current version

latest
English

Early release libtmux is released, and its APIs may still change between releases. This site's structure and URLs may change too.

Go API

method libtmux-go latest

Pane.SendKeys

SendKeys invokes tmux send-keys with the receiver's exact linked session-window-pane target. This is tmux key input, not shell execution: Literal only changes tmux key parsing, and any delivered text may still be interpreted by the pane's application. KeyName routes through a client's key table instead of delivering to the pane.

Source and package
Qualified name
tmux.Pane.SendKeys
Package
tmux
Declared in
Pane
Distribution
github.com/libtmux/libtmux-go/tmux
Source
tmux/pane_input.go
Other languages
Perlmethod Erlang PowerShell Julia Elixir Haskell Common LispPythonRubyLuaTypeScriptRust Java C#C++SwiftKotlinScalaOCaml F# Clojure

Description#

KeyName and TargetClient require tmux 3.4 and follow UnsupportedPolicy.

Stderr from either the Command send or the separate Enter becomes a redacted CommandError: Command may carry a caller's secret, so only tmux's exit code is retained. A nonzero exit with empty stderr is success, as for every mutation (see the package documentation). Transport and context errors are delivery-ambiguous, including between Command and Enter.

Examples#

Send literal text followed by Enter to a pane running cat, then wait for the text to appear. Literal controls tmux key parsing; it does not prevent the pane's application from interpreting input. SendKeys returning does not establish that the application has processed the text. Use Go 1.26 or newer and tmux 3.3a or newer on a Unix system, with tmux and cat on PATH. In a new directory, create a module and add the library from the Go module proxy:

Terminal window
$ go mod init example.com/libtmux-api && \
go get github.com/libtmux/libtmux-go@latest

Save this complete example as example_test.go. It creates a private temporary socket and stops its server before removing the directory. Cleanup failure fails the example and retains the socket directory. View source

package tmux_test
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"slices"
"time"
"github.com/libtmux/libtmux-go/tmux"
)
// Send literal text followed by Enter to a pane running cat, then wait for
// the text to appear. Literal controls tmux key parsing; it does not prevent
// the pane's application from interpreting input. SendKeys returning does
// not establish that the application has processed the text.
func ExamplePane_SendKeys_complete() {
run := func() (runErr error) {
directory, err := os.MkdirTemp("", "libtmux-go-api-")
if err != nil {
return fmt.Errorf("create socket directory: %w", err)
}
server, err := tmux.NewServer(tmux.ServerOptions{
SocketPath: filepath.Join(directory, "tmux.sock"),
ConfigFile: "/dev/null",
})
if err != nil {
return errors.Join(err, os.RemoveAll(directory))
}
defer func() {
// Cleanup has its own deadline because the operation may have timed out.
cleanup, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := server.Kill(cleanup); err != nil && !errors.Is(err, tmux.ErrNoServer) {
runErr = errors.Join(runErr, fmt.Errorf("stop server at %s: %w", directory, err))
return
}
runErr = errors.Join(runErr, os.RemoveAll(directory))
}()
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
session, err := server.NewSession(ctx, tmux.NewSessionRequest{
Name: "work", WindowName: "editor", Command: "cat", Width: 100, Height: 30,
})
if err != nil {
return fmt.Errorf("create session: %w", err)
}
pane, err := session.ResolveActivePane(ctx)
if err != nil {
return fmt.Errorf("resolve pane: %w", err)
}
text := "api input"
if err := pane.SendKeys(ctx, tmux.SendKeysRequest{Command: &text, Literal: true}); err != nil {
return fmt.Errorf("send literal input: %w", err)
}
// Capture is a point-in-time read, so wait for a complete matching line.
ticker := time.NewTicker(10 * time.Millisecond)
defer ticker.Stop()
for {
lines, err := pane.Capture(ctx, tmux.CapturePaneRequest{
Start: tmux.CaptureBoundary, End: tmux.CaptureBoundary,
})
if err != nil {
return fmt.Errorf("capture pane: %w", err)
}
if slices.Contains(lines, "api input") {
fmt.Println("captured: api input")
break
}
select {
case <-ctx.Done():
return fmt.Errorf("wait for pane text: %w", ctx.Err())
case <-ticker.C:
}
}
return nil
}
if err := run(); err != nil {
panic(err)
}
// Output:
// captured: api input
}

Run the saved file. Go checks the Output comment and fails on different output or an operation or cleanup error:

Terminal window
$ go test -count=1 -v example_test.go

tmux command#

The tmux commands behind SendKeys.

tmux C API#

The C declarations in tmux that implement these commands.

Guides#

Pages that discuss SendKeys.

Guides

In other ports#

Send keystrokes to a pane

Equivalents of Send keystrokes to a pane in other languages
Language Equivalent
Python libtmux.Pane.send_keys
Ruby LibTmux::Pane#send_keys
Lua libtmux.Pane:send_keys
Erlang tmux_pane:send_keys/2
Haskell No public Haskell equivalent is implemented; the current modules expose scalar values and version parsing.
Common Lisp libtmux:send-keys
TypeScript pane.Pane.sendKeys
Rust pane.Pane.send_keys
Java no direct equivalent; Pane.paste writes a buffer instead
Clojure libtmux.core/send-keys!
Kotlin io.github.libtmux.kotlin.Pane.sendKeys
Scala io.github.libtmux.scaladsl.Pane.sendKeys
C# LibTmux.Pane.SendKeysAsync
C++ libtmux::Pane::send_text
Swift Server.sendKeys(_:to:literally:)
OCaml Libtmux_unix.Client.send_keys
Perl LibTmux::Server::send_keys Explicit Server operation. Captured entities remain local observations; use a new snapshot to observe changes.

No equivalent is recorded in PowerShell, Julia, Elixir or F#.

Esc

Type to search.

Reference previewOpen reference